mirror of
https://github.com/HappyTanuki/BumbleCee.git
synced 2025-12-18 05:03:28 +00:00
스킵 구현
This commit is contained in:
1591
DPP-master/include/dpp/appcommand.h
Normal file
1591
DPP-master/include/dpp/appcommand.h
Normal file
File diff suppressed because it is too large
Load Diff
470
DPP-master/include/dpp/application.h
Normal file
470
DPP-master/include/dpp/application.h
Normal file
@@ -0,0 +1,470 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/permissions.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
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<std::string> 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<team_member> members;
|
||||
|
||||
/**
|
||||
* @brief The name of the team.
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* @brief The user id of the current team owner.
|
||||
*/
|
||||
snowflake owner_user_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The application class represents details of a bot application
|
||||
*/
|
||||
class DPP_EXPORT application : public managed, public json_interface<application> {
|
||||
protected:
|
||||
friend struct json_interface<application>;
|
||||
|
||||
/** 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<std::string> 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: Array of redirect URIs for the app.
|
||||
*/
|
||||
std::vector<std::string> 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 Up to 5 tags describing the content and functionality of the application.
|
||||
*/
|
||||
std::vector<std::string> tags;
|
||||
|
||||
/**
|
||||
* @brief Settings for the application's default in-app authorization link, if enabled.
|
||||
*/
|
||||
application_install_params install_params;
|
||||
|
||||
/**
|
||||
* @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<std::string> 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<snowflake, application> application_map;
|
||||
|
||||
} // namespace dpp
|
||||
481
DPP-master/include/dpp/auditlog.h
Normal file
481
DPP-master/include/dpp/auditlog.h
Normal file
@@ -0,0 +1,481 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <optional>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
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<audit_entry> {
|
||||
protected:
|
||||
friend struct json_interface<audit_entry>;
|
||||
|
||||
/** 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<audit_change> 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<audit_extra> 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<auditlog> {
|
||||
protected:
|
||||
friend struct json_interface<auditlog>;
|
||||
|
||||
/** 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<audit_entry> entries;
|
||||
|
||||
/** Constructor */
|
||||
auditlog() = default;
|
||||
|
||||
/** Destructor */
|
||||
virtual ~auditlog() = default;
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
403
DPP-master/include/dpp/automod.h
Normal file
403
DPP-master/include/dpp/automod.h
Normal file
@@ -0,0 +1,403 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
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<automod_metadata> {
|
||||
protected:
|
||||
friend struct json_interface<automod_metadata>;
|
||||
|
||||
/**
|
||||
* @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* | <u><b>cat</b></u>ch, <u><b>Cat</b></u>apult, <u><b>CAt</b></u>tLE |
|
||||
* | the mat* | <u><b>the mat</b></u>rix |
|
||||
*
|
||||
* Suffix - word must end with the keyword
|
||||
*
|
||||
* | keyword | matches |
|
||||
* |----------|--------------------------|
|
||||
* | *cat | wild<u><b>cat</b></u>, copy<u><b>Cat</b></u> |
|
||||
* | *the mat | brea<u><b>the mat</b></u> |
|
||||
*
|
||||
* Anywhere - keyword can appear anywhere in the content
|
||||
*
|
||||
* | keyword | matches |
|
||||
* |-----------|-----------------------------|
|
||||
* | \*cat* | lo<u><b>cat</b></u>ion, edu<u><b>Cat</b></u>ion |
|
||||
* | \*the mat* | brea<u><b>the mat</b></u>ter |
|
||||
*
|
||||
* Whole Word - keyword is a full word or phrase and must be surrounded by whitespace at the beginning and end
|
||||
*
|
||||
* | keyword | matches |
|
||||
* |---------|-------------|
|
||||
* | cat | <u><b>Cat</b></u> |
|
||||
* | the mat | <u><b>the mat</b></u> |
|
||||
*
|
||||
*/
|
||||
std::vector<std::string> 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<std::string> regex_patterns;
|
||||
|
||||
/**
|
||||
* @brief Preset keyword list types to moderate
|
||||
* @see automod_preset_type
|
||||
*/
|
||||
std::vector<automod_preset_type> 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* | <u><b>cat</b></u>ch, <u><b>Cat</b></u>apult, <u><b>CAt</b></u>tLE |
|
||||
* | the mat* | <u><b>the mat</b></u>rix |
|
||||
*
|
||||
* Suffix - word must end with the keyword
|
||||
*
|
||||
* | keyword | matches |
|
||||
* |----------|--------------------------|
|
||||
* | *cat | wild<u><b>cat</b></u>, copy<u><b>Cat</b></u> |
|
||||
* | *the mat | brea<u><b>the mat</b></u> |
|
||||
*
|
||||
* Anywhere - keyword can appear anywhere in the content
|
||||
*
|
||||
* | keyword | matches |
|
||||
* |-----------|-----------------------------|
|
||||
* | \*cat* | lo<u><b>cat</b></u>ion, edu<u><b>Cat</b></u>ion |
|
||||
* | \*the mat* | brea<u><b>the mat</b></u>ter |
|
||||
*
|
||||
* Whole Word - keyword is a full word or phrase and must be surrounded by whitespace at the beginning and end
|
||||
*
|
||||
* | keyword | matches |
|
||||
* |---------|-------------|
|
||||
* | cat | <u><b>Cat</b></u> |
|
||||
* | the mat | <u><b>the mat</b></u> |
|
||||
*
|
||||
*/
|
||||
std::vector<std::string> 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<automod_action> {
|
||||
protected:
|
||||
friend struct json_interface<automod_action>;
|
||||
|
||||
/**
|
||||
* @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<automod_rule> {
|
||||
protected:
|
||||
friend struct json_interface<automod_rule>;
|
||||
|
||||
/**
|
||||
* @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<automod_action> 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<snowflake> exempt_roles;
|
||||
|
||||
/**
|
||||
* @brief the channel ids that should not be affected by the rule (Maximum of 50)
|
||||
*/
|
||||
std::vector<snowflake> 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<snowflake, automod_rule> automod_rule_map;
|
||||
|
||||
} // namespace dpp
|
||||
69
DPP-master/include/dpp/ban.h
Normal file
69
DPP-master/include/dpp/ban.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief The ban class represents a ban on a guild.
|
||||
*
|
||||
*/
|
||||
class DPP_EXPORT ban : public json_interface<ban> {
|
||||
protected:
|
||||
friend struct json_interface<ban>;
|
||||
|
||||
/** 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<snowflake, ban> ban_map;
|
||||
|
||||
} // namespace dpp
|
||||
274
DPP-master/include/dpp/cache.h
Normal file
274
DPP-master/include/dpp/cache.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
extern DPP_EXPORT std::unordered_map<managed*, time_t> 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 T> 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<snowflake, T*>* 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<snowflake, T*>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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<std::mutex> 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<std::mutex> 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<guild>* c = dpp::get_guild_cache();
|
||||
* std::unordered_map<snowflake, guild*>& 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<snowflake, T*>* n = new std::unordered_map<snowflake, T*>;
|
||||
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<class type> * 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);
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
882
DPP-master/include/dpp/channel.h
Normal file
882
DPP-master/include/dpp/channel.h
Normal file
@@ -0,0 +1,882 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <dpp/voicestate.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/permissions.h>
|
||||
#include <dpp/json_interface.h>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
|
||||
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<forum_tag> {
|
||||
protected:
|
||||
friend struct json_interface<forum_tag>;
|
||||
|
||||
/**
|
||||
* @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<std::monostate, snowflake, std::string> 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<channel> {
|
||||
protected:
|
||||
friend struct json_interface<channel>;
|
||||
|
||||
/** 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<snowflake> recipients;
|
||||
|
||||
/**
|
||||
* @brief Permission overwrites to apply to base permissions.
|
||||
*/
|
||||
std::vector<permission_overwrite> permission_overwrites;
|
||||
|
||||
/**
|
||||
* @brief A set of tags that can be used in a forum or media channel.
|
||||
*/
|
||||
std::vector<forum_tag> 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<std::monostate, snowflake, std::string> 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
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @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<snowflake, class guild_member*> 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<snowflake, voicestate> The voice members of the channel
|
||||
*/
|
||||
std::map<snowflake, voicestate> 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<snowflake, channel> channel_map;
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
3713
DPP-master/include/dpp/cluster.h
Normal file
3713
DPP-master/include/dpp/cluster.h
Normal file
File diff suppressed because it is too large
Load Diff
2472
DPP-master/include/dpp/cluster_coro_calls.h
Normal file
2472
DPP-master/include/dpp/cluster_coro_calls.h
Normal file
File diff suppressed because it is too large
Load Diff
3037
DPP-master/include/dpp/cluster_sync_calls.h
Normal file
3037
DPP-master/include/dpp/cluster_sync_calls.h
Normal file
File diff suppressed because it is too large
Load Diff
473
DPP-master/include/dpp/collector.h
Normal file
473
DPP-master/include/dpp/collector.h
Normal file
@@ -0,0 +1,473 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/timed_listener.h>
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
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 T, class C> class collector
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* @brief Owning cluster.
|
||||
*/
|
||||
class cluster* owner;
|
||||
private:
|
||||
/**
|
||||
* @brief Timed listener.
|
||||
*/
|
||||
timed_listener<event_router_t<T>, std::function<void(const T&)>>* tl;
|
||||
|
||||
/**
|
||||
* @brief Stored list.
|
||||
*/
|
||||
std::vector<C> 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<T> & event) : owner(cl), triggered(false) {
|
||||
std::function<void(const T&)> f = [this](const T& event) {
|
||||
const C* v = filter(event);
|
||||
if (v) {
|
||||
stored.push_back(*v);
|
||||
}
|
||||
};
|
||||
tl = new dpp::timed_listener<event_router_t<T>, std::function<void(const T&)>>(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<C>& 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<dpp::channel_create_t, dpp::channel> channel_collector_t;
|
||||
|
||||
/**
|
||||
* @brief Template type for base class of thread collector
|
||||
*/
|
||||
typedef dpp::collector<dpp::thread_create_t, dpp::thread> thread_collector_t;
|
||||
|
||||
/**
|
||||
* @brief Template type for base class of role collector
|
||||
*/
|
||||
typedef dpp::collector<dpp::guild_role_create_t, dpp::role> role_collector_t;
|
||||
|
||||
/**
|
||||
* @brief Template type for base class of scheduled event collector
|
||||
*/
|
||||
typedef dpp::collector<dpp::guild_scheduled_event_create_t, dpp::scheduled_event> scheduled_event_collector_t;
|
||||
|
||||
/**
|
||||
* @brief Template type for base class of message collector
|
||||
*/
|
||||
typedef dpp::collector<dpp::message_create_t, dpp::message> message_collector_t;
|
||||
|
||||
/**
|
||||
* @brief Template type for base class of message reaction collector
|
||||
*/
|
||||
typedef dpp::collector<dpp::message_reaction_add_t, dpp::collected_reaction> 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<dpp::message>& 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<dpp::collected_reaction>& 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<dpp::channel>& 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<dpp::thread>& 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<dpp::role>& 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<dpp::scheduled_event>& 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;
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
745
DPP-master/include/dpp/colors.h
Normal file
745
DPP-master/include/dpp/colors.h
Normal file
@@ -0,0 +1,745 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <cstdint>
|
||||
|
||||
/**
|
||||
* @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
|
||||
428
DPP-master/include/dpp/commandhandler.h
Normal file
428
DPP-master/include/dpp/commandhandler.h
Normal file
@@ -0,0 +1,428 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/misc-enum.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/role.h>
|
||||
#include <dpp/appcommand.h>
|
||||
#include <dpp/dispatcher.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/event_router.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <variant>
|
||||
|
||||
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<std::monostate, std::string, dpp::role, dpp::channel, dpp::resolved_user, int64_t, bool, double> 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<command_value, std::string> 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<command_value, std::string> &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<std::pair<std::string, param_info>> 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<std::pair<std::string, command_parameter>> 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_create_t> message_event;
|
||||
|
||||
/**
|
||||
* @brief Copy of the underlying interaction_create_t event, if it was an interaction create event
|
||||
*/
|
||||
std::optional<interaction_create_t> 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<void(const std::string&, const parameter_list_t&, command_source)> 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 commandhandler {
|
||||
private:
|
||||
/**
|
||||
* @brief List of guild commands to bulk register
|
||||
*/
|
||||
std::map<dpp::snowflake, std::vector<dpp::slashcommand>> bulk_registration_list_guild;
|
||||
|
||||
/**
|
||||
* @brief List of global commands to bulk register
|
||||
*/
|
||||
std::vector<dpp::slashcommand> bulk_registration_list_global;
|
||||
public:
|
||||
/**
|
||||
* @brief Commands in the handler
|
||||
*/
|
||||
std::unordered_map<std::string, command_info_t> commands;
|
||||
|
||||
/**
|
||||
* @brief Valid prefixes
|
||||
*/
|
||||
std::vector<std::string> 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());
|
||||
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
28
DPP-master/include/dpp/coro.h
Normal file
28
DPP-master/include/dpp/coro.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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/async.h"
|
||||
#include "coro/coroutine.h"
|
||||
#include "coro/job.h"
|
||||
#include "coro/task.h"
|
||||
#include "coro/when_any.h"
|
||||
523
DPP-master/include/dpp/coro/async.h
Normal file
523
DPP-master/include/dpp/coro/async.h
Normal file
@@ -0,0 +1,523 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/utility.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
struct async_dummy {
|
||||
int* dummy_shared_state = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef DPP_CORO
|
||||
|
||||
#include "coro.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Empty struct used for overload resolution.
|
||||
*/
|
||||
struct empty_tag_t{};
|
||||
|
||||
namespace async {
|
||||
|
||||
/**
|
||||
* @brief Represents the step an std::async is at.
|
||||
*/
|
||||
enum class state_t {
|
||||
/**
|
||||
* @brief Request was sent but not co_await-ed. handle is nullptr, result_storage is not constructed.
|
||||
*/
|
||||
sent,
|
||||
|
||||
/**
|
||||
* @brief Request was co_await-ed. handle is valid, result_storage is not constructed.
|
||||
*/
|
||||
waiting,
|
||||
|
||||
/**
|
||||
* @brief Request was completed. handle is unknown, result_storage is valid.
|
||||
*/
|
||||
done,
|
||||
|
||||
/**
|
||||
* @brief Request was never co_await-ed.
|
||||
*/
|
||||
dangling
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief State of the async and its callback.
|
||||
*
|
||||
* Defined outside of dpp::async because this seems to work better with Intellisense.
|
||||
*/
|
||||
template <typename R>
|
||||
struct async_callback_data {
|
||||
/**
|
||||
* @brief Number of references to this callback state.
|
||||
*/
|
||||
std::atomic<int> ref_count{1};
|
||||
|
||||
/**
|
||||
* @brief State of the awaitable and the API callback
|
||||
*/
|
||||
std::atomic<state_t> state = state_t::sent;
|
||||
|
||||
/**
|
||||
* @brief The stored result of the API call, stored as an array of bytes to directly construct in place
|
||||
*/
|
||||
alignas(R) std::array<std::byte, sizeof(R)> result_storage;
|
||||
|
||||
/**
|
||||
* @brief Handle to the coroutine co_await-ing on this API call
|
||||
*
|
||||
* @see <a href="https://en.cppreference.com/w/cpp/coroutine/coroutine_handle">std::coroutine_handle</a>
|
||||
*/
|
||||
std_coroutine::coroutine_handle<> coro_handle = nullptr;
|
||||
|
||||
/**
|
||||
* @brief Convenience function to construct the result in the storage and initialize its lifetime
|
||||
*
|
||||
* @warning This is only a convenience function, ONLY CALL THIS IN THE CALLBACK, before setting state to done.
|
||||
*/
|
||||
template <typename... Ts>
|
||||
void construct_result(Ts&&... ts) {
|
||||
// Standard-compliant type punning yay
|
||||
std::construct_at<R>(reinterpret_cast<R *>(result_storage.data()), std::forward<Ts>(ts)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*
|
||||
* Also destroys the result if present.
|
||||
*/
|
||||
~async_callback_data() {
|
||||
if (state.load() == state_t::done) {
|
||||
std::destroy_at<R>(reinterpret_cast<R *>(result_storage.data()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base class of dpp::async.
|
||||
*
|
||||
* @warning This class should not be used directly by a user, use dpp::async instead.
|
||||
* @note This class contains all the functions used internally by co_await. It is intentionally opaque and a private base of dpp::async so a user cannot call await_suspend and await_resume directly.
|
||||
*/
|
||||
template <typename R>
|
||||
class async_base {
|
||||
/**
|
||||
* @brief Ref-counted callback, contains the callback logic and manages the lifetime of the callback data over multiple threads.
|
||||
*/
|
||||
struct shared_callback {
|
||||
/**
|
||||
* @brief Self-managed ref-counted pointer to the state data
|
||||
*/
|
||||
async_callback_data<R> *state = new async_callback_data<R>;
|
||||
|
||||
/**
|
||||
* @brief Callback function.
|
||||
*
|
||||
* Constructs the callback data, and if the coroutine was awaiting, resume it
|
||||
* @param cback The result of the API call.
|
||||
* @tparam V Forwarding reference convertible to R
|
||||
*/
|
||||
template <std::convertible_to<R> V>
|
||||
void operator()(V &&cback) const {
|
||||
state->construct_result(std::forward<V>(cback));
|
||||
if (auto previous_state = state->state.exchange(state_t::done); previous_state == state_t::waiting) {
|
||||
state->coro_handle.resume();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main constructor, allocates a new callback_state object.
|
||||
*/
|
||||
shared_callback() = default;
|
||||
|
||||
/**
|
||||
* @brief Empty constructor, holds no state.
|
||||
*/
|
||||
explicit shared_callback(detail::empty_tag_t) noexcept : state{nullptr} {}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor. Takes shared ownership of the callback state, increasing the reference count.
|
||||
*/
|
||||
shared_callback(const shared_callback &other) noexcept {
|
||||
this->operator=(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor. Transfers ownership from another object, leaving intact the reference count. The other object releases the callback state.
|
||||
*/
|
||||
shared_callback(shared_callback &&other) noexcept {
|
||||
this->operator=(std::move(other));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor. Releases the held reference and destroys if no other references exist.
|
||||
*/
|
||||
~shared_callback() {
|
||||
if (!state) { // Moved-from object
|
||||
return;
|
||||
}
|
||||
|
||||
auto count = state->ref_count.fetch_sub(1);
|
||||
if (count == 0) {
|
||||
delete state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment. Takes shared ownership of the callback state, increasing the reference count.
|
||||
*/
|
||||
shared_callback &operator=(const shared_callback &other) noexcept {
|
||||
state = other.state;
|
||||
++state->ref_count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move assignment. Transfers ownership from another object, leaving intact the reference count. The other object releases the callback state.
|
||||
*/
|
||||
shared_callback &operator=(shared_callback &&other) noexcept {
|
||||
state = std::exchange(other.state, nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the async when it is destroyed when it was never co_awaited, signals to the callback to abort.
|
||||
*/
|
||||
void set_dangling() noexcept {
|
||||
if (!state) { // moved-from object
|
||||
return;
|
||||
}
|
||||
state->state.store(state_t::dangling);
|
||||
}
|
||||
|
||||
bool done(std::memory_order order = std::memory_order_seq_cst) const noexcept {
|
||||
return (state->state.load(order) == state_t::done);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convenience function to get the shared callback state's result.
|
||||
*
|
||||
* @warning It is UB to call this on a callback whose state is anything else but state_t::done.
|
||||
*/
|
||||
R &get_result() noexcept {
|
||||
assert(state && done());
|
||||
return (*reinterpret_cast<R *>(state->result_storage.data()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convenience function to get the shared callback state's result.
|
||||
*
|
||||
* @warning It is UB to call this on a callback whose state is anything else but state_t::done.
|
||||
*/
|
||||
const R &get_result() const noexcept {
|
||||
assert(state && done());
|
||||
return (*reinterpret_cast<R *>(state->result_storage.data()));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Shared state of the async and its callback, to be used across threads.
|
||||
*/
|
||||
shared_callback api_callback{nullptr};
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct an async object wrapping an object method, the call is made immediately by forwarding to <a href="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::invoke</a> 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 <typename Obj, typename Fun, typename... Args>
|
||||
#ifndef _DOXYGEN_
|
||||
requires std::invocable<Fun, Obj, Args..., std::function<void(R)>>
|
||||
#endif
|
||||
explicit async_base(Obj &&obj, Fun &&fun, Args&&... args) : api_callback{} {
|
||||
std::invoke(std::forward<Fun>(fun), std::forward<Obj>(obj), std::forward<Args>(args)..., api_callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct an async object wrapping an invokeable object, the call is made immediately by forwarding to <a href="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::invoke</a> and can be awaited later to retrieve the result.
|
||||
*
|
||||
* @param fun The object to call using <a href="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::invoke</a>. 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 <typename Fun, typename... Args>
|
||||
#ifndef _DOXYGEN_
|
||||
requires std::invocable<Fun, Args..., std::function<void(R)>>
|
||||
#endif
|
||||
explicit async_base(Fun &&fun, Args&&... args) : api_callback{} {
|
||||
std::invoke(std::forward<Fun>(fun), std::forward<Args>(args)..., api_callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct an empty async. Using `co_await` on an empty async is undefined behavior.
|
||||
*/
|
||||
async_base() noexcept : api_callback{detail::empty_tag_t{}} {}
|
||||
|
||||
/**
|
||||
* @brief Destructor. If any callback is pending it will be aborted.
|
||||
*/
|
||||
~async_base() {
|
||||
api_callback.set_dangling();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor is disabled
|
||||
*/
|
||||
async_base(const async_base &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
*
|
||||
* NOTE: Despite being marked noexcept, this function uses std::lock_guard which may throw. The implementation assumes this can never happen, hence noexcept. Report it if it does, as that would be a bug.
|
||||
*
|
||||
* @remark Using the moved-from async after this function is undefined behavior.
|
||||
* @param other The async object to move the data from.
|
||||
*/
|
||||
async_base(async_base &&other) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Copy assignment is disabled
|
||||
*/
|
||||
async_base &operator=(const async_base &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move assignment operator.
|
||||
*
|
||||
* NOTE: Despite being marked noexcept, this function uses std::lock_guard which may throw. The implementation assumes this can never happen, hence noexcept. Report it if it does, as that would be a bug.
|
||||
*
|
||||
* @remark Using the moved-from async after this function is undefined behavior.
|
||||
* @param other The async object to move the data from
|
||||
*/
|
||||
async_base &operator=(async_base &&other) noexcept = default;
|
||||
|
||||
/**
|
||||
* @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 of the API call or not
|
||||
*/
|
||||
[[nodiscard]] bool await_ready() const noexcept {
|
||||
return api_callback.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Second function called by the standard library when the object is co-awaited, if await_ready returned false.
|
||||
*
|
||||
* Checks again for the presence of the result, if absent, signals to suspend and keep track of the calling coroutine for the callback to resume.
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @param caller The handle to the coroutine co_await-ing and being suspended
|
||||
*/
|
||||
[[nodiscard]] bool await_suspend(detail::std_coroutine::coroutine_handle<> caller) noexcept {
|
||||
auto sent = state_t::sent;
|
||||
api_callback.state->coro_handle = caller;
|
||||
return api_callback.state->state.compare_exchange_strong(sent, state_t::waiting); // true (suspend) if `sent` was replaced with `waiting` -- false (resume) if the value was not `sent` (`done` is the only other option)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the async is resumed. Its return value is what the whole co_await expression evaluates to
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @return The result of the API call as an lvalue reference.
|
||||
*/
|
||||
R& await_resume() & noexcept {
|
||||
return api_callback.get_result();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the async is resumed. Its return value is what the whole co_await expression evaluates to
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @return The result of the API call as a const lvalue reference.
|
||||
*/
|
||||
const R& await_resume() const& noexcept {
|
||||
return api_callback.get_result();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the async is resumed. Its return value is what the whole co_await expression evaluates to
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @return The result of the API call as an rvalue reference.
|
||||
*/
|
||||
R&& await_resume() && noexcept {
|
||||
return std::move(api_callback.get_result());
|
||||
}
|
||||
};
|
||||
|
||||
} // 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 <a href="https://github.com/brainboxdotcc/DPP/issues">GitHub issues</a> or to the <a href="https://discord.gg/dpp">D++ Discord server</a>.
|
||||
* @tparam R The return type of the API call. Defaults to confirmation_callback_t
|
||||
*/
|
||||
template <typename R>
|
||||
class async : private detail::async::async_base<R> {
|
||||
/**
|
||||
* @brief Internal use only base class. It serves to prevent await_suspend and await_resume from being used directly.
|
||||
*
|
||||
* @warning For internal use only, do not use.
|
||||
* @see operator co_await()
|
||||
*/
|
||||
friend class detail::async::async_base<R>;
|
||||
|
||||
public:
|
||||
using detail::async::async_base<R>::async_base; // use async_base's constructors. unfortunately on clang this doesn't include the templated ones so we have to delegate below
|
||||
using detail::async::async_base<R>::operator=; // use async_base's assignment operator
|
||||
using detail::async::async_base<R>::await_ready; // expose await_ready as public
|
||||
|
||||
/**
|
||||
* @brief Construct an async object wrapping an object method, the call is made immediately by forwarding to <a href="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::invoke</a> 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 <typename Obj, typename Fun, typename... Args>
|
||||
#ifndef _DOXYGEN_
|
||||
requires std::invocable<Fun, Obj, Args..., std::function<void(R)>>
|
||||
#endif
|
||||
explicit async(Obj &&obj, Fun &&fun, Args&&... args) : detail::async::async_base<R>{std::forward<Obj>(obj), std::forward<Fun>(fun), std::forward<Args>(args)...} {}
|
||||
|
||||
/**
|
||||
* @brief Construct an async object wrapping an invokeable object, the call is made immediately by forwarding to <a href="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::invoke</a> and can be awaited later to retrieve the result.
|
||||
*
|
||||
* @param fun The object to call using <a href="https://en.cppreference.com/w/cpp/utility/functional/invoke">std::invoke</a>. 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 <typename Fun, typename... Args>
|
||||
#ifndef _DOXYGEN_
|
||||
requires std::invocable<Fun, Args..., std::function<void(R)>>
|
||||
#endif
|
||||
explicit async(Fun &&fun, Args&&... args) : detail::async::async_base<R>{std::forward<Fun>(fun), std::forward<Args>(args)...} {}
|
||||
|
||||
#ifdef _DOXYGEN_ // :)
|
||||
/**
|
||||
* @brief Construct an empty async. Using `co_await` on an empty async is undefined behavior.
|
||||
*/
|
||||
async() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Destructor. If any callback is pending it will be aborted.
|
||||
*/
|
||||
~async();
|
||||
|
||||
/**
|
||||
* @brief Copy constructor is disabled
|
||||
*/
|
||||
async(const async &);
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
*
|
||||
* NOTE: Despite being marked noexcept, this function uses std::lock_guard which may throw. The implementation assumes this can never happen, hence noexcept. Report it if it does, as that would be a bug.
|
||||
*
|
||||
* @remark Using the moved-from async after this function is undefined behavior.
|
||||
* @param other The async object to move the data from.
|
||||
*/
|
||||
async(async &&other) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Copy assignment is disabled
|
||||
*/
|
||||
async &operator=(const async &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move assignment operator.
|
||||
*
|
||||
* NOTE: Despite being marked noexcept, this function uses std::lock_guard which may throw. The implementation assumes this can never happen, hence noexcept. Report it if it does, as that would be a bug.
|
||||
*
|
||||
* @remark Using the moved-from async after this function is undefined behavior.
|
||||
* @param other The async object to move the data from
|
||||
*/
|
||||
async &operator=(async &&other) noexcept = default;
|
||||
|
||||
/**
|
||||
* @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 of the API call or not
|
||||
*/
|
||||
[[nodiscard]] bool await_ready() const noexcept;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Suspend the caller until the request completes.
|
||||
*
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a reference.
|
||||
*/
|
||||
[[nodiscard]] auto& operator co_await() & noexcept {
|
||||
return static_cast<detail::async::async_base<R>&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the caller until the request completes.
|
||||
*
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a const reference.
|
||||
*/
|
||||
[[nodiscard]] const auto& operator co_await() const & noexcept {
|
||||
return static_cast<detail::async::async_base<R> const&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the caller until the request completes.
|
||||
*
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as an rvalue reference.
|
||||
*/
|
||||
[[nodiscard]] auto&& operator co_await() && noexcept {
|
||||
return static_cast<detail::async::async_base<R>&&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
DPP_CHECK_ABI_COMPAT(async<>, async_dummy);
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
#endif /* DPP_CORO */
|
||||
186
DPP-master/include/dpp/coro/coro.h
Normal file
186
DPP-master/include/dpp/coro/coro.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef DPP_CORO
|
||||
#pragma once
|
||||
|
||||
#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 <experimental/coroutine>
|
||||
#else
|
||||
# include <coroutine>
|
||||
#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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T>
|
||||
requires (has_co_await_member<T>)
|
||||
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 <typename T>
|
||||
requires (!has_co_await_member<T> && has_free_co_await<T>)
|
||||
decltype(auto) co_await_resolve(T&& expr) noexcept(noexcept(operator co_await(expr))) {
|
||||
decltype(auto) awaiter = operator co_await(static_cast<T&&>(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 <typename T>
|
||||
requires (!has_co_await_member<T> && !has_free_co_await<T>)
|
||||
decltype(auto) co_await_resolve(T&& expr) noexcept {
|
||||
return static_cast<T&&>(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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T>
|
||||
bool has_await_members;
|
||||
|
||||
/**
|
||||
* @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 <typename T>
|
||||
using awaitable_result = decltype(co_await_resolve(std::declval<T>()).await_resume());
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct confirmation_callback_t;
|
||||
|
||||
template <typename R = confirmation_callback_t>
|
||||
class async;
|
||||
|
||||
template <typename R = void>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (!std::is_reference_v<R>)
|
||||
#endif
|
||||
class task;
|
||||
|
||||
template <typename R = void>
|
||||
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 <typename T>
|
||||
inline int coro_alloc_count = 0;
|
||||
#endif
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
#endif /* DPP_CORO */
|
||||
|
||||
589
DPP-master/include/dpp/coro/coroutine.h
Normal file
589
DPP-master/include/dpp/coro/coroutine.h
Normal file
@@ -0,0 +1,589 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/utility.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
struct coroutine_dummy {
|
||||
int *handle_dummy = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef DPP_CORO
|
||||
|
||||
#include "coro.h"
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <exception>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
namespace detail {
|
||||
|
||||
namespace coroutine {
|
||||
|
||||
template <typename R>
|
||||
struct promise_t;
|
||||
|
||||
template <typename R>
|
||||
/**
|
||||
* @brief Alias for the handle_t of a coroutine.
|
||||
*/
|
||||
using handle_t = std_coroutine::coroutine_handle<promise_t<R>>;
|
||||
|
||||
/**
|
||||
* @brief Base class of dpp::coroutine<R>.
|
||||
*
|
||||
* @warn This class should not be used directly by a user, use dpp::coroutine<R> instead.
|
||||
* @note This class contains all the functions used internally by co_await. It is intentionally opaque and a private base of dpp::coroutine<R> so a user cannot call await_suspend and await_resume directly.
|
||||
*/
|
||||
template <typename R>
|
||||
class coroutine_base {
|
||||
protected:
|
||||
/**
|
||||
* @brief Promise has friend access for the constructor
|
||||
*/
|
||||
friend struct promise_t<R>;
|
||||
|
||||
/**
|
||||
* @brief Coroutine handle.
|
||||
*/
|
||||
detail::coroutine::handle_t<R> handle{nullptr};
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Construct from a handle. Internal use only.
|
||||
*/
|
||||
coroutine_base(detail::coroutine::handle_t<R> h) : handle{h} {}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor, creates an empty coroutine.
|
||||
*/
|
||||
coroutine_base() = default;
|
||||
|
||||
/**
|
||||
* @brief Copy constructor is disabled
|
||||
*/
|
||||
coroutine_base(const coroutine_base &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move constructor, grabs another coroutine's handle
|
||||
*
|
||||
* @param other Coroutine to move the handle from
|
||||
*/
|
||||
coroutine_base(coroutine_base &&other) noexcept : handle(std::exchange(other.handle, nullptr)) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor, destroys the handle.
|
||||
*/
|
||||
~coroutine_base() {
|
||||
if (handle) {
|
||||
handle.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment is disabled
|
||||
*/
|
||||
coroutine_base &operator=(const coroutine_base &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move assignment, grabs another coroutine's handle
|
||||
*
|
||||
* @param other Coroutine to move the handle from
|
||||
*/
|
||||
coroutine_base &operator=(coroutine_base &&other) noexcept {
|
||||
handle = std::exchange(other.handle, nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 (!handle) {
|
||||
throw dpp::logic_exception("cannot co_await an empty coroutine");
|
||||
}
|
||||
return 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 <typename T>
|
||||
[[nodiscard]] handle_t<R> await_suspend(detail::std_coroutine::coroutine_handle<T> caller) noexcept {
|
||||
handle.promise().parent = caller;
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is resumed.
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @throw Throws any exception thrown or uncaught by the coroutine
|
||||
* @return R The result of the coroutine. It is given to the caller as a result to `co_await`
|
||||
*/
|
||||
decltype(auto) await_resume() & {
|
||||
return static_cast<dpp::coroutine<R> &>(*this).await_resume_impl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is resumed.
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @throw Throws any exception thrown or uncaught by the coroutine
|
||||
* @return R The result of the coroutine. It is given to the caller as a result to `co_await`
|
||||
*/
|
||||
[[nodiscard]] decltype(auto) await_resume() const & {
|
||||
return static_cast<dpp::coroutine<R> const&>(*this).await_resume_impl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is resumed.
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @throw Throws any exception thrown or uncaught by the coroutine
|
||||
* @return R The result of the coroutine. It is given to the caller as a result to `co_await`
|
||||
*/
|
||||
[[nodiscard]] decltype(auto) await_resume() && {
|
||||
return static_cast<dpp::coroutine<R> &&>(*this).await_resume_impl();
|
||||
}
|
||||
};
|
||||
|
||||
} // 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 <a href="https://github.com/brainboxdotcc/DPP/issues">GitHub Issues</a> or to our <a href="https://discord.gg/dpp">Discord Server</a>.
|
||||
* @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 <typename R>
|
||||
class coroutine : private detail::coroutine::coroutine_base<R> {
|
||||
/**
|
||||
* @brief Internal use only base class containing common logic between coroutine<R> and coroutine<void>. It also serves to prevent await_suspend and await_resume from being used directly.
|
||||
*
|
||||
* @warning For internal use only, do not use.
|
||||
* @see operator co_await()
|
||||
*/
|
||||
friend class detail::coroutine::coroutine_base<R>;
|
||||
|
||||
[[nodiscard]] R& await_resume_impl() & {
|
||||
detail::coroutine::promise_t<R> &promise = this->handle.promise();
|
||||
if (promise.exception) {
|
||||
std::rethrow_exception(promise.exception);
|
||||
}
|
||||
return *promise.result;
|
||||
}
|
||||
|
||||
[[nodiscard]] const R& await_resume_impl() const & {
|
||||
detail::coroutine::promise_t<R> &promise = this->handle.promise();
|
||||
if (promise.exception) {
|
||||
std::rethrow_exception(promise.exception);
|
||||
}
|
||||
return *promise.result;
|
||||
}
|
||||
|
||||
[[nodiscard]] R&& await_resume_impl() && {
|
||||
detail::coroutine::promise_t<R> &promise = this->handle.promise();
|
||||
if (promise.exception) {
|
||||
std::rethrow_exception(promise.exception);
|
||||
}
|
||||
return *std::move(promise.result);
|
||||
}
|
||||
|
||||
public:
|
||||
#ifdef _DOXYGEN_ // :))))
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @brief Destructor, destroys the handle.
|
||||
*/
|
||||
~coroutine();
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
#else
|
||||
using detail::coroutine::coroutine_base<R>::coroutine_base; // use coroutine_base's constructors
|
||||
using detail::coroutine::coroutine_base<R>::operator=; // use coroutine_base's assignment operators
|
||||
using detail::coroutine::coroutine_base<R>::await_ready; // expose await_ready as public
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Suspend the caller until the coroutine completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a reference.
|
||||
*/
|
||||
[[nodiscard]] auto& operator co_await() & noexcept {
|
||||
return static_cast<detail::coroutine::coroutine_base<R>&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the caller until the coroutine completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a const reference.
|
||||
*/
|
||||
[[nodiscard]] const auto& operator co_await() const & noexcept {
|
||||
return static_cast<detail::coroutine::coroutine_base<R> const&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the caller until the coroutine completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as an rvalue reference.
|
||||
*/
|
||||
[[nodiscard]] auto&& operator co_await() && noexcept {
|
||||
return static_cast<detail::coroutine::coroutine_base<R>&&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef _DOXYGEN_ // don't generate this on doxygen because `using` doesn't work and 2 copies of coroutine_base's docs is enough
|
||||
/**
|
||||
* @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 <a href="https://github.com/brainboxdotcc/DPP/issues">GitHub issues</a> or to the <a href="https://discord.gg/dpp">D++ Discord server</a>.
|
||||
* @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 coroutine<void> : private detail::coroutine::coroutine_base<void> {
|
||||
/**
|
||||
* @brief Base class has friend access for CRTP downcast
|
||||
*/
|
||||
friend class detail::coroutine::coroutine_base<void>;
|
||||
|
||||
void await_resume_impl() const;
|
||||
|
||||
public:
|
||||
using detail::coroutine::coroutine_base<void>::coroutine_base; // use coroutine_base's constructors
|
||||
using detail::coroutine::coroutine_base<void>::operator=; // use coroutine_base's assignment operators
|
||||
using detail::coroutine::coroutine_base<void>::await_ready; // expose await_ready as public
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the coroutine completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a reference.
|
||||
*/
|
||||
[[nodiscard]] auto& operator co_await() & noexcept {
|
||||
return static_cast<detail::coroutine::coroutine_base<void>&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the coroutine completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a const reference.
|
||||
*/
|
||||
[[nodiscard]] const auto& operator co_await() const & noexcept {
|
||||
return static_cast<detail::coroutine::coroutine_base<void> const &>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the coroutine completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as an rvalue reference.
|
||||
*/
|
||||
[[nodiscard]] auto&& operator co_await() && noexcept {
|
||||
return static_cast<detail::coroutine::coroutine_base<void>&&>(*this);
|
||||
}
|
||||
};
|
||||
#endif /* _DOXYGEN_ */
|
||||
|
||||
namespace detail::coroutine {
|
||||
template <typename R>
|
||||
struct final_awaiter;
|
||||
|
||||
#ifdef DPP_CORO_TEST
|
||||
struct promise_t_base{};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Promise type for coroutine.
|
||||
*/
|
||||
template <typename R>
|
||||
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<R> 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_base>;
|
||||
}
|
||||
|
||||
~promise_t() {
|
||||
--coro_alloc_count<promise_t_base>;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when reaching the end of a coroutine
|
||||
*
|
||||
* @return final_awaiter<R> Resumes any coroutine co_await-ing on this
|
||||
*/
|
||||
[[nodiscard]] final_awaiter<R> final_suspend() const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine start
|
||||
*
|
||||
* @return @return <a href="https://en.cppreference.com/w/cpp/coroutine/suspend_always">std::suspend_always</a> 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<R>) requires std::move_constructible<R> {
|
||||
result = static_cast<R&&>(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<R>) requires std::copy_constructible<R> {
|
||||
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 <typename T>
|
||||
requires (!std::is_same_v<R, std::remove_cvref_t<T>> && std::convertible_to<T, R>)
|
||||
void return_value(T&& expr) noexcept (std::is_nothrow_convertible_v<T, R>) {
|
||||
result = std::forward<T>(expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called to get the coroutine object
|
||||
*/
|
||||
dpp::coroutine<R> get_return_object() {
|
||||
return dpp::coroutine<R>{handle_t<R>::from_promise(*this)};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Struct returned by a coroutine's final_suspend, resumes the continuation
|
||||
*/
|
||||
template <typename R>
|
||||
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<promise_t<R>> 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 <typename R>
|
||||
final_awaiter<R> promise_t<R>::final_suspend() const noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Struct returned by a coroutine's final_suspend, resumes the continuation
|
||||
*/
|
||||
template <>
|
||||
struct promise_t<void> {
|
||||
/**
|
||||
* @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<R> Resumes any coroutine co_await-ing on this
|
||||
*/
|
||||
[[nodiscard]] final_awaiter<void> final_suspend() const noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine start
|
||||
*
|
||||
* @return @return <a href="https://en.cppreference.com/w/cpp/coroutine/suspend_always">std::suspend_always</a> 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<void> get_return_object() {
|
||||
return dpp::coroutine<void>{handle_t<void>::from_promise(*this)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#ifndef _DOXYGEN_
|
||||
inline void coroutine<void>::await_resume_impl() const {
|
||||
if (handle.promise().exception) {
|
||||
std::rethrow_exception(handle.promise().exception);
|
||||
}
|
||||
}
|
||||
#endif /* _DOXYGEN_ */
|
||||
|
||||
DPP_CHECK_ABI_COMPAT(coroutine<void>, coroutine_dummy)
|
||||
DPP_CHECK_ABI_COMPAT(coroutine<uint64_t>, coroutine_dummy)
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
/**
|
||||
* @brief Specialization of std::coroutine_traits, helps the standard library figure out a promise type from a coroutine function.
|
||||
*/
|
||||
template<typename R, typename... Args>
|
||||
struct dpp::detail::std_coroutine::coroutine_traits<dpp::coroutine<R>, Args...> {
|
||||
using promise_type = dpp::detail::coroutine::promise_t<R>;
|
||||
};
|
||||
|
||||
#endif /* DPP_CORO */
|
||||
145
DPP-master/include/dpp/coro/job.h
Normal file
145
DPP-master/include/dpp/coro/job.h
Normal file
@@ -0,0 +1,145 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/utility.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
struct job_dummy {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef DPP_CORO
|
||||
|
||||
#include "coro.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
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 <a href="https://github.com/brainboxdotcc/DPP/issues">GitHub Issues</a> or to our <a href="https://discord.gg/dpp">Discord Server</a>.
|
||||
* @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 <typename... Args>
|
||||
struct promise {
|
||||
|
||||
#ifdef DPP_CORO_TEST
|
||||
promise() {
|
||||
++coro_alloc_count<job_promise_base>;
|
||||
}
|
||||
|
||||
~promise() {
|
||||
--coro_alloc_count<job_promise_base>;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function called when the job is done.
|
||||
*
|
||||
* @return <a href="https://en.cppreference.com/w/cpp/coroutine/suspend_never">std::suspend_never</a> 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 <a href="https://en.cppreference.com/w/cpp/coroutine/suspend_never">std::suspend_never</a> 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<typename... Args>
|
||||
struct dpp::detail::std_coroutine::coroutine_traits<dpp::job, Args...> {
|
||||
/**
|
||||
* @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<Args...>;
|
||||
};
|
||||
|
||||
#endif /* DPP_CORO */
|
||||
784
DPP-master/include/dpp/coro/task.h
Normal file
784
DPP-master/include/dpp/coro/task.h
Normal file
@@ -0,0 +1,784 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/utility.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
struct task_dummy {
|
||||
int* handle_dummy = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef DPP_CORO
|
||||
|
||||
#include "coro.h"
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <exception>
|
||||
#include <atomic>
|
||||
|
||||
#include <iostream> // std::cerr in final_suspend
|
||||
|
||||
namespace dpp {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/* Internal cogwheels for dpp::task */
|
||||
namespace task {
|
||||
|
||||
/**
|
||||
* @brief State of a task
|
||||
*/
|
||||
enum class state_t {
|
||||
/**
|
||||
* @brief Task was started but never co_await-ed
|
||||
*/
|
||||
started,
|
||||
/**
|
||||
* @brief Task was co_await-ed and is pending completion
|
||||
*/
|
||||
awaited,
|
||||
/**
|
||||
* @brief Task is completed
|
||||
*/
|
||||
done,
|
||||
/**
|
||||
* @brief Task is still running but the actual dpp::task object is destroyed
|
||||
*/
|
||||
dangling
|
||||
};
|
||||
|
||||
/**
|
||||
* @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 <typename R>
|
||||
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 <typename R>
|
||||
struct final_awaiter;
|
||||
|
||||
/**
|
||||
* @brief Alias for <a href="https://en.cppreference.com/w/cpp/coroutine/coroutine_handle"std::coroutine_handle</a> for a @ref dpp::task "task"'s @ref promise_t.
|
||||
*
|
||||
* @tparam R Return type of the task
|
||||
*/
|
||||
template <typename R>
|
||||
using handle_t = std_coroutine::coroutine_handle<promise_t<R>>;
|
||||
|
||||
/**
|
||||
* @brief Base class of @ref dpp::task.
|
||||
*
|
||||
* @warning This class should not be used directly by a user, use @ref dpp::task instead.
|
||||
* @note This class contains all the functions used internally by co_await. It is intentionally opaque and a private base of @ref dpp::task so a user cannot call await_suspend() and await_resume() directly.
|
||||
*/
|
||||
template <typename R>
|
||||
class task_base {
|
||||
protected:
|
||||
/**
|
||||
* @brief The coroutine handle of this task.
|
||||
*/
|
||||
handle_t<R> handle;
|
||||
|
||||
/**
|
||||
* @brief Promise type of this coroutine. For internal use only, do not use.
|
||||
*/
|
||||
friend struct promise_t<R>;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Construct from a coroutine handle. Internal use only
|
||||
*/
|
||||
explicit task_base(handle_t<R> handle_) : handle(handle_) {}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor, creates a task not bound to a coroutine.
|
||||
*/
|
||||
task_base() = default;
|
||||
|
||||
/**
|
||||
* @brief Copy constructor is disabled
|
||||
*/
|
||||
task_base(const task_base &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move constructor, grabs another task's coroutine handle
|
||||
*
|
||||
* @param other Task to move the handle from
|
||||
*/
|
||||
task_base(task_base &&other) noexcept : handle(std::exchange(other.handle, nullptr)) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*
|
||||
* Destroys the handle.
|
||||
* @warning The coroutine must be finished before this is called, otherwise it runs the risk of being resumed after it is destroyed, resuming in use-after-free undefined behavior.
|
||||
*/
|
||||
~task_base() {
|
||||
if (handle) {
|
||||
promise_t<R> &promise = handle.promise();
|
||||
state_t previous_state = promise.state.exchange(state_t::dangling);
|
||||
|
||||
if (previous_state == state_t::done) {
|
||||
handle.destroy();
|
||||
}
|
||||
else {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment is disabled
|
||||
*/
|
||||
task_base &operator=(const task_base &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move assignment, grabs another task's coroutine handle
|
||||
*
|
||||
* @param other Task to move the handle from
|
||||
*/
|
||||
task_base &operator=(task_base &&other) noexcept {
|
||||
handle = std::exchange(other.handle, nullptr);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether or not a call to co_await will suspend the caller.
|
||||
*
|
||||
* This function is called by the standard library as a first step when using co_await. If it returns true then the caller is not suspended.
|
||||
* @throws logic_exception if the task is empty.
|
||||
* @return bool Whether not to suspend the caller or not
|
||||
*/
|
||||
[[nodiscard]] bool await_ready() const {
|
||||
if (!handle) {
|
||||
throw dpp::logic_exception{"cannot co_await an empty task"};
|
||||
}
|
||||
return handle.promise().state.load() == state_t::done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Second function called by the standard library when the task is co_await-ed, if await_ready returned false.
|
||||
*
|
||||
* Stores the calling coroutine in the promise to resume when this task suspends.
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @param caller The calling coroutine, now suspended
|
||||
* @return bool Whether to suspend the caller or not
|
||||
*/
|
||||
[[nodiscard]] bool await_suspend(std_coroutine::coroutine_handle<> caller) noexcept {
|
||||
promise_t<R> &my_promise = handle.promise();
|
||||
auto previous_state = state_t::started;
|
||||
|
||||
my_promise.parent = caller;
|
||||
// Replace `sent` state with `awaited` ; if that fails, the only logical option is the state was `done`, in which case return false to resume
|
||||
if (!handle.promise().state.compare_exchange_strong(previous_state, state_t::awaited) && previous_state == state_t::done) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 && handle.promise().state.load(std::memory_order_relaxed) == state_t::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
|
||||
*/
|
||||
dpp::task<R>& cancel() & noexcept {
|
||||
handle.promise().cancelled.exchange(true, std::memory_order_relaxed);
|
||||
return static_cast<dpp::task<R> &>(*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
|
||||
*/
|
||||
dpp::task<R>&& cancel() && noexcept {
|
||||
handle.promise().cancelled.exchange(true, std::memory_order_relaxed);
|
||||
return static_cast<dpp::task<R> &&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when resuming.
|
||||
*
|
||||
* @return Return value of the coroutine, handed to the caller of co_await.
|
||||
*/
|
||||
decltype(auto) await_resume() & {
|
||||
return static_cast<dpp::task<R> &>(*this).await_resume_impl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when resuming.
|
||||
*
|
||||
* @return Return value of the coroutine, handed to the caller of co_await.
|
||||
*/
|
||||
decltype(auto) await_resume() const & {
|
||||
return static_cast<const dpp::task<R> &>(*this).await_resume_impl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when resuming.
|
||||
*
|
||||
* @return Return value of the coroutine, handed to the caller of co_await.
|
||||
*/
|
||||
decltype(auto) await_resume() && {
|
||||
return static_cast<dpp::task<R> &&>(*this).await_resume_impl();
|
||||
}
|
||||
};
|
||||
|
||||
} // 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 <a href="https://github.com/brainboxdotcc/DPP/issues">GitHub Issues</a> or to our <a href="https://discord.gg/dpp">Discord Server</a>.
|
||||
* @tparam R Return type of the task. Cannot be a reference but can be void.
|
||||
*/
|
||||
template <typename R>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (!std::is_reference_v<R>)
|
||||
#endif
|
||||
class task : private detail::task::task_base<R> {
|
||||
/**
|
||||
* @brief Internal use only base class containing common logic between task<R> and task<void>. It also serves to prevent await_suspend and await_resume from being used directly.
|
||||
*
|
||||
* @warning For internal use only, do not use.
|
||||
* @see operator co_await()
|
||||
*/
|
||||
friend class detail::task::task_base<R>;
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is resumed.
|
||||
*
|
||||
* @throw Throws any exception thrown or uncaught by the coroutine
|
||||
* @return The result of the coroutine. This is returned to the awaiter as the result of co_await
|
||||
*/
|
||||
R& await_resume_impl() & {
|
||||
detail::task::promise_t<R> &promise = this->handle.promise();
|
||||
if (promise.exception) {
|
||||
std::rethrow_exception(promise.exception);
|
||||
}
|
||||
return *reinterpret_cast<R *>(promise.result_storage.data());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is resumed.
|
||||
*
|
||||
* @throw Throws any exception thrown or uncaught by the coroutine
|
||||
* @return The result of the coroutine. This is returned to the awaiter as the result of co_await
|
||||
*/
|
||||
const R& await_resume_impl() const & {
|
||||
detail::task::promise_t<R> &promise = this->handle.promise();
|
||||
if (promise.exception) {
|
||||
std::rethrow_exception(promise.exception);
|
||||
}
|
||||
return *reinterpret_cast<R *>(promise.result_storage.data());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is resumed.
|
||||
*
|
||||
* @throw Throws any exception thrown or uncaught by the coroutine
|
||||
* @return The result of the coroutine. This is returned to the awaiter as the result of co_await
|
||||
*/
|
||||
R&& await_resume_impl() && {
|
||||
detail::task::promise_t<R> &promise = this->handle.promise();
|
||||
if (promise.exception) {
|
||||
std::rethrow_exception(promise.exception);
|
||||
}
|
||||
return *reinterpret_cast<R *>(promise.result_storage.data());
|
||||
}
|
||||
|
||||
public:
|
||||
#ifdef _DOXYGEN_ // :)
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*
|
||||
* Destroys the handle.
|
||||
* @warning The coroutine must be finished before this is called, otherwise it runs the risk of being resumed after it is destroyed, resuming in use-after-free undefined behavior.
|
||||
*/
|
||||
~task();
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @brief Function to check if the task has finished its execution entirely
|
||||
*
|
||||
* @return bool Whether the task is finished.
|
||||
*/
|
||||
[[nodiscard]] bool done() const noexcept;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
dpp::task<R>& cancel() & noexcept;
|
||||
|
||||
/**
|
||||
* @brief Check whether or not a call to co_await will suspend the caller.
|
||||
*
|
||||
* This function is called by the standard library as a first step when using co_await. If it returns true then the caller is not suspended.
|
||||
* @throws logic_exception if the task is empty.
|
||||
* @return bool Whether not to suspend the caller or not
|
||||
*/
|
||||
[[nodiscard]] bool await_ready() const;
|
||||
#else
|
||||
using detail::task::task_base<R>::task_base; // use task_base's constructors
|
||||
using detail::task::task_base<R>::operator=; // use task_base's assignment operators
|
||||
using detail::task::task_base<R>::done; // expose done() as public
|
||||
using detail::task::task_base<R>::cancel; // expose cancel() as public
|
||||
using detail::task::task_base<R>::await_ready; // expose await_ready as public
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the task completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a reference.
|
||||
*/
|
||||
[[nodiscard]] auto& operator co_await() & noexcept {
|
||||
return static_cast<detail::task::task_base<R>&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the task completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as a const reference.
|
||||
*/
|
||||
[[nodiscard]] const auto& operator co_await() const & noexcept {
|
||||
return static_cast<const detail::task::task_base<R>&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the task completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, this expression evaluates to the result object of type R, as an rvalue reference.
|
||||
*/
|
||||
[[nodiscard]] auto&& operator co_await() && noexcept {
|
||||
return static_cast<detail::task::task_base<R>&&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef _DOXYGEN_ // don't generate this on doxygen because `using` doesn't work and 2 copies of coroutine_base's docs is enough
|
||||
/**
|
||||
* @brief A coroutine task. It starts immediately on construction and can be co_await-ed, making it perfect for parallel coroutines returning a value.
|
||||
*
|
||||
* Can be used in conjunction with coroutine events via dpp::event_router_t::co_attach, or on its own.
|
||||
*
|
||||
* @warning - This feature is EXPERIMENTAL. The API may change at any time and there may be bugs. Please report any to <a href="https://github.com/brainboxdotcc/DPP/issues">GitHub issues</a> or to the <a href="https://discord.gg/dpp">D++ Discord server</a>.
|
||||
* @tparam R Return type of the coroutine. Cannot be a reference, can be void.
|
||||
*/
|
||||
template <>
|
||||
class task<void> : private detail::task::task_base<void> {
|
||||
/**
|
||||
* @brief Private base class containing common logic between task<R> and task<void>. It also serves to prevent await_suspend and await_resume from being used directly.
|
||||
*
|
||||
* @see operator co_await()
|
||||
*/
|
||||
friend class detail::task::task_base<void>;
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is resumed.
|
||||
*
|
||||
* @remark Do not call this manually, use the co_await keyword instead.
|
||||
* @throw Throws any exception thrown or uncaught by the coroutine
|
||||
*/
|
||||
void await_resume_impl() const;
|
||||
|
||||
public:
|
||||
using detail::task::task_base<void>::task_base; // use task_base's constructors
|
||||
using detail::task::task_base<void>::operator=; // use task_base's assignment operators
|
||||
using detail::task::task_base<void>::done; // expose done() as public
|
||||
using detail::task::task_base<void>::cancel; // expose cancel() as public
|
||||
using detail::task::task_base<void>::await_ready; // expose await_ready as public
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the task completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, returns a reference to the contained result.
|
||||
*/
|
||||
auto& operator co_await() & {
|
||||
return static_cast<detail::task::task_base<void>&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the task completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, returns a const reference to the contained result.
|
||||
*/
|
||||
const auto& operator co_await() const & {
|
||||
return static_cast<const detail::task::task_base<void>&>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend the current coroutine until the task completes.
|
||||
*
|
||||
* @throw On resumption, any exception thrown by the coroutine is propagated to the caller.
|
||||
* @return On resumption, returns a reference to the contained result.
|
||||
*/
|
||||
auto&& operator co_await() && {
|
||||
return static_cast<detail::task::task_base<void>&&>(*this);
|
||||
}
|
||||
};
|
||||
#endif /* _DOXYGEN_ */
|
||||
|
||||
namespace detail::task {
|
||||
/**
|
||||
* @brief Awaitable returned from task::promise_t's final_suspend. Resumes the parent and cleans up its handle if needed
|
||||
*/
|
||||
template <typename R>
|
||||
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<R> 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
|
||||
*/
|
||||
struct promise_base {
|
||||
/**
|
||||
* @brief State of the task, used to keep track of lifetime and status
|
||||
*/
|
||||
std::atomic<state_t> state = state_t::started;
|
||||
|
||||
/**
|
||||
* @brief Whether the task is cancelled or not.
|
||||
*/
|
||||
std::atomic<bool> cancelled = false;
|
||||
|
||||
/**
|
||||
* @brief Parent coroutine to return to for nested coroutines.
|
||||
*/
|
||||
detail::std_coroutine::coroutine_handle<> parent = nullptr;
|
||||
|
||||
/**
|
||||
* @brief Exception ptr if any was thrown during the coroutine
|
||||
*
|
||||
* @see <a href="https://en.cppreference.com/w/cpp/error/exception_ptr>std::exception_ptr</a>
|
||||
*/
|
||||
std::exception_ptr exception = nullptr;
|
||||
|
||||
#ifdef DPP_CORO_TEST
|
||||
promise_base() {
|
||||
++coro_alloc_count<promise_base>;
|
||||
}
|
||||
|
||||
~promise_base() {
|
||||
--coro_alloc_count<promise_base>;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is created.
|
||||
*
|
||||
* @return <a href="https://en.cppreference.com/w/cpp/coroutine/suspend_never">std::suspend_never</a> Don't suspend, the coroutine starts immediately.
|
||||
*/
|
||||
[[nodiscard]] 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() {
|
||||
exception = std::current_exception();
|
||||
if ((state.load() == task::state_t::dangling) && !cancelled) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proxy awaitable that wraps any co_await inside the task and checks for cancellation on resumption
|
||||
*
|
||||
* @see await_transform
|
||||
*/
|
||||
template <typename A>
|
||||
struct proxy_awaiter {
|
||||
/** @brief The promise_t object bound to this proxy */
|
||||
const task::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 <typename T>
|
||||
[[nodiscard]] decltype(auto) await_suspend(T&& handle) noexcept(noexcept(awaitable.await_suspend(std::forward<T>(handle)))) {
|
||||
return awaitable.await_suspend(std::forward<T>(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 <typename T>
|
||||
[[nodiscard]] auto await_transform(T&& expr) const noexcept(noexcept(co_await_resolve(std::forward<T>(expr)))) {
|
||||
using awaitable_t = decltype(co_await_resolve(std::forward<T>(expr)));
|
||||
return proxy_awaiter<awaitable_t>{*this, co_await_resolve(std::forward<T>(expr))};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implementation of task::promise_t for non-void return type
|
||||
*/
|
||||
template <typename R>
|
||||
struct promise_t : promise_base {
|
||||
/**
|
||||
* @brief Destructor. Destroys the value if it was constructed.
|
||||
*/
|
||||
~promise_t() {
|
||||
if (state.load() == state_t::done && !exception) {
|
||||
std::destroy_at(reinterpret_cast<R *>(result_storage.data()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stored return value of the coroutine.
|
||||
*
|
||||
*/
|
||||
alignas(R) std::array<std::byte, sizeof(R)> result_storage;
|
||||
|
||||
/**
|
||||
* @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<R>) requires std::move_constructible<R> {
|
||||
std::construct_at<R>(reinterpret_cast<R *>(result_storage.data()), static_cast<R&&>(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<R>) requires std::copy_constructible<R> {
|
||||
std::construct_at<R>(reinterpret_cast<R *>(result_storage.data()), 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 <typename T>
|
||||
requires (!std::is_same_v<R, std::remove_cvref_t<T>> && std::convertible_to<T, R>)
|
||||
void return_value(T&& expr) noexcept (std::is_nothrow_convertible_v<T, R>) {
|
||||
std::construct_at<R>(reinterpret_cast<R *>(result_storage.data()), std::forward<T>(expr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is created.
|
||||
*
|
||||
* @return dpp::task The coroutine object
|
||||
*/
|
||||
[[nodiscard]] dpp::task<R> get_return_object() noexcept {
|
||||
return dpp::task<R>{handle_t<R>::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<R> final_suspend() const noexcept {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implementation of task::promise_t for void return type
|
||||
*/
|
||||
template <>
|
||||
struct promise_t<void> : promise_base {
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine co_returns
|
||||
*
|
||||
* Does nothing but is required by the standard library.
|
||||
*/
|
||||
void return_void() const noexcept {}
|
||||
|
||||
/**
|
||||
* @brief Function called by the standard library when the coroutine is created.
|
||||
*
|
||||
* @return task The coroutine object
|
||||
*/
|
||||
[[nodiscard]] dpp::task<void> get_return_object() noexcept {
|
||||
return dpp::task<void>{handle_t<void>::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<void> final_suspend() const noexcept {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
std_coroutine::coroutine_handle<> final_awaiter<R>::await_suspend(handle_t<R> handle) const noexcept {
|
||||
promise_t<R> &promise = handle.promise();
|
||||
state_t previous_state = promise.state.exchange(state_t::done);
|
||||
|
||||
switch (previous_state) {
|
||||
case state_t::started: // started but never awaited, suspend
|
||||
return std_coroutine::noop_coroutine();
|
||||
case state_t::awaited: // co_await-ed, resume parent
|
||||
return promise.parent;
|
||||
case state_t::dangling: // task object is gone, free the handle
|
||||
handle.destroy();
|
||||
return std_coroutine::noop_coroutine();
|
||||
case state_t::done: // what
|
||||
// this should never happen. log it. we don't have a cluster so just write it on cerr
|
||||
std::cerr << "dpp::task: final_suspend called twice. something went very wrong here, please report to GitHub issues or the D++ Discord server" << std::endl;
|
||||
}
|
||||
// TODO: replace with __builtin_unreachable when we confirm this never happens with normal usage
|
||||
return std_coroutine::noop_coroutine();
|
||||
}
|
||||
|
||||
} // namespace detail::task
|
||||
|
||||
#ifndef _DOXYGEN_
|
||||
inline void task<void>::await_resume_impl() const {
|
||||
if (handle.promise().exception) {
|
||||
std::rethrow_exception(handle.promise().exception);
|
||||
}
|
||||
}
|
||||
#endif /* _DOXYGEN_ */
|
||||
|
||||
DPP_CHECK_ABI_COMPAT(task<void>, task_dummy)
|
||||
DPP_CHECK_ABI_COMPAT(task<uint64_t>, task_dummy)
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
/**
|
||||
* @brief Specialization of std::coroutine_traits, helps the standard library figure out a promise_t type from a coroutine function.
|
||||
*/
|
||||
template<typename T, typename... Args>
|
||||
struct dpp::detail::std_coroutine::coroutine_traits<dpp::task<T>, Args...> {
|
||||
using promise_type = dpp::detail::task::promise_t<T>;
|
||||
};
|
||||
|
||||
#endif /* DPP_CORO */
|
||||
532
DPP-master/include/dpp/coro/when_any.h
Normal file
532
DPP-master/include/dpp/coro/when_any.h
Normal file
@@ -0,0 +1,532 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef DPP_CORO
|
||||
#pragma once
|
||||
|
||||
#include "coro.h"
|
||||
#include "job.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
template <typename T>
|
||||
class event_router_t;
|
||||
|
||||
namespace detail {
|
||||
|
||||
namespace event_router {
|
||||
|
||||
template <typename T>
|
||||
class awaitable;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal cogwheels for dpp::when_any
|
||||
*/
|
||||
namespace when_any {
|
||||
|
||||
/**
|
||||
* @brief Current state of a when_any object
|
||||
*/
|
||||
enum class await_state {
|
||||
/**
|
||||
* @brief Object was started but not awaited
|
||||
*/
|
||||
started,
|
||||
/**
|
||||
* @brief Object is being awaited
|
||||
*/
|
||||
waiting,
|
||||
/**
|
||||
* @brief Object was resumed
|
||||
*/
|
||||
done,
|
||||
/**
|
||||
* @brief Object was destroyed
|
||||
*/
|
||||
dangling
|
||||
};
|
||||
|
||||
/**
|
||||
* @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 <typename T>
|
||||
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<decltype(v)>(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct arg_helper_s<dpp::event_router_t<T>> {
|
||||
using type = event_router::awaitable<T>;
|
||||
|
||||
template <typename U>
|
||||
#ifndef _DOXYGEN
|
||||
requires (std::same_as<std::remove_cvref_t<U>, dpp::event_router_t<T>>)
|
||||
#endif
|
||||
static event_router::awaitable<T> get(U&& v) {
|
||||
return static_cast<U>(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 <typename T>
|
||||
using awaitable_type = typename arg_helper_s<T>::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 <typename T>
|
||||
using arg_helper = arg_helper_s<std::remove_cvref_t<T>>;
|
||||
|
||||
/**
|
||||
* @brief Empty result from void-returning awaitable
|
||||
*/
|
||||
struct empty{};
|
||||
|
||||
/**
|
||||
* @brief Actual type a result will be stores as in when_any
|
||||
*/
|
||||
template <typename T>
|
||||
using storage_type = std::conditional_t<std::is_void_v<T>, empty, T>;
|
||||
|
||||
/**
|
||||
* @brief Concept satisfied if a stored result is void
|
||||
*/
|
||||
template <typename T>
|
||||
concept void_result = std::same_as<T, empty>;
|
||||
|
||||
}
|
||||
|
||||
} // 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<N>() 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 <typename... Args>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (sizeof...(Args) >= 1)
|
||||
#endif
|
||||
class when_any {
|
||||
/**
|
||||
* @brief Alias for the type of the result variant
|
||||
*/
|
||||
using variant_type = std::variant<std::exception_ptr, std::remove_cvref_t<detail::when_any::storage_type<detail::awaitable_result<Args>>>...>;
|
||||
|
||||
/**
|
||||
* @brief Alias for the result type of the Nth arg.
|
||||
*
|
||||
* @tparam N index of the argument to fetch
|
||||
*/
|
||||
template <size_t N>
|
||||
using result_t = std::variant_alternative_t<N + 1, variant_type>;
|
||||
|
||||
/**
|
||||
* @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 <typename... Args_>
|
||||
state_t(Args_&&... args) : awaitables{std::forward<Args_>(args)...} {}
|
||||
|
||||
/**
|
||||
* @brief Awaitable objects to handle.
|
||||
*/
|
||||
std::tuple<Args...> 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<std::size_t>::max();
|
||||
|
||||
/**
|
||||
* @brief State of the when_any object.
|
||||
*
|
||||
* @see detail::when_any::await_state
|
||||
*/
|
||||
std::atomic<detail::when_any::await_state> owner_state{detail::when_any::await_state::started};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Shared pointer to the state shared between the jobs spawned. Contains the awaitable objects and the result.
|
||||
*/
|
||||
std::shared_ptr<state_t> 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 <size_t N>
|
||||
static dpp::job make_job(std::shared_ptr<state_t> shared_state) {
|
||||
/**
|
||||
* 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<result_t<N>, detail::when_any::empty>) {
|
||||
decltype(auto) result = co_await std::get<N>(shared_state->awaitables);
|
||||
|
||||
if (auto s = shared_state->owner_state.load(std::memory_order_relaxed); s == detail::when_any::await_state::dangling || s == detail::when_any::await_state::done) {
|
||||
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<result_t> && !std::is_const_v<result_t> && std::is_move_constructible_v<std::remove_cvref_t<result_t>>) {
|
||||
shared_state->result.template emplace<N + 1>(std::move(result));
|
||||
} else {
|
||||
shared_state->result.template emplace<N + 1>(result);
|
||||
}
|
||||
} catch (...) {
|
||||
shared_state->result.template emplace<0>(std::current_exception());
|
||||
}
|
||||
} else {
|
||||
co_await std::get<N>(shared_state->awaitables);
|
||||
|
||||
if (auto s = shared_state->owner_state.load(std::memory_order_relaxed); s == detail::when_any::await_state::dangling || s == detail::when_any::await_state::done) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
shared_state->result.template emplace<N + 1>();
|
||||
}
|
||||
|
||||
if (shared_state->owner_state.exchange(detail::when_any::await_state::done) != detail::when_any::await_state::waiting) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
if (auto handle = shared_state->handle; handle) {
|
||||
shared_state->index_finished = N;
|
||||
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() {
|
||||
[]<size_t... Ns>(when_any *self, std::index_sequence<Ns...>) {
|
||||
(make_job<Ns>(self->my_state), ...);
|
||||
}(this, std::index_sequence_for<Args...>{});
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Object returned by \ref operator co_await() on resumption. Can be moved but not copied.
|
||||
*/
|
||||
class result {
|
||||
friend class when_any<Args...>;
|
||||
|
||||
/**
|
||||
* @brief Reference to the shared state to pull the data from
|
||||
*/
|
||||
std::shared_ptr<state_t> shared_state;
|
||||
|
||||
/**
|
||||
* @brief Default construction is deleted
|
||||
*/
|
||||
result() = delete;
|
||||
|
||||
/**
|
||||
* @brief Internal constructor taking the shared state
|
||||
*/
|
||||
result(std::shared_ptr<state_t> 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 <size_t N>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (!detail::when_any::void_result<result_t<N>>)
|
||||
#endif
|
||||
result_t<N>& get() & {
|
||||
if (is_exception()) {
|
||||
std::rethrow_exception(std::get<0>(shared_state->result));
|
||||
}
|
||||
return std::get<N + 1>(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 <size_t N>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (!detail::when_any::void_result<result_t<N>>)
|
||||
#endif
|
||||
const result_t<N>& get() const& {
|
||||
if (is_exception()) {
|
||||
std::rethrow_exception(std::get<0>(shared_state->result));
|
||||
}
|
||||
return std::get<N + 1>(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 <size_t N>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (!detail::when_any::void_result<result_t<N>>)
|
||||
#endif
|
||||
result_t<N>&& get() && {
|
||||
if (is_exception()) {
|
||||
std::rethrow_exception(std::get<0>(shared_state->result));
|
||||
}
|
||||
return std::get<N + 1>(shared_state->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cannot retrieve a void result.
|
||||
*/
|
||||
template <size_t N>
|
||||
#ifndef _DOXYGEN
|
||||
requires (detail::when_any::void_result<result_t<N>>)
|
||||
#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 {
|
||||
auto sent = detail::when_any::await_state::started;
|
||||
self->my_state->handle = caller;
|
||||
return self->my_state->owner_state.compare_exchange_strong(sent, detail::when_any::await_state::waiting); // true (suspend) if `started` was replaced with `waiting` -- false (resume) if the value was not `started` (`done` is the only other option)
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 <typename... Args_>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (sizeof...(Args_) == sizeof...(Args))
|
||||
#endif /* _DOXYGEN_ */
|
||||
when_any(Args_&&... args) : my_state{std::make_shared<state_t>(detail::when_any::arg_helper<Args_>::get(std::forward<Args_>(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;
|
||||
|
||||
[]<size_t... Ns>(when_any *self, std::index_sequence<Ns...>) constexpr {
|
||||
constexpr auto cancel = []<size_t N>(when_any *self) constexpr {
|
||||
if constexpr (requires { std::get<N>(self->my_state->awaitables).cancel(); }) {
|
||||
try {
|
||||
std::get<N>(self->my_state->awaitables).cancel();
|
||||
} catch (...) {
|
||||
// swallow any exception. no choice here, we're in a destructor
|
||||
}
|
||||
}
|
||||
};
|
||||
(cancel.template operator()<Ns>(self), ...);
|
||||
}(this, std::index_sequence_for<Args...>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 == detail::when_any::await_state::done;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 <typename... Args>
|
||||
#ifndef _DOXYGEN_
|
||||
requires (sizeof...(Args) >= 1)
|
||||
#endif /* _DOXYGEN_ */
|
||||
when_any(Args...) -> when_any<detail::when_any::awaitable_type<Args>...>;
|
||||
|
||||
} /* namespace dpp */
|
||||
|
||||
#endif
|
||||
526
DPP-master/include/dpp/discordclient.h
Normal file
526
DPP-master/include/dpp/discordclient.h
Normal file
@@ -0,0 +1,526 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/wsclient.h>
|
||||
#include <dpp/dispatcher.h>
|
||||
#include <dpp/event.h>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
|
||||
|
||||
#define DISCORD_API_VERSION "10"
|
||||
#define API_PATH "/api/v" DISCORD_API_VERSION
|
||||
namespace dpp {
|
||||
|
||||
// Forward declarations
|
||||
class cluster;
|
||||
|
||||
/**
|
||||
* @brief This is an opaque class containing zlib library specific structures.
|
||||
* We define it this way so that the public facing D++ library doesn't require
|
||||
* the zlib headers be available to build against it.
|
||||
*/
|
||||
class zlibcontext;
|
||||
|
||||
/**
|
||||
* @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 Construct a new voiceconn object
|
||||
*/
|
||||
voiceconn() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new voiceconn object
|
||||
*
|
||||
* @param o owner
|
||||
* @param _channel_id voice channel id
|
||||
*/
|
||||
voiceconn(class discord_client* o, snowflake _channel_id);
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @brief return true if the connection is active (websocket exists)
|
||||
*
|
||||
* @return true if has an active websocket
|
||||
*/
|
||||
bool is_active();
|
||||
|
||||
/**
|
||||
* @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 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 True if the shard is terminating
|
||||
*/
|
||||
bool terminating;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Mutex for message queue
|
||||
*/
|
||||
std::shared_mutex queue_mutex;
|
||||
|
||||
/**
|
||||
* @brief Queue of outbound messages
|
||||
*/
|
||||
std::deque<std::string> message_queue;
|
||||
|
||||
/**
|
||||
* @brief Thread this shard is executing on
|
||||
*/
|
||||
std::thread* runner;
|
||||
|
||||
/**
|
||||
* @brief Run shard loop under a thread.
|
||||
* Calls discord_client::run() from within a std::thread.
|
||||
*/
|
||||
void thread_run();
|
||||
|
||||
/**
|
||||
* @brief If true, stream compression is enabled
|
||||
*/
|
||||
bool compressed;
|
||||
|
||||
/**
|
||||
* @brief ZLib decompression buffer
|
||||
*/
|
||||
unsigned char* decomp_buffer;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
zlibcontext* zlib;
|
||||
|
||||
/**
|
||||
* @brief Total decompressed received bytes
|
||||
*/
|
||||
uint64_t decompressed_total;
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
class etf_parser* 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 Initialise ZLib (websocket compression)
|
||||
* @throw dpp::exception if ZLib cannot be initialised
|
||||
*/
|
||||
void setup_zlib();
|
||||
|
||||
/**
|
||||
* @brief Shut down ZLib (websocket compression)
|
||||
*/
|
||||
void end_zlib();
|
||||
|
||||
/**
|
||||
* @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 Thread ID
|
||||
*/
|
||||
std::thread::native_handle_type thread_id;
|
||||
|
||||
/**
|
||||
* @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<snowflake, std::unique_ptr<voiceconn>> 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;
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/** Fires every second from the underlying socket I/O loop, used for sending heartbeats */
|
||||
virtual void one_second_timer();
|
||||
|
||||
/**
|
||||
* @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 Destroy the discord client object
|
||||
*/
|
||||
virtual ~discord_client();
|
||||
|
||||
/**
|
||||
* @brief Get the decompressed bytes in objectGet decompressed total bytes received
|
||||
* @return uint64_t bytes received
|
||||
*/
|
||||
uint64_t get_decompressed_bytes_in();
|
||||
|
||||
/**
|
||||
* @brief Handle JSON from the websocket.
|
||||
* @param buffer The entire buffer content from the websocket client
|
||||
* @returns True if a frame has been handled
|
||||
*/
|
||||
virtual bool handle_frame(const std::string &buffer);
|
||||
|
||||
/**
|
||||
* @brief Handle a websocket error.
|
||||
* @param errorcode The error returned from the websocket
|
||||
*/
|
||||
virtual void error(uint32_t errorcode);
|
||||
|
||||
/**
|
||||
* @brief Start and monitor I/O loop.
|
||||
* @note this is a blocking call and is usually executed within a
|
||||
* thread by whatever creates the object.
|
||||
*/
|
||||
void run();
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
232
DPP-master/include/dpp/discordevents.h
Normal file
232
DPP-master/include/dpp/discordevents.h
Normal file
@@ -0,0 +1,232 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
|
||||
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<class snowflake> &v);
|
||||
|
||||
/**
|
||||
* @brief Applies a function to each element of a json array.
|
||||
* @param j 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<void(nlohmann::json*)> &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 keyname key name to check for the values
|
||||
* @param v Value to change
|
||||
*/
|
||||
template<class T> void set_object_array_not_null(nlohmann::json* j, std::string_view key, std::vector<T>& 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);
|
||||
|
||||
} // namespace dpp
|
||||
970
DPP-master/include/dpp/discordvoiceclient.h
Normal file
970
DPP-master/include/dpp/discordvoiceclient.h
Normal file
@@ -0,0 +1,970 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/wsclient.h>
|
||||
#include <dpp/dispatcher.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/socket.h>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
|
||||
struct OpusDecoder;
|
||||
struct OpusEncoder;
|
||||
struct OpusRepacketizer;
|
||||
|
||||
namespace dpp {
|
||||
|
||||
class audio_mixer;
|
||||
|
||||
// !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;
|
||||
|
||||
/*
|
||||
* @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<int64_t> 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 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 Mutex for outbound packet stream
|
||||
*/
|
||||
std::mutex stream_mutex;
|
||||
|
||||
/**
|
||||
* @brief Mutex for message queue
|
||||
*/
|
||||
std::shared_mutex queue_mutex;
|
||||
|
||||
/**
|
||||
* @brief Queue of outbound messages
|
||||
*/
|
||||
std::deque<std::string> message_queue;
|
||||
|
||||
/**
|
||||
* @brief Thread this connection is executing on
|
||||
*/
|
||||
std::thread* runner;
|
||||
|
||||
/**
|
||||
* @brief Run shard loop under a thread
|
||||
*/
|
||||
void thread_run();
|
||||
|
||||
/**
|
||||
* @brief Last connect time of voice session
|
||||
*/
|
||||
time_t connect_time;
|
||||
|
||||
/*
|
||||
* @brief For mixing outgoing voice data.
|
||||
*/
|
||||
std::unique_ptr<audio_mixer> 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<std::string> modes;
|
||||
|
||||
/**
|
||||
* @brief Timescale in nanoseconds
|
||||
*/
|
||||
uint64_t timescale;
|
||||
|
||||
/**
|
||||
* @brief Output buffer
|
||||
*/
|
||||
std::vector<voice_out_packet> 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<voice_receive_t> 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<voice_payload> parked_payloads;
|
||||
|
||||
/**
|
||||
* @brief The decoder ctls to be set on the decoder.
|
||||
*/
|
||||
std::vector<std::function<void(OpusDecoder&)>> 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<OpusDecoder> 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<snowflake, voice_payload_parking_lot> 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;
|
||||
|
||||
#ifdef HAVE_VOICE
|
||||
/**
|
||||
* @brief libopus encoder
|
||||
*/
|
||||
OpusEncoder* encoder;
|
||||
|
||||
/**
|
||||
* @brief libopus repacketizer
|
||||
* (merges frames into one packet)
|
||||
*/
|
||||
OpusRepacketizer* repacketizer;
|
||||
#else
|
||||
/**
|
||||
* @brief libopus encoder
|
||||
*/
|
||||
void* encoder;
|
||||
|
||||
/**
|
||||
* @brief libopus repacketizer
|
||||
* (merges frames into one packet)
|
||||
*/
|
||||
void* repacketizer;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief File descriptor for UDP connection
|
||||
*/
|
||||
dpp::socket fd;
|
||||
|
||||
/**
|
||||
* @brief Secret key for encrypting voice.
|
||||
* If it has been sent, this is non-null and points to a
|
||||
* sequence of exactly 32 bytes.
|
||||
*/
|
||||
uint8_t* secret_key;
|
||||
|
||||
/**
|
||||
* @brief Sequence number of outbound audio. This is incremented
|
||||
* once per frame sent.
|
||||
*/
|
||||
uint16_t 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 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<uint32_t, snowflake> 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<std::string> track_meta;
|
||||
|
||||
/**
|
||||
* @brief Encoding buffer for opus repacketizer and encode
|
||||
*/
|
||||
uint8_t encode_buffer[65536];
|
||||
|
||||
/**
|
||||
* @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 This hooks the ssl_client, returning the file
|
||||
* descriptor if we want to send buffered data, or
|
||||
* -1 if there is nothing to send
|
||||
*
|
||||
* @return int file descriptor or -1
|
||||
*/
|
||||
dpp::socket want_write();
|
||||
|
||||
/**
|
||||
* @brief This hooks the ssl_client, returning the file
|
||||
* descriptor if we want to receive buffered data, or
|
||||
* -1 if we are not wanting to receive
|
||||
*
|
||||
* @return int file descriptor or -1
|
||||
*/
|
||||
dpp::socket want_read();
|
||||
|
||||
/**
|
||||
* @brief Called by ssl_client 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 ssl_client 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
|
||||
*/
|
||||
void send(const char* packet, size_t len, uint64_t duration);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Owning cluster
|
||||
*/
|
||||
class dpp::cluster* creator;
|
||||
|
||||
/**
|
||||
* @brief This needs to be static, we only initialise libsodium once per program start,
|
||||
* so initialising it on first use in a voice connection is best.
|
||||
*/
|
||||
static bool sodium_initialised;
|
||||
|
||||
/**
|
||||
* @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 Thread ID
|
||||
*/
|
||||
std::thread::native_handle_type thread_id;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @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)
|
||||
* @throw dpp::voice_exception Sodium or Opus failed to initialise, or D++ is not compiled with voice support
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Destroy the discord voice client object
|
||||
*/
|
||||
virtual ~discord_voice_client();
|
||||
|
||||
/**
|
||||
* @brief Handle JSON from the websocket.
|
||||
* @param buffer The entire buffer content from the websocket client
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Handle a websocket error.
|
||||
* @param errorcode The error returned from the websocket
|
||||
*/
|
||||
virtual void error(uint32_t errorcode);
|
||||
|
||||
/**
|
||||
* @brief Start and monitor I/O loop
|
||||
*/
|
||||
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 libsodium.
|
||||
*
|
||||
* @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
|
||||
* libsodium 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)
|
||||
*
|
||||
* @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(uint8_t* opus_packet, const size_t length, uint64_t duration);
|
||||
|
||||
/**
|
||||
* @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
|
||||
* libsodium 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(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 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 time 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<std::string>& list of metadata strings
|
||||
*/
|
||||
const std::vector<std::string> 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();
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
2116
DPP-master/include/dpp/dispatcher.h
Normal file
2116
DPP-master/include/dpp/dispatcher.h
Normal file
File diff suppressed because it is too large
Load Diff
76
DPP-master/include/dpp/dns.h
Normal file
76
DPP-master/include/dpp/dns.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#ifdef _WIN32
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Represents a cached DNS result.
|
||||
* Used by the ssl_client class to store cached copies of dns lookups.
|
||||
*/
|
||||
struct dns_cache_entry {
|
||||
/**
|
||||
* @brief Resolved address information
|
||||
*/
|
||||
addrinfo addr;
|
||||
|
||||
/**
|
||||
* @brief Socket address.
|
||||
* Discord only supports ipv4, but sockaddr_in6 is larger
|
||||
* than sockaddr_in, sockaddr_storage will hold either. This
|
||||
* means that if discord ever do support ipv6 we just flip
|
||||
* one value in dns.cpp and that should be all that is needed.
|
||||
*/
|
||||
sockaddr_storage ai_addr;
|
||||
|
||||
/**
|
||||
* @brief Time at which this cache entry is invalidated
|
||||
*/
|
||||
time_t expire_timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Cache container type
|
||||
*/
|
||||
using dns_cache_t = std::unordered_map<std::string, dns_cache_entry*>;
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
const dns_cache_entry* resolve_hostname(const std::string& hostname, const std::string& port);
|
||||
} // namespace dpp
|
||||
76
DPP-master/include/dpp/dpp.h
Normal file
76
DPP-master/include/dpp/dpp.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/version.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <dpp/exception.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/misc-enum.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <dpp/voicestate.h>
|
||||
#include <dpp/permissions.h>
|
||||
#include <dpp/role.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/thread.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/invite.h>
|
||||
#include <dpp/dtemplate.h>
|
||||
#include <dpp/emoji.h>
|
||||
#include <dpp/ban.h>
|
||||
#include <dpp/prune.h>
|
||||
#include <dpp/voiceregion.h>
|
||||
#include <dpp/integration.h>
|
||||
#include <dpp/webhook.h>
|
||||
#include <dpp/presence.h>
|
||||
#include <dpp/intents.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/appcommand.h>
|
||||
#include <dpp/stage_instance.h>
|
||||
#include <dpp/auditlog.h>
|
||||
#include <dpp/application.h>
|
||||
#include <dpp/scheduled_event.h>
|
||||
#include <dpp/discordclient.h>
|
||||
#include <dpp/dispatcher.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/httpsclient.h>
|
||||
#include <dpp/queues.h>
|
||||
#include <dpp/commandhandler.h>
|
||||
#include <dpp/once.h>
|
||||
#include <dpp/sync.h>
|
||||
#include <dpp/colors.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/timed_listener.h>
|
||||
#include <dpp/collector.h>
|
||||
115
DPP-master/include/dpp/dtemplate.h
Normal file
115
DPP-master/include/dpp/dtemplate.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Represents a guild template
|
||||
*/
|
||||
class DPP_EXPORT dtemplate : public json_interface<dtemplate> {
|
||||
protected:
|
||||
friend struct json_interface<dtemplate>;
|
||||
|
||||
/** 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<snowflake, dtemplate> dtemplate_map;
|
||||
|
||||
} // namespace dpp
|
||||
251
DPP-master/include/dpp/emoji.h
Normal file
251
DPP-master/include/dpp/emoji.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/misc-enum.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
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<emoji> {
|
||||
protected:
|
||||
friend struct json_interface<emoji>;
|
||||
|
||||
/**
|
||||
* @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<snowflake> 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 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(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<snowflake, emoji> emoji_map;
|
||||
|
||||
} // namespace dpp
|
||||
162
DPP-master/include/dpp/entitlement.h
Normal file
162
DPP-master/include/dpp/entitlement.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief The type of entitlement.
|
||||
* */
|
||||
enum entitlement_type : uint8_t {
|
||||
/**
|
||||
* @brief A subscription for a guild.
|
||||
* @warning This can only be used when creating a test entitlement.
|
||||
*/
|
||||
GUILD_SUBSCRIPTION = 1,
|
||||
|
||||
/**
|
||||
* @brief A subscription for a user.
|
||||
* @warning This can only be used when creating a test entitlement.
|
||||
*/
|
||||
USER_SUBSCRIPTION = 2,
|
||||
|
||||
/**
|
||||
* @brief Entitlement was purchased as an app subscription.
|
||||
*/
|
||||
APPLICATION_SUBSCRIPTION = 8
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Entitlement flags.
|
||||
*/
|
||||
enum entitlement_flags : uint16_t {
|
||||
/**
|
||||
* @brief Entitlement was deleted
|
||||
*/
|
||||
ent_deleted = 0b000000000000001,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A definition of a discord entitlement.
|
||||
*/
|
||||
class DPP_EXPORT entitlement : public managed, public json_interface<entitlement> {
|
||||
protected:
|
||||
friend struct json_interface<entitlement>;
|
||||
|
||||
/** 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 SKU
|
||||
*/
|
||||
snowflake sku_id{0};
|
||||
|
||||
/**
|
||||
* @brief ID of the parent application
|
||||
*/
|
||||
snowflake application_id{0};
|
||||
|
||||
/**
|
||||
* @brief Optional: ID of the user/guild that is granted access to the entitlement's SKU
|
||||
*/
|
||||
snowflake owner_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
|
||||
*/
|
||||
entitlement_type get_type() const;
|
||||
|
||||
/**
|
||||
* @brief Was the entitlement deleted?
|
||||
*
|
||||
* @return true if the entitlement was deleted.
|
||||
*/
|
||||
bool is_deleted() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Group of entitlements.
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, entitlement> entitlement_map;
|
||||
|
||||
} // namespace dpp
|
||||
711
DPP-master/include/dpp/etf.h
Normal file
711
DPP-master/include/dpp/etf.h
Normal file
@@ -0,0 +1,711 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
|
||||
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<char> 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);
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
157
DPP-master/include/dpp/event.h
Normal file
157
DPP-master/include/dpp/event.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
|
||||
#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);
|
||||
|
||||
/* 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);
|
||||
|
||||
} // namespace dpp::events
|
||||
767
DPP-master/include/dpp/event_router.h
Normal file
767
DPP-master/include/dpp/event_router.h
Normal file
@@ -0,0 +1,767 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <variant>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/misc-enum.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <cstring>
|
||||
#include <atomic>
|
||||
#include <dpp/exception.h>
|
||||
#include <dpp/coro/job.h>
|
||||
#include <dpp/coro/task.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
#ifdef DPP_CORO
|
||||
|
||||
template <typename T>
|
||||
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 <typename T>
|
||||
class awaitable {
|
||||
friend class event_router_t<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<T> *self;
|
||||
|
||||
/** @brief Predicate on the event, or nullptr for always match */
|
||||
std::function<bool (const T &)> 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<awaiter_state> 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 <typename F>
|
||||
awaitable(event_router_t<T> *router, F&& fun) : self{router}, predicate{std::forward<F>(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<log_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 T> class event_router_t {
|
||||
private:
|
||||
friend class cluster;
|
||||
|
||||
/**
|
||||
* @brief Non-coro event handler type
|
||||
*/
|
||||
using regular_handler_t = std::function<void(const T&)>;
|
||||
|
||||
/**
|
||||
* @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<regular_handler_t, std::function<task_dummy(T)>>;
|
||||
|
||||
#ifdef DPP_CORO
|
||||
friend class detail::event_router::awaitable<T>;
|
||||
|
||||
/** @brief dpp::task coro event handler */
|
||||
using task_handler_t = std::function<dpp::task<void>(const T&)>;
|
||||
|
||||
/** @brief Type that event handlers are stored as */
|
||||
using event_handler_t = std::variant<regular_handler_t, task_handler_t>;
|
||||
|
||||
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<event_handle, event_handler_t> dispatch_container;
|
||||
|
||||
#ifdef DPP_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<detail::event_router::awaitable<T> *> coro_awaiters;
|
||||
#else
|
||||
/**
|
||||
* @brief Dummy for ABI compatibility between DPP_CORO and not
|
||||
*/
|
||||
utility::dummy<std::shared_mutex> definitely_not_a_mutex;
|
||||
|
||||
/**
|
||||
* @brief Dummy for ABI compatibility between DPP_CORO and not
|
||||
*/
|
||||
utility::dummy<std::vector<void*>> 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<void(const T&)> 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<void(const T&)> 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<regular_handler_t>(listener)) {
|
||||
std::get<regular_handler_t>(listener)(event);
|
||||
} else {
|
||||
throw dpp::logic_exception("cannot handle a coroutine event handler with a library built without DPP_CORO");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef DPP_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<dpp::task<void>> tasks;
|
||||
{
|
||||
std::shared_lock l(mutex);
|
||||
|
||||
for (const auto& [_, listener] : dispatch_container) {
|
||||
if (!event.is_cancelled()) {
|
||||
if (std::holds_alternative<task_handler_t>(listener)) {
|
||||
tasks.push_back(std::get<task_handler_t>(listener)(event));
|
||||
} else if (std::holds_alternative<regular_handler_t>(listener)) {
|
||||
std::get<regular_handler_t>(listener)(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for (dpp::task<void>& 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<T> *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<T> 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<detail::event_router::awaitable<T>*> to_resume;
|
||||
std::unique_lock lock{coro_mutex};
|
||||
|
||||
for (auto it = coro_awaiters.begin(); it != coro_awaiters.end();) {
|
||||
detail::event_router::awaitable<T>* 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<T>* 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() {
|
||||
#ifdef DPP_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 {
|
||||
#ifdef DPP_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 {
|
||||
#ifdef DPP_CORO
|
||||
handle_coro(std::move(event));
|
||||
#else
|
||||
handle(std::move(event));
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef DPP_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::job my_handler(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 <b>a reference</b> 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 <typename Predicate>
|
||||
#ifndef _DOXYGEN_
|
||||
requires utility::callable_returns<Predicate, bool, const T&>
|
||||
#endif
|
||||
auto when(Predicate&& pred)
|
||||
#ifndef _DOXYGEN_
|
||||
noexcept(noexcept(std::function<bool(const T&)>{std::declval<Predicate>()}))
|
||||
#endif
|
||||
{
|
||||
return detail::event_router::awaitable<T>{this, std::forward<Predicate>(pred)};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Obtain an awaitable object that refers to any event.
|
||||
* It can be co_await-ed to wait for the next event.
|
||||
*
|
||||
* Example:
|
||||
* @details Example: @code{cpp}
|
||||
* dpp::job my_handler(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 <b>a reference</b> 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<T>{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 {
|
||||
#ifdef DPP_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<void>(const T&)` (the latter requires DPP_CORO to be defined),
|
||||
* 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 <typename F>
|
||||
[[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<void>(const T&)` (the latter requires DPP_CORO to be defined),
|
||||
* 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 <typename F>
|
||||
[[maybe_unused]] event_handle attach(F&& fun);
|
||||
#else /* not _DOXYGEN_ */
|
||||
# ifdef DPP_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<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 <typename F>
|
||||
requires (utility::callable_returns<F, dpp::job, const T&> || utility::callable_returns<F, dpp::task<void>, const T&> || utility::callable_returns<F, void, const T&>)
|
||||
[[maybe_unused]] event_handle operator()(F&& fun) {
|
||||
return this->attach(std::forward<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<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 <typename F>
|
||||
requires (utility::callable_returns<F, void, const T&>)
|
||||
[[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<regular_handler_t>{}, std::forward<F>(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<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 <typename F>
|
||||
requires (utility::callable_returns<F, task<void>, 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<task_handler_t>{}, std::forward<F>(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<void>(const T&)`, where T is the event type for this event router.
|
||||
*
|
||||
* @deprecated dpp::job event handlers are deprecated and will be removed in a future version, use dpp::task<void> instead.
|
||||
* @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 <typename F>
|
||||
requires (utility::callable_returns<F, dpp::job, const T&>)
|
||||
DPP_DEPRECATED("dpp::job event handlers are deprecated and will be removed in a future version, use dpp::task<void> instead")
|
||||
[[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<regular_handler_t>{}, std::forward<F>(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 <typename F>
|
||||
[[maybe_unused]] std::enable_if_t<utility::callable_returns_v<F, void, const T&>, event_handle> operator()(F&& fun) {
|
||||
return this->attach(std::forward<F>(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.
|
||||
*
|
||||
* @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 <typename F>
|
||||
[[maybe_unused]] std::enable_if_t<utility::callable_returns_v<F, void, const T&>, event_handle> attach(F&& fun) {
|
||||
std::unique_lock l(mutex);
|
||||
event_handle h = next_handle++;
|
||||
dispatch_container.emplace(h, std::forward<F>(fun));
|
||||
return h;
|
||||
}
|
||||
# endif /* DPP_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);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef DPP_CORO
|
||||
|
||||
namespace detail::event_router {
|
||||
|
||||
template <typename T>
|
||||
void awaitable<T>::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 <typename T>
|
||||
constexpr bool awaitable<T>::await_ready() const noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void awaitable<T>::await_suspend(detail::std_coroutine::coroutine_handle<> caller) {
|
||||
state.store(awaiter_state::waiting);
|
||||
handle = caller.address();
|
||||
self->attach_awaiter(this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T &awaitable<T>::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
|
||||
|
||||
} // namespace dpp
|
||||
605
DPP-master/include/dpp/exception.h
Normal file
605
DPP-master/include/dpp/exception.h
Normal file
@@ -0,0 +1,605 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <algorithm>
|
||||
|
||||
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, sodium 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_sodium = 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 { };
|
||||
#ifdef DPP_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_CORO */
|
||||
#else
|
||||
derived_exception(logic_exception, exception);
|
||||
derived_exception(file_exception, exception);
|
||||
derived_exception(connection_exception, exception);
|
||||
derived_exception(voice_exception, 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);
|
||||
# ifdef DPP_CORO
|
||||
derived_exception(task_cancelled_exception, exception);
|
||||
# endif /* DPP_CORO */
|
||||
#endif
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
137
DPP-master/include/dpp/export.h
Normal file
137
DPP-master/include/dpp/export.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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
|
||||
|
||||
#ifndef DPP_STATIC
|
||||
/* Dynamic linked build as shared object or dll */
|
||||
#ifdef DPP_BUILD
|
||||
/* Building the library */
|
||||
#ifdef _WIN32
|
||||
#include <dpp/win32_safe_warnings.h>
|
||||
#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 <dpp/win32_safe_warnings.h>
|
||||
#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 <build_type>
|
||||
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<build_type::debug>();
|
||||
#else
|
||||
inline const bool is_valid_config = validate_configuration<build_type::release>();
|
||||
#endif /* _DEBUG */
|
||||
#else
|
||||
inline const bool is_valid_config = validate_configuration<build_type::universal>();
|
||||
#endif /* _WIN32 */
|
||||
#endif /* !DPP_BYPASS_VERSION_CHECKING */
|
||||
#endif /* !DPP_BUILD */
|
||||
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#define SOCKET int
|
||||
#else
|
||||
#define NOMINMAX
|
||||
|
||||
#include <WinSock2.h>
|
||||
#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_ */
|
||||
2041
DPP-master/include/dpp/guild.h
Normal file
2041
DPP-master/include/dpp/guild.h
Normal file
File diff suppressed because it is too large
Load Diff
354
DPP-master/include/dpp/httpsclient.h
Normal file
354
DPP-master/include/dpp/httpsclient.h
Normal file
@@ -0,0 +1,354 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <dpp/sslclient.h>
|
||||
#include <dpp/version.h>
|
||||
#include <dpp/stringops.h>
|
||||
|
||||
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<std::string, std::string> 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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_client {
|
||||
/**
|
||||
* @brief Current connection state
|
||||
*/
|
||||
http_state state;
|
||||
|
||||
/**
|
||||
* @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<std::string, std::string> response_headers;
|
||||
|
||||
/**
|
||||
* @brief Handle input buffer
|
||||
*
|
||||
* @param buffer Buffer to read
|
||||
* @return returns true if the connection should remain open
|
||||
*/
|
||||
bool do_buffer(std::string& buffer);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Start the connection
|
||||
*/
|
||||
virtual void connect();
|
||||
|
||||
/**
|
||||
* @brief Get request state
|
||||
* @return request state
|
||||
*/
|
||||
http_state get_state();
|
||||
|
||||
public:
|
||||
/**
|
||||
* @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 http_protocol Request HTTP protocol
|
||||
*/
|
||||
https_client(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");
|
||||
|
||||
/**
|
||||
* @brief Destroy the https client object
|
||||
*/
|
||||
virtual ~https_client() = default;
|
||||
|
||||
/**
|
||||
* @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<std::string>& filenames = {}, const std::vector<std::string>& contents = {}, const std::vector<std::string>& 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);
|
||||
|
||||
/**
|
||||
* @brief Close HTTPS socket
|
||||
*/
|
||||
virtual void close();
|
||||
|
||||
/**
|
||||
* @brief Fires every second from the underlying socket I/O loop, used for timeouts
|
||||
*/
|
||||
virtual void one_second_timer();
|
||||
|
||||
/**
|
||||
* @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<std::string> get_header_list(std::string header_name) const;
|
||||
|
||||
/**
|
||||
* @brief Get all HTTP response headers
|
||||
*
|
||||
* @return headers as a map
|
||||
*/
|
||||
const std::multimap<std::string, std::string> 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);
|
||||
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
339
DPP-master/include/dpp/integration.h
Normal file
339
DPP-master/include/dpp/integration.h
Normal file
@@ -0,0 +1,339 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
#include <dpp/user.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Integration types
|
||||
*/
|
||||
enum integration_type {
|
||||
/**
|
||||
* @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 {
|
||||
/**
|
||||
* @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<integration> {
|
||||
protected:
|
||||
friend struct json_interface<integration>;
|
||||
|
||||
/** 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<std::string> 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<connection> {
|
||||
protected:
|
||||
friend struct json_interface<connection>;
|
||||
|
||||
/** 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<integration> 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<snowflake, integration> integration_map;
|
||||
|
||||
/**
|
||||
* @brief A group of connections
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, connection> connection_map;
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
155
DPP-master/include/dpp/intents.h
Normal file
155
DPP-master/include/dpp/intents.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
245
DPP-master/include/dpp/invite.h
Normal file
245
DPP-master/include/dpp/invite.h
Normal file
@@ -0,0 +1,245 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/stage_instance.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/guild.h>
|
||||
|
||||
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<invite> {
|
||||
protected:
|
||||
friend struct json_interface<invite>;
|
||||
|
||||
/** 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<std::string, invite> invite_map;
|
||||
|
||||
} // namespace dpp
|
||||
110
DPP-master/include/dpp/isa/avx.h
Normal file
110
DPP-master/include/dpp/isa/avx.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <immintrin.h>
|
||||
#include <numeric>
|
||||
|
||||
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<float>(std::numeric_limits<int16_t>::min()))),
|
||||
_mm_min_ps(current_samples_new, _mm_set1_ps(static_cast<float>(std::numeric_limits<int16_t>::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<typename value_type> 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<value_type>(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<typename value_type> inline avx_float gather_values(value_type* values_new) {
|
||||
for (uint64_t x = 0; x < byte_blocks_per_register; ++x) {
|
||||
values[x] = static_cast<float>(values_new[x]);
|
||||
}
|
||||
return _mm_load_ps(values);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
#endif
|
||||
113
DPP-master/include/dpp/isa/avx2.h
Normal file
113
DPP-master/include/dpp/isa/avx2.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <immintrin.h>
|
||||
#include <numeric>
|
||||
|
||||
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<float>(std::numeric_limits<int16_t>::min()))),
|
||||
_mm256_min_ps(current_samples_new, _mm256_set1_ps(static_cast<float>(std::numeric_limits<int16_t>::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<typename value_type> 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<value_type>(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<typename value_type> 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<float>(values_new[x]);
|
||||
}
|
||||
return _mm256_load_ps(values);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
#endif
|
||||
116
DPP-master/include/dpp/isa/avx512.h
Normal file
116
DPP-master/include/dpp/isa/avx512.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <immintrin.h>
|
||||
#include <numeric>
|
||||
|
||||
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<float>(std::numeric_limits<int16_t>::min()));
|
||||
__m512 upper_limit = _mm512_set1_ps(static_cast<float>(std::numeric_limits<int16_t>::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<typename value_type> 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<value_type>(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<typename value_type> 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<float>(values_new[x]);
|
||||
}
|
||||
return _mm512_load_ps(values);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
#endif
|
||||
76
DPP-master/include/dpp/isa/fallback.h
Normal file
76
DPP-master/include/dpp/isa/fallback.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <numeric>
|
||||
|
||||
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<int16_t>::max()) {
|
||||
current_sample_new = std::numeric_limits<int16_t>::max();
|
||||
}
|
||||
else if (current_sample_new <= std::numeric_limits<int16_t>::min()) {
|
||||
current_sample_new = std::numeric_limits<int16_t>::min();
|
||||
}
|
||||
data_out[x] = static_cast<int16_t>(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<int32_t>(decoded_data[x]);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
31
DPP-master/include/dpp/isa_detection.h
Normal file
31
DPP-master/include/dpp/isa_detection.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 == 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
|
||||
32
DPP-master/include/dpp/json.h
Normal file
32
DPP-master/include/dpp/json.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <nlohmann/json.hpp>
|
||||
#else
|
||||
#include <dpp/nlohmann/json.hpp>
|
||||
#endif
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
}
|
||||
32
DPP-master/include/dpp/json_fwd.h
Normal file
32
DPP-master/include/dpp/json_fwd.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <nlohmann/json_fwd.hpp>
|
||||
#else
|
||||
#include <dpp/nlohmann/json_fwd.hpp>
|
||||
#endif
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
}
|
||||
73
DPP-master/include/dpp/json_interface.h
Normal file
73
DPP-master/include/dpp/json_interface.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
|
||||
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<typename T>
|
||||
struct json_interface {
|
||||
/**
|
||||
* @brief Convert object from nlohmann::json
|
||||
*
|
||||
* @param j nlohmann::json object
|
||||
* @return T& Reference to self for fluent calling
|
||||
*/
|
||||
template <typename U = T, typename = decltype(std::declval<U&>().fill_from_json_impl(std::declval<nlohmann::json*>()))>
|
||||
T& fill_from_json(nlohmann::json* j) {
|
||||
return static_cast<T*>(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 <typename U = T, typename = decltype(std::declval<U&>().to_json_impl(bool{}))>
|
||||
auto to_json(bool with_id = false) const {
|
||||
return static_cast<const T*>(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 <typename U = T, typename = decltype(std::declval<U&>().to_json_impl(bool{}))>
|
||||
std::string build_json(bool with_id = false) const {
|
||||
return to_json(with_id).dump();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
116
DPP-master/include/dpp/managed.h
Normal file
116
DPP-master/include/dpp/managed.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <string>
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
2289
DPP-master/include/dpp/message.h
Normal file
2289
DPP-master/include/dpp/message.h
Normal file
File diff suppressed because it is too large
Load Diff
88
DPP-master/include/dpp/misc-enum.h
Normal file
88
DPP-master/include/dpp/misc-enum.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Supported image types for profile pictures and CDN endpoints
|
||||
*/
|
||||
enum image_type {
|
||||
/**
|
||||
* @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
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
24596
DPP-master/include/dpp/nlohmann/json.hpp
Normal file
24596
DPP-master/include/dpp/nlohmann/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
175
DPP-master/include/dpp/nlohmann/json_fwd.hpp
Normal file
175
DPP-master/include/dpp/nlohmann/json_fwd.hpp
Normal file
@@ -0,0 +1,175 @@
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++
|
||||
// | | |__ | | | | | | version 3.11.2
|
||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||
|
||||
#include <cstdint> // int64_t, uint64_t
|
||||
#include <map> // map
|
||||
#include <memory> // allocator
|
||||
#include <string> // string
|
||||
#include <vector> // vector
|
||||
|
||||
// #include <nlohmann/detail/abi_macros.hpp>
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++
|
||||
// | | |__ | | | | | | version 3.11.2
|
||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
|
||||
// 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
|
||||
|
||||
|
||||
/*!
|
||||
@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<typename T = void, typename SFINAE = void>
|
||||
struct adl_serializer;
|
||||
|
||||
/// a class to store JSON values
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/
|
||||
template<template<typename U, typename V, typename... Args> class ObjectType =
|
||||
std::map,
|
||||
template<typename U, typename... Args> 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<typename U> class AllocatorType = std::allocator,
|
||||
template<typename T, typename SFINAE = void> class JSONSerializer =
|
||||
adl_serializer,
|
||||
class BinaryType = std::vector<std::uint8_t>>
|
||||
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<typename RefStringType>
|
||||
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<class Key, class T, class IgnoredLess, class Allocator>
|
||||
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::ordered_map>;
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
|
||||
#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||
46
DPP-master/include/dpp/once.h
Normal file
46
DPP-master/include/dpp/once.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <utility>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Run some code within an if() statement only once.
|
||||
*
|
||||
* Use this template like this:
|
||||
*
|
||||
* ```
|
||||
* if (dpp::run_once<struct any_unique_name_you_like_here>()) {
|
||||
* // Your code here
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @tparam T any unique 'tag' identifier name
|
||||
* @return auto a true/false return to say if we should execute or not
|
||||
*/
|
||||
template <typename T> auto run_once() {
|
||||
static auto called = false;
|
||||
return !std::exchange(called, true);
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
459
DPP-master/include/dpp/permissions.h
Normal file
459
DPP-master/include/dpp/permissions.h
Normal file
@@ -0,0 +1,459 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/json.h>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Represents the various discord permissions
|
||||
*/
|
||||
enum permissions : uint64_t {
|
||||
/**
|
||||
* @brief Allows creation of instant invites.
|
||||
*/
|
||||
p_create_instant_invite = 0x00000000001,
|
||||
|
||||
/**
|
||||
* @brief Allows kicking members.
|
||||
*/
|
||||
p_kick_members = 0x00000000002,
|
||||
|
||||
/**
|
||||
* @brief Allows banning members.
|
||||
*/
|
||||
p_ban_members = 0x00000000004,
|
||||
|
||||
/**
|
||||
* @brief Allows all permissions and bypasses channel permission overwrites.
|
||||
*/
|
||||
p_administrator = 0x00000000008,
|
||||
|
||||
/**
|
||||
* @brief Allows management and editing of channels.
|
||||
*/
|
||||
p_manage_channels = 0x00000000010,
|
||||
|
||||
/**
|
||||
* @brief Allows management and editing of the guild.
|
||||
*/
|
||||
p_manage_guild = 0x00000000020,
|
||||
|
||||
/**
|
||||
* @brief Allows for the addition of reactions to messages.
|
||||
*/
|
||||
p_add_reactions = 0x00000000040,
|
||||
|
||||
/**
|
||||
* @brief Allows for viewing of audit logs.
|
||||
*/
|
||||
p_view_audit_log = 0x00000000080,
|
||||
|
||||
/**
|
||||
* @brief Allows for using priority speaker in a voice channel.
|
||||
*/
|
||||
p_priority_speaker = 0x00000000100,
|
||||
|
||||
/**
|
||||
* @brief Allows the user to go live.
|
||||
*/
|
||||
p_stream = 0x00000000200,
|
||||
|
||||
/**
|
||||
* @brief Allows guild members to view a channel,
|
||||
* which includes reading messages in text channels and joining voice channels.
|
||||
*/
|
||||
p_view_channel = 0x00000000400,
|
||||
|
||||
/**
|
||||
* @brief Allows for sending messages in a channel.
|
||||
*/
|
||||
p_send_messages = 0x00000000800,
|
||||
|
||||
/**
|
||||
* @brief Allows for sending of /tts messages.
|
||||
*/
|
||||
p_send_tts_messages = 0x00000001000,
|
||||
|
||||
/**
|
||||
* @brief Allows for deletion of other users messages.
|
||||
*/
|
||||
p_manage_messages = 0x00000002000,
|
||||
|
||||
/**
|
||||
* @brief Links sent by users with this permission will be auto-embedded.
|
||||
*/
|
||||
p_embed_links = 0x00000004000,
|
||||
|
||||
/**
|
||||
* @brief Allows for uploading images and files.
|
||||
*/
|
||||
p_attach_files = 0x00000008000,
|
||||
|
||||
/**
|
||||
* @brief Allows for reading of message history.
|
||||
*/
|
||||
p_read_message_history = 0x00000010000,
|
||||
|
||||
/**
|
||||
* @brief Allows for using the everyone and the here tag to notify users in a channel.
|
||||
*/
|
||||
p_mention_everyone = 0x00000020000,
|
||||
|
||||
/**
|
||||
* @brief Allows the usage of custom emojis from other servers.
|
||||
*/
|
||||
p_use_external_emojis = 0x00000040000,
|
||||
|
||||
/**
|
||||
* @brief Allows for viewing guild insights.
|
||||
*/
|
||||
p_view_guild_insights = 0x00000080000,
|
||||
|
||||
/**
|
||||
* @brief Allows for joining of a voice channel.
|
||||
*/
|
||||
p_connect = 0x00000100000,
|
||||
|
||||
/**
|
||||
* @brief Allows for speaking in a voice channel.
|
||||
*/
|
||||
p_speak = 0x00000200000,
|
||||
|
||||
/**
|
||||
* @brief Allows for muting members in a voice channel.
|
||||
*/
|
||||
p_mute_members = 0x00000400000,
|
||||
|
||||
/**
|
||||
* @brief Allows for deafening of members in a voice channel.
|
||||
*/
|
||||
p_deafen_members = 0x00000800000,
|
||||
|
||||
/**
|
||||
* @brief Allows for moving of members between voice channels.
|
||||
*/
|
||||
p_move_members = 0x00001000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for using voice-activity-detection in a voice channel.
|
||||
*/
|
||||
p_use_vad = 0x00002000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for modification of own nickname.
|
||||
*/
|
||||
p_change_nickname = 0x00004000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for modification of other users nicknames.
|
||||
*/
|
||||
p_manage_nicknames = 0x00008000000,
|
||||
|
||||
/**
|
||||
* @brief Allows management and editing of roles.
|
||||
*/
|
||||
p_manage_roles = 0x00010000000,
|
||||
|
||||
/**
|
||||
* @brief Allows management and editing of webhooks.
|
||||
*/
|
||||
p_manage_webhooks = 0x00020000000,
|
||||
|
||||
/**
|
||||
* @brief Allows management and editing of emojis and stickers.
|
||||
*/
|
||||
p_manage_emojis_and_stickers = 0x00040000000,
|
||||
|
||||
/**
|
||||
* @brief Allows members to use application commands,
|
||||
* including slash commands and context menus.
|
||||
*/
|
||||
p_use_application_commands = 0x00080000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for requesting to speak in stage channels.
|
||||
*
|
||||
* @warning Discord: This permission is under active development and may be changed or removed.
|
||||
*/
|
||||
p_request_to_speak = 0x00100000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for management (creation, updating, deleting, starting) of scheduled events.
|
||||
*/
|
||||
p_manage_events = 0x00200000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for deleting and archiving threads, and viewing all private threads.
|
||||
*/
|
||||
p_manage_threads = 0x00400000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for creating public and announcement threads.
|
||||
*/
|
||||
p_create_public_threads = 0x00800000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for creating private threads.
|
||||
*/
|
||||
p_create_private_threads = 0x01000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows the usage of custom stickers from other servers.
|
||||
*/
|
||||
p_use_external_stickers = 0x02000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for sending messages in threads.
|
||||
*/
|
||||
p_send_messages_in_threads = 0x04000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for using activities (applications with the EMBEDDED flag) in a voice channel.
|
||||
*/
|
||||
p_use_embedded_activities = 0x08000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for timing out users
|
||||
* to prevent them from sending or reacting to messages in chat and threads,
|
||||
* and from speaking in voice and stage channels.
|
||||
*/
|
||||
p_moderate_members = 0x10000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for viewing role subscription insights.
|
||||
*/
|
||||
p_view_creator_monetization_analytics = 0x20000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows for using soundboard in a voice channel.
|
||||
*/
|
||||
p_use_soundboard = 0x40000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows the usage of custom soundboard sounds from other servers.
|
||||
*/
|
||||
p_use_external_sounds = 0x0000200000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows sending voice messages.
|
||||
*/
|
||||
p_send_voice_messages = 0x0000400000000000,
|
||||
|
||||
/**
|
||||
* @brief Allows use of Clyde AI.
|
||||
*/
|
||||
p_use_clyde_ai = 0x0000800000000000,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the various discord permissions
|
||||
* @deprecated Use dpp::permissions instead.
|
||||
*/
|
||||
using role_permissions = permissions;
|
||||
|
||||
/**
|
||||
* @brief Represents a permission bitmask (refer to enum dpp::permissions) which are held in an uint64_t
|
||||
*/
|
||||
class DPP_EXPORT permission {
|
||||
protected:
|
||||
/**
|
||||
* @brief The permission bitmask value
|
||||
*/
|
||||
uint64_t value{0};
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor, initializes permission to 0
|
||||
*/
|
||||
constexpr permission() = default;
|
||||
|
||||
/**
|
||||
* @brief Bitmask constructor, initializes permission to the argument
|
||||
* @param value The bitmask to initialize the permission to
|
||||
*/
|
||||
constexpr permission(uint64_t value) noexcept : value{value} {}
|
||||
|
||||
/**
|
||||
* @brief For acting like an integer
|
||||
* @return The permission bitmask value
|
||||
*/
|
||||
constexpr operator uint64_t() const noexcept {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For acting like an integer
|
||||
* @return A reference to the permission bitmask value
|
||||
*/
|
||||
constexpr operator uint64_t &() noexcept {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For building json
|
||||
* @return The permission bitmask value as a string
|
||||
*/
|
||||
operator nlohmann::json() const;
|
||||
|
||||
/**
|
||||
* @brief Check for certain permissions, taking into account administrator privileges. It uses the Bitwise AND operator
|
||||
* @tparam T one or more uint64_t permission bits
|
||||
* @param values The permissions (from dpp::permissions) to check for
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```cpp
|
||||
* bool is_mod = permission.can(dpp::p_kick_members, dpp::p_ban_members);
|
||||
* // Returns true if it has permission to p_kick_members and p_ban_members
|
||||
* ```
|
||||
*
|
||||
* @return bool True if it has **all** the given permissions or dpp::p_administrator
|
||||
*/
|
||||
template <typename... T>
|
||||
constexpr bool can(T... values) const noexcept {
|
||||
return has(values...) || (value & p_administrator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for certain permissions, taking into account administrator privileges. It uses the Bitwise AND operator
|
||||
* @tparam T one or more uint64_t permission bits
|
||||
* @param values The permissions (from dpp::permissions) to check for
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```cpp
|
||||
* bool is_mod = permission.can_any(dpp::p_kick_members, dpp::p_ban_members);
|
||||
* // Returns true if it has permission to p_kick_members or p_ban_members
|
||||
* ```
|
||||
*
|
||||
* @return bool True if it has **any** of the given permissions or dpp::p_administrator
|
||||
*/
|
||||
template <typename... T>
|
||||
constexpr bool can_any(T... values) const noexcept {
|
||||
return has_any(values...) || (value & p_administrator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for permission flags set. It uses the Bitwise AND operator
|
||||
* @tparam T one or more uint64_t permission bits
|
||||
* @param values The permissions (from dpp::permissions) to check for
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```cpp
|
||||
* bool is_mod = permission.has(dpp::p_kick_members, dpp::p_ban_members);
|
||||
* // Returns true if the permission bitmask contains p_kick_members and p_ban_members
|
||||
* ```
|
||||
*
|
||||
* @return bool True if it has **all** the given permissions
|
||||
*/
|
||||
template <typename... T>
|
||||
constexpr bool has(T... values) const noexcept {
|
||||
return (value & (0 | ... | values)) == (0 | ... | values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for permission flags set. It uses the Bitwise AND operator
|
||||
* @tparam T one or more uint64_t permission bits
|
||||
* @param values The permissions (from dpp::permissions) to check for
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```cpp
|
||||
* bool is_mod = permission.has_any(dpp::p_administrator, dpp::p_ban_members);
|
||||
* // Returns true if the permission bitmask contains p_administrator or p_ban_members
|
||||
* ```
|
||||
*
|
||||
* @return bool True if it has **any** of the given permissions
|
||||
*/
|
||||
template <typename... T>
|
||||
constexpr bool has_any(T... values) const noexcept {
|
||||
return (value & (0 | ... | values)) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a permission with the Bitwise OR operation
|
||||
* @tparam T one or more uint64_t permission bits
|
||||
* @param values The permissions (from dpp::permissions) to add
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```cpp
|
||||
* permission.add(dpp::p_view_channel, dpp::p_send_messages);
|
||||
* // Adds p_view_channel and p_send_messages to the permission bitmask
|
||||
* ```
|
||||
*
|
||||
* @return permission& reference to self for chaining
|
||||
*/
|
||||
template <typename... T>
|
||||
std::enable_if_t<(std::is_convertible_v<T, uint64_t> && ...), permission&>
|
||||
constexpr add(T... values) noexcept {
|
||||
value |= (0 | ... | values);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assign permissions. This will reset the bitmask to the new value.
|
||||
* @tparam T one or more uint64_t permission bits
|
||||
* @param values The permissions (from dpp::permissions) to set
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```cpp
|
||||
* permission.set(dpp::p_view_channel, dpp::p_send_messages);
|
||||
* ```
|
||||
*
|
||||
* @return permission& reference to self for chaining
|
||||
*/
|
||||
template <typename... T>
|
||||
std::enable_if_t<(std::is_convertible_v<T, uint64_t> && ...), permission&>
|
||||
constexpr set(T... values) noexcept {
|
||||
value = (0 | ... | values);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a permission with the Bitwise NOT operation
|
||||
* @tparam T one or more uint64_t permission bits
|
||||
* @param values The permissions (from dpp::permissions) to remove
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```cpp
|
||||
* permission.remove(dpp::p_view_channel, dpp::p_send_messages);
|
||||
* // Removes p_view_channel and p_send_messages permission
|
||||
* ```
|
||||
*
|
||||
* @return permission& reference to self for chaining
|
||||
*/
|
||||
template <typename... T>
|
||||
std::enable_if_t<(std::is_convertible_v<T, uint64_t> && ...), permission&>
|
||||
constexpr remove(T... values) noexcept {
|
||||
value &= ~(0 | ... | values);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
598
DPP-master/include/dpp/presence.h
Normal file
598
DPP-master/include/dpp/presence.h
Normal file
@@ -0,0 +1,598 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/emoji.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Presence flags bitmask
|
||||
*/
|
||||
enum presence_flags {
|
||||
/**
|
||||
* @brief Desktop: Online.
|
||||
*/
|
||||
p_desktop_online = 0b00000001,
|
||||
|
||||
/**
|
||||
* @brief Desktop: DND.
|
||||
*/
|
||||
p_desktop_dnd = 0b00000010,
|
||||
|
||||
/**
|
||||
* @brief Desktop: Idle.
|
||||
*/
|
||||
p_desktop_idle = 0b00000011,
|
||||
|
||||
/**
|
||||
* @brief Web: Online.
|
||||
*/
|
||||
p_web_online = 0b00000100,
|
||||
|
||||
/**
|
||||
* @brief Web: DND.
|
||||
*/
|
||||
p_web_dnd = 0b00001000,
|
||||
|
||||
/**
|
||||
* @brief Web: Idle.
|
||||
*/
|
||||
p_web_idle = 0b00001100,
|
||||
|
||||
/**
|
||||
* @brief Mobile: Online.
|
||||
*/
|
||||
p_mobile_online = 0b00010000,
|
||||
|
||||
/**
|
||||
* @brief Mobile: DND.
|
||||
*/
|
||||
p_mobile_dnd = 0b00100000,
|
||||
|
||||
/**
|
||||
* @brief Mobile: Idle.
|
||||
*/
|
||||
p_mobile_idle = 0b00110000,
|
||||
|
||||
/**
|
||||
* @brief General: Online.
|
||||
*/
|
||||
p_status_online = 0b01000000,
|
||||
|
||||
/**
|
||||
* @brief General: DND.
|
||||
*/
|
||||
p_status_dnd = 0b10000000,
|
||||
|
||||
/**
|
||||
* @brief General: Idle.
|
||||
*/
|
||||
p_status_idle = 0b11000000
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Online presence status values
|
||||
*/
|
||||
enum presence_status : uint8_t {
|
||||
/**
|
||||
* @brief Offline.
|
||||
*/
|
||||
ps_offline = 0,
|
||||
|
||||
/**
|
||||
* @brief Online.
|
||||
*/
|
||||
ps_online = 1,
|
||||
|
||||
/**
|
||||
* @brief DND.
|
||||
*/
|
||||
ps_dnd = 2,
|
||||
|
||||
/**
|
||||
* @brief Idle.
|
||||
*/
|
||||
ps_idle = 3,
|
||||
|
||||
/**
|
||||
* @brief Invisible (show as offline).
|
||||
*/
|
||||
ps_invisible = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Bit shift for desktop status.
|
||||
*/
|
||||
#define PF_SHIFT_DESKTOP 0
|
||||
|
||||
/**
|
||||
* @brief Bit shift for web status.
|
||||
*/
|
||||
#define PF_SHIFT_WEB 2
|
||||
|
||||
/**
|
||||
* @brief Bit shift for mobile status.
|
||||
*/
|
||||
#define PF_SHIFT_MOBILE 4
|
||||
|
||||
/**
|
||||
* @brief Bit shift for main status.
|
||||
*/
|
||||
#define PF_SHIFT_MAIN 6
|
||||
|
||||
/**
|
||||
* @brief Bit mask for status.
|
||||
*/
|
||||
#define PF_STATUS_MASK 0b00000011
|
||||
|
||||
/**
|
||||
* @brief Bit mask for clearing desktop status.
|
||||
*/
|
||||
#define PF_CLEAR_DESKTOP 0b11111100
|
||||
|
||||
/**
|
||||
* @brief Bit mask for clearing web status.
|
||||
*/
|
||||
#define PF_CLEAR_WEB 0b11110011
|
||||
|
||||
/**
|
||||
* @brief Bit mask for clearing mobile status.
|
||||
*/
|
||||
#define PF_CLEAR_MOBILE 0b11001111
|
||||
|
||||
/**
|
||||
* @brief Bit mask for clearing main status.
|
||||
*/
|
||||
#define PF_CLEAR_STATUS 0b00111111
|
||||
|
||||
/**
|
||||
* @brief Game types
|
||||
*/
|
||||
enum activity_type : uint8_t {
|
||||
/**
|
||||
* @brief "Playing ..."
|
||||
*/
|
||||
at_game = 0,
|
||||
|
||||
/**
|
||||
* @brief "Streaming ..."
|
||||
*/
|
||||
at_streaming = 1,
|
||||
|
||||
/**
|
||||
* @brief "Listening to..."
|
||||
*/
|
||||
at_listening = 2,
|
||||
|
||||
/**
|
||||
* @brief "Watching..."
|
||||
*/
|
||||
at_watching = 3,
|
||||
|
||||
/**
|
||||
* @brief "Emoji..."
|
||||
*/
|
||||
at_custom = 4,
|
||||
|
||||
/**
|
||||
* @brief "Competing in..."
|
||||
*/
|
||||
at_competing = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Activity types for rich presence
|
||||
*/
|
||||
enum activity_flags {
|
||||
/**
|
||||
* @brief In an instance.
|
||||
*/
|
||||
af_instance = 0b000000001,
|
||||
|
||||
/**
|
||||
* @brief Joining.
|
||||
*/
|
||||
af_join = 0b000000010,
|
||||
|
||||
/**
|
||||
* @brief Spectating.
|
||||
*/
|
||||
af_spectate = 0b000000100,
|
||||
|
||||
/**
|
||||
* @brief Sending join request.
|
||||
*/
|
||||
af_join_request = 0b000001000,
|
||||
|
||||
/**
|
||||
* @brief Synchronising.
|
||||
*/
|
||||
af_sync = 0b000010000,
|
||||
|
||||
/**
|
||||
* @brief Playing.
|
||||
*/
|
||||
af_play = 0b000100000,
|
||||
|
||||
/**
|
||||
* @brief Party privacy friends.
|
||||
*/
|
||||
af_party_privacy_friends = 0b001000000,
|
||||
|
||||
/**
|
||||
* @brief Party privacy voice channel.
|
||||
*/
|
||||
af_party_privacy_voice_channel = 0b010000000,
|
||||
|
||||
/**
|
||||
* @brief Embedded.
|
||||
*/
|
||||
af_embedded = 0b100000000
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An activity button is a custom button shown in the rich presence. Can be to join a game or whatever
|
||||
*/
|
||||
struct DPP_EXPORT activity_button {
|
||||
public:
|
||||
/**
|
||||
* @brief The text shown on the button (1-32 characters).
|
||||
*/
|
||||
std::string label;
|
||||
|
||||
/**
|
||||
* @brief The url opened when clicking the button (1-512 characters, can be empty).
|
||||
*
|
||||
* @note Bots cannot access the activity button URLs.
|
||||
*/
|
||||
std::string url;
|
||||
|
||||
/** Constructor */
|
||||
activity_button() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An activity asset are the images and the hover text displayed in the rich presence
|
||||
*/
|
||||
struct DPP_EXPORT activity_assets {
|
||||
public:
|
||||
/**
|
||||
* @brief The large asset image which usually contain snowflake ID or prefixed image ID.
|
||||
*/
|
||||
std::string large_image;
|
||||
|
||||
/**
|
||||
* @brief Text displayed when hovering over the large image of the activity.
|
||||
*/
|
||||
std::string large_text;
|
||||
|
||||
/**
|
||||
* @brief The small asset image which usually contain snowflake ID or prefixed image ID.
|
||||
*/
|
||||
std::string small_image;
|
||||
|
||||
/**
|
||||
* @brief Text displayed when hovering over the small image of the activity.
|
||||
*/
|
||||
std::string small_text;
|
||||
|
||||
/** Constructor */
|
||||
activity_assets() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Secrets for Rich Presence joining and spectating.
|
||||
*/
|
||||
struct DPP_EXPORT activity_secrets {
|
||||
public:
|
||||
/**
|
||||
* @brief The secret for joining a party.
|
||||
*/
|
||||
std::string join;
|
||||
|
||||
/**
|
||||
* @brief The secret for spectating a game.
|
||||
*/
|
||||
std::string spectate;
|
||||
|
||||
/**
|
||||
* @brief The secret for a specific instanced match.
|
||||
*/
|
||||
std::string match;
|
||||
|
||||
/** Constructor */
|
||||
activity_secrets() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Information for the current party of the player
|
||||
*/
|
||||
struct DPP_EXPORT activity_party {
|
||||
public:
|
||||
/**
|
||||
* @brief The ID of the party.
|
||||
*/
|
||||
snowflake id;
|
||||
|
||||
/**
|
||||
* @brief The party's current size.
|
||||
* Used to show the party's current size.
|
||||
*/
|
||||
int32_t current_size;
|
||||
|
||||
/**
|
||||
* @brief The party's maximum size.
|
||||
* Used to show the party's maximum size.
|
||||
*/
|
||||
int32_t maximum_size;
|
||||
|
||||
/** Constructor */
|
||||
activity_party();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An activity is a representation of what a user is doing. It might be a game, or a website, or a movie. Whatever.
|
||||
*/
|
||||
class DPP_EXPORT activity {
|
||||
public:
|
||||
/**
|
||||
* @brief Name of activity.
|
||||
* e.g. "Fortnite", "Mr Boom's Firework Factory", etc.
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* @brief State of activity or the custom user status.
|
||||
* e.g. "Waiting in lobby".
|
||||
*/
|
||||
std::string state;
|
||||
|
||||
/**
|
||||
* @brief What the player is currently doing.
|
||||
*/
|
||||
std::string details;
|
||||
|
||||
/**
|
||||
* @brief Images for the presence and their hover texts.
|
||||
*/
|
||||
activity_assets assets;
|
||||
|
||||
/**
|
||||
* @brief URL of activity (this is also named details).
|
||||
*
|
||||
* @note Only applicable for certain sites such a YouTube
|
||||
*/
|
||||
std::string url;
|
||||
|
||||
/**
|
||||
* @brief The custom buttons shown in the Rich Presence (max 2).
|
||||
*/
|
||||
std::vector<activity_button> buttons;
|
||||
|
||||
/**
|
||||
* @brief The emoji used for the custom status.
|
||||
*/
|
||||
dpp::emoji emoji;
|
||||
|
||||
/**
|
||||
* @brief Information of the current party if there is one.
|
||||
*/
|
||||
activity_party party;
|
||||
|
||||
/**
|
||||
* @brief Secrets for rich presence joining and spectating.
|
||||
*/
|
||||
activity_secrets secrets;
|
||||
|
||||
/**
|
||||
* @brief Activity type.
|
||||
*/
|
||||
activity_type type;
|
||||
|
||||
/**
|
||||
* @brief Time activity was created.
|
||||
*/
|
||||
time_t created_at;
|
||||
|
||||
/**
|
||||
* @brief Start time.
|
||||
* e.g. when game was started.
|
||||
*/
|
||||
time_t start;
|
||||
|
||||
/**
|
||||
* @brief End time.
|
||||
* e.g. for songs on spotify.
|
||||
*/
|
||||
time_t end;
|
||||
|
||||
/**
|
||||
* @brief Creating application.
|
||||
* e.g. a linked account on the user's client.
|
||||
*/
|
||||
snowflake application_id;
|
||||
|
||||
/**
|
||||
* @brief Flags bitmask from dpp::activity_flags.
|
||||
*/
|
||||
uint8_t flags;
|
||||
|
||||
/**
|
||||
* @brief Whether or not the activity is an instanced game session.
|
||||
*/
|
||||
bool is_instance;
|
||||
|
||||
/**
|
||||
* @brief Get the assets large image url if they have one, otherwise returns an empty string. In case of prefixed image IDs (mp:{image_id}) it returns an empty string.
|
||||
*
|
||||
* @see https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-asset-image
|
||||
*
|
||||
* @param size The size of the image in pixels. It can be any power of two between 16 and 4096,
|
||||
* otherwise the default sized 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 image url or an empty string, if required attributes are missing or an invalid format was passed
|
||||
*/
|
||||
std::string get_large_asset_url(uint16_t size = 0, const image_type format = i_png) const;
|
||||
|
||||
/**
|
||||
* @brief Get the assets small image url if they have one, otherwise returns an empty string. In case of prefixed image IDs (mp:{image_id}) it returns an empty string.
|
||||
*
|
||||
* @see https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-asset-image
|
||||
*
|
||||
* @param size The size of the image in pixels. It can be any power of two between 16 and 4096,
|
||||
* otherwise the default sized 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 image url or an empty string, if required attributes are missing or an invalid format was passed
|
||||
*/
|
||||
std::string get_small_asset_url(uint16_t size = 0, const image_type format = i_png) const;
|
||||
|
||||
activity();
|
||||
|
||||
/**
|
||||
* @brief Construct a new activity
|
||||
*
|
||||
* @param typ activity type
|
||||
* @param nam Name of the activity
|
||||
* @param stat State of the activity
|
||||
* @param url_ url of the activity, only works for certain sites, such as YouTube
|
||||
*/
|
||||
activity(const activity_type typ, const std::string& nam, const std::string& stat, const std::string& url_);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents user presence, e.g. what game they are playing and if they are online
|
||||
*/
|
||||
class DPP_EXPORT presence : public json_interface<presence> {
|
||||
protected:
|
||||
friend struct json_interface<presence>;
|
||||
|
||||
/** Fill this object from json.
|
||||
* @param j JSON object to fill from
|
||||
* @return A reference to self
|
||||
*/
|
||||
presence& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/** Build JSON from this object.
|
||||
*
|
||||
* @note This excludes any part of the presence object that are not valid for websockets and bots,
|
||||
* and includes websocket opcode 3. You will not get what you expect if you call this on a user's
|
||||
* presence received from on_presence_update or on_guild_create!
|
||||
*
|
||||
* @param with_id Add ID to output
|
||||
* @return The JSON text of the presence
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The user the presence applies to.
|
||||
*/
|
||||
snowflake user_id;
|
||||
|
||||
/**
|
||||
* @brief Guild ID.
|
||||
*
|
||||
* @note Apparently, Discord supports this internally, but the client doesn't...
|
||||
*/
|
||||
snowflake guild_id;
|
||||
|
||||
/**
|
||||
* @brief Flags bitmask containing dpp::presence_flags
|
||||
*/
|
||||
uint8_t flags;
|
||||
|
||||
/**
|
||||
* @brief List of activities.
|
||||
*/
|
||||
std::vector<activity> activities;
|
||||
|
||||
/** Constructor */
|
||||
presence();
|
||||
|
||||
/**
|
||||
* @brief Construct a new presence object with some parameters for sending to a websocket
|
||||
*
|
||||
* @param status Status of the activity
|
||||
* @param type Type of activity
|
||||
* @param activity_description Description of the activity
|
||||
*/
|
||||
presence(presence_status status, activity_type type, const std::string& activity_description);
|
||||
|
||||
/**
|
||||
* @brief Construct a new presence object with some parameters for sending to a websocket.
|
||||
*
|
||||
* @param status Status of the activity
|
||||
* @param a Activity itself
|
||||
*/
|
||||
presence(presence_status status, const activity& a);
|
||||
|
||||
/** Destructor */
|
||||
~presence();
|
||||
|
||||
/**
|
||||
* @brief The users status on desktop
|
||||
* @return The user's status on desktop
|
||||
*/
|
||||
presence_status desktop_status() const;
|
||||
|
||||
/**
|
||||
* @brief The user's status on web
|
||||
* @return The user's status on web
|
||||
*/
|
||||
presence_status web_status() const;
|
||||
|
||||
/**
|
||||
* @brief The user's status on mobile
|
||||
* @return The user's status on mobile
|
||||
*/
|
||||
presence_status mobile_status() const;
|
||||
|
||||
/**
|
||||
* @brief The user's status as shown to other users
|
||||
* @return The user's status as shown to other users
|
||||
*/
|
||||
presence_status status() const;
|
||||
|
||||
/**
|
||||
* @brief Build JSON from this object.
|
||||
*
|
||||
* @note This excludes any part of the presence object that are not valid for websockets and bots,
|
||||
* and includes websocket opcode 3. You will not get what you expect if you call this on a user's
|
||||
* presence received from on_presence_update or on_guild_create!
|
||||
*
|
||||
* @param with_id Add ID to output
|
||||
* @return The JSON of the presence
|
||||
*/
|
||||
json to_json(bool with_id = false) const; // Intentional shadow of json_interface, mostly present for documentation
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A container of presences
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, presence> presence_map;
|
||||
|
||||
} // namespace dpp
|
||||
80
DPP-master/include/dpp/prune.h
Normal file
80
DPP-master/include/dpp/prune.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Defines a request to count prunable users, or start a prune operation
|
||||
*/
|
||||
struct DPP_EXPORT prune : public json_interface<prune> {
|
||||
protected:
|
||||
friend struct json_interface<prune>;
|
||||
|
||||
/** Fill this object from json.
|
||||
* @param j JSON object to fill from
|
||||
* @return A reference to self
|
||||
*/
|
||||
prune& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/** Build JSON from this object.
|
||||
* @param with_prune_count True if the prune count boolean is to be set in the built JSON
|
||||
* @return The JSON of the prune object
|
||||
*/
|
||||
virtual json to_json_impl(bool with_prune_count = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destroy this prune object
|
||||
*/
|
||||
virtual ~prune() = default;
|
||||
|
||||
/**
|
||||
* @brief Number of days to include in the prune.
|
||||
*/
|
||||
uint32_t days = 0;
|
||||
|
||||
/**
|
||||
* @brief Roles to include in the prune (empty to include everyone).
|
||||
*/
|
||||
std::vector<snowflake> include_roles;
|
||||
|
||||
/**
|
||||
* @brief True if the count of pruneable users should be returned.
|
||||
* @warning Discord recommend not using this on big guilds.
|
||||
*/
|
||||
bool compute_prune_count;
|
||||
|
||||
/**
|
||||
* @brief Build JSON from this object.
|
||||
*
|
||||
* @param with_prune_count True if the prune count boolean is to be set in the built JSON
|
||||
* @return The JSON of the prune object
|
||||
*/
|
||||
json to_json(bool with_id = false) const; // Intentional shadow of json_interface, mostly present for documentation
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
616
DPP-master/include/dpp/queues.h
Normal file
616
DPP-master/include/dpp/queues.h
Normal file
@@ -0,0 +1,616 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <shared_mutex>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Error values. Most of these are currently unused in https_client.
|
||||
*/
|
||||
enum http_error {
|
||||
/**
|
||||
* @brief Request successful.
|
||||
*/
|
||||
h_success = 0,
|
||||
|
||||
/**
|
||||
* @brief Status unknown.
|
||||
*/
|
||||
h_unknown,
|
||||
|
||||
/**
|
||||
* @brief Connect failed.
|
||||
*/
|
||||
h_connection,
|
||||
|
||||
/**
|
||||
* @brief Invalid local ip address.
|
||||
*/
|
||||
h_bind_ip_address,
|
||||
|
||||
/**
|
||||
* @brief Read error.
|
||||
*/
|
||||
h_read,
|
||||
|
||||
/**
|
||||
* @brief Write error.
|
||||
*/
|
||||
h_write,
|
||||
|
||||
/**
|
||||
* @brief Too many 30x redirects.
|
||||
*/
|
||||
h_exceed_redirect_count,
|
||||
|
||||
/**
|
||||
* @brief Request cancelled.
|
||||
*/
|
||||
h_canceled,
|
||||
|
||||
/**
|
||||
* @brief SSL connection error.
|
||||
*/
|
||||
h_ssl_connection,
|
||||
|
||||
/**
|
||||
* @brief SSL cert loading error.
|
||||
*/
|
||||
h_ssl_loading_certs,
|
||||
|
||||
/**
|
||||
* @brief SSL server verification error.
|
||||
*/
|
||||
h_ssl_server_verification,
|
||||
|
||||
/**
|
||||
* @brief Unsupported multipart boundary characters.
|
||||
*/
|
||||
h_unsupported_multipart_boundary_chars,
|
||||
|
||||
/**
|
||||
* @brief Compression error.
|
||||
*/
|
||||
h_compression,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The result of any HTTP request. Contains the headers, vital
|
||||
* rate limit figures, and returned request body.
|
||||
*/
|
||||
struct DPP_EXPORT http_request_completion_t {
|
||||
/**
|
||||
* @brief HTTP headers of response.
|
||||
*/
|
||||
std::multimap<std::string, std::string> headers;
|
||||
|
||||
/**
|
||||
* @brief HTTP status.
|
||||
* e.g. 200 = OK, 404 = Not found, 429 = Rate limited, etc.
|
||||
*/
|
||||
uint16_t status = 0;
|
||||
|
||||
/**
|
||||
* @brief Error status.
|
||||
* e.g. if the request could not connect at all.
|
||||
*/
|
||||
http_error error = h_success;
|
||||
|
||||
/**
|
||||
* @brief Ratelimit bucket.
|
||||
*/
|
||||
std::string ratelimit_bucket;
|
||||
|
||||
/**
|
||||
* @brief Ratelimit limit of requests.
|
||||
*/
|
||||
uint64_t ratelimit_limit = 0;
|
||||
|
||||
/**
|
||||
* @brief Ratelimit remaining requests.
|
||||
*/
|
||||
uint64_t ratelimit_remaining = 0;
|
||||
|
||||
/**
|
||||
* @brief Ratelimit reset after (seconds).
|
||||
*/
|
||||
uint64_t ratelimit_reset_after = 0;
|
||||
|
||||
/**
|
||||
* @brief Ratelimit retry after (seconds).
|
||||
*/
|
||||
uint64_t ratelimit_retry_after = 0;
|
||||
|
||||
/**
|
||||
* @brief True if this request has caused us to be globally rate limited.
|
||||
*/
|
||||
bool ratelimit_global = false;
|
||||
|
||||
/**
|
||||
* @brief Reply body.
|
||||
*/
|
||||
std::string body;
|
||||
|
||||
/**
|
||||
* @brief Ping latency.
|
||||
*/
|
||||
double latency;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Results of HTTP requests are called back to these std::function types.
|
||||
*
|
||||
* @note Returned http_completion_events are called ASYNCHRONOUSLY in your
|
||||
* code which means they execute in a separate thread. The completion events
|
||||
* arrive in order.
|
||||
*/
|
||||
typedef std::function<void(const http_request_completion_t&)> http_completion_event;
|
||||
|
||||
/**
|
||||
* @brief Various types of http method supported by the Discord API
|
||||
*/
|
||||
enum http_method {
|
||||
/**
|
||||
* @brief GET.
|
||||
*/
|
||||
m_get,
|
||||
|
||||
/**
|
||||
* @brief POST.
|
||||
*/
|
||||
m_post,
|
||||
|
||||
/**
|
||||
* @brief PUT.
|
||||
*/
|
||||
m_put,
|
||||
|
||||
/**
|
||||
* @brief PATCH.
|
||||
*/
|
||||
m_patch,
|
||||
|
||||
/**
|
||||
* @brief DELETE.
|
||||
*/
|
||||
m_delete
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A HTTP request.
|
||||
*
|
||||
* You should instantiate one of these objects via its constructor,
|
||||
* and pass a pointer to it into an instance of request_queue. Although you can
|
||||
* directly call the run() method of the object and it will make a HTTP call, be
|
||||
* aware that if you do this, it will be a **BLOCKING call** (not asynchronous) and
|
||||
* will not respect rate limits, as both of these functions are managed by the
|
||||
* request_queue class.
|
||||
*/
|
||||
class DPP_EXPORT http_request {
|
||||
/**
|
||||
* @brief Completion callback.
|
||||
*/
|
||||
http_completion_event complete_handler;
|
||||
|
||||
/**
|
||||
* @brief True if request has been made.
|
||||
*/
|
||||
bool completed;
|
||||
|
||||
/**
|
||||
* @brief True for requests that are not going to discord (rate limits code skipped).
|
||||
*/
|
||||
bool non_discord;
|
||||
public:
|
||||
/**
|
||||
* @brief Endpoint name
|
||||
* e.g. /api/users.
|
||||
*/
|
||||
std::string endpoint;
|
||||
|
||||
/**
|
||||
* @brief Major and minor parameters.
|
||||
*/
|
||||
std::string parameters;
|
||||
|
||||
/**
|
||||
* @brief Postdata for POST and PUT.
|
||||
*/
|
||||
std::string postdata;
|
||||
|
||||
/**
|
||||
* @brief HTTP method for request.
|
||||
*/
|
||||
http_method method;
|
||||
|
||||
/**
|
||||
* @brief Audit log reason for Discord requests, if non-empty.
|
||||
*/
|
||||
std::string reason;
|
||||
|
||||
/**
|
||||
* @brief Upload file name (server side).
|
||||
*/
|
||||
std::vector<std::string> file_name;
|
||||
|
||||
/**
|
||||
* @brief Upload file contents (binary).
|
||||
*/
|
||||
std::vector<std::string> file_content;
|
||||
|
||||
/**
|
||||
* @brief Upload file mime types.
|
||||
* application/octet-stream if unspecified.
|
||||
*/
|
||||
std::vector<std::string> file_mimetypes;
|
||||
|
||||
/**
|
||||
* @brief Request mime type.
|
||||
*/
|
||||
std::string mimetype;
|
||||
|
||||
/**
|
||||
* @brief Request headers (non-discord requests only).
|
||||
*/
|
||||
std::multimap<std::string, std::string> req_headers;
|
||||
|
||||
/**
|
||||
* @brief Waiting for rate limit to expire.
|
||||
*/
|
||||
bool waiting;
|
||||
|
||||
/**
|
||||
* @brief HTTP protocol.
|
||||
*/
|
||||
std::string protocol;
|
||||
|
||||
/**
|
||||
* @brief Constructor. When constructing one of these objects it should be passed to request_queue::post_request().
|
||||
* @param _endpoint The API endpoint, e.g. /api/guilds
|
||||
* @param _parameters Major and minor parameters for the endpoint e.g. a user id or guild id
|
||||
* @param completion completion event to call when done
|
||||
* @param _postdata Data to send in POST and PUT requests
|
||||
* @param method The HTTP method to use from dpp::http_method
|
||||
* @param audit_reason Audit log reason to send, empty to send none
|
||||
* @param filename The filename (server side) of any uploaded file
|
||||
* @param filecontent The binary content of any uploaded file for the request
|
||||
* @param filemimetype The MIME type of any uploaded file for the request
|
||||
* @param http_protocol HTTP protocol
|
||||
*/
|
||||
http_request(const std::string &_endpoint, const std::string &_parameters, http_completion_event completion, const std::string &_postdata = "", http_method method = m_get, const std::string &audit_reason = "", const std::string &filename = "", const std::string &filecontent = "", const std::string &filemimetype = "", const std::string &http_protocol = "1.1");
|
||||
|
||||
/**
|
||||
* @brief Constructor. When constructing one of these objects it should be passed to request_queue::post_request().
|
||||
* @param _endpoint The API endpoint, e.g. /api/guilds
|
||||
* @param _parameters Major and minor parameters for the endpoint e.g. a user id or guild id
|
||||
* @param completion completion event to call when done
|
||||
* @param _postdata Data to send in POST and PUT requests
|
||||
* @param method The HTTP method to use from dpp::http_method
|
||||
* @param audit_reason Audit log reason to send, empty to send none
|
||||
* @param filename The filename (server side) of any uploaded file
|
||||
* @param filecontent The binary content of any uploaded file for the request
|
||||
* @param filemimetypes The MIME type of any uploaded file for the request
|
||||
* @param http_protocol HTTP protocol
|
||||
*/
|
||||
http_request(const std::string &_endpoint, const std::string &_parameters, http_completion_event completion, const std::string &_postdata = "", http_method method = m_get, const std::string &audit_reason = "", const std::vector<std::string> &filename = {}, const std::vector<std::string> &filecontent = {}, const std::vector<std::string> &filemimetypes = {}, const std::string &http_protocol = "1.1");
|
||||
|
||||
/**
|
||||
* @brief Constructor. When constructing one of these objects it should be passed to request_queue::post_request().
|
||||
* @param _url Raw HTTP url
|
||||
* @param completion completion event to call when done
|
||||
* @param method The HTTP method to use from dpp::http_method
|
||||
* @param _postdata Data to send in POST and PUT requests
|
||||
* @param _mimetype POST data mime type
|
||||
* @param _headers HTTP headers to send
|
||||
* @param http_protocol HTTP protocol
|
||||
*/
|
||||
http_request(const std::string &_url, http_completion_event completion, http_method method = m_get, const std::string &_postdata = "", const std::string &_mimetype = "text/plain", const std::multimap<std::string, std::string> &_headers = {}, const std::string &http_protocol = "1.1");
|
||||
|
||||
/**
|
||||
* @brief Destroy the http request object
|
||||
*/
|
||||
~http_request();
|
||||
|
||||
/**
|
||||
* @brief Call the completion callback, if the request is complete.
|
||||
* @param c callback to call
|
||||
*/
|
||||
void complete(const http_request_completion_t &c);
|
||||
|
||||
/**
|
||||
* @brief Execute the HTTP request and mark the request complete.
|
||||
* @param owner creating cluster
|
||||
*/
|
||||
http_request_completion_t run(class cluster* owner);
|
||||
|
||||
/** @brief Returns true if the request is complete */
|
||||
bool is_completed();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A rate limit bucket. The library builds one of these for
|
||||
* each endpoint.
|
||||
*/
|
||||
struct DPP_EXPORT bucket_t {
|
||||
/**
|
||||
* @brief Request limit.
|
||||
*/
|
||||
uint64_t limit;
|
||||
|
||||
/**
|
||||
* @brief Requests remaining.
|
||||
*/
|
||||
uint64_t remaining;
|
||||
|
||||
/**
|
||||
* @brief Rate-limit of this bucket resets after this many seconds.
|
||||
*/
|
||||
uint64_t reset_after;
|
||||
|
||||
/**
|
||||
* @brief Rate-limit of this bucket can be retried after this many seconds.
|
||||
*/
|
||||
uint64_t retry_after;
|
||||
|
||||
/**
|
||||
* @brief Timestamp this buckets counters were updated.
|
||||
*/
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Represents a thread in the thread pool handling requests to HTTP(S) servers.
|
||||
* There are several of these, the total defined by a constant in queues.cpp, and each
|
||||
* one will always receive requests for the same rate limit bucket based on its endpoint
|
||||
* portion of the url. This makes rate limit handling reliable and easy to manage.
|
||||
* Each of these also has its own mutex, so that requests are less likely to block while
|
||||
* waiting for internal containers to be usable.
|
||||
*/
|
||||
class DPP_EXPORT in_thread {
|
||||
private:
|
||||
/**
|
||||
* @brief True if ending.
|
||||
*/
|
||||
bool terminating;
|
||||
|
||||
/**
|
||||
* @brief Request queue that owns this in_thread.
|
||||
*/
|
||||
class request_queue* requests;
|
||||
|
||||
/**
|
||||
* @brief The cluster that owns this in_thread.
|
||||
*/
|
||||
class cluster* creator;
|
||||
|
||||
/**
|
||||
* @brief Inbound queue mutex thread safety.
|
||||
*/
|
||||
std::shared_mutex in_mutex;
|
||||
|
||||
/**
|
||||
* @brief Inbound queue thread.
|
||||
*/
|
||||
std::thread* in_thr;
|
||||
|
||||
/**
|
||||
* @brief Inbound queue condition, signalled when there are requests to fulfill.
|
||||
*/
|
||||
std::condition_variable in_ready;
|
||||
|
||||
/**
|
||||
* @brief Rate-limit bucket counters.
|
||||
*/
|
||||
std::map<std::string, bucket_t> buckets;
|
||||
|
||||
/**
|
||||
* @brief Queue of requests to be made.
|
||||
*/
|
||||
std::map<std::string, std::vector<http_request*>> requests_in;
|
||||
|
||||
/**
|
||||
* @brief Inbound queue thread loop.
|
||||
* @param index Thread index
|
||||
*/
|
||||
void in_loop(uint32_t index);
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new in thread object
|
||||
*
|
||||
* @param owner Owning cluster
|
||||
* @param req_q Owning request queue
|
||||
* @param index Thread index number
|
||||
*/
|
||||
in_thread(class cluster* owner, class request_queue* req_q, uint32_t index);
|
||||
|
||||
/**
|
||||
* @brief Destroy the in thread object
|
||||
* This will end the thread that is owned by this object by joining it.
|
||||
*/
|
||||
~in_thread();
|
||||
|
||||
/**
|
||||
* @brief Post a http_request to this thread.
|
||||
*
|
||||
* @param req http_request to post. The pointer will be freed when it has
|
||||
* been executed.
|
||||
*/
|
||||
void post_request(http_request* req);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The request_queue class manages rate limits and marshalls HTTP requests that have
|
||||
* been built as http_request objects.
|
||||
*
|
||||
* It ensures asynchronous delivery of events and queueing of requests.
|
||||
*
|
||||
* It will spawn two threads, one to make outbound HTTP requests and push the returned
|
||||
* results into a queue, and the second to call the callback methods with these results.
|
||||
* They are separated so that if the user decides to take a long time processing a reply
|
||||
* in their callback it won't affect when other requests are sent, and if a HTTP request
|
||||
* takes a long time due to latency, it won't hold up user processing.
|
||||
*
|
||||
* There are usually two request_queue objects in each dpp::cluster, one of which is used
|
||||
* internally for the various REST methods to Discord such as sending messages, and the other
|
||||
* used to support user REST calls via dpp::cluster::request().
|
||||
*/
|
||||
class DPP_EXPORT request_queue {
|
||||
protected:
|
||||
/**
|
||||
* @brief Required so in_thread can access these member variables
|
||||
*/
|
||||
friend class in_thread;
|
||||
|
||||
/**
|
||||
* @brief The cluster that owns this request_queue
|
||||
*/
|
||||
class cluster* creator;
|
||||
|
||||
/**
|
||||
* @brief Outbound queue mutex thread safety
|
||||
*/
|
||||
std::shared_mutex out_mutex;
|
||||
|
||||
/**
|
||||
* @brief Outbound queue thread
|
||||
* Note that although there are many 'in queues', which handle the HTTP requests,
|
||||
* there is only ever one 'out queue' which dispatches the results to the caller.
|
||||
* This is to simplify thread management in bots that use the library, as less mutexing
|
||||
* and thread safety boilerplate is required.
|
||||
*/
|
||||
std::thread* out_thread;
|
||||
|
||||
/**
|
||||
* @brief Outbound queue condition.
|
||||
* Signalled when there are requests completed to call callbacks for.
|
||||
*/
|
||||
std::condition_variable out_ready;
|
||||
|
||||
/**
|
||||
* @brief Completed requests queue
|
||||
*/
|
||||
std::queue<std::pair<http_request_completion_t*, http_request*>> responses_out;
|
||||
|
||||
/**
|
||||
* @brief A vector of inbound request threads forming a pool.
|
||||
* There are a set number of these defined by a constant in queues.cpp. A request is always placed
|
||||
* on the same element in this vector, based upon its url, so that two conditions are satisfied:
|
||||
* 1) Any requests for the same ratelimit bucket are handled by the same thread in the pool so that
|
||||
* they do not create unnecessary 429 errors,
|
||||
* 2) Requests for different endpoints go into different buckets, so that they may be requested in parallel
|
||||
* A global ratelimit event pauses all threads in the pool. These are few and far between.
|
||||
*/
|
||||
std::vector<in_thread*> requests_in;
|
||||
|
||||
/**
|
||||
* @brief Completed requests to delete
|
||||
*/
|
||||
std::multimap<time_t, std::pair<http_request_completion_t*, http_request*>> responses_to_delete;
|
||||
|
||||
/**
|
||||
* @brief Set to true if the threads should terminate
|
||||
*/
|
||||
bool terminating;
|
||||
|
||||
/**
|
||||
* @brief True if globally rate limited - makes the entire request thread wait
|
||||
*/
|
||||
bool globally_ratelimited;
|
||||
|
||||
/**
|
||||
* @brief How many seconds we are globally rate limited for
|
||||
*
|
||||
* @note Only if globally_ratelimited is true.
|
||||
*/
|
||||
uint64_t globally_limited_for;
|
||||
|
||||
/**
|
||||
* @brief Number of request threads in the thread pool
|
||||
*/
|
||||
uint32_t in_thread_pool_size;
|
||||
|
||||
/**
|
||||
* @brief Outbound queue thread loop
|
||||
*/
|
||||
void out_loop();
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief constructor
|
||||
* @param owner The creating cluster.
|
||||
* @param request_threads The number of http request threads to allocate to the threadpool.
|
||||
* By default eight threads are allocated.
|
||||
* Side effects: Creates threads for the queue
|
||||
*/
|
||||
request_queue(class cluster* owner, uint32_t request_threads = 8);
|
||||
|
||||
/**
|
||||
* @brief Add more request threads to the library at runtime.
|
||||
* @note You should do this at a quiet time when there are few requests happening.
|
||||
* This will reorganise the hashing used to place requests into the thread pool so if you do
|
||||
* this while the bot is busy there is a small chance of receiving "429 rate limited" errors.
|
||||
* @param request_threads Number of threads to add. It is not possible to scale down at runtime.
|
||||
* @return reference to self
|
||||
*/
|
||||
request_queue& add_request_threads(uint32_t request_threads);
|
||||
|
||||
/**
|
||||
* @brief Get the request thread count
|
||||
* @return uint32_t number of request threads that are active
|
||||
*/
|
||||
uint32_t get_request_thread_count() const;
|
||||
|
||||
/**
|
||||
* @brief Destroy the request queue object.
|
||||
* Side effects: Joins and deletes queue threads
|
||||
*/
|
||||
~request_queue();
|
||||
|
||||
/**
|
||||
* @brief Put a http_request into the request queue. You should ALWAYS "new" an object
|
||||
* to pass to here -- don't submit an object that's on the stack!
|
||||
* @note Will use a simple hash function to determine which of the 'in queues' to place
|
||||
* this request onto.
|
||||
* @param req request to add
|
||||
* @return reference to self
|
||||
*/
|
||||
request_queue& post_request(http_request *req);
|
||||
|
||||
/**
|
||||
* @brief Returns true if the bot is currently globally rate limited
|
||||
* @return true if globally rate limited
|
||||
*/
|
||||
bool is_globally_ratelimited() const;
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
264
DPP-master/include/dpp/restrequest.h
Normal file
264
DPP-master/include/dpp/restrequest.h
Normal file
@@ -0,0 +1,264 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/invite.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing
|
||||
*
|
||||
* @tparam T type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<class T> inline void rest_request(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, T().fill_from_json(&j), http));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (specialised for message)
|
||||
*
|
||||
* @tparam T type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<> inline void rest_request<message>(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, message(c).fill_from_json(&j), http));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (specialised for confirmation)
|
||||
*
|
||||
* @tparam T type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<> inline void rest_request<confirmation>(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, confirmation(), http));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (for returned lists)
|
||||
*
|
||||
* @tparam T singular type to return in lambda callback
|
||||
* @tparam T map type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param key Key name of elements in the json list
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<class T> inline void rest_request_list(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback, const std::string& key = "id") {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, key, callback](json &j, const http_request_completion_t& http) {
|
||||
std::unordered_map<snowflake, T> list;
|
||||
confirmation_callback_t e(c, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
for (auto & curr_item : j) {
|
||||
list[snowflake_not_null(&curr_item, key.c_str())] = T().fill_from_json(&curr_item);
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, list, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (for returned lists, specialised for invites)
|
||||
*
|
||||
* @tparam T singular type to return in lambda callback
|
||||
* @tparam T map type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param key Key name of elements in the json list
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<> inline void rest_request_list<invite>(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback, const std::string& key) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, callback](json &j, const http_request_completion_t& http) {
|
||||
invite_map list;
|
||||
confirmation_callback_t e(c, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
for (auto & curr_item : j) {
|
||||
list[string_not_null(&curr_item, "code")] = invite().fill_from_json(&curr_item);
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, list, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (for returned lists, specialised for voiceregions)
|
||||
*
|
||||
* @tparam T singular type to return in lambda callback
|
||||
* @tparam T map type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param key Key name of elements in the json list
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<> inline void rest_request_list<voiceregion>(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback, const std::string& key) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, callback](json &j, const http_request_completion_t& http) {
|
||||
voiceregion_map list;
|
||||
confirmation_callback_t e(c, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
for (auto & curr_item : j) {
|
||||
list[string_not_null(&curr_item, "id")] = voiceregion().fill_from_json(&curr_item);
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, list, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (for returned lists, specialised for bans)
|
||||
*
|
||||
* @tparam T singular type to return in lambda callback
|
||||
* @tparam T map type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param key Key name of elements in the json list
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<> inline void rest_request_list<ban>(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback, const std::string& key) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, callback](json &j, const http_request_completion_t& http) {
|
||||
std::unordered_map<snowflake, ban> list;
|
||||
confirmation_callback_t e(c, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
for (auto & curr_item : j) {
|
||||
ban curr_ban = ban().fill_from_json(&curr_item);
|
||||
list[curr_ban.user_id] = curr_ban;
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, list, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (for returned lists, specialised for sticker packs)
|
||||
*
|
||||
* @tparam T singular type to return in lambda callback
|
||||
* @tparam T map type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param key Key name of elements in the json list
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<> inline void rest_request_list<sticker_pack>(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback, const std::string& key) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, key, callback](json &j, const http_request_completion_t& http) {
|
||||
std::unordered_map<snowflake, sticker_pack> list;
|
||||
confirmation_callback_t e(c, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
if (j.contains("sticker_packs")) {
|
||||
for (auto &curr_item: j["sticker_packs"]) {
|
||||
list[snowflake_not_null(&curr_item, key.c_str())] = sticker_pack().fill_from_json(&curr_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, list, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Templated REST request helper to save on typing (for returned lists, specialised for objects which doesn't have ids)
|
||||
*
|
||||
* @tparam T singular type to return in lambda callback
|
||||
* @tparam T vector type to return in lambda callback
|
||||
* @param c calling cluster
|
||||
* @param basepath base path for API call
|
||||
* @param major major API function
|
||||
* @param minor minor API function
|
||||
* @param method HTTP method
|
||||
* @param postdata Post data or empty string
|
||||
* @param callback Callback lambda
|
||||
*/
|
||||
template<class T> inline void rest_request_vector(dpp::cluster* c, const char* basepath, const std::string &major, const std::string &minor, http_method method, const std::string& postdata, command_completion_event_t callback) {
|
||||
c->post_rest(basepath, major, minor, method, postdata, [c, callback](json &j, const http_request_completion_t& http) {
|
||||
std::vector<T> list;
|
||||
confirmation_callback_t e(c, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
for (auto & curr_item : j) {
|
||||
list.push_back(T().fill_from_json(&curr_item));
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(c, list, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
} // namespace dpp
|
||||
337
DPP-master/include/dpp/restresults.h
Normal file
337
DPP-master/include/dpp/restresults.h
Normal file
@@ -0,0 +1,337 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <variant>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/dispatcher.h>
|
||||
#include <dpp/misc-enum.h>
|
||||
#include <dpp/timer.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/discordclient.h>
|
||||
#include <dpp/voiceregion.h>
|
||||
#include <dpp/dtemplate.h>
|
||||
#include <dpp/prune.h>
|
||||
#include <dpp/auditlog.h>
|
||||
#include <dpp/queues.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/intents.h>
|
||||
#include <dpp/sync.h>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <shared_mutex>
|
||||
#include <cstring>
|
||||
#include <dpp/entitlement.h>
|
||||
#include <dpp/sku.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief A list of shards
|
||||
*/
|
||||
typedef std::map<uint32_t, class discord_client*> shard_list;
|
||||
|
||||
/**
|
||||
* @brief Represents the various information from the 'get gateway bot' api call
|
||||
*/
|
||||
struct DPP_EXPORT gateway : public json_interface<gateway> {
|
||||
protected:
|
||||
friend struct json_interface<gateway>;
|
||||
|
||||
/**
|
||||
* @brief Fill this object from json
|
||||
*
|
||||
* @param j json to fill from
|
||||
* @return gateway& reference to self
|
||||
*/
|
||||
gateway& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Gateway websocket url.
|
||||
*/
|
||||
std::string url;
|
||||
|
||||
/**
|
||||
* @brief Number of suggested shards to start.
|
||||
*/
|
||||
uint32_t shards;
|
||||
|
||||
/**
|
||||
* @brief Total number of sessions that can be started.
|
||||
*/
|
||||
uint32_t session_start_total;
|
||||
|
||||
/**
|
||||
* @brief How many sessions are left.
|
||||
*/
|
||||
uint32_t session_start_remaining;
|
||||
|
||||
/**
|
||||
* @brief How many seconds until the session start quota resets.
|
||||
*/
|
||||
uint32_t session_start_reset_after;
|
||||
|
||||
/**
|
||||
* @brief How many sessions can be started at the same time.
|
||||
*/
|
||||
uint32_t session_start_max_concurrency;
|
||||
|
||||
/**
|
||||
* @brief Construct a new gateway object
|
||||
*
|
||||
* @param j JSON data to construct from
|
||||
*/
|
||||
gateway(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Construct a new gateway object
|
||||
*/
|
||||
gateway();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Confirmation object represents any true or false simple REST request
|
||||
*
|
||||
*/
|
||||
struct DPP_EXPORT confirmation {
|
||||
bool success;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A container for types that can be returned for a REST API call
|
||||
*
|
||||
*/
|
||||
typedef std::variant<
|
||||
active_threads,
|
||||
application_role_connection,
|
||||
application_role_connection_metadata_list,
|
||||
confirmation,
|
||||
message,
|
||||
message_map,
|
||||
user,
|
||||
user_identified,
|
||||
user_map,
|
||||
guild_member,
|
||||
guild_member_map,
|
||||
channel,
|
||||
channel_map,
|
||||
thread_member,
|
||||
thread_member_map,
|
||||
guild,
|
||||
guild_map,
|
||||
guild_command_permissions,
|
||||
guild_command_permissions_map,
|
||||
role,
|
||||
role_map,
|
||||
invite,
|
||||
invite_map,
|
||||
dtemplate,
|
||||
dtemplate_map,
|
||||
emoji,
|
||||
emoji_map,
|
||||
ban,
|
||||
ban_map,
|
||||
voiceregion,
|
||||
voiceregion_map,
|
||||
integration,
|
||||
integration_map,
|
||||
webhook,
|
||||
webhook_map,
|
||||
prune,
|
||||
guild_widget,
|
||||
gateway,
|
||||
interaction,
|
||||
interaction_response,
|
||||
auditlog,
|
||||
slashcommand,
|
||||
slashcommand_map,
|
||||
stage_instance,
|
||||
sticker,
|
||||
sticker_map,
|
||||
sticker_pack,
|
||||
sticker_pack_map,
|
||||
application,
|
||||
application_map,
|
||||
connection,
|
||||
connection_map,
|
||||
thread,
|
||||
thread_map,
|
||||
scheduled_event,
|
||||
scheduled_event_map,
|
||||
event_member,
|
||||
event_member_map,
|
||||
automod_rule,
|
||||
automod_rule_map,
|
||||
onboarding,
|
||||
welcome_screen,
|
||||
entitlement,
|
||||
entitlement_map,
|
||||
sku,
|
||||
sku_map
|
||||
> confirmable_t;
|
||||
|
||||
/**
|
||||
* @brief The details of a field in an error response
|
||||
*/
|
||||
struct DPP_EXPORT error_detail {
|
||||
/**
|
||||
* @brief Object name which is in error
|
||||
*/
|
||||
std::string object;
|
||||
|
||||
/**
|
||||
* @brief Field name which is in error
|
||||
*/
|
||||
std::string field;
|
||||
|
||||
/**
|
||||
* @brief Error code
|
||||
*/
|
||||
std::string code;
|
||||
|
||||
/**
|
||||
* @brief Error reason (full message)
|
||||
*/
|
||||
std::string reason;
|
||||
|
||||
/**
|
||||
* @brief Object field index
|
||||
*/
|
||||
int index = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The full details of an error from a REST response
|
||||
*/
|
||||
struct DPP_EXPORT error_info {
|
||||
/**
|
||||
* @brief Error code
|
||||
*/
|
||||
uint32_t code = 0;
|
||||
|
||||
/**
|
||||
* @brief Error message
|
||||
*
|
||||
*/
|
||||
std::string message;
|
||||
|
||||
/**
|
||||
* @brief Field specific error descriptions
|
||||
*/
|
||||
std::vector<error_detail> errors;
|
||||
|
||||
/**
|
||||
* @brief Human readable error message constructed from the above
|
||||
*/
|
||||
std::string human_readable;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The results of a REST call wrapped in a convenient struct
|
||||
*/
|
||||
struct DPP_EXPORT confirmation_callback_t {
|
||||
/**
|
||||
* @brief Information about the HTTP call used to make the request.
|
||||
*/
|
||||
http_request_completion_t http_info;
|
||||
|
||||
/**
|
||||
* @brief Value returned, wrapped in variant.
|
||||
*/
|
||||
confirmable_t value;
|
||||
|
||||
/**
|
||||
* @brief Owner/creator of the callback object.
|
||||
*/
|
||||
const class cluster* bot;
|
||||
|
||||
/**
|
||||
* @brief Construct a new confirmation callback t object.
|
||||
*/
|
||||
confirmation_callback_t() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new confirmation callback t object
|
||||
*
|
||||
* @param creator owning cluster object
|
||||
*/
|
||||
confirmation_callback_t(cluster* creator);
|
||||
|
||||
/**
|
||||
* @brief Construct a new confirmation callback object
|
||||
*
|
||||
* @param _http The HTTP metadata from the REST call
|
||||
*/
|
||||
confirmation_callback_t(const http_request_completion_t& _http);
|
||||
|
||||
/**
|
||||
* @brief Construct a new confirmation callback object
|
||||
*
|
||||
* @param creator owning cluster object
|
||||
* @param _value The value to encapsulate in the confirmable_t
|
||||
* @param _http The HTTP metadata from the REST call
|
||||
*/
|
||||
confirmation_callback_t(cluster* creator, const confirmable_t& _value, const http_request_completion_t& _http);
|
||||
|
||||
/**
|
||||
* @brief Returns true if the call resulted in an error rather than a legitimate value in the
|
||||
* confirmation_callback_t::value member.
|
||||
*
|
||||
* @return true There was an error who's details can be obtained by get_error()
|
||||
* @return false There was no error
|
||||
*/
|
||||
bool is_error() const;
|
||||
|
||||
/**
|
||||
* @brief Get the error_info object.
|
||||
* The error_info object contains the details of any REST error, if there is an error
|
||||
* (to find out if there is an error check confirmation_callback_t::is_error())
|
||||
*
|
||||
* @return error_info The details of the error message
|
||||
*/
|
||||
error_info get_error() const;
|
||||
|
||||
/**
|
||||
* @brief Get the stored value via std::get
|
||||
* @tparam T type to get
|
||||
* @return stored value as type T
|
||||
*/
|
||||
template<typename T>
|
||||
T get() const {
|
||||
return std::get<T>(value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A callback upon command completion
|
||||
*/
|
||||
typedef std::function<void(const confirmation_callback_t&)> command_completion_event_t;
|
||||
|
||||
/**
|
||||
* @brief Automatically JSON encoded HTTP result
|
||||
*/
|
||||
typedef std::function<void(json&, const http_request_completion_t&)> json_encode_t;
|
||||
} // namespace dpp
|
||||
997
DPP-master/include/dpp/role.h
Normal file
997
DPP-master/include/dpp/role.h
Normal file
@@ -0,0 +1,997 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <variant>
|
||||
#include <dpp/export.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/permissions.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Various flags related to dpp::role
|
||||
*/
|
||||
enum role_flags : uint8_t {
|
||||
/**
|
||||
* @brief Hoisted role (if the role is pinned in the user listing).
|
||||
*/
|
||||
r_hoist = 0b00000001,
|
||||
|
||||
/**
|
||||
* @brief Managed role (introduced by a bot or application).
|
||||
*/
|
||||
r_managed = 0b00000010,
|
||||
|
||||
/**
|
||||
* @brief Whether this role is mentionable with a ping.
|
||||
*/
|
||||
r_mentionable = 0b00000100,
|
||||
|
||||
/**
|
||||
* @brief Whether this is the guild's booster role.
|
||||
*/
|
||||
r_premium_subscriber = 0b00001000,
|
||||
|
||||
/**
|
||||
* @brief Whether the role is available for purchase.
|
||||
*/
|
||||
r_available_for_purchase = 0b00010000,
|
||||
|
||||
/**
|
||||
* @brief Whether the role is a guild's linked role.
|
||||
*/
|
||||
r_guild_connections = 0b00100000,
|
||||
|
||||
/**
|
||||
* @brief Whether the role can be selected by members in an onboarding prompt.
|
||||
*/
|
||||
r_in_prompt = 0b01000000,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a role within a dpp::guild.
|
||||
* Roles are combined via logical OR of the permission bitmasks, then channel-specific overrides
|
||||
* can be applied on top, deny types apply a logic NOT to the bit mask, and allows apply a logical OR.
|
||||
*
|
||||
* @note Every guild has at least one role, called the 'everyone' role, which always has the same role
|
||||
* ID as the guild's ID. This is the base permission set applied to all users where no other role or override
|
||||
* applies, and is the starting value of the bit mask looped through to calculate channel permissions.
|
||||
*/
|
||||
class DPP_EXPORT role : public managed, public json_interface<role> {
|
||||
protected:
|
||||
friend struct json_interface<role>;
|
||||
|
||||
/**
|
||||
* @brief Fill this role from json.
|
||||
*
|
||||
* @param j The json data
|
||||
* @return A reference to self
|
||||
*/
|
||||
role& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Build a json from this object.
|
||||
*
|
||||
* @param with_id true if the ID is to be included in the json
|
||||
* @return The json of the role
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Role name
|
||||
* Between 1 and 100 characters.
|
||||
*/
|
||||
std::string name{};
|
||||
|
||||
/**
|
||||
* @brief Guild ID
|
||||
*/
|
||||
snowflake guild_id{0};
|
||||
|
||||
/**
|
||||
* @brief Role colour.
|
||||
* A colour of 0 means no colour. If you want a black role,
|
||||
* you must use the value 0x000001.
|
||||
*/
|
||||
uint32_t colour{0};
|
||||
|
||||
/**
|
||||
* @brief Role position.
|
||||
*/
|
||||
uint8_t position{0};
|
||||
|
||||
/**
|
||||
* @brief Role permissions bitmask values from dpp::permissions.
|
||||
*/
|
||||
permission permissions{};
|
||||
|
||||
/**
|
||||
* @brief Role flags from dpp::role_flags
|
||||
*/
|
||||
uint8_t flags{0};
|
||||
|
||||
/**
|
||||
* @brief Integration id if any.
|
||||
* (e.g. role is a bot's role created when it was invited).
|
||||
*/
|
||||
snowflake integration_id{};
|
||||
|
||||
/**
|
||||
* @brief Bot id if any.
|
||||
* (e.g. role is a bot's role created when it was invited)
|
||||
*/
|
||||
snowflake bot_id{};
|
||||
|
||||
/**
|
||||
* @brief The id of the role's subscription sku and listing.
|
||||
*/
|
||||
snowflake subscription_listing_id{};
|
||||
|
||||
/**
|
||||
* @brief The unicode emoji used for the role's icon.
|
||||
*
|
||||
* @note This can be an empty string.
|
||||
*/
|
||||
std::string unicode_emoji{};
|
||||
|
||||
/**
|
||||
* @brief The role icon.
|
||||
*/
|
||||
utility::icon icon{};
|
||||
|
||||
/**
|
||||
* @brief Construct a new role object
|
||||
*/
|
||||
role() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new role object.
|
||||
*
|
||||
* @param rhs Role object to copy
|
||||
*/
|
||||
role(const role& rhs) = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new role object.
|
||||
*
|
||||
* @param rhs Role object to move
|
||||
*/
|
||||
role(role&& rhs) = default;
|
||||
|
||||
/**
|
||||
* @brief Copy another role object
|
||||
*
|
||||
* @param rhs Role object to copy
|
||||
*/
|
||||
role &operator=(const role& rhs) = default;
|
||||
|
||||
/**
|
||||
* @brief Move from another role object
|
||||
*
|
||||
* @param rhs Role object to copy
|
||||
*/
|
||||
role &operator=(role&& rhs) = default;
|
||||
|
||||
/**
|
||||
* @brief Destroy the role object
|
||||
*/
|
||||
virtual ~role() = default;
|
||||
|
||||
/**
|
||||
* @brief Create a mentionable role.
|
||||
* @param id The ID of the role.
|
||||
* @return std::string The formatted mention of the role.
|
||||
*/
|
||||
static std::string get_mention(const snowflake& id);
|
||||
|
||||
/**
|
||||
* @brief Set the name of the role.
|
||||
* Maximum length: 100
|
||||
* Minimum length: 1
|
||||
* @param n Name to set
|
||||
* @return role& reference to self
|
||||
* @throw dpp::exception thrown if role length is less than 1 character
|
||||
*/
|
||||
role& set_name(const std::string& n);
|
||||
|
||||
/**
|
||||
* @brief Set the colour.
|
||||
*
|
||||
* @param c Colour to set
|
||||
* @note There is an americanised version of this method, role::set_color().
|
||||
* @return role& reference to self
|
||||
*/
|
||||
role& set_colour(uint32_t c);
|
||||
|
||||
/**
|
||||
* @brief Set the color.
|
||||
*
|
||||
* @param c Colour to set
|
||||
* @note This is an alias of role::set_colour for American spelling.
|
||||
* @return role& reference to self
|
||||
*/
|
||||
role& set_color(uint32_t c);
|
||||
|
||||
/**
|
||||
* @brief Set the flags.
|
||||
*
|
||||
* @param f Flags to set from dpp::role_flags
|
||||
* @return role& reference to self
|
||||
*/
|
||||
role& set_flags(uint8_t f);
|
||||
|
||||
/**
|
||||
* @brief Set the integration ID.
|
||||
*
|
||||
* @param i Integration ID to set
|
||||
* @return role& reference to self
|
||||
*/
|
||||
role& set_integration_id(snowflake i);
|
||||
|
||||
/**
|
||||
* @brief Set the bot ID.
|
||||
*
|
||||
* @param b Bot ID to set
|
||||
* @return role& reference to self
|
||||
*/
|
||||
role& set_bot_id(snowflake b);
|
||||
|
||||
/**
|
||||
* @brief Set the guild ID.
|
||||
*
|
||||
* @param gid Guild ID to set
|
||||
* @return role& reference to self
|
||||
*/
|
||||
role& set_guild_id(snowflake gid);
|
||||
|
||||
using json_interface<role>::fill_from_json;
|
||||
|
||||
/**
|
||||
* @brief Fill this role from json.
|
||||
*
|
||||
* @param guild_id the guild id to place in the json
|
||||
* @param j The json data
|
||||
* @return A reference to self
|
||||
*/
|
||||
role& fill_from_json(snowflake guild_id, nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Get the mention/ping for the role.
|
||||
*
|
||||
* @return std::string mention
|
||||
*/
|
||||
std::string get_mention() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the role's icon url if they have one, otherwise returns an empty string.
|
||||
*
|
||||
* @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 Load a role icon.
|
||||
*
|
||||
* @param image_blob Image binary data
|
||||
* @param type Type of image. It can be one of `i_gif`, `i_jpg` or `i_png`.
|
||||
* @return emoji& Reference to self
|
||||
*/
|
||||
role& load_image(std::string_view image_blob, const image_type type);
|
||||
|
||||
/**
|
||||
* @brief Load a role icon.
|
||||
*
|
||||
* @param image_blob Image binary data
|
||||
* @param type Type of image. It can be one of `i_gif`, `i_jpg` or `i_png`.
|
||||
* @return emoji& Reference to self
|
||||
*/
|
||||
role& load_image(const std::byte* data, uint32_t size, const image_type type);
|
||||
|
||||
/**
|
||||
* @brief Operator less than, used for checking if a role is below another.
|
||||
*
|
||||
* @param lhs first role to compare
|
||||
* @param rhs second role to compare
|
||||
* @return true if lhs is less than rhs
|
||||
*/
|
||||
friend inline bool operator< (const role& lhs, const role& rhs) {
|
||||
return lhs.position < rhs.position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Operator greater than, used for checking if a role is above another.
|
||||
*
|
||||
* @param lhs first role to compare
|
||||
* @param rhs second role to compare
|
||||
* @return true if lhs is greater than rhs
|
||||
*/
|
||||
friend inline bool operator> (const role& lhs, const role& rhs) {
|
||||
return lhs.position > rhs.position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Operator equals, used for checking if a role is ranked equal to another.
|
||||
*
|
||||
* @param other role to compare
|
||||
* @return true if is equal to other
|
||||
*/
|
||||
inline bool operator== (const role& other) const {
|
||||
return this->position == other.position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Operator not equals, used for checking if a role is ranked equal to another.
|
||||
*
|
||||
* @param other role to compare
|
||||
* @return true if is not equal to other
|
||||
*/
|
||||
inline bool operator!= (const role& other) const {
|
||||
return this->position != other.position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief True if the role is hoisted.
|
||||
*
|
||||
* @return bool Role appears separated from others in the member list
|
||||
*/
|
||||
bool is_hoisted() const;
|
||||
|
||||
/**
|
||||
* @brief True if the role is mentionable.
|
||||
*
|
||||
* @return bool Role is mentionable
|
||||
*/
|
||||
bool is_mentionable() const;
|
||||
|
||||
/**
|
||||
* @brief True if the role is managed (belongs to a bot or application).
|
||||
*
|
||||
* @return bool True if the role is managed (introduced for a bot or other application by Discord)
|
||||
*/
|
||||
bool is_managed() const;
|
||||
|
||||
/**
|
||||
* @brief True if the role is the guild's Booster role.
|
||||
*
|
||||
* @return bool whether the role is the premium subscriber, AKA "boost", role for the guild
|
||||
*/
|
||||
bool is_premium_subscriber() const;
|
||||
|
||||
/**
|
||||
* @brief True if the role is available for purchase.
|
||||
*
|
||||
* @return bool whether this role is available for purchase
|
||||
*/
|
||||
bool is_available_for_purchase() const;
|
||||
|
||||
/**
|
||||
* @brief True if the role is a linked role.
|
||||
*
|
||||
* @return bool True if the role is a linked role
|
||||
*/
|
||||
bool is_linked() const;
|
||||
|
||||
/**
|
||||
* @brief True if the role can be selected by members in an onboarding prompt.
|
||||
*
|
||||
* @return bool True if the role can be selected by members in an onboarding prompt
|
||||
*/
|
||||
bool is_selectable_in_prompt() const;
|
||||
|
||||
/**
|
||||
* @brief True if has create instant invite permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the instant invite permission or is administrator.
|
||||
*/
|
||||
bool has_create_instant_invite() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the kick members permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the kick members permission or is administrator.
|
||||
*/
|
||||
bool has_kick_members() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the ban members permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the ban members permission or is administrator.
|
||||
*/
|
||||
bool has_ban_members() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the administrator permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the administrator permission or is administrator.
|
||||
*/
|
||||
bool has_administrator() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage channels permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage channels permission or is administrator.
|
||||
*/
|
||||
bool has_manage_channels() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage guild permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage guild permission or is administrator.
|
||||
*/
|
||||
bool has_manage_guild() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the add reactions permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the add reactions permission or is administrator.
|
||||
*/
|
||||
bool has_add_reactions() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the view audit log permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the view audit log permission or is administrator.
|
||||
*/
|
||||
bool has_view_audit_log() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the priority speaker permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the priority speaker permission or is administrator.
|
||||
*/
|
||||
bool has_priority_speaker() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the stream permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the stream permission or is administrator.
|
||||
*/
|
||||
bool has_stream() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the view channel permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the view channel permission or is administrator.
|
||||
*/
|
||||
bool has_view_channel() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the send messages permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the send messages permission or is administrator.
|
||||
*/
|
||||
bool has_send_messages() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the send TTS messages permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the send TTS messages permission or is administrator.
|
||||
*/
|
||||
bool has_send_tts_messages() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage messages permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage messages permission or is administrator.
|
||||
*/
|
||||
bool has_manage_messages() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the embed links permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the embed links permission or is administrator.
|
||||
*/
|
||||
bool has_embed_links() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the attach files permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the attach files permission or is administrator.
|
||||
*/
|
||||
bool has_attach_files() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the read message history permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the read message history permission or is administrator.
|
||||
*/
|
||||
bool has_read_message_history() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the mention \@everyone and \@here permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the mention \@everyone and \@here permission or is administrator.
|
||||
*/
|
||||
bool has_mention_everyone() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the use external emojis permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the use external emojis permission or is administrator.
|
||||
*/
|
||||
bool has_use_external_emojis() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the view guild insights permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the view guild insights permission or is administrator.
|
||||
*/
|
||||
bool has_view_guild_insights() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the connect voice permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the connect voice permission or is administrator.
|
||||
*/
|
||||
bool has_connect() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the speak permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the speak permission or is administrator.
|
||||
*/
|
||||
bool has_speak() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the mute members permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the mute members permission or is administrator.
|
||||
*/
|
||||
bool has_mute_members() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the deafen members permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the deafen members permission or is administrator.
|
||||
*/
|
||||
bool has_deafen_members() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the move members permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the move members permission or is administrator.
|
||||
*/
|
||||
bool has_move_members() const;
|
||||
|
||||
/**
|
||||
* @brief True if has use voice activity detection permission
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has use voice activity detection permission or is administrator.
|
||||
*/
|
||||
bool has_use_vad() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the change nickname permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the change nickname permission or is administrator.
|
||||
*/
|
||||
bool has_change_nickname() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage nicknames permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage nicknames permission or is administrator.
|
||||
*/
|
||||
bool has_manage_nicknames() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage roles permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage roles permission or is administrator.
|
||||
*/
|
||||
bool has_manage_roles() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage webhooks permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage webhooks permission or is administrator.
|
||||
*/
|
||||
bool has_manage_webhooks() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage emojis and stickers permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage emojis and stickers permission or is administrator.
|
||||
*/
|
||||
bool has_manage_emojis_and_stickers() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the use application commands permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the use application commands permission or is administrator.
|
||||
*/
|
||||
bool has_use_application_commands() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the request to speak permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the request to speak permission or is administrator.
|
||||
*/
|
||||
bool has_request_to_speak() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage threads permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage threads permission or is administrator.
|
||||
*/
|
||||
bool has_manage_threads() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the create public threads permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the create public threads permission or is administrator.
|
||||
*/
|
||||
bool has_create_public_threads() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the create private threads permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the create private threads permission or is administrator.
|
||||
*/
|
||||
bool has_create_private_threads() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the use external stickers permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the use external stickers permission or is administrator.
|
||||
*/
|
||||
|
||||
bool has_use_external_stickers() const;
|
||||
/**
|
||||
* @brief True if has the send messages in threads permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the send messages in threads permission or is administrator.
|
||||
*/
|
||||
bool has_send_messages_in_threads() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the start embedded activities permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the start embedded activities permission or is administrator.
|
||||
*/
|
||||
bool has_use_embedded_activities() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the manage events permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the manage events permission or is administrator.
|
||||
*/
|
||||
bool has_manage_events() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the moderate users permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the moderate users permission or is administrator.
|
||||
*/
|
||||
bool has_moderate_members() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the view creator monetization analytics permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the view creator monetization analytics permission or is administrator.
|
||||
*/
|
||||
bool has_view_creator_monetization_analytics() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the use soundboard permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the use soundboard permission or is administrator.
|
||||
*/
|
||||
bool has_use_soundboard() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the use external sounds permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the use external sounds permission or is administrator.
|
||||
*/
|
||||
bool has_use_external_sounds() const;
|
||||
|
||||
/**
|
||||
* @brief True if has the send voice messages permission.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the send voice messages permission or is administrator.
|
||||
*/
|
||||
bool has_send_voice_messages() const;
|
||||
|
||||
/**
|
||||
* @brief True if has permission to use clyde AI.
|
||||
*
|
||||
* @note Having the administrator permission causes this method to always return true
|
||||
* Channel specific overrides may apply to permissions.
|
||||
* @return bool True if user has the clyde AI permission or is administrator.
|
||||
*/
|
||||
bool has_use_clyde_ai() const;
|
||||
|
||||
/**
|
||||
* @brief Get guild members who have this role.
|
||||
*
|
||||
* @note This method requires user/members cache to be active
|
||||
* @return members_container List of members who have this role
|
||||
*/
|
||||
members_container get_members() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Application Role Connection Metadata Type
|
||||
*
|
||||
* @note Each metadata type offers a comparison operation that allows guilds
|
||||
* to configure role requirements based on metadata values stored by the bot.
|
||||
* Bots specify a `metadata value` for each user and guilds specify the
|
||||
* required `guild's configured value` within the guild role settings.
|
||||
*/
|
||||
enum application_role_connection_metadata_type : uint8_t {
|
||||
/**
|
||||
* @brief The metadata value (integer) is less than or equal to the guild's configured value (integer).
|
||||
*/
|
||||
rc_integer_less_than_or_equal = 1,
|
||||
|
||||
/**
|
||||
* @brief The metadata value (integer) is greater than or equal to the guild's configured value (integer).
|
||||
*/
|
||||
rc_integer_greater_than_or_equal = 2,
|
||||
|
||||
/**
|
||||
* @brief The metadata value (integer) is equal to the guild's configured value (integer).
|
||||
*/
|
||||
rc_integer_equal = 3,
|
||||
|
||||
/**
|
||||
* @brief The metadata value (integer) is not equal to the guild's configured value (integer).
|
||||
*/
|
||||
rc_integer_not_equal = 4,
|
||||
|
||||
/**
|
||||
* @brief The metadata value (ISO8601 string) is less than or equal to the guild's configured value (integer; days before current date).
|
||||
*/
|
||||
rc_datetime_less_than_or_equal = 5,
|
||||
|
||||
/**
|
||||
* @brief The metadata value (ISO8601 string) is greater than or equal to the guild's configured value (integer; days before current date).
|
||||
*/
|
||||
rc_datetime_greater_than_or_equal = 6,
|
||||
|
||||
/**
|
||||
* @brief The metadata value (integer) is equal to the guild's configured value (integer; 1).
|
||||
*/
|
||||
rc_boolean_equal = 7,
|
||||
|
||||
/**
|
||||
* @brief The metadata value (integer) is not equal to the guild's configured value (integer; 1).
|
||||
*/
|
||||
rc_boolean_not_equal = 8,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Application Role Connection Metadata. Represents a role connection metadata for an dpp::application
|
||||
*/
|
||||
class DPP_EXPORT application_role_connection_metadata : public json_interface<application_role_connection_metadata> {
|
||||
protected:
|
||||
friend struct json_interface<application_role_connection_metadata>;
|
||||
|
||||
/** Fill this record from json.
|
||||
* @param j The json to fill this record from
|
||||
* @return Reference to self
|
||||
*/
|
||||
application_role_connection_metadata& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Convert to JSON
|
||||
*
|
||||
* @param with_id include ID in output
|
||||
* @return json JSON output
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Type of metadata value.
|
||||
*/
|
||||
application_role_connection_metadata_type type;
|
||||
|
||||
/**
|
||||
* @brief Dictionary key for the metadata field (must be `a-z`, `0-9`, or `_` characters; 1-50 characters).
|
||||
*/
|
||||
std::string key;
|
||||
|
||||
/**
|
||||
* @brief Name of the metadata field (1-100 characters).
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* @brief Translations of the name.
|
||||
*/
|
||||
std::map<std::string, std::string> name_localizations;
|
||||
|
||||
/**
|
||||
* @brief Description of the metadata field (1-200 characters).
|
||||
*/
|
||||
std::string description;
|
||||
|
||||
/**
|
||||
* @brief Translations of the description.
|
||||
*/
|
||||
std::map<std::string, std::string> description_localizations;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
application_role_connection_metadata();
|
||||
|
||||
virtual ~application_role_connection_metadata() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The application role connection that an application has attached to a user.
|
||||
*/
|
||||
class DPP_EXPORT application_role_connection : public json_interface<application_role_connection> {
|
||||
protected:
|
||||
friend struct json_interface<application_role_connection>;
|
||||
|
||||
/**
|
||||
* @brief Fill this record from json.
|
||||
* @param j The json to fill this record from
|
||||
* @return Reference to self
|
||||
*/
|
||||
application_role_connection& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Convert to JSON
|
||||
*
|
||||
* @param with_id include ID in output
|
||||
* @return json JSON output
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Optional: The vanity name of the platform a bot has connected (max 50 characters).
|
||||
*/
|
||||
std::string platform_name;
|
||||
|
||||
/**
|
||||
* @brief Optional: The username on the platform a bot has connected (max 100 characters).
|
||||
*/
|
||||
std::string platform_username;
|
||||
|
||||
/**
|
||||
* @brief Optional: Object mapping application role connection metadata keys to their "stringified" value (max 100 characters) for the user on the platform a bot has connected.
|
||||
*/
|
||||
std::variant<std::monostate, application_role_connection_metadata> metadata;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
application_role_connection();
|
||||
|
||||
virtual ~application_role_connection() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A group of roles.
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, role> role_map;
|
||||
|
||||
/**
|
||||
* @brief A group of dpp::application_role_connection_metadata objects.
|
||||
*/
|
||||
typedef std::vector<application_role_connection_metadata> application_role_connection_metadata_list;
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
338
DPP-master/include/dpp/scheduled_event.h
Normal file
338
DPP-master/include/dpp/scheduled_event.h
Normal file
@@ -0,0 +1,338 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Represents the privacy of an event.
|
||||
*/
|
||||
enum event_privacy_level : uint8_t {
|
||||
/**
|
||||
* @brief The event is visible to only guild members.
|
||||
*/
|
||||
ep_guild_only = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Event entity types.
|
||||
*/
|
||||
enum event_entity_type : uint8_t {
|
||||
/**
|
||||
* @brief A stage instance.
|
||||
*/
|
||||
eet_stage_instance = 1,
|
||||
|
||||
/**
|
||||
* @brief A voice channel.
|
||||
*/
|
||||
eet_voice = 2,
|
||||
|
||||
/**
|
||||
* @brief External to discord, or a text channel etc.
|
||||
*/
|
||||
eet_external = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Event status types.
|
||||
*/
|
||||
enum event_status : uint8_t {
|
||||
/**
|
||||
* @brief Scheduled.
|
||||
*/
|
||||
es_scheduled = 1,
|
||||
|
||||
/**
|
||||
* @brief Active now.
|
||||
*/
|
||||
es_active = 2,
|
||||
|
||||
/**
|
||||
* @brief Completed.
|
||||
*/
|
||||
es_completed = 3,
|
||||
|
||||
/**
|
||||
* @brief Cancelled.
|
||||
*/
|
||||
es_cancelled = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Entities for the event.
|
||||
*/
|
||||
struct DPP_EXPORT event_entities {
|
||||
/**
|
||||
* @brief Location of the event.
|
||||
*/
|
||||
std::string location;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a guild member/user who has registered interest in an event.
|
||||
*
|
||||
*/
|
||||
struct DPP_EXPORT event_member {
|
||||
/**
|
||||
* @brief Event ID associated with.
|
||||
*/
|
||||
snowflake guild_scheduled_event_id;
|
||||
|
||||
/**
|
||||
* @brief User details of associated user.
|
||||
*
|
||||
*/
|
||||
dpp::user user;
|
||||
|
||||
/**
|
||||
* @brief Member details of user on the associated guild.
|
||||
*/
|
||||
dpp::guild_member member;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A scheduled event.
|
||||
*/
|
||||
struct DPP_EXPORT scheduled_event : public managed, public json_interface<scheduled_event> {
|
||||
protected:
|
||||
friend struct json_interface<scheduled_event>;
|
||||
|
||||
/**
|
||||
* @brief Serialise a scheduled_event object from json
|
||||
*
|
||||
* @return scheduled_event& a reference to self
|
||||
*/
|
||||
scheduled_event& fill_from_json_impl(const nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Build json for this object
|
||||
* @param with_id Include id field in json
|
||||
*
|
||||
* @return std::string Json of this object
|
||||
*/
|
||||
json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The guild ID which the scheduled event belongs to.
|
||||
*/
|
||||
snowflake guild_id;
|
||||
|
||||
/**
|
||||
* @brief The channel ID in which the scheduled event will be hosted, or null if scheduled entity type is EXTERNAL.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
snowflake channel_id;
|
||||
|
||||
/**
|
||||
* @brief Optional: The ID of the user that created the scheduled event.
|
||||
*/
|
||||
snowflake creator_id;
|
||||
|
||||
/**
|
||||
* @brief The name of the scheduled event.
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* @brief Optional: The description of the scheduled event (1-1000 characters).
|
||||
*/
|
||||
std::string description;
|
||||
|
||||
/**
|
||||
* @brief The image of the scheduled event.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
utility::icon image;
|
||||
|
||||
/**
|
||||
* @brief The time the scheduled event will start.
|
||||
*/
|
||||
time_t scheduled_start_time;
|
||||
|
||||
/**
|
||||
* @brief The time the scheduled event will end, or null if the event does not have a scheduled time to end.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
time_t scheduled_end_time;
|
||||
|
||||
/**
|
||||
* @brief The privacy level of the scheduled event.
|
||||
*/
|
||||
event_privacy_level privacy_level;
|
||||
|
||||
/**
|
||||
* @brief The status of the scheduled event.
|
||||
*/
|
||||
event_status status;
|
||||
|
||||
/**
|
||||
* @brief The type of hosting entity associated with a scheduled event.
|
||||
* e.g. voice channel or stage channel.
|
||||
*/
|
||||
event_entity_type entity_type;
|
||||
|
||||
/**
|
||||
* @brief Any additional ID of the hosting entity associated with event.
|
||||
* e.g. stage instance ID.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
snowflake entity_id;
|
||||
|
||||
/**
|
||||
* @brief The entity metadata for the scheduled event.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
event_entities entity_metadata;
|
||||
|
||||
/**
|
||||
* @brief Optional: The creator of the scheduled event.
|
||||
*/
|
||||
user creator;
|
||||
|
||||
/**
|
||||
* @brief Optional: The number of users subscribed to the scheduled event.
|
||||
*/
|
||||
uint32_t user_count;
|
||||
|
||||
/**
|
||||
* @brief Create a scheduled_event object.
|
||||
*/
|
||||
scheduled_event();
|
||||
|
||||
/**
|
||||
* @brief Set the name of the event.
|
||||
* Minimum length: 1, Maximum length: 100
|
||||
* @param n event name
|
||||
* @return scheduled_event& reference to self
|
||||
* @throw dpp::length_error if length < 1
|
||||
*/
|
||||
scheduled_event& set_name(const std::string& n);
|
||||
|
||||
/**
|
||||
* @brief Set the description of the event.
|
||||
* Minimum length: 1 (if set), Maximum length: 100
|
||||
* @param d event description
|
||||
* @return scheduled_event& reference to self
|
||||
* @throw dpp::length_error if length < 1
|
||||
*/
|
||||
scheduled_event& set_description(const std::string& d);
|
||||
|
||||
/**
|
||||
* @brief Clear the description of the event.
|
||||
* @return scheduled_event& reference to self
|
||||
*/
|
||||
scheduled_event& clear_description();
|
||||
|
||||
/**
|
||||
* @brief Set the location of the event.
|
||||
* Minimum length: 1, Maximum length: 1000
|
||||
* @note Clears channel_id
|
||||
* @param l event location
|
||||
* @return scheduled_event& reference to self
|
||||
* @throw dpp::length_error if length < 1
|
||||
*/
|
||||
scheduled_event& set_location(const std::string& l);
|
||||
|
||||
/**
|
||||
* @brief Set the voice channel id of the event.
|
||||
* @note clears location
|
||||
* @param c channel ID
|
||||
* @return scheduled_event& reference to self
|
||||
*/
|
||||
scheduled_event& set_channel_id(snowflake c);
|
||||
|
||||
/**
|
||||
* @brief Set the creator id of the event.
|
||||
* @param c creator user ID
|
||||
* @return scheduled_event& reference to self
|
||||
*/
|
||||
scheduled_event& set_creator_id(snowflake c);
|
||||
|
||||
/**
|
||||
* @brief Set the status of the event.
|
||||
* @param s status to set
|
||||
* @return scheduled_event& reference to self
|
||||
* @throw dpp::logic_exception if status change is not valid
|
||||
*/
|
||||
scheduled_event& set_status(event_status s);
|
||||
|
||||
/**
|
||||
* @brief Set the start time of the event.
|
||||
* @param t starting time
|
||||
* @return scheduled_event& reference to self
|
||||
* @throw dpp::length_error if time is before now
|
||||
*/
|
||||
scheduled_event& set_start_time(time_t t);
|
||||
|
||||
/**
|
||||
* @brief Set the end time of the event.
|
||||
* @param t ending time
|
||||
* @return scheduled_event& reference to self
|
||||
* @throw dpp::length_error if time is before now
|
||||
*/
|
||||
scheduled_event& set_end_time(time_t t);
|
||||
|
||||
/**
|
||||
* @brief Load an image for the event cover.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
scheduled_event& load_image(std::string_view image_blob, const image_type type);
|
||||
|
||||
/**
|
||||
* @brief Load an image for the event cover.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
scheduled_event& load_image(const std::byte* data, uint32_t size, const image_type type);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A group of scheduled events.
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, scheduled_event> scheduled_event_map;
|
||||
|
||||
/**
|
||||
* @brief A group of scheduled event members.
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, event_member> event_member_map;
|
||||
|
||||
|
||||
} // namespace dpp
|
||||
162
DPP-master/include/dpp/sku.h
Normal file
162
DPP-master/include/dpp/sku.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief The type of SKU.
|
||||
* */
|
||||
enum sku_type : uint8_t {
|
||||
/**
|
||||
* @brief Represents a recurring subscription
|
||||
*/
|
||||
SUBSCRIPTION = 5,
|
||||
|
||||
/**
|
||||
* @brief System-generated group for each SUBSCRIPTION SKU created
|
||||
* @warning These are automatically created for each subscription SKU and are not used at this time. Please refrain from using these.
|
||||
*/
|
||||
SUBSCRIPTION_GROUP = 6,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SKU flags.
|
||||
*/
|
||||
enum sku_flags : uint16_t {
|
||||
/**
|
||||
* @brief SKU is available for purchase
|
||||
*/
|
||||
sku_available = 0b000000000000100,
|
||||
|
||||
/**
|
||||
* @brief Recurring SKU that can be purchased by a user and applied to a single server. Grants access to every user in that server.
|
||||
*/
|
||||
sku_guild_subscription = 0b000000010000000,
|
||||
|
||||
/**
|
||||
* @brief Recurring SKU purchased by a user for themselves. Grants access to the purchasing user in every server.
|
||||
*/
|
||||
sku_user_subscription = 0b000000100000000,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A definition of a discord SKU.
|
||||
*/
|
||||
class DPP_EXPORT sku : public managed, public json_interface<sku> {
|
||||
protected:
|
||||
friend struct json_interface<sku>;
|
||||
|
||||
/** Read class values from json object
|
||||
* @param j A json object to read from
|
||||
* @return A reference to self
|
||||
*/
|
||||
sku& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Build json for this SKU 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 type of SKU.
|
||||
*/
|
||||
sku_type type{sku_type::SUBSCRIPTION};
|
||||
|
||||
/**
|
||||
* @brief ID of the parent application
|
||||
*/
|
||||
snowflake application_id{0};
|
||||
|
||||
/**
|
||||
* @brief Customer-facing name of your premium offering
|
||||
*/
|
||||
std::string name{};
|
||||
|
||||
/**
|
||||
* @brief System-generated URL slug based on the SKU's name
|
||||
*/
|
||||
std::string slug{};
|
||||
|
||||
/**
|
||||
* @brief Flags bitmap from dpp::sku_flags
|
||||
*/
|
||||
uint16_t flags{0};
|
||||
|
||||
/**
|
||||
* @brief Construct a new SKU object
|
||||
*/
|
||||
sku() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new SKU object with all data required.
|
||||
*
|
||||
* @param id SKU id.
|
||||
*/
|
||||
sku(const snowflake id, const sku_type type, const snowflake application_id, const std::string name, const std::string slug, const uint16_t flags);
|
||||
|
||||
/**
|
||||
* @brief Get the type of SKU.
|
||||
*
|
||||
* @return sku_type SKU type
|
||||
*/
|
||||
sku_type get_type() const;
|
||||
|
||||
/**
|
||||
* @brief Is the SKU available for purchase?
|
||||
*
|
||||
* @return true if the SKU can be purchased.
|
||||
*/
|
||||
bool is_available() const;
|
||||
|
||||
/**
|
||||
* @brief Is the SKU a guild subscription?
|
||||
*
|
||||
* @return true if the SKU is a guild subscription.
|
||||
*/
|
||||
bool is_guild_subscription() const;
|
||||
|
||||
/**
|
||||
* @brief Is the SKU a user subscription?
|
||||
*
|
||||
* @return true if the SKU is a user subscription
|
||||
*/
|
||||
bool is_user_subscription() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Group of SKUs.
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, sku> sku_map;
|
||||
|
||||
} // namespace dpp
|
||||
283
DPP-master/include/dpp/snowflake.h
Normal file
283
DPP-master/include/dpp/snowflake.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/exception.h>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
/**
|
||||
* @brief The main namespace for D++ functions. classes and types
|
||||
*/
|
||||
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 snowflake value.
|
||||
*
|
||||
* Snowflakes are:
|
||||
*
|
||||
* - Performant (very fast to generate at source and to compare in code)
|
||||
* - Uncoordinated (allowing high availability across clusters, data centres etc)
|
||||
* - Time ordered (newer snowflakes have higher IDs)
|
||||
* - Directly Sortable (due to time ordering)
|
||||
* - Compact (64 bit numbers, not 128 bit, or string)
|
||||
*
|
||||
* An identical format of snowflake is used by Twitter, Instagram and several other platforms.
|
||||
*
|
||||
* @see https://en.wikipedia.org/wiki/Snowflake_ID
|
||||
* @see https://github.com/twitter-archive/snowflake/tree/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231
|
||||
*/
|
||||
class DPP_EXPORT snowflake final {
|
||||
friend struct std::hash<dpp::snowflake>;
|
||||
protected:
|
||||
/**
|
||||
* @brief The snowflake value
|
||||
*/
|
||||
uint64_t value = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a snowflake object
|
||||
*/
|
||||
constexpr snowflake() noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Copy a snowflake object
|
||||
*/
|
||||
constexpr snowflake(const snowflake &rhs) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Move a snowflake object
|
||||
*/
|
||||
constexpr snowflake(snowflake &&rhs) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a snowflake from an integer value
|
||||
*
|
||||
* @throw dpp::logic_exception on assigning a negative value. The function is noexcept if the type given is unsigned
|
||||
* @param snowflake_val snowflake value as an integer type
|
||||
*/
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>>>
|
||||
constexpr snowflake(T snowflake_val) noexcept(std::is_unsigned_v<T>) : value(static_cast<std::make_unsigned_t<T>>(snowflake_val)) {
|
||||
/**
|
||||
* we cast to the unsigned version of the type given - this maintains "possible loss of data" warnings for sizeof(T) > sizeof(value)
|
||||
* while suppressing them for signed to unsigned conversion (for example snowflake(42) will call snowflake(int) which is a signed type)
|
||||
*/
|
||||
if constexpr (!std::is_unsigned_v<T>) {
|
||||
/* if the type is signed, at compile-time, add a check at runtime that the value is unsigned */
|
||||
if (snowflake_val < 0) {
|
||||
value = 0;
|
||||
throw dpp::logic_exception{"cannot assign a negative value to dpp::snowflake"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a snowflake object from an unsigned integer in a string
|
||||
*
|
||||
* On invalid string the value will be 0
|
||||
* @param string_value A snowflake value
|
||||
*/
|
||||
snowflake(std::string_view string_value) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Construct a snowflake object from an unsigned integer in a string
|
||||
*
|
||||
* On invalid string the value will be 0
|
||||
* @param string_value A snowflake value
|
||||
*/
|
||||
template <typename T, typename = std::enable_if_t<std::is_same_v<T, std::string>>>
|
||||
snowflake(const T &string_value) noexcept : snowflake(std::string_view{string_value}) {}
|
||||
/* ^ this exists to preserve `message_cache.find(std::get<std::string>(event.get_parameter("message_id")));` */
|
||||
|
||||
/**
|
||||
* @brief Copy value from another snowflake
|
||||
*
|
||||
* @param rhs The snowflake to copy from
|
||||
*/
|
||||
constexpr dpp::snowflake &operator=(const dpp::snowflake& rhs) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Move value from another snowflake
|
||||
*
|
||||
* @param rhs The snowflake to move from
|
||||
*/
|
||||
constexpr dpp::snowflake &operator=(dpp::snowflake&& rhs) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Assign integer value to the snowflake
|
||||
*
|
||||
* @throw dpp::logic_exception on assigning a negative value. The function is noexcept if the type given is unsigned
|
||||
* @param snowflake_val snowflake value as an integer type
|
||||
*/
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
constexpr dpp::snowflake &operator=(T snowflake_val) noexcept(std::is_unsigned_v<T>) {
|
||||
return *this = dpp::snowflake{snowflake_val};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assign value converted from a string to the snowflake
|
||||
*
|
||||
* On invalid string the value will be 0
|
||||
* @param snowflake_val snowflake value as a string
|
||||
*/
|
||||
template <typename T, typename = std::enable_if_t<std::is_convertible_v<T, std::string_view>>>
|
||||
constexpr dpp::snowflake &operator=(T&& snowflake_val) noexcept {
|
||||
return *this = dpp::snowflake{std::forward<T>(snowflake_val)};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the snowflake holds an empty value (is 0)
|
||||
*
|
||||
* @return true if empty (zero)
|
||||
*/
|
||||
constexpr bool empty() const noexcept {
|
||||
return value == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the stringified version of the snowflake value
|
||||
*
|
||||
* @return std::string string form of snowflake value
|
||||
*/
|
||||
inline std::string str() const {
|
||||
return std::to_string(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Comparison operator with another snowflake
|
||||
*
|
||||
* @param snowflake_val snowflake
|
||||
*/
|
||||
constexpr bool operator==(dpp::snowflake snowflake_val) const noexcept {
|
||||
return value == snowflake_val.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Comparison operator with a string
|
||||
*
|
||||
* @param snowflake_val snowflake value as a string
|
||||
*/
|
||||
bool operator==(std::string_view snowflake_val) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Comparison operator with an integer
|
||||
*
|
||||
* @param snowflake_val snowflake value as an integer type
|
||||
*/
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
constexpr bool operator==(T snowflake_val) const noexcept {
|
||||
/* We use the std::enable_if_t trick to disable implicit conversions so there is a perfect candidate for overload resolution for integers, and it isn't ambiguous */
|
||||
return *this == dpp::snowflake{snowflake_val};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For acting like an integer
|
||||
* @return The snowflake value
|
||||
*/
|
||||
constexpr operator uint64_t() const noexcept {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For acting like an integer
|
||||
* @return A reference to the snowflake value
|
||||
*/
|
||||
constexpr operator uint64_t &() noexcept {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For building json
|
||||
* @return The snowflake value as a string
|
||||
*/
|
||||
operator json() const;
|
||||
|
||||
/**
|
||||
* @brief Get the creation time of this snowflake 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 {
|
||||
constexpr uint64_t first_january_2016 = 1420070400000ull;
|
||||
return static_cast<double>((value >> 22) + first_january_2016) / 1000.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the worker id that produced this snowflake value
|
||||
*
|
||||
* @return uint8_t worker id
|
||||
*/
|
||||
constexpr uint8_t get_worker_id() const noexcept {
|
||||
return static_cast<uint8_t>((value & 0x3E0000) >> 17);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the process id that produced this snowflake value
|
||||
*
|
||||
* @return uint8_t process id
|
||||
*/
|
||||
constexpr uint8_t get_process_id() const noexcept {
|
||||
return static_cast<uint8_t>((value & 0x1F000) >> 12);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the increment, which is incremented for every snowflake
|
||||
* created over the one millisecond resolution in the timestamp.
|
||||
*
|
||||
* @return uint64_t millisecond increment
|
||||
*/
|
||||
constexpr uint16_t get_increment() const noexcept {
|
||||
return static_cast<uint16_t>(value & 0xFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function for libfmt so that a snowflake can be directly formatted as a uint64_t.
|
||||
*
|
||||
* @see https://fmt.dev/latest/api.html#formatting-user-defined-types
|
||||
* @return uint64_t snowflake ID
|
||||
*/
|
||||
friend constexpr uint64_t format_as(snowflake s) noexcept {
|
||||
/* note: this function must stay as "friend" - this declares it as a free function but makes it invisible unless the argument is snowflake
|
||||
* this effectively means no implicit conversions are performed to snowflake, for example format_as(0) doesn't call this function */
|
||||
return s.value;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
|
||||
template<>
|
||||
struct std::hash<dpp::snowflake>
|
||||
{
|
||||
/**
|
||||
* @brief Hashing function for dpp::snowflake
|
||||
* Used by std::unordered_map. This just calls std::hash<uint64_t>.
|
||||
*
|
||||
* @param s Snowflake value to hash
|
||||
* @return std::size_t hash value
|
||||
*/
|
||||
std::size_t operator()(dpp::snowflake s) const noexcept {
|
||||
return std::hash<uint64_t>{}(s.value);
|
||||
}
|
||||
};
|
||||
30
DPP-master/include/dpp/socket.h
Normal file
30
DPP-master/include/dpp/socket.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifndef SOCKET
|
||||
#define SOCKET int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace dpp
|
||||
{
|
||||
/**
|
||||
* @brief Represents a socket file descriptor.
|
||||
* This is used to ensure parity between windows and unix-like systems.
|
||||
*/
|
||||
typedef SOCKET socket;
|
||||
} // namespace dpp
|
||||
|
||||
#ifndef SOCKET_ERROR
|
||||
/**
|
||||
* @brief Represents a socket in error state
|
||||
*/
|
||||
#define SOCKET_ERROR -1
|
||||
#endif
|
||||
|
||||
#ifndef INVALID_SOCKET
|
||||
/**
|
||||
* @brief Represents a socket which is not yet assigned
|
||||
*/
|
||||
#define INVALID_SOCKET ~0
|
||||
#endif
|
||||
259
DPP-master/include/dpp/sslclient.h
Normal file
259
DPP-master/include/dpp/sslclient.h
Normal file
@@ -0,0 +1,259 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/misc-enum.h>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <dpp/socket.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief This is an opaque class containing openssl library specific structures.
|
||||
* We define it this way so that the public facing D++ library doesn't require
|
||||
* the openssl headers be available to build against it.
|
||||
*/
|
||||
class openssl_connection;
|
||||
|
||||
/**
|
||||
* @brief A callback for socket status
|
||||
*/
|
||||
typedef std::function<dpp::socket()> socket_callback_t;
|
||||
|
||||
/**
|
||||
* @brief A socket notification callback
|
||||
*/
|
||||
typedef std::function<void()> socket_notification_t;
|
||||
|
||||
/**
|
||||
* @brief Close a socket
|
||||
*
|
||||
* @param sfd Socket to close
|
||||
* @return false on error, true on success
|
||||
*/
|
||||
bool close_socket(dpp::socket sfd);
|
||||
|
||||
/**
|
||||
* @brief Set a socket to blocking or non-blocking IO
|
||||
*
|
||||
* @param sockfd socket to act upon
|
||||
* @return false on error, true on success
|
||||
*/
|
||||
bool set_nonblocking(dpp::socket sockfd, bool non_blocking);
|
||||
|
||||
/**
|
||||
* @brief Implements a simple non-blocking SSL stream client.
|
||||
*
|
||||
* @note although the design is non-blocking the run() method will
|
||||
* execute in an infinite loop until the socket disconnects. This is intended
|
||||
* to be run within a std::thread.
|
||||
*/
|
||||
class DPP_EXPORT ssl_client
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief Clean up resources
|
||||
*/
|
||||
void cleanup();
|
||||
protected:
|
||||
/**
|
||||
* @brief Input buffer received from socket
|
||||
*/
|
||||
std::string buffer;
|
||||
|
||||
/**
|
||||
* @brief Output buffer for sending to socket
|
||||
*/
|
||||
std::string obuffer;
|
||||
|
||||
/**
|
||||
* @brief True if in nonblocking mode. The socket switches to nonblocking mode
|
||||
* once ReadLoop is called.
|
||||
*/
|
||||
bool nonblocking;
|
||||
|
||||
/**
|
||||
* @brief Raw file descriptor of connection
|
||||
*/
|
||||
dpp::socket sfd;
|
||||
|
||||
/**
|
||||
* @brief Openssl opaque contexts
|
||||
*/
|
||||
openssl_connection* ssl;
|
||||
|
||||
/**
|
||||
* @brief SSL cipher in use
|
||||
*/
|
||||
std::string cipher;
|
||||
|
||||
/**
|
||||
* @brief For timers
|
||||
*/
|
||||
time_t last_tick;
|
||||
|
||||
/**
|
||||
* @brief Hostname connected to
|
||||
*/
|
||||
std::string hostname;
|
||||
|
||||
/**
|
||||
* @brief Port connected to
|
||||
*/
|
||||
std::string port;
|
||||
|
||||
/**
|
||||
* @brief Bytes out
|
||||
*/
|
||||
uint64_t bytes_out;
|
||||
|
||||
/**
|
||||
* @brief Bytes in
|
||||
*/
|
||||
uint64_t bytes_in;
|
||||
|
||||
/**
|
||||
* @brief True for a plain text connection
|
||||
*/
|
||||
bool plaintext;
|
||||
|
||||
/**
|
||||
* @brief True if we are establishing a new connection, false if otherwise.
|
||||
*/
|
||||
bool make_new;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Called every second
|
||||
*/
|
||||
virtual void one_second_timer();
|
||||
|
||||
/**
|
||||
* @brief Start SSL connection and connect to TCP endpoint
|
||||
* @throw dpp::exception Failed to initialise connection
|
||||
*/
|
||||
virtual void connect();
|
||||
public:
|
||||
/**
|
||||
* @brief Get the bytes out objectGet total bytes sent
|
||||
* @return uint64_t bytes sent
|
||||
*/
|
||||
uint64_t get_bytes_out();
|
||||
|
||||
/**
|
||||
* @brief Get total bytes received
|
||||
* @return uint64_t bytes received
|
||||
*/
|
||||
uint64_t get_bytes_in();
|
||||
|
||||
/**
|
||||
* @brief Get SSL cipher name
|
||||
* @return std::string ssl cipher name
|
||||
*/
|
||||
std::string get_cipher();
|
||||
|
||||
/**
|
||||
* @brief Attaching an additional file descriptor to this function will send notifications when there is data to read.
|
||||
*
|
||||
* NOTE: Only hook this if you NEED it as it can increase CPU usage of the thread!
|
||||
* Returning -1 means that you don't want to be notified.
|
||||
*/
|
||||
socket_callback_t custom_readable_fd;
|
||||
|
||||
/**
|
||||
* @brief Attaching an additional file descriptor to this function will send notifications when you are able to write
|
||||
* to the socket.
|
||||
*
|
||||
* NOTE: Only hook this if you NEED it as it can increase CPU usage of the thread! You should toggle this
|
||||
* to -1 when you do not have anything to write otherwise it'll keep triggering repeatedly (it is level triggered).
|
||||
*/
|
||||
socket_callback_t custom_writeable_fd;
|
||||
|
||||
/**
|
||||
* @brief This event will be called when you can read from the custom fd
|
||||
*/
|
||||
socket_notification_t custom_readable_ready;
|
||||
|
||||
/**
|
||||
* @brief This event will be called when you can write to a custom fd
|
||||
*/
|
||||
socket_notification_t custom_writeable_ready;
|
||||
|
||||
/**
|
||||
* @brief True if we are keeping the connection alive after it has finished
|
||||
*/
|
||||
bool keepalive;
|
||||
|
||||
/**
|
||||
* @brief Connect to a specified host and port. Throws std::runtime_error on fatal error.
|
||||
* @param _hostname The hostname to connect to
|
||||
* @param _port the Port number to connect to
|
||||
* @param plaintext_downgrade Set to true to connect using plaintext only, without initialising SSL.
|
||||
* @param reuse Attempt to reuse previous connections for this hostname and port, if available
|
||||
* Note that no Discord endpoints will function when downgraded. This option is provided only for
|
||||
* connection to non-Discord addresses such as within dpp::cluster::request().
|
||||
* @throw dpp::exception Failed to initialise connection
|
||||
*/
|
||||
ssl_client(const std::string &_hostname, const std::string &_port = "443", bool plaintext_downgrade = false, bool reuse = false);
|
||||
|
||||
/**
|
||||
* @brief Nonblocking I/O loop
|
||||
* @throw std::exception Any std::exception (or derivative) thrown from read_loop() causes reconnection of the shard
|
||||
*/
|
||||
void read_loop();
|
||||
|
||||
/**
|
||||
* @brief Destroy the ssl_client object
|
||||
*/
|
||||
virtual ~ssl_client();
|
||||
|
||||
/**
|
||||
* @brief Handle input from the input buffer. This function will be called until
|
||||
* all data in the buffer has been processed and the buffer is empty.
|
||||
* @param buffer the buffer content. Will be modified removing any processed front elements
|
||||
* @return bool True if the socket should remain connected
|
||||
*/
|
||||
virtual bool handle_buffer(std::string &buffer);
|
||||
|
||||
/**
|
||||
* @brief Write to the output buffer.
|
||||
* @param data Data to be written to the buffer
|
||||
* @note The data may not be written immediately and may be written at a later time to the socket.
|
||||
*/
|
||||
virtual void write(const std::string &data);
|
||||
|
||||
/**
|
||||
* @brief Close socket connection
|
||||
*/
|
||||
virtual void close();
|
||||
|
||||
/**
|
||||
* @brief Log a message
|
||||
* @param severity severity of log message
|
||||
* @param msg Log message to send
|
||||
*/
|
||||
virtual void log(dpp::loglevel severity, const std::string &msg) const;
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
112
DPP-master/include/dpp/stage_instance.h
Normal file
112
DPP-master/include/dpp/stage_instance.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Represents the privacy of a stage instance
|
||||
*/
|
||||
enum stage_privacy_level : uint8_t {
|
||||
/**
|
||||
* @brief The Stage instance is visible publicly, such as on Stage Discovery.
|
||||
*/
|
||||
sp_public = 1,
|
||||
|
||||
/**
|
||||
* @brief The Stage instance is visible to only guild members.
|
||||
*/
|
||||
sp_guild_only = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A stage instance.
|
||||
* Stage instances are like a conference facility, with moderators/speakers and listeners.
|
||||
*/
|
||||
struct DPP_EXPORT stage_instance : public managed, public json_interface<stage_instance> {
|
||||
protected:
|
||||
friend struct json_interface<stage_instance>;
|
||||
|
||||
/**
|
||||
* @brief Serialise a stage_instance object rom json
|
||||
*
|
||||
* @return stage_instance& a reference to self
|
||||
*/
|
||||
stage_instance& fill_from_json_impl(const nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Build json for this object
|
||||
*
|
||||
* @param with_id include ID
|
||||
* @return json Json of this object
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The guild ID of the associated Stage channel.
|
||||
*/
|
||||
snowflake guild_id;
|
||||
|
||||
/**
|
||||
* @brief The ID of the associated Stage channel.
|
||||
*/
|
||||
snowflake channel_id;
|
||||
|
||||
/**
|
||||
* @brief The topic of the Stage instance (1-120 characters).
|
||||
*/
|
||||
std::string topic;
|
||||
|
||||
/**
|
||||
* @brief The privacy level of the Stage instance.
|
||||
*/
|
||||
stage_privacy_level privacy_level;
|
||||
|
||||
/**
|
||||
* @brief Whether or not Stage Discovery is disabled.
|
||||
*/
|
||||
bool discoverable_disabled;
|
||||
|
||||
/**
|
||||
* @brief Create a stage_instance object
|
||||
*/
|
||||
stage_instance();
|
||||
|
||||
/**
|
||||
* @brief Destroy the stage_instance object
|
||||
*/
|
||||
~stage_instance() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A group of stage instances
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, stage_instance> stage_instance_map;
|
||||
|
||||
} // namespace dpp
|
||||
220
DPP-master/include/dpp/stringops.h
Normal file
220
DPP-master/include/dpp/stringops.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* D++ - A Lightweight C++ Library for Discord
|
||||
*
|
||||
* stringops.h taken from TriviaBot
|
||||
*
|
||||
* Copyright 2004 Craig Edwards <support@sporks.gg>
|
||||
*
|
||||
* Core based on Sporks, the Learning Discord Bot, Craig Edwards (c) 2019.
|
||||
*
|
||||
* 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 <string>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <charconv>
|
||||
|
||||
namespace dpp {
|
||||
/**
|
||||
* @brief Convert a string to lowercase using tolower()
|
||||
*
|
||||
* @tparam T type of string
|
||||
* @param s String to lowercase
|
||||
* @return std::basic_string<T> lowercased string
|
||||
*/
|
||||
template <typename T> std::basic_string<T> lowercase(const std::basic_string<T>& s)
|
||||
{
|
||||
std::basic_string<T> s2 = s;
|
||||
std::transform(s2.begin(), s2.end(), s2.begin(), tolower);
|
||||
return s2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a string to uppercase using toupper()
|
||||
*
|
||||
* @tparam T type of string
|
||||
* @param s String to uppercase
|
||||
* @return std::basic_string<T> uppercased string
|
||||
*/
|
||||
template <typename T> std::basic_string<T> uppercase(const std::basic_string<T>& s)
|
||||
{
|
||||
std::basic_string<T> s2 = s;
|
||||
std::transform(s2.begin(), s2.end(), s2.begin(), toupper);
|
||||
return s2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief trim from end of string (right)
|
||||
*
|
||||
* @param s String to trim
|
||||
* @return std::string trimmed string
|
||||
*/
|
||||
inline std::string rtrim(std::string s)
|
||||
{
|
||||
s.erase(s.find_last_not_of(" \t\n\r\f\v") + 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief trim from beginning of string (left)
|
||||
*
|
||||
* @param s string to trim
|
||||
* @return std::string trimmed string
|
||||
*/
|
||||
inline std::string ltrim(std::string s)
|
||||
{
|
||||
s.erase(0, s.find_first_not_of(" \t\n\r\f\v"));
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trim from both ends of string (right then left)
|
||||
*
|
||||
* @param s string to trim
|
||||
* @return std::string trimmed string
|
||||
*/
|
||||
inline std::string trim(std::string s)
|
||||
{
|
||||
return ltrim(rtrim(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add commas to a string (or dots) based on current locale server-side
|
||||
*
|
||||
* @tparam T type of numeric value
|
||||
* @param value Value
|
||||
* @return std::string number with commas added
|
||||
*/
|
||||
template<class T> std::string comma(T value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale(""));
|
||||
ss << std::fixed << value;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert any value from a string to another type using stringstream.
|
||||
* The optional second parameter indicates the format of the input string,
|
||||
* e.g. std::dec for decimal, std::hex for hex, std::oct for octal.
|
||||
*
|
||||
* @tparam T Type to convert to
|
||||
* @param s String to convert from
|
||||
* @param f Numeric base, e.g. `std::dec` or `std::hex`
|
||||
* @return T Returned numeric value
|
||||
*/
|
||||
template <typename T> T from_string(const std::string &s, std::ios_base & (*f)(std::ios_base&))
|
||||
{
|
||||
T t;
|
||||
std::istringstream iss(s);
|
||||
iss >> f, iss >> t;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert any value from a string to another type using stringstream.
|
||||
*
|
||||
* @tparam T Type to convert to
|
||||
* @param s String to convert from
|
||||
* @return T Returned numeric value
|
||||
*
|
||||
* @note Base 10 for numeric conversions.
|
||||
*/
|
||||
template <typename T> T from_string(const std::string &s)
|
||||
{
|
||||
T t;
|
||||
std::istringstream iss(s);
|
||||
iss >> t;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specialised conversion of uint64_t from string
|
||||
*
|
||||
* @tparam int64_t
|
||||
* @param s string to convert
|
||||
* @return uint64_t return value
|
||||
*/
|
||||
template <uint64_t> uint64_t from_string(const std::string &s)
|
||||
{
|
||||
return std::stoull(s, 0, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specialised conversion of uint32_t from string
|
||||
*
|
||||
* @tparam uint32_t
|
||||
* @param s string to convert
|
||||
* @return uint32_t return value
|
||||
*/
|
||||
template <uint32_t> uint32_t from_string(const std::string &s)
|
||||
{
|
||||
return (uint32_t) std::stoul(s, 0, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specialised conversion of int from string
|
||||
*
|
||||
* @tparam int
|
||||
* @param s string to convert
|
||||
* @return int return value
|
||||
*/
|
||||
template <int> int from_string(const std::string &s)
|
||||
{
|
||||
return std::stoi(s, 0, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a numeric value to hex
|
||||
*
|
||||
* @tparam T numeric type
|
||||
* @param i numeric value
|
||||
* @param leading_zeroes set to false if you don't want the leading zeroes in the output
|
||||
* @return std::string value in hex, the length will be 2* the raw size of the type
|
||||
*/
|
||||
template <typename T> std::string to_hex(T i, bool leading_zeroes = true)
|
||||
{
|
||||
char str[26] = { 0 };
|
||||
size_t size = sizeof(T) * 2;
|
||||
std::to_chars(std::begin(str), std::end(str), i, 16);
|
||||
std::string out{str};
|
||||
if (leading_zeroes && out.length() < size) {
|
||||
out.insert(out.begin(), size - out.length(), '0');
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Format a numeric type as a string with leading zeroes
|
||||
*
|
||||
* @tparam T numeric type
|
||||
* @param i numeric value
|
||||
* @param width width of type including the leading zeroes
|
||||
* @return std::string resultant string with leading zeroes
|
||||
*/
|
||||
template <typename T> std::string leading_zeroes(T i, size_t width)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream.imbue(std::locale::classic());
|
||||
stream << std::setfill('0') << std::setw((int)width) << std::dec << i;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
} // namespace dpp
|
||||
81
DPP-master/include/dpp/sync.h
Normal file
81
DPP-master/include/dpp/sync.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <future>
|
||||
#include <utility>
|
||||
#include <dpp/exception.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Call a D++ REST function synchronously.
|
||||
*
|
||||
* Synchronously calling a REST function means *IT WILL BLOCK* - This is a Bad Thing™ and strongly discouraged.
|
||||
* There are very few circumstances you actually need this. If you do need to use this, you'll know it.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```cpp
|
||||
* dpp::message m = dpp::sync<dpp::message>(&bot, &dpp::cluster::message_create, dpp::message(channel_id, "moo."));
|
||||
* ```
|
||||
*
|
||||
* @warning As previously mentioned, this template will block. It is ill-advised to call this outside of
|
||||
* a separate thread and this should never be directly used in any event such as dpp::cluster::on_interaction_create!
|
||||
* @tparam T type of expected return value, should match up with the method called
|
||||
* @tparam F Type of class method in dpp::cluster to call.
|
||||
* @tparam Ts Function parameters in method call
|
||||
* @param c A pointer to dpp::cluster object
|
||||
* @param func pointer to class method in dpp::cluster to call. This can call any
|
||||
* dpp::cluster member function who's last parameter is a dpp::command_completion_event_t callback type.
|
||||
* @param args Zero or more arguments for the method call
|
||||
* @return An instantiated object of type T
|
||||
* @throw dpp::rest_exception On failure of the method call, an exception is thrown
|
||||
*/
|
||||
template<typename T, class F, class... Ts> T sync(class cluster* c, F func, Ts&&... args) {
|
||||
std::promise<T> _p;
|
||||
std::future<T> _f = _p.get_future();
|
||||
/* (obj ->* func) is the obscure syntax for calling a method pointer on an object instance */
|
||||
(c ->* func)(std::forward<Ts>(args)..., [&_p](const auto& cc) {
|
||||
try {
|
||||
if (cc.is_error()) {
|
||||
const auto& error = cc.get_error();
|
||||
throw dpp::rest_exception((exception_error_code)error.code, error.message);
|
||||
} else {
|
||||
try {
|
||||
_p.set_value(std::get<T>(cc.value));
|
||||
} catch (const std::exception& e) {
|
||||
throw dpp::rest_exception(err_unknown, e.what());
|
||||
}
|
||||
}
|
||||
} catch (const dpp::rest_exception&) {
|
||||
_p.set_exception(std::current_exception());
|
||||
}
|
||||
});
|
||||
|
||||
/* Blocking calling thread until rest request is completed.
|
||||
* Exceptions encountered on the other thread are re-thrown.
|
||||
*/
|
||||
return _f.get();
|
||||
}
|
||||
|
||||
} // namespace dpp
|
||||
120
DPP-master/include/dpp/sysdep.h
Normal file
120
DPP-master/include/dpp/sysdep.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Discord erlpack - tidied up for D++, Craig Edwards 2021.
|
||||
*
|
||||
* MessagePack system dependencies modified for erlpack.
|
||||
*
|
||||
* Copyright (C) 2008-2010 FURUHASHI Sadayuki
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#if defined(__linux__)
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* numeric_limits<T>::min,max */
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <arpa/inet.h> /* __BYTE_ORDER */
|
||||
#endif
|
||||
|
||||
#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define __LITTLE_ENDIAN__
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define __BIG_ENDIAN__
|
||||
#elif _WIN32
|
||||
#define __LITTLE_ENDIAN__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
|
||||
#ifdef _WIN32
|
||||
# if defined(ntohs)
|
||||
# define etf_byte_order_16(x) ntohs(x)
|
||||
# elif defined(_byteswap_ushort) || (defined(_MSC_VER) && _MSC_VER >= 1400)
|
||||
# define etf_byte_order_16(x) ((uint16_t)_byteswap_ushort((unsigned short)x))
|
||||
# else
|
||||
# define etf_byte_order_16(x) ( \
|
||||
((((uint16_t)x) << 8) ) | \
|
||||
((((uint16_t)x) >> 8) ) )
|
||||
# endif
|
||||
#else
|
||||
# define etf_byte_order_16(x) ntohs(x)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# if defined(ntohl)
|
||||
# define etf_byte_order_32(x) ntohl(x)
|
||||
# elif defined(_byteswap_ulong) || (defined(_MSC_VER) && _MSC_VER >= 1400)
|
||||
# define etf_byte_order_32(x) ((uint32_t)_byteswap_ulong((unsigned long)x))
|
||||
# else
|
||||
# define etf_byte_order_32(x) \
|
||||
( ((((uint32_t)x) << 24) ) | \
|
||||
((((uint32_t)x) << 8) & 0x00ff0000U ) | \
|
||||
((((uint32_t)x) >> 8) & 0x0000ff00U ) | \
|
||||
((((uint32_t)x) >> 24) ) )
|
||||
# endif
|
||||
#else
|
||||
# define etf_byte_order_32(x) ntohl(x)
|
||||
#endif
|
||||
|
||||
#if defined(_byteswap_uint64) || (defined(_MSC_VER) && _MSC_VER >= 1400)
|
||||
# define etf_byte_order_64(x) (_byteswap_uint64(x))
|
||||
#elif defined(bswap_64)
|
||||
# define etf_byte_order_64(x) bswap_64(x)
|
||||
#elif defined(__DARWIN_OSSwapInt64)
|
||||
# define etf_byte_order_64(x) __DARWIN_OSSwapInt64(x)
|
||||
#elif defined(__linux__)
|
||||
# define etf_byte_order_64(x) be64toh(x)
|
||||
#else
|
||||
# define etf_byte_order_64(x) \
|
||||
( ((((uint64_t)x) << 56) ) | \
|
||||
((((uint64_t)x) << 40) & 0x00ff000000000000ULL ) | \
|
||||
((((uint64_t)x) << 24) & 0x0000ff0000000000ULL ) | \
|
||||
((((uint64_t)x) << 8) & 0x000000ff00000000ULL ) | \
|
||||
((((uint64_t)x) >> 8) & 0x00000000ff000000ULL ) | \
|
||||
((((uint64_t)x) >> 24) & 0x0000000000ff0000ULL ) | \
|
||||
((((uint64_t)x) >> 40) & 0x000000000000ff00ULL ) | \
|
||||
((((uint64_t)x) >> 56) ) )
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define etf_byte_order_16(x) (x)
|
||||
#define etf_byte_order_32(x) (x)
|
||||
#define etf_byte_order_64(x) (x)
|
||||
#endif
|
||||
|
||||
#define store_16_bits(to, num) \
|
||||
do { uint16_t val = etf_byte_order_16(num); memcpy(to, &val, 2); } while(0)
|
||||
#define store_32_bits(to, num) \
|
||||
do { uint32_t val = etf_byte_order_32(num); memcpy(to, &val, 4); } while(0)
|
||||
#define store_64_bits(to, num) \
|
||||
do { uint64_t val = etf_byte_order_64(num); memcpy(to, &val, 8); } while(0)
|
||||
230
DPP-master/include/dpp/thread.h
Normal file
230
DPP-master/include/dpp/thread.h
Normal file
@@ -0,0 +1,230 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/message.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief represents membership of a user with a thread
|
||||
*/
|
||||
struct DPP_EXPORT thread_member : public json_interface<thread_member> {
|
||||
protected:
|
||||
friend struct json_interface<thread_member>;
|
||||
|
||||
/**
|
||||
* @brief Read struct values from a json object
|
||||
* @param j json to read values from
|
||||
* @return A reference to self
|
||||
*/
|
||||
thread_member& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief ID of the thread member is part of.
|
||||
*/
|
||||
snowflake thread_id = {};
|
||||
|
||||
/**
|
||||
* @brief ID of the member.
|
||||
*/
|
||||
snowflake user_id = {};
|
||||
|
||||
/**
|
||||
* @brief The time when user last joined the thread.
|
||||
*/
|
||||
time_t joined = 0;
|
||||
|
||||
/**
|
||||
* @brief Any user-thread settings, currently only used for notifications.
|
||||
*/
|
||||
uint32_t flags = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A group of thread member objects. the key is the user_id of the dpp::thread_member
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, thread_member> thread_member_map;
|
||||
|
||||
/**
|
||||
* @brief metadata for threads
|
||||
*/
|
||||
struct DPP_EXPORT thread_metadata {
|
||||
/**
|
||||
* @brief Timestamp when the thread's archive status was last changed, used for calculating recent activity.
|
||||
*/
|
||||
time_t archive_timestamp;
|
||||
|
||||
/**
|
||||
* @brief The duration in minutes to automatically archive the thread after recent activity (60, 1440, 4320, 10080).
|
||||
*/
|
||||
uint16_t auto_archive_duration;
|
||||
|
||||
/**
|
||||
* @brief Whether a thread is archived
|
||||
*/
|
||||
bool archived;
|
||||
|
||||
/**
|
||||
* @brief Whether a thread is locked. When a thread is locked,
|
||||
* only users with `MANAGE_THREADS` can un-archive it.
|
||||
*/
|
||||
bool locked;
|
||||
|
||||
/**
|
||||
* @brief Whether non-moderators can add other non-moderators. Only for private threads.
|
||||
*/
|
||||
bool invitable;
|
||||
};
|
||||
|
||||
/** @brief A definition of a discord thread.
|
||||
* A thread is a superset of a channel. Not to be confused with `std::thread`!
|
||||
*/
|
||||
class DPP_EXPORT thread : public channel, public json_interface<thread> {
|
||||
protected:
|
||||
friend struct json_interface<thread>;
|
||||
|
||||
/** Read class values from json object
|
||||
* @param j A json object to read from
|
||||
* @return A reference to self
|
||||
*/
|
||||
thread& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Build json for this thread object
|
||||
*
|
||||
* @param with_id include the ID in the json
|
||||
* @return std::string JSON string
|
||||
*/
|
||||
json to_json_impl(bool with_id = false) const override;
|
||||
|
||||
public:
|
||||
using json_interface<thread>::fill_from_json;
|
||||
using json_interface<thread>::build_json;
|
||||
using json_interface<thread>::to_json;
|
||||
|
||||
/**
|
||||
* @brief Thread member of current user if joined to the thread.
|
||||
* Note this is only set by certain api calls otherwise contains default data
|
||||
*/
|
||||
thread_member member = {};
|
||||
|
||||
/**
|
||||
* @brief Thread metadata (threads)
|
||||
*/
|
||||
thread_metadata metadata = {};
|
||||
|
||||
/**
|
||||
* @brief Created message. Only filled within the cluster::thread_create_in_forum() method
|
||||
*/
|
||||
message msg = {};
|
||||
|
||||
/**
|
||||
* @brief A list of dpp::forum_tag IDs that have been applied to a thread in a forum or media channel.
|
||||
*/
|
||||
std::vector<snowflake> applied_tags = {};
|
||||
|
||||
/**
|
||||
* @brief Number of messages ever sent in the thread.
|
||||
* It's similar to thread::message_count on message creation, but will not decrement the number when a message is deleted
|
||||
*/
|
||||
uint32_t total_messages_sent = 0;
|
||||
|
||||
/**
|
||||
* @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 = 0;
|
||||
|
||||
/**
|
||||
* @brief Approximate count of members in a thread (stops counting at 50)
|
||||
*/
|
||||
uint8_t member_count = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the thread is within an announcement channel
|
||||
*
|
||||
* @return true if announcement thread
|
||||
*/
|
||||
constexpr bool is_news_thread() const noexcept {
|
||||
return (flags & channel::CHANNEL_TYPE_MASK) == CHANNEL_ANNOUNCEMENT_THREAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the channel is a public thread
|
||||
*
|
||||
* @return true if public thread
|
||||
*/
|
||||
constexpr bool is_public_thread() const noexcept {
|
||||
return (flags & channel::CHANNEL_TYPE_MASK) == CHANNEL_PUBLIC_THREAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the channel is a private thread
|
||||
*
|
||||
* @return true if private thread
|
||||
*/
|
||||
constexpr bool is_private_thread() const noexcept {
|
||||
return (flags & channel::CHANNEL_TYPE_MASK) == CHANNEL_PRIVATE_THREAD;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Serialize a thread_metadata object to json
|
||||
*
|
||||
* @param j JSON object to serialize to
|
||||
* @param tmdata object to serialize
|
||||
*/
|
||||
void to_json(nlohmann::json& j, const thread_metadata& tmdata);
|
||||
|
||||
/**
|
||||
* @brief A group of threads
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, thread> thread_map;
|
||||
|
||||
/**
|
||||
* @brief A thread alongside the bot's optional thread_member object tied to it
|
||||
*/
|
||||
struct active_thread_info {
|
||||
/**
|
||||
* @brief The thread object
|
||||
*/
|
||||
thread active_thread;
|
||||
|
||||
/**
|
||||
* @brief The bot as a thread member, only present if the bot is in the thread
|
||||
*/
|
||||
std::optional<thread_member> bot_member;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A map of threads alongside optionally the thread_member tied to the bot if it is in the thread. The map's key is the thread id. Returned from the cluster::threads_get_active method
|
||||
*/
|
||||
using active_threads = std::map<snowflake, active_thread_info>;
|
||||
|
||||
}
|
||||
105
DPP-master/include/dpp/timed_listener.h
Normal file
105
DPP-master/include/dpp/timed_listener.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <time.h>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief A timed_listener is a way to temporarily attach to an event for a specific timeframe, then detach when complete.
|
||||
* A lambda may also be optionally called when the timeout is reached. Destructing the timed_listener detaches any attached
|
||||
* event listeners, and cancels any created timers, but does not call any timeout lambda.
|
||||
*
|
||||
* @tparam attached_event Event within cluster to attach to within the cluster::dispatch member (dpp::dispatcher object)
|
||||
* @tparam listening_function Definition of lambda function that matches up with the attached_event.
|
||||
*/
|
||||
template <typename attached_event, class listening_function> class timed_listener
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief Owning cluster.
|
||||
*/
|
||||
cluster* owner;
|
||||
|
||||
/**
|
||||
* @brief Duration of listen.
|
||||
*/
|
||||
time_t duration;
|
||||
|
||||
/**
|
||||
* @brief Reference to attached event in cluster.
|
||||
*/
|
||||
//event_router_t<thread_member_update_t> on_thread_member_update;
|
||||
attached_event& ev;
|
||||
|
||||
/**
|
||||
* @brief Timer handle.
|
||||
*/
|
||||
timer th;
|
||||
|
||||
/**
|
||||
* @brief Event handle.
|
||||
*/
|
||||
event_handle listener_handle;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new timed listener object
|
||||
*
|
||||
* @param cl Owning cluster
|
||||
* @param _duration Duration of timed event in seconds
|
||||
* @param event Event to hook, e.g. cluster.on_message_create
|
||||
* @param on_end An optional void() lambda to trigger when the timed_listener times out.
|
||||
* Calling the destructor before the timeout is reached does not call this lambda.
|
||||
* @param listener Lambda to receive events. Type must match up properly with that passed into the 'event' parameter.
|
||||
*/
|
||||
timed_listener(cluster* cl, uint64_t _duration, attached_event& event, listening_function listener, timer_callback_t on_end = {})
|
||||
: owner(cl), duration(_duration), ev(event)
|
||||
{
|
||||
/* Attach event */
|
||||
listener_handle = ev(listener);
|
||||
/* Create timer */
|
||||
th = cl->start_timer([this]([[maybe_unused]] dpp::timer timer_handle) {
|
||||
/* Timer has finished, detach it from event.
|
||||
* Only allowed to tick once.
|
||||
*/
|
||||
ev.detach(listener_handle);
|
||||
owner->stop_timer(th);
|
||||
}, duration, on_end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy the timed listener object
|
||||
*/
|
||||
~timed_listener() {
|
||||
/* Stop timer and detach event, but do not call on_end */
|
||||
ev.detach(listener_handle);
|
||||
owner->stop_timer(th);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
132
DPP-master/include/dpp/timer.h
Normal file
132
DPP-master/include/dpp/timer.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <stddef.h>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Represents a timer handle.
|
||||
* Returned from cluster::start_timer and used by cluster::stop_timer.
|
||||
* This is obtained from a simple incrementing value, internally.
|
||||
*/
|
||||
typedef size_t timer;
|
||||
|
||||
/**
|
||||
* @brief The type for a timer callback
|
||||
*/
|
||||
typedef std::function<void(timer)> timer_callback_t;
|
||||
|
||||
/**
|
||||
* @brief Used internally to store state of active timers
|
||||
*/
|
||||
struct DPP_EXPORT timer_t {
|
||||
/**
|
||||
* @brief Timer handle
|
||||
*/
|
||||
timer handle;
|
||||
|
||||
/**
|
||||
* @brief Next timer tick as unix epoch
|
||||
*/
|
||||
time_t next_tick;
|
||||
|
||||
/**
|
||||
* @brief Frequency between ticks
|
||||
*/
|
||||
uint64_t frequency;
|
||||
|
||||
/**
|
||||
* @brief Lambda to call on tick
|
||||
*/
|
||||
timer_callback_t on_tick;
|
||||
|
||||
/**
|
||||
* @brief Lambda to call on stop (optional)
|
||||
*/
|
||||
timer_callback_t on_stop;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A map of timers, ordered by earliest first so that map::begin() is always the
|
||||
* soonest to be due.
|
||||
*/
|
||||
typedef std::multimap<time_t, timer_t*> timer_next_t;
|
||||
|
||||
/**
|
||||
* @brief A map of timers stored by handle
|
||||
*/
|
||||
typedef std::unordered_map<timer, timer_t*> timer_reg_t;
|
||||
|
||||
/**
|
||||
* @brief Trigger a timed event once.
|
||||
* The provided callback is called only once.
|
||||
*/
|
||||
class DPP_EXPORT oneshot_timer
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief Owning cluster.
|
||||
*/
|
||||
class cluster* owner;
|
||||
|
||||
/**
|
||||
* @brief Timer handle.
|
||||
*/
|
||||
timer th;
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new oneshot timer object
|
||||
*
|
||||
* @param cl cluster owner
|
||||
* @param duration duration before firing
|
||||
* @param callback callback to call on firing
|
||||
*/
|
||||
oneshot_timer(class cluster* cl, uint64_t duration, timer_callback_t callback);
|
||||
|
||||
/**
|
||||
* @brief Get the handle for the created one-shot timer
|
||||
*
|
||||
* @return timer handle for use with stop_timer
|
||||
*/
|
||||
timer get_handle();
|
||||
|
||||
/**
|
||||
* @brief Cancel the one shot timer immediately.
|
||||
* Callback function is not called.
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* @brief Destroy the oneshot timer object
|
||||
*/
|
||||
~oneshot_timer();
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
5485
DPP-master/include/dpp/unicode_emoji.h
Normal file
5485
DPP-master/include/dpp/unicode_emoji.h
Normal file
File diff suppressed because it is too large
Load Diff
582
DPP-master/include/dpp/user.h
Normal file
582
DPP-master/include/dpp/user.h
Normal file
@@ -0,0 +1,582 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/utility.h>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Various bitmask flags used to represent information about a dpp::user
|
||||
*/
|
||||
enum user_flags : uint32_t {
|
||||
/**
|
||||
* @brief User is a bot.
|
||||
*/
|
||||
u_bot = 0b00000000000000000000000000000001,
|
||||
|
||||
/**
|
||||
* @brief User is a system user (Clyde!).
|
||||
*/
|
||||
u_system = 0b00000000000000000000000000000010,
|
||||
|
||||
/**
|
||||
* @brief User has multi-factor authentication enabled.
|
||||
*/
|
||||
u_mfa_enabled = 0b00000000000000000000000000000100,
|
||||
|
||||
/**
|
||||
* @brief User is verified (verified email address).
|
||||
*/
|
||||
u_verified = 0b00000000000000000000000000001000,
|
||||
|
||||
/**
|
||||
* @brief User has full nitro.
|
||||
*/
|
||||
u_nitro_full = 0b00000000000000000000000000010000,
|
||||
|
||||
/**
|
||||
* @brief User has nitro classic.
|
||||
*/
|
||||
u_nitro_classic = 0b00000000000000000000000000100000,
|
||||
|
||||
/**
|
||||
* @brief User is discord staff.
|
||||
*/
|
||||
u_discord_employee = 0b00000000000000000000000001000000,
|
||||
|
||||
/**
|
||||
* @brief User owns a partnered server.
|
||||
*/
|
||||
u_partnered_owner = 0b00000000000000000000000010000000,
|
||||
|
||||
/**
|
||||
* @brief User is a member of hypesquad events.
|
||||
*/
|
||||
u_hypesquad_events = 0b00000000000000000000000100000000,
|
||||
|
||||
/**
|
||||
* @brief User has BugHunter level 1.
|
||||
*/
|
||||
u_bughunter_1 = 0b00000000000000000000001000000000,
|
||||
|
||||
/**
|
||||
* @brief User is a member of House Bravery.
|
||||
*/
|
||||
u_house_bravery = 0b00000000000000000000010000000000,
|
||||
|
||||
/**
|
||||
* @brief User is a member of House Brilliance.
|
||||
*/
|
||||
u_house_brilliance = 0b00000000000000000000100000000000,
|
||||
|
||||
/**
|
||||
* @brief User is a member of House Balance.
|
||||
*/
|
||||
u_house_balance = 0b00000000000000000001000000000000,
|
||||
|
||||
/**
|
||||
* @brief User is an early supporter.
|
||||
*/
|
||||
u_early_supporter = 0b00000000000000000010000000000000,
|
||||
|
||||
/**
|
||||
* @brief User is a team user.
|
||||
*/
|
||||
u_team_user = 0b00000000000000000100000000000000,
|
||||
|
||||
/**
|
||||
* @brief User is has Bug Hunter level 2.
|
||||
*/
|
||||
u_bughunter_2 = 0b00000000000000001000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User is a verified bot.
|
||||
*/
|
||||
u_verified_bot = 0b00000000000000010000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User has the Early Verified Bot Developer badge.
|
||||
*/
|
||||
u_verified_bot_dev = 0b00000000000000100000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User's icon is animated.
|
||||
*/
|
||||
u_animated_icon = 0b00000000000001000000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User is a certified moderator.
|
||||
*/
|
||||
u_certified_moderator = 0b00000000000010000000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User is a bot using HTTP interactions.
|
||||
*
|
||||
* @note shows online even when not connected to a websocket.
|
||||
*/
|
||||
u_bot_http_interactions = 0b00000000000100000000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User has nitro basic.
|
||||
*/
|
||||
u_nitro_basic = 0b00000000001000000000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User has the active developer badge.
|
||||
*/
|
||||
u_active_developer = 0b00000000010000000000000000000000,
|
||||
|
||||
/**
|
||||
* @brief User's banner is animated.
|
||||
*/
|
||||
u_animated_banner = 0b00000000100000000000000000000000,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a user on discord. May or may not be a member of a dpp::guild.
|
||||
*/
|
||||
class DPP_EXPORT user : public managed, public json_interface<user> {
|
||||
protected:
|
||||
friend struct json_interface<user>;
|
||||
|
||||
/** Fill this record from json.
|
||||
* @param j The json to fill this record from
|
||||
* @return Reference to self
|
||||
*/
|
||||
user& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Convert to JSON
|
||||
*
|
||||
* @param with_id include ID in output
|
||||
* @return json JSON output
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = true) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Discord username.
|
||||
*/
|
||||
std::string username;
|
||||
|
||||
/**
|
||||
* @brief Global display name.
|
||||
*/
|
||||
std::string global_name;
|
||||
|
||||
/**
|
||||
* @brief Avatar hash.
|
||||
*/
|
||||
utility::iconhash avatar;
|
||||
|
||||
/**
|
||||
* @brief Avatar decoration hash.
|
||||
*/
|
||||
utility::iconhash avatar_decoration;
|
||||
|
||||
/**
|
||||
* @brief Flags built from a bitmask of values in dpp::user_flags.
|
||||
*/
|
||||
uint32_t flags;
|
||||
|
||||
/**
|
||||
* @brief Discriminator (aka tag), 4 digits usually displayed with leading zeroes.
|
||||
*
|
||||
* @note To print the discriminator with leading zeroes, use format_username().
|
||||
* 0 for users that have migrated to the new username format.
|
||||
*/
|
||||
uint16_t discriminator;
|
||||
|
||||
/**
|
||||
* @brief Reference count of how many guilds this user is in.
|
||||
*/
|
||||
uint8_t refcount;
|
||||
|
||||
/**
|
||||
* @brief Construct a new user object
|
||||
*/
|
||||
user();
|
||||
|
||||
/**
|
||||
* @brief Destroy the user object
|
||||
*/
|
||||
virtual ~user() = default;
|
||||
|
||||
/**
|
||||
* @brief Create a mentionable user.
|
||||
* @param id The ID of the user.
|
||||
* @return std::string The formatted mention of the user.
|
||||
*/
|
||||
static std::string get_mention(const snowflake& id);
|
||||
|
||||
/**
|
||||
* @brief Get the avatar url of the user
|
||||
*
|
||||
* @note If the user doesn't have an avatar, the default user avatar url is returned which is always in `png` format!
|
||||
*
|
||||
* @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 Get the default avatar url of the user. This is calculated by the discriminator.
|
||||
*
|
||||
* @return std::string avatar url or an empty string, if the discriminator is empty
|
||||
*/
|
||||
std::string get_default_avatar_url() const;
|
||||
|
||||
/**
|
||||
* @brief Get the avatar decoration url of the user if they have one, otherwise returns an empty string.
|
||||
*
|
||||
* @param size The size of the avatar decoration in pixels. It can be any power of two between 16 and 4096,
|
||||
* otherwise the default sized avatar decoration is returned.
|
||||
* @return std::string avatar url or an empty string
|
||||
*/
|
||||
std::string get_avatar_decoration_url(uint16_t size = 0) const;
|
||||
|
||||
/**
|
||||
* @brief Return a ping/mention for the user
|
||||
*
|
||||
* @return std::string mention
|
||||
*/
|
||||
std::string get_mention() const;
|
||||
|
||||
/**
|
||||
* @brief Returns URL to user
|
||||
*
|
||||
* @return string of URL to user
|
||||
*/
|
||||
std::string get_url() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has the active Developer badge
|
||||
*
|
||||
* @return true if has active developer
|
||||
*/
|
||||
bool is_active_developer() const;
|
||||
|
||||
/**
|
||||
* @brief User is a bot
|
||||
*
|
||||
* @return True if the user is a bot
|
||||
*/
|
||||
bool is_bot() const;
|
||||
|
||||
/**
|
||||
* @brief User is a system user (Clyde)
|
||||
*
|
||||
* @return true if user is a system user
|
||||
*/
|
||||
bool is_system() const;
|
||||
|
||||
/**
|
||||
* @brief User has multi-factor authentication enabled
|
||||
*
|
||||
* @return true if multi-factor is enabled
|
||||
*/
|
||||
bool is_mfa_enabled() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has verified account
|
||||
*
|
||||
* @return true if verified
|
||||
*/
|
||||
bool is_verified() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has full nitro.
|
||||
* This is mutually exclusive with full nitro.
|
||||
*
|
||||
* @return true if user has full nitro
|
||||
*/
|
||||
bool has_nitro_full() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has nitro classic.
|
||||
* This is mutually exclusive with nitro classic.
|
||||
*
|
||||
* @return true if user has nitro classic
|
||||
*/
|
||||
bool has_nitro_classic() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has nitro basic.
|
||||
* This is mutually exclusive with nitro basic.
|
||||
*
|
||||
* @return true if user has nitro basic
|
||||
*/
|
||||
bool has_nitro_basic() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is a discord employee
|
||||
*
|
||||
* @return true if user is discord staff
|
||||
*/
|
||||
bool is_discord_employee() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user owns a partnered server
|
||||
*
|
||||
* @return true if user has partnered server
|
||||
*/
|
||||
bool is_partnered_owner() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has hypesquad events
|
||||
*
|
||||
* @return true if has hypesquad events
|
||||
*/
|
||||
bool has_hypesquad_events() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has the bughunter level 1 badge
|
||||
*
|
||||
* @return true if has bughunter level 1
|
||||
*/
|
||||
bool is_bughunter_1() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is in house bravery
|
||||
*
|
||||
* @return true if in house bravery
|
||||
*/
|
||||
bool is_house_bravery() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is in house brilliance
|
||||
*
|
||||
* @return true if in house brilliance
|
||||
*/
|
||||
bool is_house_brilliance() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is in house balance
|
||||
*
|
||||
* @return true if in house brilliance
|
||||
*/
|
||||
bool is_house_balance() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is an early supporter
|
||||
*
|
||||
* @return true if early supporter
|
||||
*/
|
||||
bool is_early_supporter() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is a team user
|
||||
*
|
||||
* @return true if a team user
|
||||
*/
|
||||
bool is_team_user() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has the bughunter level 2 badge
|
||||
*
|
||||
* @return true if has bughunter level 2
|
||||
*/
|
||||
bool is_bughunter_2() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has the verified bot badge
|
||||
*
|
||||
* @return true if verified bot
|
||||
*/
|
||||
bool is_verified_bot() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is an early verified bot developer
|
||||
*
|
||||
* @return true if verified bot developer
|
||||
*/
|
||||
bool is_verified_bot_dev() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is a certified moderator
|
||||
*
|
||||
* @return true if certified moderator
|
||||
*/
|
||||
bool is_certified_moderator() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is a bot which exclusively uses HTTP interactions.
|
||||
* Bots using HTTP interactions are always considered online even when not connected to a websocket.
|
||||
*
|
||||
* @return true if is a http interactions only bot
|
||||
*/
|
||||
bool is_bot_http_interactions() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has an animated icon
|
||||
*
|
||||
* @return true if icon is animated (gif)
|
||||
*/
|
||||
bool has_animated_icon() const;
|
||||
|
||||
/**
|
||||
* @brief Format a username into user\#discriminator
|
||||
*
|
||||
* For example Brain#0001
|
||||
*
|
||||
* @note This will, most often, return something like Brain#0000 due to discriminators slowly being removed.
|
||||
* Some accounts, along with most bots, still have discriminators, so they will still show as Bot#1234.
|
||||
*
|
||||
* @return Formatted username and discriminator
|
||||
*/
|
||||
std::string format_username() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A user with additional fields only available via the oauth2 identify scope.
|
||||
* These are not included in dpp::user as additional scopes are needed to fetch them
|
||||
* which bots do not normally have.
|
||||
*/
|
||||
class DPP_EXPORT user_identified : public user, public json_interface<user_identified> {
|
||||
protected:
|
||||
friend struct json_interface<user_identified>;
|
||||
|
||||
/** Fill this record from json.
|
||||
* @param j The json to fill this record from
|
||||
* @return Reference to self
|
||||
*/
|
||||
user_identified& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Convert to JSON
|
||||
*
|
||||
* @param with_id include ID in output
|
||||
* @return json JSON output
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = true) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Optional: The user's chosen language option identify.
|
||||
*/
|
||||
std::string locale;
|
||||
|
||||
/**
|
||||
* @brief Optional: The user's email.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
std::string email;
|
||||
|
||||
/**
|
||||
* @brief Optional: The user's banner hash identify.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
utility::iconhash banner;
|
||||
|
||||
/**
|
||||
* @brief Optional: The user's banner color encoded as an integer representation of hexadecimal color code identify.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
uint32_t accent_color;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Optional: Whether the email on this account has been verified email.
|
||||
*/
|
||||
bool verified;
|
||||
|
||||
/**
|
||||
* @brief Construct a new user identified object
|
||||
*/
|
||||
user_identified();
|
||||
|
||||
/**
|
||||
* @brief Construct a new user identified object from a user object
|
||||
*
|
||||
* @param u user object
|
||||
*/
|
||||
user_identified(const user& u);
|
||||
|
||||
/**
|
||||
* @brief Destroy the user identified object
|
||||
*/
|
||||
virtual ~user_identified() = default;
|
||||
|
||||
using json_interface<user_identified>::fill_from_json;
|
||||
using json_interface<user_identified>::build_json;
|
||||
using json_interface<user_identified>::to_json;
|
||||
|
||||
/**
|
||||
* @brief Return true if user has an animated banner
|
||||
*
|
||||
* @return true if banner is animated (gif)
|
||||
*/
|
||||
bool has_animated_banner() const;
|
||||
|
||||
/**
|
||||
* @brief Get the user identified's banner url if they 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`.
|
||||
* 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 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 helper function to deserialize a user from json
|
||||
*
|
||||
* @see https://github.com/nlohmann/json#arbitrary-types-conversions
|
||||
*
|
||||
* @param j output json object
|
||||
* @param u user to be deserialized
|
||||
*/
|
||||
void from_json(const nlohmann::json& j, user& u);
|
||||
|
||||
/**
|
||||
* @brief helper function to deserialize a user_identified from json
|
||||
*
|
||||
* @see https://github.com/nlohmann/json#arbitrary-types-conversions
|
||||
*
|
||||
* @param j output json object
|
||||
* @param u user to be deserialized
|
||||
*/
|
||||
void from_json(const nlohmann::json& j, user_identified& u);
|
||||
|
||||
/**
|
||||
* @brief A group of users.
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, user> user_map;
|
||||
|
||||
} // namespace dpp
|
||||
1054
DPP-master/include/dpp/utility.h
Normal file
1054
DPP-master/include/dpp/utility.h
Normal file
File diff suppressed because it is too large
Load Diff
32
DPP-master/include/dpp/version.h
Normal file
32
DPP-master/include/dpp/version.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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
|
||||
|
||||
#if !defined(DPP_VERSION_LONG)
|
||||
#define DPP_VERSION_LONG 0x00100029
|
||||
#define DPP_VERSION_SHORT 100029
|
||||
#define DPP_VERSION_TEXT "D++ 10.0.29 (05-Nov-2023)"
|
||||
|
||||
#define DPP_VERSION_MAJOR ((DPP_VERSION_LONG & 0x00ff0000) >> 16)
|
||||
#define DPP_VERSION_MINOR ((DPP_VERSION_LONG & 0x0000ff00) >> 8)
|
||||
#define DPP_VERSION_PATCH (DPP_VERSION_LONG & 0x000000ff)
|
||||
#endif
|
||||
126
DPP-master/include/dpp/voiceregion.h
Normal file
126
DPP-master/include/dpp/voiceregion.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Flags related to a voice region
|
||||
*/
|
||||
enum voiceregion_flags {
|
||||
/**
|
||||
* @brief The closest (optimal) voice region.
|
||||
*/
|
||||
v_optimal = 0x00000001,
|
||||
|
||||
/**
|
||||
* @brief A Deprecated voice region (avoid switching to these).
|
||||
*/
|
||||
v_deprecated = 0x00000010,
|
||||
|
||||
/**
|
||||
* @brief A custom voice region (used for events/etc).
|
||||
*/
|
||||
v_custom = 0x00000100
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a voice region on discord
|
||||
*/
|
||||
class DPP_EXPORT voiceregion : public json_interface<voiceregion> {
|
||||
protected:
|
||||
friend struct json_interface<voiceregion>;
|
||||
|
||||
/**
|
||||
* @brief Fill object properties from JSON
|
||||
*
|
||||
* @param j JSON to fill from
|
||||
* @return voiceregion& Reference to self
|
||||
*/
|
||||
voiceregion& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Build a json for this object
|
||||
*
|
||||
* @param with_id Add ID to output
|
||||
* @return json JSON string
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Voice server ID
|
||||
*/
|
||||
std::string id;
|
||||
|
||||
/**
|
||||
* @brief Voice server name
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* @brief Flags bitmap
|
||||
*/
|
||||
uint8_t flags;
|
||||
|
||||
/**
|
||||
* @brief Construct a new voiceregion object
|
||||
*/
|
||||
voiceregion();
|
||||
|
||||
/**
|
||||
* @brief Destroy the voiceregion object
|
||||
*/
|
||||
virtual ~voiceregion() = default;
|
||||
|
||||
/**
|
||||
* @brief True if is the optimal voice server
|
||||
*
|
||||
* @return true if optimal
|
||||
*/
|
||||
bool is_optimal() const;
|
||||
|
||||
/**
|
||||
* @brief True if is a deprecated voice server
|
||||
*
|
||||
* @return true if deprecated
|
||||
*/
|
||||
bool is_deprecated() const;
|
||||
|
||||
/**
|
||||
* @brief True if is a custom voice server
|
||||
*
|
||||
* @return true if custom
|
||||
*/
|
||||
bool is_custom() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A group of voice regions
|
||||
*/
|
||||
typedef std::unordered_map<std::string, voiceregion> voiceregion_map;
|
||||
|
||||
} // namespace dpp
|
||||
179
DPP-master/include/dpp/voicestate.h
Normal file
179
DPP-master/include/dpp/voicestate.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Bit mask flags relating to voice states
|
||||
*/
|
||||
enum voicestate_flags {
|
||||
/**
|
||||
* @brief Deafened by the server.
|
||||
*/
|
||||
vs_deaf = 0b00000001,
|
||||
|
||||
/**
|
||||
* @brief Muted by the server.
|
||||
*/
|
||||
vs_mute = 0b00000010,
|
||||
|
||||
/**
|
||||
* @brief Locally Muted.
|
||||
*/
|
||||
vs_self_mute = 0b00000100,
|
||||
|
||||
/**
|
||||
* @brief Locally deafened.
|
||||
*/
|
||||
vs_self_deaf = 0b00001000,
|
||||
|
||||
/**
|
||||
* @brief Whether this user is streaming using "Go Live".
|
||||
*/
|
||||
vs_self_stream = 0b00010000,
|
||||
|
||||
/**
|
||||
* @brief Whether this user's camera is enabled.
|
||||
*/
|
||||
vs_self_video = 0b00100000,
|
||||
|
||||
/**
|
||||
* @brief Whether this user's permission to speak is denied.
|
||||
*/
|
||||
vs_suppress = 0b01000000
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the voice state of a user on a guild
|
||||
* These are stored in the dpp::guild object, and accessible there,
|
||||
* or via dpp::channel::get_voice_members
|
||||
*/
|
||||
class DPP_EXPORT voicestate : public json_interface<voicestate> {
|
||||
protected:
|
||||
friend struct json_interface<voicestate>;
|
||||
|
||||
/**
|
||||
* @brief Fill voicestate object from json data
|
||||
*
|
||||
* @param j JSON data to fill from
|
||||
* @return voicestate& Reference to self
|
||||
*/
|
||||
voicestate& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Owning shard.
|
||||
*/
|
||||
class discord_client* shard;
|
||||
|
||||
/**
|
||||
* @brief Optional: The guild id this voice state is for.
|
||||
*/
|
||||
snowflake guild_id{0};
|
||||
|
||||
/**
|
||||
* @brief The channel id this user is connected to.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
snowflake channel_id{0};
|
||||
|
||||
/**
|
||||
* @brief The user id this voice state is for.
|
||||
*/
|
||||
snowflake user_id{0};
|
||||
|
||||
/**
|
||||
* @brief The session id for this voice state.
|
||||
*/
|
||||
std::string session_id;
|
||||
|
||||
/**
|
||||
* @brief Voice state flags from dpp::voicestate_flags.
|
||||
*/
|
||||
uint8_t flags{0};
|
||||
|
||||
/**
|
||||
* @brief The time at which the user requested to speak.
|
||||
*
|
||||
* @note If the user never requested to speak, this is 0.
|
||||
*/
|
||||
time_t request_to_speak{0};
|
||||
|
||||
/**
|
||||
* @brief Construct a new voicestate object
|
||||
*/
|
||||
voicestate();
|
||||
|
||||
/**
|
||||
* @brief Destroy the voicestate object
|
||||
*/
|
||||
virtual ~voicestate() = default;
|
||||
|
||||
/**
|
||||
* @brief Return true if the user is deafened by the server.
|
||||
*/
|
||||
bool is_deaf() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if the user is muted by the server.
|
||||
*/
|
||||
bool is_mute() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user muted themselves.
|
||||
*/
|
||||
bool is_self_mute() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user deafened themselves.
|
||||
*/
|
||||
bool is_self_deaf() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if the user is streaming using "Go Live".
|
||||
*/
|
||||
bool self_stream() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if the user's camera is enabled.
|
||||
*/
|
||||
bool self_video() const;
|
||||
|
||||
/**
|
||||
* @brief Return true if user is suppressed.
|
||||
*
|
||||
* "HELP HELP I'M BEING SUPPRESSED!"
|
||||
*/
|
||||
bool is_suppressed() const;
|
||||
};
|
||||
|
||||
/** A container of voicestates */
|
||||
typedef std::unordered_map<std::string, voicestate> voicestate_map;
|
||||
|
||||
} // namespace dpp
|
||||
199
DPP-master/include/dpp/webhook.h
Normal file
199
DPP-master/include/dpp/webhook.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/misc-enum.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/json_fwd.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <unordered_map>
|
||||
#include <dpp/json_interface.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Defines types of webhook
|
||||
*/
|
||||
enum webhook_type {
|
||||
/**
|
||||
* @brief Incoming webhook.
|
||||
*/
|
||||
w_incoming = 1,
|
||||
|
||||
/**
|
||||
* @brief Channel following webhook.
|
||||
*/
|
||||
w_channel_follower = 2,
|
||||
|
||||
/**
|
||||
* @brief Application webhooks for interactions.
|
||||
*/
|
||||
w_application = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a discord webhook
|
||||
*/
|
||||
class DPP_EXPORT webhook : public managed, public json_interface<webhook> {
|
||||
protected:
|
||||
friend struct json_interface<webhook>;
|
||||
|
||||
/**
|
||||
* @brief Fill in object from json data
|
||||
*
|
||||
* @param j JSON data
|
||||
* @return webhook& Reference to self
|
||||
*/
|
||||
webhook& fill_from_json_impl(nlohmann::json* j);
|
||||
|
||||
/**
|
||||
* @brief Build JSON string from object
|
||||
*
|
||||
* @param with_id Include the ID of the webhook in the json
|
||||
* @return std::string JSON encoded object
|
||||
*/
|
||||
virtual json to_json_impl(bool with_id = false) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Type of the webhook from dpp::webhook_type.
|
||||
*/
|
||||
uint8_t type;
|
||||
|
||||
/**
|
||||
* @brief The guild id this webhook is for.
|
||||
*
|
||||
* @note This field is optional, and may also be empty.
|
||||
*/
|
||||
snowflake guild_id;
|
||||
|
||||
/**
|
||||
* @brief The channel id this webhook is for.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
snowflake channel_id;
|
||||
|
||||
/**
|
||||
* @brief The user this webhook was created by.
|
||||
*
|
||||
* @note This field is optional.
|
||||
* @warning This is not returned when getting a webhook with its token!
|
||||
*/
|
||||
user user_obj;
|
||||
|
||||
/**
|
||||
* @brief The default name of the webhook.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* @brief The default avatar of the webhook.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
utility::iconhash avatar;
|
||||
|
||||
/**
|
||||
* @brief The secure token of the webhook (returned for Incoming Webhooks).
|
||||
*
|
||||
* @note This field is optional.
|
||||
*/
|
||||
std::string token;
|
||||
|
||||
/**
|
||||
* @brief The bot/OAuth2 application that created this webhook.
|
||||
*
|
||||
* @note This may be empty.
|
||||
*/
|
||||
snowflake application_id;
|
||||
|
||||
/**
|
||||
* @brief The guild of the channel that this webhook is following (only for Channel Follower Webhooks).
|
||||
*
|
||||
* @warning This will be absent if the webhook creator has since lost access to the guild where the followed channel resides!
|
||||
*/
|
||||
guild source_guild;
|
||||
|
||||
/**
|
||||
* @brief The channel that this webhook is following (only for Channel Follower Webhooks).
|
||||
*
|
||||
* @warning This will be absent if the webhook creator has since lost access to the guild where the followed channel resides!
|
||||
*/
|
||||
channel source_channel;
|
||||
|
||||
/**
|
||||
* @brief The url used for executing the webhook (returned by the webhooks OAuth2 flow).
|
||||
*/
|
||||
std::string url;
|
||||
|
||||
/**
|
||||
* @brief base64 encoded image data if uploading a new image.
|
||||
*
|
||||
* @warning You should only ever read data from here. If you want to set the data, use dpp::webhook::load_image.
|
||||
*/
|
||||
std::string image_data;
|
||||
|
||||
/**
|
||||
* @brief Construct a new webhook object
|
||||
*/
|
||||
webhook();
|
||||
|
||||
/**
|
||||
* @brief Construct a new webhook object using the Webhook URL provided by Discord
|
||||
*
|
||||
* @param webhook_url a fully qualified web address of an existing webhook
|
||||
* @throw logic_exception if the webhook url could not be parsed
|
||||
*/
|
||||
webhook(const std::string& webhook_url);
|
||||
|
||||
/**
|
||||
* @brief Construct a new webhook object using the webhook ID and the webhook token
|
||||
*
|
||||
* @param webhook_id id taken from a link of an existing webhook
|
||||
* @param webhook_token token taken from a link of an existing webhook
|
||||
*/
|
||||
webhook(const snowflake webhook_id, const std::string& webhook_token);
|
||||
|
||||
/**
|
||||
* @brief Base64 encode image data and allocate it to image_data
|
||||
*
|
||||
* @param image_blob Binary image data
|
||||
* @param type Image type. It can be one of `i_gif`, `i_jpg` or `i_png`.
|
||||
* @param is_base64_encoded True if the image data is already base64 encoded
|
||||
* @return webhook& Reference to self
|
||||
* @throw dpp::length_exception Image data is larger than the maximum size of 256 kilobytes
|
||||
*/
|
||||
webhook& load_image(const std::string &image_blob, const image_type type, bool is_base64_encoded = false);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A group of webhooks
|
||||
*/
|
||||
typedef std::unordered_map<snowflake, webhook> webhook_map;
|
||||
|
||||
} // namespace dpp
|
||||
33
DPP-master/include/dpp/win32_safe_warnings.h
Normal file
33
DPP-master/include/dpp/win32_safe_warnings.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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
|
||||
|
||||
/* This file contains pragmas to disable warnings on win32 builds with msvc only.
|
||||
* It is only included during build of D++ itself, and not when including the headers
|
||||
* into a user's project.
|
||||
*
|
||||
* Before adding a warning here please be ABSOLUTELY SURE it is one we cannot easily fix
|
||||
* and is to be silenced, thrown into the sarlacc pit to be eaten for 1000 years...
|
||||
*/
|
||||
|
||||
_Pragma("warning( disable : 4251 )"); // 4251 warns when we export classes or structures with stl member variables
|
||||
_Pragma("warning( disable : 5105 )"); // 5105 is to do with macro warnings
|
||||
235
DPP-master/include/dpp/wsclient.h
Normal file
235
DPP-master/include/dpp/wsclient.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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 <dpp/export.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <dpp/sslclient.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Websocket protocol types available on Discord
|
||||
*/
|
||||
enum websocket_protocol_t : uint8_t {
|
||||
/**
|
||||
* @brief JSON data, text, UTF-8 character set
|
||||
*/
|
||||
ws_json = 0,
|
||||
|
||||
/**
|
||||
* @brief Erlang Term Format (ETF) binary protocol
|
||||
*/
|
||||
ws_etf = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Websocket connection status
|
||||
*/
|
||||
enum ws_state : uint8_t {
|
||||
/**
|
||||
* @brief Sending/receiving HTTP headers, acting as a standard HTTP connection.
|
||||
* This is the state prior to receiving "HTTP/1.1 101 Switching Protocols" from the
|
||||
* server side.
|
||||
*/
|
||||
HTTP_HEADERS,
|
||||
|
||||
/**
|
||||
* @brief Connected as a websocket, and "upgraded". Now talking using binary frames.
|
||||
*/
|
||||
CONNECTED
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Low-level websocket opcodes for frames
|
||||
*/
|
||||
enum ws_opcode : uint8_t {
|
||||
/**
|
||||
* @brief Continuation.
|
||||
*/
|
||||
OP_CONTINUATION = 0x00,
|
||||
|
||||
/**
|
||||
* @brief Text frame.
|
||||
*/
|
||||
OP_TEXT = 0x01,
|
||||
|
||||
/**
|
||||
* @brief Binary frame.
|
||||
*/
|
||||
OP_BINARY = 0x02,
|
||||
|
||||
/**
|
||||
* @brief Close notification with close code.
|
||||
*/
|
||||
OP_CLOSE = 0x08,
|
||||
|
||||
/**
|
||||
* @brief Low level ping.
|
||||
*/
|
||||
OP_PING = 0x09,
|
||||
|
||||
/**
|
||||
* @brief Low level pong.
|
||||
*/
|
||||
OP_PONG = 0x0a
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements a websocket client based on the SSL client
|
||||
*/
|
||||
class DPP_EXPORT websocket_client : public ssl_client {
|
||||
/**
|
||||
* @brief Connection key used in the HTTP headers
|
||||
*/
|
||||
std::string key;
|
||||
|
||||
/**
|
||||
* @brief Current websocket state
|
||||
*/
|
||||
ws_state state;
|
||||
|
||||
/**
|
||||
* @brief Path part of URL for websocket
|
||||
*/
|
||||
std::string path;
|
||||
|
||||
/**
|
||||
* @brief Data opcode, represents the type of frames we send
|
||||
*/
|
||||
ws_opcode data_opcode;
|
||||
|
||||
/**
|
||||
* @brief HTTP headers received on connecting/upgrading
|
||||
*/
|
||||
std::map<std::string, std::string> http_headers;
|
||||
|
||||
/**
|
||||
* @brief Parse headers for a websocket frame from the buffer.
|
||||
* @param buffer The buffer to operate on. Will modify the string removing completed items from the head of the queue
|
||||
* @return true if a complete header has been received
|
||||
*/
|
||||
bool parseheader(std::string &buffer);
|
||||
|
||||
/**
|
||||
* @brief Unpack a frame and pass completed frames up the stack.
|
||||
* @param buffer The buffer to operate on. Gets modified to remove completed frames on the head of the buffer
|
||||
* @param offset The offset to start at (reserved for future use)
|
||||
* @param first True if is the first element (reserved for future use)
|
||||
* @return true if a complete frame has been received
|
||||
*/
|
||||
bool unpack(std::string &buffer, uint32_t offset, bool first = true);
|
||||
|
||||
/**
|
||||
* @brief Fill a header for outbound messages
|
||||
* @param outbuf The raw frame to fill
|
||||
* @param sendlength The size of the data to encapsulate
|
||||
* @param opcode the ws_opcode to send in the header
|
||||
* @return size of filled header
|
||||
*/
|
||||
size_t fill_header(unsigned char* outbuf, size_t sendlength, ws_opcode opcode);
|
||||
|
||||
/**
|
||||
* @brief Handle ping and pong requests.
|
||||
* @param ping True if this is a ping, false if it is a pong
|
||||
* @param payload The ping payload, to be returned as-is for a ping
|
||||
*/
|
||||
void handle_ping_pong(bool ping, const std::string &payload);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief (Re)connect
|
||||
*/
|
||||
virtual void connect();
|
||||
|
||||
/**
|
||||
* @brief Get websocket state
|
||||
* @return websocket state
|
||||
*/
|
||||
ws_state get_state();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Connect to a specific websocket server.
|
||||
* @param hostname Hostname to connect to
|
||||
* @param port Port to connect to
|
||||
* @param urlpath The URL path components of the HTTP request to send
|
||||
* @param opcode The encoding type to use, either OP_BINARY or OP_TEXT
|
||||
* @note Voice websockets only support OP_TEXT, and other websockets must be
|
||||
* OP_BINARY if you are going to send ETF.
|
||||
*/
|
||||
websocket_client(const std::string &hostname, const std::string &port = "443", const std::string &urlpath = "", ws_opcode opcode = OP_BINARY);
|
||||
|
||||
/**
|
||||
* @brief Destroy the websocket client object
|
||||
*/
|
||||
virtual ~websocket_client() = default;
|
||||
|
||||
/**
|
||||
* @brief Write to websocket. Encapsulates data in frames if the status is CONNECTED.
|
||||
* @param data The data to send.
|
||||
*/
|
||||
virtual void write(const std::string &data);
|
||||
|
||||
/**
|
||||
* @brief Processes incoming frames 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);
|
||||
|
||||
/**
|
||||
* @brief Close websocket
|
||||
*/
|
||||
virtual void close();
|
||||
|
||||
/**
|
||||
* @brief Receives raw frame content only without headers
|
||||
*
|
||||
* @param buffer The buffer contents
|
||||
* @return True if the frame was successfully handled. False if no valid frame is in the buffer.
|
||||
*/
|
||||
virtual bool handle_frame(const std::string &buffer);
|
||||
|
||||
/**
|
||||
* @brief Called upon error frame.
|
||||
*
|
||||
* @param errorcode The error code from the websocket server
|
||||
*/
|
||||
virtual void error(uint32_t errorcode);
|
||||
|
||||
/**
|
||||
* @brief Fires every second from the underlying socket I/O loop, used for sending websocket pings
|
||||
*/
|
||||
virtual void one_second_timer();
|
||||
|
||||
/**
|
||||
* @brief Send OP_CLOSE error code 1000 to the other side of the connection.
|
||||
* This indicates graceful close.
|
||||
*/
|
||||
void send_close_packet();
|
||||
};
|
||||
|
||||
} // namespace dpp
|
||||
Reference in New Issue
Block a user