mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-11-26 11:07:17 +01:00
Add D++ library.
This commit is contained in:
133
vendor/DPP/src/dpp/application.cpp
vendored
Normal file
133
vendor/DPP/src/dpp/application.cpp
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/application.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/managed.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
application::application() : managed(0), bot_public(false), bot_require_code_grant(false), guild_id(0), primary_sku_id(0), flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
application::~application() = default;
|
||||
|
||||
application& application::fill_from_json(nlohmann::json* j) {
|
||||
set_snowflake_not_null(j, "id", id);
|
||||
set_string_not_null(j, "name", name);
|
||||
std::string ic = string_not_null(j, "icon");
|
||||
if (!ic.empty()) {
|
||||
icon = ic;
|
||||
}
|
||||
set_string_not_null(j, "description", description);
|
||||
set_string_not_null(j, "rpc_origins", rpc_origins);
|
||||
set_bool_not_null(j, "bot_public", bot_public);
|
||||
set_bool_not_null(j, "bot_require_code_grant", bot_require_code_grant);
|
||||
set_string_not_null(j, "terms_of_service_url", terms_of_service_url);
|
||||
set_string_not_null(j, "privacy_policy_url", privacy_policy_url);
|
||||
owner = user().fill_from_json(&((*j)["owner"]));
|
||||
set_string_not_null(j, "summary", summary);
|
||||
set_string_not_null(j, "verify_key", verify_key);
|
||||
set_snowflake_not_null(j, "guild_id", guild_id);
|
||||
set_snowflake_not_null(j, "primary_sku_id", primary_sku_id);
|
||||
set_string_not_null(j, "slug", slug);
|
||||
std::string ci = string_not_null(j, "cover_image");
|
||||
if (!ci.empty()) {
|
||||
cover_image = ci;
|
||||
}
|
||||
set_int32_not_null(j, "flags", flags);
|
||||
if (j->contains("tags")) {
|
||||
for (const auto& tag : (*j)["tags"]) {
|
||||
this->tags.push_back(to_string(tag));
|
||||
}
|
||||
}
|
||||
if (j->contains("install_params")) {
|
||||
json& p = (*j)["install_params"];
|
||||
set_snowflake_not_null(&p, "permissions", this->install_params.permissions);
|
||||
for (const auto& scope : p["scopes"]) {
|
||||
this->install_params.scopes.push_back(to_string(scope));
|
||||
}
|
||||
}
|
||||
set_string_not_null(j, "custom_install_url", custom_install_url);
|
||||
if (j->contains("team")) {
|
||||
json& t = (*j)["team"];
|
||||
std::string i = string_not_null(&t, "icon");
|
||||
if (!i.empty()) {
|
||||
this->team.icon = i;
|
||||
}
|
||||
set_snowflake_not_null(&t, "id", this->team.id);
|
||||
set_string_not_null(&t, "name", this->team.name);
|
||||
set_snowflake_not_null(&t, "owner_user_id", this->team.owner_user_id);
|
||||
for (auto m : t["members"]) {
|
||||
team_member tm;
|
||||
tm.membership_state = (team_member_status)int32_not_null(&m, "membership_state");
|
||||
set_string_not_null(&m, "permissions", tm.permissions);
|
||||
set_snowflake_not_null(&m, "team_id", tm.team_id);
|
||||
tm.member_user = user().fill_from_json(&m["user"]);
|
||||
this->team.members.emplace_back(tm);
|
||||
}
|
||||
}
|
||||
set_string_not_null(j, "role_connections_verification_url", role_connections_verification_url);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string application::get_cover_image_url(uint16_t size, const image_type format) const {
|
||||
static const std::map<image_type, std::string> extensions = {
|
||||
{ i_jpg, "jpg" },
|
||||
{ i_png, "png" },
|
||||
{ i_webp, "webp" },
|
||||
};
|
||||
|
||||
if (extensions.find(format) == extensions.end()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (!this->cover_image.to_string().empty() && this->id) {
|
||||
return utility::cdn_host + "/app-icons/" + std::to_string(this->id) + "/" + this->cover_image.to_string() + "." + extensions.find(format)->second + utility::avatar_size(size);
|
||||
} else {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string application::get_icon_url(uint16_t size, const image_type format) const {
|
||||
static const std::map<image_type, std::string> extensions = {
|
||||
{ i_jpg, "jpg" },
|
||||
{ i_png, "png" },
|
||||
{ i_webp, "webp" },
|
||||
};
|
||||
|
||||
if (extensions.find(format) == extensions.end()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (!this->icon.to_string().empty() && this->id) {
|
||||
return utility::cdn_host + "/app-icons/" + std::to_string(this->id) + "/" + this->icon.to_string() + "." + extensions.find(format)->second + utility::avatar_size(size);
|
||||
} else {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
73
vendor/DPP/src/dpp/auditlog.cpp
vendored
Normal file
73
vendor/DPP/src/dpp/auditlog.cpp
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/auditlog.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
auditlog& auditlog::fill_from_json(nlohmann::json* j) {
|
||||
for (auto &ai : (*j)["audit_log_entries"]) {
|
||||
audit_entry ae;
|
||||
ae.id = snowflake_not_null(&ai, "id");
|
||||
ae.type = (audit_type)int8_not_null(&ai, "action_type");
|
||||
ae.user_id = snowflake_not_null(&ai, "user_id");
|
||||
ae.target_id = snowflake_not_null(&ai, "target_id");
|
||||
ae.reason = string_not_null(&ai, "reason");
|
||||
if (ai.contains("changes")) {
|
||||
auto &c = ai["changes"];
|
||||
for (auto & change : c) {
|
||||
audit_change ac;
|
||||
ac.key = string_not_null(&change, "key");
|
||||
if (change.find("new_value") != change.end()) {
|
||||
ac.new_value = change["new_value"].dump();
|
||||
}
|
||||
if (change.find("old_value") != change.end()) {
|
||||
ac.old_value = change["old_value"].dump();
|
||||
}
|
||||
ae.changes.push_back(ac);
|
||||
}
|
||||
}
|
||||
if (ai.contains("options")) {
|
||||
auto &o = ai["options"];
|
||||
audit_extra opts;
|
||||
opts.automod_rule_name = string_not_null(&o, "auto_moderation_rule_name");
|
||||
opts.automod_rule_trigger_type = string_not_null(&o, "auto_moderation_rule_trigger_type");
|
||||
opts.channel_id = snowflake_not_null(&o, "channel_id");
|
||||
opts.count = string_not_null(&o, "count");
|
||||
opts.delete_member_days = string_not_null(&o, "delete_member_days");
|
||||
opts.id = snowflake_not_null(&o, "id");
|
||||
opts.members_removed = string_not_null(&o, "members_removed");
|
||||
opts.message_id = snowflake_not_null(&o, "message_id");
|
||||
opts.role_name = string_not_null(&o, "role_name");
|
||||
opts.type = string_not_null(&o, "type");
|
||||
opts.application_id = snowflake_not_null(&o, "application_id");
|
||||
ae.extra = opts;
|
||||
}
|
||||
this->entries.emplace_back(ae);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
195
vendor/DPP/src/dpp/automod.cpp
vendored
Normal file
195
vendor/DPP/src/dpp/automod.cpp
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/automod.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
automod_action::automod_action() : channel_id(0), duration_seconds(0)
|
||||
{
|
||||
}
|
||||
|
||||
automod_action::~automod_action() = default;
|
||||
|
||||
automod_action& automod_action::fill_from_json(nlohmann::json* j) {
|
||||
type = (automod_action_type)int8_not_null(j, "type");
|
||||
switch (type) {
|
||||
case amod_action_block_message:
|
||||
custom_message = string_not_null(&((*j)["metadata"]), "custom_message");
|
||||
break;
|
||||
case amod_action_send_alert:
|
||||
channel_id = snowflake_not_null(&((*j)["metadata"]), "channel_id");
|
||||
break;
|
||||
case amod_action_timeout:
|
||||
duration_seconds = int32_not_null(&((*j)["metadata"]), "duration_seconds");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string automod_action::build_json(bool with_id) const {
|
||||
json j({
|
||||
{ "type", type }
|
||||
});
|
||||
switch (type) {
|
||||
case amod_action_block_message:
|
||||
if (!custom_message.empty()) {
|
||||
j["metadata"] = json::object();
|
||||
j["metadata"]["custom_message"] = custom_message;
|
||||
}
|
||||
break;
|
||||
case amod_action_send_alert:
|
||||
if (channel_id) {
|
||||
j["metadata"] = json::object();
|
||||
j["metadata"]["channel_id"] = std::to_string(channel_id);
|
||||
}
|
||||
break;
|
||||
case amod_action_timeout:
|
||||
if (duration_seconds) {
|
||||
j["metadata"] = json::object();
|
||||
j["metadata"]["duration_seconds"] = duration_seconds;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
automod_metadata::automod_metadata() : mention_total_limit(0) {}
|
||||
|
||||
automod_metadata::~automod_metadata() = default;
|
||||
|
||||
automod_metadata& automod_metadata::fill_from_json(nlohmann::json* j) {
|
||||
for (auto k : (*j)["keyword_filter"]) {
|
||||
keywords.push_back(k);
|
||||
}
|
||||
for (auto k : (*j)["regex_patterns"]) {
|
||||
regex_patterns.push_back(k);
|
||||
}
|
||||
for (auto k : (*j)["presets"]) {
|
||||
presets.push_back((automod_preset_type)k.get<uint32_t>());
|
||||
}
|
||||
for (auto k : (*j)["allow_list"]) {
|
||||
allow_list.push_back(k);
|
||||
}
|
||||
mention_total_limit = int8_not_null(j, "mention_total_limit");
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string automod_metadata::build_json(bool with_id) const {
|
||||
json j;
|
||||
j["keyword_filter"] = json::array();
|
||||
j["regex_patterns"] = json::array();
|
||||
j["presets"] = json::array();
|
||||
j["allow_list"] = json::array();
|
||||
for (auto &v : keywords) {
|
||||
j["keyword_filter"].push_back(v);
|
||||
}
|
||||
for (auto &v : regex_patterns) {
|
||||
j["regex_patterns"].push_back(v);
|
||||
}
|
||||
for (auto v : presets) {
|
||||
j["presets"].push_back((uint32_t)v);
|
||||
}
|
||||
for (auto &v : allow_list) {
|
||||
j["allow_list"].push_back(v);
|
||||
}
|
||||
j["mention_total_limit"] = mention_total_limit;
|
||||
return j.dump();
|
||||
|
||||
}
|
||||
|
||||
automod_rule::automod_rule() : managed(), guild_id(0), creator_id(0), event_type(amod_message_send), trigger_type(amod_type_keyword), enabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
automod_rule::~automod_rule() = default;
|
||||
|
||||
automod_rule& automod_rule::fill_from_json(nlohmann::json* j) {
|
||||
id = snowflake_not_null(j, "id");
|
||||
guild_id = snowflake_not_null(j, "guild_id");
|
||||
name = string_not_null(j, "name");
|
||||
creator_id = snowflake_not_null(j, "creator_id");
|
||||
event_type = (automod_event_type)int8_not_null(j, "event_type");
|
||||
trigger_type = (automod_trigger_type)int8_not_null(j, "trigger_type");
|
||||
if (j->contains("trigger_metadata")) {
|
||||
trigger_metadata.fill_from_json(&((*j)["trigger_metadata"]));
|
||||
}
|
||||
enabled = bool_not_null(j, "enabled");
|
||||
exempt_roles.clear();
|
||||
exempt_channels.clear();
|
||||
for (auto k : (*j)["automod_actions"]) {
|
||||
actions.push_back(automod_action().fill_from_json(&k));
|
||||
}
|
||||
for (auto k : (*j)["exempt_roles"]) {
|
||||
exempt_roles.push_back(stoull(k.get<std::string>()));
|
||||
}
|
||||
for (auto k : (*j)["exempt_channels"]) {
|
||||
exempt_channels.push_back(stoull(k.get<std::string>()));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string automod_rule::build_json(bool with_id) const {
|
||||
json j;
|
||||
if (with_id && id) {
|
||||
j["id"] = std::to_string(id);
|
||||
}
|
||||
if (guild_id) {
|
||||
j["guild_id"] = std::to_string(guild_id);
|
||||
}
|
||||
j["name"] = name;
|
||||
j["enabled"] = enabled;
|
||||
j["event_type"] = event_type;
|
||||
j["trigger_type"] = trigger_type;
|
||||
j["trigger_metadata"] = json::parse(trigger_metadata.build_json());
|
||||
if (actions.size()) {
|
||||
j["actions"] = json::array();
|
||||
json& act = j["actions"];
|
||||
for (auto v : actions) {
|
||||
act.push_back(json::parse(v.build_json()));
|
||||
}
|
||||
}
|
||||
if (exempt_roles.size()) {
|
||||
j["exempt_roles"] = json::array();
|
||||
json& roles = j["exempt_roles"];
|
||||
for (auto v : exempt_roles) {
|
||||
roles.push_back(std::to_string(v));
|
||||
}
|
||||
}
|
||||
if (exempt_channels.size()) {
|
||||
j["exempt_channels"] = json::array();
|
||||
json& channels = j["exempt_channels"];
|
||||
for (auto v : exempt_channels) {
|
||||
channels.push_back(std::to_string(v));
|
||||
}
|
||||
}
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
48
vendor/DPP/src/dpp/ban.cpp
vendored
Normal file
48
vendor/DPP/src/dpp/ban.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/ban.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
ban::ban() : user_id(0)
|
||||
{
|
||||
}
|
||||
|
||||
ban& ban::fill_from_json(nlohmann::json* j) {
|
||||
reason = string_not_null(j, "reason");
|
||||
if (j->contains("user")) {
|
||||
json & user = (*j)["user"];
|
||||
user_id = snowflake_not_null(&user, "id");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string ban::build_json(bool with_id) const {
|
||||
/* This is an unused stub, because sending a ban is simple as a user id and a reason */
|
||||
return "{}";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
87
vendor/DPP/src/dpp/cache.cpp
vendored
Normal file
87
vendor/DPP/src/dpp/cache.cpp
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/export.h>
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <variant>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/exception.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
std::unordered_map<managed*, time_t> deletion_queue;
|
||||
std::mutex deletion_mutex;
|
||||
|
||||
#define cache_helper(type, cache_name, setter, getter, counter) \
|
||||
cache<type>* cache_name = nullptr; \
|
||||
type * setter (snowflake id) { \
|
||||
return cache_name ? ( type * ) cache_name ->find(id) : nullptr; \
|
||||
} \
|
||||
cache<type>* getter () { \
|
||||
if (! cache_name ) { \
|
||||
cache_name = new cache<type>(); \
|
||||
} \
|
||||
return cache_name ; \
|
||||
} \
|
||||
uint64_t counter () { \
|
||||
return ( cache_name ? cache_name ->count() : 0 ); \
|
||||
}
|
||||
|
||||
|
||||
/* Because other threads and systems may run for a short while after an event is received, we don't immediately
|
||||
* delete pointers when objects are replaced. We put them into a queue, and periodically delete pointers in the
|
||||
* queue. This also rehashes unordered_maps to ensure they free their memory.
|
||||
*/
|
||||
void garbage_collection() {
|
||||
time_t now = time(NULL);
|
||||
bool repeat = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> delete_lock(deletion_mutex);
|
||||
do {
|
||||
repeat = false;
|
||||
for (auto g = deletion_queue.begin(); g != deletion_queue.end(); ++g) {
|
||||
if (now > g->second + 60) {
|
||||
delete g->first;
|
||||
deletion_queue.erase(g);
|
||||
repeat = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (repeat);
|
||||
if (deletion_queue.size() == 0) {
|
||||
deletion_queue = {};
|
||||
}
|
||||
}
|
||||
dpp::get_user_cache()->rehash();
|
||||
dpp::get_channel_cache()->rehash();
|
||||
dpp::get_guild_cache()->rehash();
|
||||
dpp::get_role_cache()->rehash();
|
||||
dpp::get_emoji_cache()->rehash();
|
||||
}
|
||||
|
||||
|
||||
cache_helper(user, user_cache, find_user, get_user_cache, get_user_count);
|
||||
cache_helper(channel, channel_cache, find_channel, get_channel_cache, get_channel_count);
|
||||
cache_helper(role, role_cache, find_role, get_role_cache, get_role_count);
|
||||
cache_helper(guild, guild_cache, find_guild, get_guild_cache, get_guild_count);
|
||||
cache_helper(emoji, emoji_cache, find_emoji, get_emoji_cache, get_emoji_count);
|
||||
|
||||
};
|
||||
616
vendor/DPP/src/dpp/channel.cpp
vendored
Normal file
616
vendor/DPP/src/dpp/channel.cpp
vendored
Normal file
@@ -0,0 +1,616 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/role.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp {
|
||||
|
||||
permission_overwrite::permission_overwrite() : id(0), allow(0), deny(0), type(0) {}
|
||||
|
||||
permission_overwrite::permission_overwrite(snowflake id, uint64_t allow, uint64_t deny, overwrite_type type) : id(id), allow(allow), deny(deny), type(type) {}
|
||||
|
||||
forum_tag::forum_tag() : managed(), moderated(false) {}
|
||||
|
||||
forum_tag::forum_tag(const std::string& name) : forum_tag() {
|
||||
this->set_name(name);
|
||||
}
|
||||
|
||||
forum_tag::~forum_tag()
|
||||
{
|
||||
}
|
||||
|
||||
forum_tag& forum_tag::fill_from_json(nlohmann::json *j) {
|
||||
set_snowflake_not_null(j, "id", this->id);
|
||||
set_string_not_null(j, "name", this->name);
|
||||
set_bool_not_null(j, "moderated", this->moderated);
|
||||
auto emoji_id = snowflake_not_null(j, "emoji_id");
|
||||
auto emoji_name = string_not_null(j, "emoji_name");
|
||||
if (emoji_id) {
|
||||
this->emoji = emoji_id;
|
||||
} else if (!emoji_name.empty()) {
|
||||
this->emoji = emoji_name;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string forum_tag::build_json(bool with_id) const {
|
||||
json j;
|
||||
if (with_id && id) {
|
||||
j["id"] = std::to_string(id);
|
||||
}
|
||||
j["name"] = name;
|
||||
j["moderated"] = moderated;
|
||||
if (std::holds_alternative<snowflake>(emoji)) {
|
||||
j["emoji_id"] = std::get<snowflake>(emoji);
|
||||
} else if (std::holds_alternative<std::string>(emoji)) {
|
||||
j["emoji_name"] = std::get<std::string>(emoji);
|
||||
}
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
forum_tag &forum_tag::set_name(const std::string &name) {
|
||||
this->name = utility::utf8substr(name, 0, 20);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const uint16_t CHANNEL_TYPE_MASK = 0b0000000000001111;
|
||||
const uint16_t DEFAULT_FORUM_LAYOUT_MASK = 0b0000011000000000;
|
||||
|
||||
thread_member& thread_member::fill_from_json(nlohmann::json* j) {
|
||||
set_snowflake_not_null(j, "id", this->thread_id);
|
||||
set_snowflake_not_null(j, "user_id", this->user_id);
|
||||
set_ts_not_null(j, "join_timestamp", this->joined);
|
||||
set_int32_not_null(j, "flags", this->flags);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json& j, const thread_metadata& tmdata) {
|
||||
j["archived"] = tmdata.archived;
|
||||
j["auto_archive_duration"] = tmdata.auto_archive_duration;
|
||||
j["locked"] = tmdata.locked;
|
||||
j["invitable"] = tmdata.invitable;
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json& j, const permission_overwrite& po) {
|
||||
j["id"] = std::to_string(po.id);
|
||||
j["allow"] = std::to_string(po.allow);
|
||||
j["deny"] = std::to_string(po.deny);
|
||||
j["type"] = po.type;
|
||||
}
|
||||
|
||||
channel::channel() :
|
||||
managed(),
|
||||
owner_id(0),
|
||||
parent_id(0),
|
||||
guild_id(0),
|
||||
last_message_id(0),
|
||||
last_pin_timestamp(0),
|
||||
permissions(0),
|
||||
position(0),
|
||||
bitrate(0),
|
||||
rate_limit_per_user(0),
|
||||
default_thread_rate_limit_per_user(0),
|
||||
default_auto_archive_duration(arc_1_day),
|
||||
default_sort_order(so_latest_activity),
|
||||
flags(0),
|
||||
user_limit(0)
|
||||
{
|
||||
}
|
||||
|
||||
channel::~channel(){
|
||||
}
|
||||
|
||||
std::string channel::get_mention(const snowflake &id) {
|
||||
return utility::channel_mention(id);
|
||||
}
|
||||
|
||||
std::string channel::get_mention() const {
|
||||
return utility::channel_mention(id);
|
||||
}
|
||||
|
||||
channel& channel::set_name(const std::string& name) {
|
||||
this->name = utility::validate(name, 1, 100, "name must be at least 1 character");
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_topic(const std::string& topic) {
|
||||
this->topic = utility::utf8substr(topic, 0, 1024);
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_type(channel_type type) {
|
||||
this->flags &= ~CHANNEL_TYPE_MASK;
|
||||
this->flags |= type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_default_forum_layout(forum_layout_type layout_type) {
|
||||
this->flags &= ~DEFAULT_FORUM_LAYOUT_MASK;
|
||||
auto type = (uint16_t)layout_type;
|
||||
this->flags |= ((type << 9) & DEFAULT_FORUM_LAYOUT_MASK);
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel &channel::set_default_sort_order(default_forum_sort_order_t sort_order) {
|
||||
this->default_sort_order = sort_order;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_guild_id(const snowflake guild_id) {
|
||||
this->guild_id = guild_id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_parent_id(const snowflake parent_id) {
|
||||
this->parent_id = parent_id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_rate_limit_per_user(const uint16_t rate_limit_per_user) {
|
||||
this->rate_limit_per_user = rate_limit_per_user;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_position(const uint16_t position) {
|
||||
this->position = position;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_bitrate(const uint16_t bitrate) {
|
||||
this->bitrate = bitrate;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_flags(const uint16_t flags) {
|
||||
this->flags = flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::add_flag(const channel_flags flag) {
|
||||
this->flags |= flag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::remove_flag(const channel_flags flag) {
|
||||
this->flags &= ~flag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_nsfw(const bool is_nsfw) {
|
||||
this->flags = (is_nsfw) ? this->flags | dpp::c_nsfw : this->flags & ~dpp::c_nsfw;;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_lock_permissions(const bool is_lock_permissions) {
|
||||
this->flags = (is_lock_permissions) ? this->flags | dpp::c_lock_permissions : this->flags & ~dpp::c_lock_permissions;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::set_user_limit(const uint8_t user_limit) {
|
||||
this->user_limit = user_limit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
channel& channel::add_permission_overwrite(const snowflake id, const overwrite_type type, const uint64_t allowed_permissions, const uint64_t denied_permissions) {
|
||||
permission_overwrite po {id, allowed_permissions, denied_permissions, type};
|
||||
this->permission_overwrites.push_back(po);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool channel::is_nsfw() const {
|
||||
return flags & dpp::c_nsfw;
|
||||
}
|
||||
|
||||
bool channel::is_locked_permissions() const {
|
||||
return flags & dpp::c_lock_permissions;
|
||||
}
|
||||
|
||||
bool channel::is_text_channel() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_TEXT;
|
||||
}
|
||||
|
||||
bool channel::is_dm() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == DM;
|
||||
}
|
||||
|
||||
bool channel::is_voice_channel() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_VOICE;
|
||||
}
|
||||
|
||||
bool channel::is_group_dm() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == GROUP_DM;
|
||||
}
|
||||
|
||||
bool channel::is_category() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_CATEGORY;
|
||||
}
|
||||
|
||||
bool channel::is_forum() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_FORUM;
|
||||
}
|
||||
|
||||
bool channel::is_stage_channel() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_STAGE;
|
||||
}
|
||||
|
||||
bool channel::is_news_channel() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_ANNOUNCEMENT;
|
||||
}
|
||||
|
||||
bool channel::is_store_channel() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_STORE;
|
||||
}
|
||||
|
||||
bool channel::is_video_auto() const {
|
||||
/* Note: c_video_auto has no real flag (its value is 0)
|
||||
* as absence of the 720p FULL quality flag indicates it must be
|
||||
* c_video_auto instead -- discord decided to put what is basically
|
||||
* a bool into two potential values, 1 and 2. hmmm...
|
||||
*/
|
||||
return !is_video_720p();
|
||||
}
|
||||
|
||||
bool channel::is_video_720p() const {
|
||||
return flags & dpp::c_video_quality_720p;
|
||||
}
|
||||
|
||||
bool channel::is_pinned_thread() const {
|
||||
return flags & dpp::c_pinned_thread;
|
||||
}
|
||||
|
||||
bool channel::is_tag_required() const {
|
||||
return flags & dpp::c_require_tag;
|
||||
}
|
||||
|
||||
bool thread::is_news_thread() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_ANNOUNCEMENT_THREAD;
|
||||
}
|
||||
|
||||
bool thread::is_public_thread() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_PUBLIC_THREAD;
|
||||
}
|
||||
|
||||
bool thread::is_private_thread() const {
|
||||
return (flags & CHANNEL_TYPE_MASK) == CHANNEL_PRIVATE_THREAD;
|
||||
}
|
||||
|
||||
thread& thread::fill_from_json(json* j) {
|
||||
channel::fill_from_json(j);
|
||||
|
||||
uint8_t type = int8_not_null(j, "type");
|
||||
this->flags |= (type & CHANNEL_TYPE_MASK);
|
||||
|
||||
if (j->contains("applied_tags")) {
|
||||
for (const auto &t : (*j)["applied_tags"]) {
|
||||
this->applied_tags.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
set_int32_not_null(j, "total_message_sent", this->total_messages_sent);
|
||||
set_int8_not_null(j, "message_count", this->message_count);
|
||||
set_int8_not_null(j, "member_count", this->member_count);
|
||||
auto json_metadata = (*j)["thread_metadata"];
|
||||
metadata.archived = bool_not_null(&json_metadata, "archived");
|
||||
metadata.archive_timestamp = ts_not_null(&json_metadata, "archive_timestamp");
|
||||
metadata.auto_archive_duration = int16_not_null(&json_metadata, "auto_archive_duration");
|
||||
metadata.locked = bool_not_null(&json_metadata, "locked");
|
||||
metadata.invitable = bool_not_null(&json_metadata, "invitable");
|
||||
|
||||
/* Only certain events set this */
|
||||
if (j->contains("member")) {
|
||||
member.fill_from_json(&((*j)["member"]));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
thread::thread() : channel(), total_messages_sent(0), message_count(0), member_count(0) {
|
||||
}
|
||||
|
||||
thread::~thread() {
|
||||
}
|
||||
|
||||
channel& channel::fill_from_json(json* j) {
|
||||
this->id = snowflake_not_null(j, "id");
|
||||
set_snowflake_not_null(j, "guild_id", this->guild_id);
|
||||
set_int16_not_null(j, "position", this->position);
|
||||
set_string_not_null(j, "name", this->name);
|
||||
set_string_not_null(j, "topic", this->topic);
|
||||
set_snowflake_not_null(j, "last_message_id", this->last_message_id);
|
||||
set_int8_not_null(j, "user_limit", this->user_limit);
|
||||
set_int16_not_null(j, "rate_limit_per_user", this->rate_limit_per_user);
|
||||
set_int16_not_null(j, "default_thread_rate_limit_per_user", this->default_thread_rate_limit_per_user);
|
||||
set_snowflake_not_null(j, "owner_id", this->owner_id);
|
||||
set_snowflake_not_null(j, "parent_id", this->parent_id);
|
||||
this->bitrate = int32_not_null(j, "bitrate")/1000;
|
||||
this->flags |= bool_not_null(j, "nsfw") ? dpp::c_nsfw : 0;
|
||||
|
||||
uint16_t arc = int16_not_null(j, "default_auto_archive_duration");
|
||||
switch (arc) {
|
||||
case 60:
|
||||
this->default_auto_archive_duration = arc_1_hour;
|
||||
break;
|
||||
case 1440:
|
||||
this->default_auto_archive_duration = arc_1_day;
|
||||
break;
|
||||
case 4320:
|
||||
this->default_auto_archive_duration = arc_3_days;
|
||||
break;
|
||||
case 10080:
|
||||
this->default_auto_archive_duration = arc_1_week;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (j->contains("available_tags")) {
|
||||
available_tags = {};
|
||||
for (auto & available_tag : (*j)["available_tags"]) {
|
||||
this->available_tags.emplace_back(forum_tag().fill_from_json(&available_tag));
|
||||
}
|
||||
}
|
||||
|
||||
if (j->contains("default_reaction_emoji")) {
|
||||
auto emoji_id = snowflake_not_null(&(*j)["default_reaction_emoji"], "emoji_id");
|
||||
auto emoji_name = string_not_null(&(*j)["default_reaction_emoji"], "emoji_name");
|
||||
if (emoji_id) {
|
||||
this->default_reaction = emoji_id;
|
||||
} else if (!emoji_name.empty()) {
|
||||
this->default_reaction = emoji_name;
|
||||
}
|
||||
}
|
||||
|
||||
this->default_sort_order = (default_forum_sort_order_t)int8_not_null(j, "default_sort_order");
|
||||
|
||||
uint8_t type = int8_not_null(j, "type");
|
||||
this->flags |= (type & CHANNEL_TYPE_MASK);
|
||||
|
||||
uint16_t forum_layout = int16_not_null(j, "default_forum_layout");
|
||||
this->flags |= ((forum_layout << 9) & DEFAULT_FORUM_LAYOUT_MASK);
|
||||
|
||||
uint8_t dflags = int8_not_null(j, "flags");
|
||||
this->flags |= (dflags & dpp::dc_pinned_thread) ? dpp::c_pinned_thread : 0;
|
||||
this->flags |= (dflags & dpp::dc_require_tag) ? dpp::c_require_tag : 0;
|
||||
|
||||
uint8_t vqm = int8_not_null(j, "video_quality_mode");
|
||||
if (vqm == 2) {
|
||||
/* If this is set to 2, this means full quality 720p video for voice channel.
|
||||
* Undefined, or a value of 1 (the other two possibilities right now) means
|
||||
* video quality AUTO.
|
||||
*/
|
||||
this->flags |= dpp::c_video_quality_720p;
|
||||
}
|
||||
|
||||
if (j->contains("recipients")) {
|
||||
recipients = {};
|
||||
for (auto & r : (*j)["recipients"]) {
|
||||
recipients.push_back(from_string<uint64_t>(r["id"].get<std::string>()));
|
||||
}
|
||||
}
|
||||
|
||||
if (j->contains("permission_overwrites")) {
|
||||
permission_overwrites = {};
|
||||
for (auto & overwrite : (*j)["permission_overwrites"]) {
|
||||
permission_overwrite po;
|
||||
po.id = snowflake_not_null(&overwrite, "id");
|
||||
po.allow = snowflake_not_null(&overwrite, "allow");
|
||||
po.deny = snowflake_not_null(&overwrite, "deny");
|
||||
po.type = int8_not_null(&overwrite, "type");
|
||||
permission_overwrites.emplace_back(po);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: This is only set when the channel is in the resolved set from an interaction.
|
||||
* When set it contains the invokers permissions on channel. Any other time, contains 0.
|
||||
*/
|
||||
if (j->contains("permissions")) {
|
||||
set_snowflake_not_null(j, "permissions", permissions);
|
||||
}
|
||||
|
||||
std::string _icon = string_not_null(j, "icon");
|
||||
|
||||
if (!_icon.empty()) {
|
||||
this->icon = _icon;
|
||||
}
|
||||
|
||||
set_string_not_null(j, "rtc_region", rtc_region);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string thread::build_json(bool with_id) const {
|
||||
json j = json::parse(channel::build_json(with_id));
|
||||
j["type"] = (flags & CHANNEL_TYPE_MASK);
|
||||
j["thread_metadata"] = this->metadata;
|
||||
if (!this->applied_tags.empty()) {
|
||||
j["applied_tags"] = json::array();
|
||||
for (auto &tag_id: this->applied_tags) {
|
||||
if (tag_id) {
|
||||
j["applied_tags"].push_back(tag_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
std::string channel::build_json(bool with_id) const {
|
||||
json j;
|
||||
if (with_id && id) {
|
||||
j["id"] = std::to_string(id);
|
||||
}
|
||||
j["guild_id"] = std::to_string(guild_id);
|
||||
if (position) {
|
||||
j["position"] = position;
|
||||
}
|
||||
j["name"] = name;
|
||||
if (!topic.empty()) {
|
||||
j["topic"] = topic;
|
||||
}
|
||||
if (!permission_overwrites.empty()) {
|
||||
j["permission_overwrites"] = json::array();
|
||||
for (const auto& po : permission_overwrites) {
|
||||
json jpo = po;
|
||||
j["permission_overwrites"].push_back(jpo);
|
||||
}
|
||||
}
|
||||
if (rate_limit_per_user) {
|
||||
j["rate_limit_per_user"] = rate_limit_per_user;
|
||||
}
|
||||
if (default_thread_rate_limit_per_user) {
|
||||
j["default_thread_rate_limit_per_user"] = default_thread_rate_limit_per_user;
|
||||
}
|
||||
if (is_voice_channel()) {
|
||||
j["user_limit"] = user_limit;
|
||||
if (bitrate) {
|
||||
j["bitrate"] = bitrate * 1000;
|
||||
}
|
||||
}
|
||||
if (is_forum()) {
|
||||
j["flags"] = (flags & dpp::c_require_tag) ? dpp::dc_require_tag : 0;
|
||||
|
||||
if (get_default_forum_layout()) {
|
||||
j["default_forum_layout"] = get_default_forum_layout();
|
||||
}
|
||||
}
|
||||
j["type"] = (flags & CHANNEL_TYPE_MASK);
|
||||
if (!is_dm()) {
|
||||
if (parent_id) {
|
||||
j["parent_id"] = std::to_string(parent_id);
|
||||
}
|
||||
j["nsfw"] = is_nsfw();
|
||||
}
|
||||
switch (default_auto_archive_duration) {
|
||||
case arc_1_hour:
|
||||
j["default_auto_archive_duration"] = 60;
|
||||
break;
|
||||
case arc_1_day:
|
||||
j["default_auto_archive_duration"] = 1440;
|
||||
break;
|
||||
case arc_3_days:
|
||||
j["default_auto_archive_duration"] = 4320;
|
||||
break;
|
||||
case arc_1_week:
|
||||
j["default_auto_archive_duration"] = 10080;
|
||||
break;
|
||||
}
|
||||
if (!available_tags.empty()) {
|
||||
j["available_tags"] = json::array();
|
||||
for (const auto &available_tag : this->available_tags) {
|
||||
j["available_tags"].push_back(json::parse(available_tag.build_json()));
|
||||
}
|
||||
}
|
||||
if (std::holds_alternative<snowflake>(this->default_reaction)) {
|
||||
j["default_reaction_emoji"]["emoji_id"] = std::get<snowflake>(this->default_reaction);
|
||||
} else if (std::holds_alternative<std::string>(this->default_reaction)) {
|
||||
j["default_reaction_emoji"]["emoji_name"] = std::get<std::string>(this->default_reaction);
|
||||
}
|
||||
if (default_sort_order) {
|
||||
j["default_sort_order"] = default_sort_order;
|
||||
}
|
||||
if (flags & c_lock_permissions) {
|
||||
j["lock_permissions"] = true;
|
||||
}
|
||||
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
permission channel::get_user_permissions(const user* user) const {
|
||||
if (user == nullptr)
|
||||
return 0;
|
||||
|
||||
guild* g = dpp::find_guild(guild_id);
|
||||
if (g == nullptr)
|
||||
return 0;
|
||||
|
||||
return g->permission_overwrites(g->base_permissions(user), user, this);
|
||||
}
|
||||
|
||||
permission channel::get_user_permissions(const guild_member &member) const {
|
||||
|
||||
guild* g = dpp::find_guild(guild_id);
|
||||
if (g == nullptr)
|
||||
return 0;
|
||||
|
||||
return g->permission_overwrites(member, *this);
|
||||
}
|
||||
|
||||
std::map<snowflake, guild_member*> channel::get_members() {
|
||||
std::map<snowflake, guild_member*> rv;
|
||||
guild* g = dpp::find_guild(guild_id);
|
||||
if (g) {
|
||||
for (auto m = g->members.begin(); m != g->members.end(); ++m) {
|
||||
if (g->permission_overwrites(m->second, *this) & p_view_channel) {
|
||||
rv[m->second.user_id] = &(m->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
std::map<snowflake, voicestate> channel::get_voice_members() {
|
||||
std::map<snowflake, voicestate> rv;
|
||||
guild* g = dpp::find_guild(guild_id);
|
||||
if (g) {
|
||||
for (auto & m : g->voice_members) {
|
||||
if (m.second.channel_id == this->id) {
|
||||
rv[m.second.user_id] = m.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
std::string channel::get_icon_url(uint16_t size, const image_type format) const {
|
||||
static const std::map<image_type, std::string> extensions = {
|
||||
{ i_jpg, "jpg" },
|
||||
{ i_png, "png" },
|
||||
{ i_webp, "webp" },
|
||||
};
|
||||
|
||||
if (extensions.find(format) == extensions.end()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (this->id && !this->icon.to_string().empty()) {
|
||||
return utility::cdn_host + "/channel-icons/" + std::to_string(this->id) + "/" + this->icon.to_string() + "." + extensions.find(format)->second + utility::avatar_size(size);
|
||||
} else {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
channel_type channel::get_type() const {
|
||||
return static_cast<channel_type>(flags & CHANNEL_TYPE_MASK);
|
||||
}
|
||||
|
||||
forum_layout_type channel::get_default_forum_layout() const {
|
||||
return static_cast<forum_layout_type>((flags & DEFAULT_FORUM_LAYOUT_MASK) >> 9);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
400
vendor/DPP/src/dpp/cluster.cpp
vendored
Normal file
400
vendor/DPP/src/dpp/cluster.cpp
vendored
Normal file
@@ -0,0 +1,400 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <map>
|
||||
#include <dpp/exception.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/discordclient.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/once.h>
|
||||
#include <dpp/sync.h>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <dpp/json.h>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _DEBUG
|
||||
extern "C" void you_are_using_a_debug_build_of_dpp_on_a_release_project() {
|
||||
}
|
||||
#else
|
||||
extern "C" void you_are_using_a_release_build_of_dpp_on_a_debug_project() {
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief An audit reason for each thread. These are per-thread to make the cluster
|
||||
* methods like cluster::get_audit_reason and cluster::set_audit_reason thread safe across
|
||||
* multiple threads. You must ensure you set the audit reason on the same thread that makes
|
||||
* the request associated with it.
|
||||
*/
|
||||
thread_local std::string audit_reason;
|
||||
|
||||
/**
|
||||
* @brief Make a warning lambda for missing message intents
|
||||
*
|
||||
* @tparam T type of parameter for the event in the router
|
||||
* @param cl Creating cluster
|
||||
* @param required_intent Intent which is required
|
||||
* @param message Message to display
|
||||
* @return std::function<void(const T&)> Returned lambda
|
||||
*/
|
||||
template<typename T> std::function<void(const T&)> make_intent_warning(cluster* cl, const intents required_intent, const std::string& message) {
|
||||
return [cl, required_intent, message](const T& event) {
|
||||
if (!(cl->intents & required_intent) && event.msg.guild_id) {
|
||||
cl->log(ll_warning, message);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
cluster::cluster(const std::string &_token, uint32_t _intents, uint32_t _shards, uint32_t _cluster_id, uint32_t _maxclusters, bool comp, cache_policy_t policy, uint32_t request_threads, uint32_t request_threads_raw)
|
||||
: default_gateway("gateway.discord.gg"), rest(nullptr), raw_rest(nullptr), compressed(comp), start_time(0), token(_token), last_identify(time(NULL) - 5), intents(_intents),
|
||||
numshards(_shards), cluster_id(_cluster_id), maxclusters(_maxclusters), rest_ping(0.0), cache_policy(policy), ws_mode(ws_json)
|
||||
{
|
||||
/* Instantiate REST request queues */
|
||||
try {
|
||||
rest = new request_queue(this, request_threads);
|
||||
raw_rest = new request_queue(this, request_threads_raw);
|
||||
}
|
||||
catch (std::bad_alloc&) {
|
||||
delete rest;
|
||||
delete raw_rest;
|
||||
throw;
|
||||
}
|
||||
|
||||
/* Add checks for missing intents, these emit a one-off warning to the log if bound without the right intents */
|
||||
on_message_create.set_warning_callback(
|
||||
make_intent_warning<message_create_t>(
|
||||
this,
|
||||
i_message_content,
|
||||
"You have attached an event to cluster::on_message_create() but have not specified the privileged intent dpp::i_message_content. Message content, embeds, attachments, and components on received guild messages will be empty.")
|
||||
);
|
||||
on_message_update.set_warning_callback(
|
||||
make_intent_warning<message_update_t>(
|
||||
this,
|
||||
i_message_content,
|
||||
"You have attached an event to cluster::on_message_update() but have not specified the privileged intent dpp::i_message_content. Message content, embeds, attachments, and components on received guild messages will be empty.")
|
||||
);
|
||||
}
|
||||
|
||||
cluster::~cluster()
|
||||
{
|
||||
this->shutdown();
|
||||
delete rest;
|
||||
delete raw_rest;
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
request_queue* cluster::get_rest() {
|
||||
return rest;
|
||||
}
|
||||
|
||||
request_queue* cluster::get_raw_rest() {
|
||||
return raw_rest;
|
||||
}
|
||||
|
||||
cluster& cluster::set_websocket_protocol(websocket_protocol_t mode) {
|
||||
ws_mode = mode;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void cluster::log(dpp::loglevel severity, const std::string &msg) const {
|
||||
if (!on_log.empty()) {
|
||||
/* Pass to user if they've hooked the event */
|
||||
dpp::log_t logmsg(nullptr, msg);
|
||||
logmsg.severity = severity;
|
||||
logmsg.message = msg;
|
||||
on_log.call(logmsg);
|
||||
}
|
||||
}
|
||||
|
||||
dpp::utility::uptime cluster::uptime()
|
||||
{
|
||||
return dpp::utility::uptime(time(NULL) - start_time);
|
||||
}
|
||||
|
||||
void cluster::start(bool return_after) {
|
||||
|
||||
auto block_calling_thread = [this]() {
|
||||
std::mutex thread_mutex;
|
||||
std::unique_lock thread_lock(thread_mutex);
|
||||
this->terminating.wait(thread_lock);
|
||||
};
|
||||
|
||||
/* Start up all shards */
|
||||
gateway g;
|
||||
try {
|
||||
g = dpp::sync<gateway>(this, &cluster::get_gateway_bot);
|
||||
log(ll_debug, "Cluster: " + std::to_string(g.session_start_remaining) + " of " + std::to_string(g.session_start_total) + " session starts remaining");
|
||||
if (g.session_start_remaining < g.shards) {
|
||||
throw dpp::connection_exception("Discord indicates you cannot start enough sessions to boot this cluster! Cluster startup aborted. Try again later.");
|
||||
}
|
||||
if (g.session_start_max_concurrency > 1) {
|
||||
log(ll_debug, "Cluster: Large bot sharding; Using session concurrency: " + std::to_string(g.session_start_max_concurrency));
|
||||
}
|
||||
if (numshards == 0) {
|
||||
if (g.shards) {
|
||||
log(ll_info, "Auto Shard: Bot requires " + std::to_string(g.shards) + std::string(" shard") + ((g.shards > 1) ? "s" : ""));
|
||||
} else {
|
||||
throw dpp::connection_exception("Auto Shard: Cannot determine number of shards. Cluster startup aborted. Check your connection.");
|
||||
}
|
||||
numshards = g.shards;
|
||||
}
|
||||
}
|
||||
catch (const dpp::rest_exception& e) {
|
||||
if (std::string(e.what()) == "401: Unauthorized") {
|
||||
/* Throw special form of exception for invalid token */
|
||||
throw dpp::invalid_token_exception("Invalid bot token (401: Unauthorized when getting gateway shard count)");
|
||||
} else {
|
||||
/* Rethrow */
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
start_time = time(NULL);
|
||||
|
||||
log(ll_debug, "Starting with " + std::to_string(numshards) + " shards...");
|
||||
|
||||
for (uint32_t s = 0; s < numshards; ++s) {
|
||||
/* Filter out shards that aren't part of the current cluster, if the bot is clustered */
|
||||
if (s % maxclusters == cluster_id) {
|
||||
/* Each discord_client spawns its own thread in its run() */
|
||||
try {
|
||||
this->shards[s] = new discord_client(this, s, numshards, token, intents, compressed, ws_mode);
|
||||
this->shards[s]->run();
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
log(dpp::ll_critical, "Could not start shard " + std::to_string(s) + ": " + std::string(e.what()));
|
||||
}
|
||||
/* Stagger the shard startups, pausing every 'session_start_max_concurrency' shards for 5 seconds.
|
||||
* This means that for bots that don't have large bot sharding, any number % 1 is always 0,
|
||||
* so it will pause after every shard. For any with non-zero concurrency it'll pause 5 seconds
|
||||
* after every batch.
|
||||
*/
|
||||
if (((s + 1) % g.session_start_max_concurrency) == 0) {
|
||||
size_t wait_time = 5;
|
||||
if (g.session_start_max_concurrency > 1) {
|
||||
/* If large bot sharding, be sure to give the batch of shards time to settle */
|
||||
bool all_connected = true;
|
||||
do {
|
||||
all_connected = true;
|
||||
for (auto& shard : this->shards) {
|
||||
if (!shard.second->ready) {
|
||||
all_connected = false;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (all_connected);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::seconds(wait_time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get all active DM channels and map them to user id -> dm id */
|
||||
this->current_user_get_dms([this](const dpp::confirmation_callback_t& completion) {
|
||||
dpp::channel_map dmchannels = std::get<channel_map>(completion.value);
|
||||
for (auto & c : dmchannels) {
|
||||
for (auto & u : c.second.recipients) {
|
||||
this->set_dm_channel(u, c.second.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
log(ll_debug, "Shards started.");
|
||||
|
||||
if (!return_after)
|
||||
block_calling_thread();
|
||||
}
|
||||
|
||||
void cluster::shutdown() {
|
||||
/* Signal condition variable to terminate */
|
||||
terminating.notify_all();
|
||||
/* Free memory for active timers */
|
||||
for (auto & t : timer_list) {
|
||||
delete t.second;
|
||||
}
|
||||
timer_list.clear();
|
||||
/* Terminate shards */
|
||||
for (const auto& sh : shards) {
|
||||
log(ll_info, "Terminating shard id " + std::to_string(sh.second->shard_id));
|
||||
delete sh.second;
|
||||
}
|
||||
shards.clear();
|
||||
}
|
||||
|
||||
snowflake cluster::get_dm_channel(snowflake user_id) {
|
||||
std::lock_guard<std::mutex> lock(dm_list_lock);
|
||||
auto i = dm_channels.find(user_id);
|
||||
if (i != dm_channels.end()) {
|
||||
return i->second;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cluster::set_dm_channel(snowflake user_id, snowflake channel_id) {
|
||||
std::lock_guard<std::mutex> lock(dm_list_lock);
|
||||
dm_channels[user_id] = channel_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Given an error exception from nlohmann::json, turn it into a discord-style error object
|
||||
* that can be parsed by the get_error() function. Modifies the http request body, moving it to
|
||||
* `.get_error().errors[0].reason` in the callback.
|
||||
*
|
||||
* @param message Exception message
|
||||
* @param rv Request completion data
|
||||
* @return json
|
||||
*/
|
||||
json error_response(const std::string& message, http_request_completion_t& rv)
|
||||
{
|
||||
json j({
|
||||
{"code", rv.status},
|
||||
{"errors", {
|
||||
{"json", {
|
||||
{"0", {
|
||||
{"body", {
|
||||
{"_errors", {{
|
||||
{"code", "JSON_PARSE"},
|
||||
{"message", rv.body},
|
||||
}}}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}},
|
||||
{"message", message}
|
||||
});
|
||||
rv.body = j.dump();
|
||||
return j;
|
||||
}
|
||||
|
||||
void cluster::post_rest(const std::string &endpoint, const std::string &major_parameters, const std::string ¶meters, http_method method, const std::string &postdata, json_encode_t callback, const std::string &filename, const std::string &filecontent) {
|
||||
/* NOTE: This is not a memory leak! The request_queue will free the http_request once it reaches the end of its lifecycle */
|
||||
rest->post_request(new http_request(endpoint + "/" + major_parameters, parameters, [endpoint, callback](http_request_completion_t rv) {
|
||||
json j;
|
||||
if (rv.error == h_success && !rv.body.empty()) {
|
||||
try {
|
||||
j = json::parse(rv.body);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
j = error_response(e.what(), rv);
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(j, rv);
|
||||
}
|
||||
}, postdata, method, get_audit_reason(), filename, filecontent));
|
||||
}
|
||||
|
||||
void cluster::post_rest_multipart(const std::string &endpoint, const std::string &major_parameters, const std::string ¶meters, http_method method, const std::string &postdata, json_encode_t callback, const std::vector<std::string> &filename, const std::vector<std::string> &filecontent) {
|
||||
/* NOTE: This is not a memory leak! The request_queue will free the http_request once it reaches the end of its lifecycle */
|
||||
rest->post_request(new http_request(endpoint + "/" + major_parameters, parameters, [endpoint, callback](http_request_completion_t rv) {
|
||||
json j;
|
||||
if (rv.error == h_success && !rv.body.empty()) {
|
||||
try {
|
||||
j = json::parse(rv.body);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
j = error_response(e.what(), rv);
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(j, rv);
|
||||
}
|
||||
}, postdata, method, get_audit_reason(), filename, filecontent));
|
||||
}
|
||||
|
||||
|
||||
void cluster::request(const std::string &url, http_method method, http_completion_event callback, const std::string &postdata, const std::string &mimetype, const std::multimap<std::string, std::string> &headers) {
|
||||
/* NOTE: This is not a memory leak! The request_queue will free the http_request once it reaches the end of its lifecycle */
|
||||
raw_rest->post_request(new http_request(url, callback, method, postdata, mimetype, headers));
|
||||
}
|
||||
|
||||
gateway::gateway() : shards(0), session_start_total(0), session_start_remaining(0), session_start_reset_after(0), session_start_max_concurrency(0) {
|
||||
}
|
||||
|
||||
gateway& gateway::fill_from_json(nlohmann::json* j) {
|
||||
url = string_not_null(j, "url");
|
||||
shards = int32_not_null(j, "shards");
|
||||
session_start_total = int32_not_null(&((*j)["session_start_limit"]), "total");
|
||||
session_start_remaining = int32_not_null(&((*j)["session_start_limit"]), "remaining");
|
||||
session_start_reset_after = int32_not_null(&((*j)["session_start_limit"]), "reset_after");
|
||||
session_start_max_concurrency = int32_not_null(&((*j)["session_start_limit"]), "max_concurrency");
|
||||
return *this;
|
||||
}
|
||||
|
||||
gateway::gateway(nlohmann::json* j) {
|
||||
fill_from_json(j);
|
||||
}
|
||||
|
||||
void cluster::set_presence(const dpp::presence &p) {
|
||||
json pres = json::parse(p.build_json());
|
||||
for (auto& s : shards) {
|
||||
if (s.second->is_connected()) {
|
||||
s.second->queue_message(s.second->jsonobj_to_string(pres));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cluster& cluster::set_audit_reason(const std::string &reason) {
|
||||
audit_reason = reason;
|
||||
return *this;
|
||||
}
|
||||
|
||||
cluster& cluster::clear_audit_reason() {
|
||||
audit_reason.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
cluster& cluster::set_default_gateway(std::string &default_gateway_new) {
|
||||
default_gateway = default_gateway_new;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string cluster::get_audit_reason() {
|
||||
std::string r = audit_reason;
|
||||
audit_reason.clear();
|
||||
return r;
|
||||
}
|
||||
|
||||
discord_client* cluster::get_shard(uint32_t id) {
|
||||
auto i = shards.find(id);
|
||||
if (i != shards.end()) {
|
||||
return i->second;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const shard_list& cluster::get_shards() {
|
||||
return shards;
|
||||
}
|
||||
|
||||
};
|
||||
178
vendor/DPP/src/dpp/cluster/appcommand.cpp
vendored
Normal file
178
vendor/DPP/src/dpp/cluster/appcommand.cpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/appcommand.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::global_bulk_command_create(const std::vector<slashcommand> &commands, command_completion_event_t callback) {
|
||||
json j = json::array();
|
||||
for (auto & s : commands) {
|
||||
j.push_back(json::parse(s.build_json(false)));
|
||||
}
|
||||
rest_request_list<slashcommand>(this, API_PATH "/applications", std::to_string(commands.size() > 0 && commands[0].application_id ? commands[0].application_id : me.id), "commands", m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::global_command_create(const slashcommand &s, command_completion_event_t callback) {
|
||||
rest_request<slashcommand>(this, API_PATH "/applications", std::to_string(s.application_id ? s.application_id : me.id), "commands", m_post, s.build_json(false), callback);
|
||||
}
|
||||
|
||||
void cluster::global_command_get(snowflake id, command_completion_event_t callback) {
|
||||
rest_request<slashcommand>(this, API_PATH "/applications", std::to_string(me.id), "commands/" + std::to_string(id), m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::global_command_delete(snowflake id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/applications", std::to_string(me.id), "commands/" + std::to_string(id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::global_command_edit(const slashcommand &s, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/applications", std::to_string(s.application_id ? s.application_id : me.id), "commands/" + std::to_string(s.id), m_patch, s.build_json(true), callback);
|
||||
}
|
||||
|
||||
void cluster::global_commands_get(command_completion_event_t callback) {
|
||||
rest_request_list<slashcommand>(this, API_PATH "/applications", std::to_string(me.id), "commands", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_bulk_command_create(const std::vector<slashcommand> &commands, snowflake guild_id, command_completion_event_t callback) {
|
||||
json j = json::array();
|
||||
for (auto & s : commands) {
|
||||
j.push_back(json::parse(s.build_json(false)));
|
||||
}
|
||||
rest_request_list<slashcommand>(this, API_PATH "/applications", std::to_string(commands.size() > 0 && commands[0].application_id ? commands[0].application_id : me.id), "guilds/" + std::to_string(guild_id) + "/commands", m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_commands_get_permissions(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<guild_command_permissions>(this, API_PATH "/applications", std::to_string(me.id), "guilds/" + std::to_string(guild_id) + "/commands/permissions", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_bulk_command_edit_permissions(const std::vector<slashcommand> &commands, snowflake guild_id, command_completion_event_t callback) {
|
||||
if (commands.empty()) {
|
||||
return;
|
||||
}
|
||||
json j = json::array();
|
||||
for (auto & s : commands) {
|
||||
json jcommand;
|
||||
jcommand["id"] = s.id;
|
||||
jcommand["permissions"] = json::array();
|
||||
for (auto & c : s.permissions) {
|
||||
jcommand["permissions"].push_back(c);
|
||||
}
|
||||
j.push_back(jcommand);
|
||||
}
|
||||
rest_request_list<guild_command_permissions>(this, API_PATH "/applications", std::to_string(me.id), "guilds/" + std::to_string(guild_id) + "/commands/permissions", m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_command_create(const slashcommand &s, snowflake guild_id, command_completion_event_t callback) {
|
||||
this->post_rest(API_PATH "/applications", std::to_string(s.application_id ? s.application_id : me.id), "guilds/" + std::to_string(guild_id) + "/commands", m_post, s.build_json(false), [s, this, guild_id, callback] (json &j, const http_request_completion_t& http) mutable {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, slashcommand().fill_from_json(&j), http));
|
||||
}
|
||||
|
||||
if (http.status < 300 && s.permissions.size()) {
|
||||
slashcommand n;
|
||||
n.fill_from_json(&j);
|
||||
n.permissions = s.permissions;
|
||||
guild_command_edit_permissions(n, guild_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void cluster::guild_command_delete(snowflake id, snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/applications", std::to_string(me.id), "guilds/" + std::to_string(guild_id) + "/commands/" + std::to_string(id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_command_edit_permissions(const slashcommand &s, snowflake guild_id, command_completion_event_t callback) {
|
||||
json j;
|
||||
if (!s.permissions.empty()) {
|
||||
j["permissions"] = json();
|
||||
for (const auto& perm : s.permissions) {
|
||||
json jperm = perm;
|
||||
j["permissions"].push_back(jperm);
|
||||
}
|
||||
}
|
||||
rest_request<confirmation>(this, API_PATH "/applications", std::to_string(s.application_id ? s.application_id : me.id), "guilds/" + std::to_string(guild_id) + "/commands/" + std::to_string(s.id) + "/permissions", m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_command_get(snowflake id, snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<slashcommand>(this, API_PATH "/applications", std::to_string(me.id), "guilds/" + std::to_string(guild_id) + "/commands/" + std::to_string(id), m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_command_get_permissions(snowflake id, snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<guild_command_permissions>(this, API_PATH "/applications", std::to_string(me.id), "guilds/" + std::to_string(guild_id) + "/commands/" + std::to_string(id) + "/permissions", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_command_edit(const slashcommand &s, snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/applications", std::to_string(s.application_id ? s.application_id : me.id), "guilds/" + std::to_string(guild_id) + "/commands/" + std::to_string(s.id), m_patch, s.build_json(true), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_commands_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<slashcommand>(this, API_PATH "/applications", std::to_string(me.id), "/guilds/" + std::to_string(guild_id) + "/commands", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::interaction_response_create(snowflake interaction_id, const std::string &token, const interaction_response &r, command_completion_event_t callback) {
|
||||
this->post_rest_multipart(API_PATH "/interactions", std::to_string(interaction_id), utility::url_encode(token) + "/callback", m_post, r.build_json(), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, confirmation(), http));
|
||||
}
|
||||
}, r.msg->filename, r.msg->filecontent);
|
||||
}
|
||||
|
||||
void cluster::interaction_response_edit(const std::string &token, const message &m, command_completion_event_t callback) {
|
||||
this->post_rest_multipart(API_PATH "/webhooks", std::to_string(me.id), utility::url_encode(token) + "/messages/@original", m_patch, m.build_json(), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, confirmation(), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
void cluster::interaction_followup_create(const std::string &token, const message &m, command_completion_event_t callback) {
|
||||
this->post_rest_multipart(API_PATH "/webhooks", std::to_string(me.id), utility::url_encode(token), m_post, m.build_json(), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, confirmation(), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
void cluster::interaction_followup_edit_original(const std::string &token, const message &m, command_completion_event_t callback) {
|
||||
this->post_rest_multipart(API_PATH "/webhooks", std::to_string(me.id), utility::url_encode(token) + "/messages/@original", m_patch, m.build_json(), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, confirmation(), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
void cluster::interaction_followup_delete(const std::string &token, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/webhooks",std::to_string(me.id), utility::url_encode(token) + "/messages/@original", m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::interaction_followup_edit(const std::string &token, const message &m, command_completion_event_t callback) {
|
||||
this->post_rest_multipart(API_PATH "/webhooks", std::to_string(me.id), utility::url_encode(token) + "/messages/" + std::to_string(m.id), m_patch, m.build_json(), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, confirmation(), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
void cluster::interaction_followup_get(const std::string &token, snowflake message_id, command_completion_event_t callback) {
|
||||
rest_request<message>(this, API_PATH "/webhooks",std::to_string(me.id), utility::url_encode(token) + "/messages/" + std::to_string(message_id), m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
46
vendor/DPP/src/dpp/cluster/automod.cpp
vendored
Normal file
46
vendor/DPP/src/dpp/cluster/automod.cpp
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/automod.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::automod_rules_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<automod_rule>(this, API_PATH "/guilds", std::to_string(guild_id), "/auto-moderation/rules", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::automod_rule_get(snowflake guild_id, snowflake rule_id, command_completion_event_t callback) {
|
||||
rest_request<automod_rule>(this, API_PATH "/guilds", std::to_string(guild_id), "/auto-moderation/rules/" + std::to_string(rule_id), m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::automod_rule_create(snowflake guild_id, const automod_rule& r, command_completion_event_t callback) {
|
||||
rest_request<automod_rule>(this, API_PATH "/guilds", std::to_string(guild_id), "/auto-moderation/rules", m_post, r.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::automod_rule_edit(snowflake guild_id, const automod_rule& r, command_completion_event_t callback) {
|
||||
rest_request<automod_rule>(this, API_PATH "/guilds", std::to_string(guild_id), "/auto-moderation/rules/" + std::to_string(r.id), m_patch, r.build_json(true), callback);
|
||||
}
|
||||
|
||||
void cluster::automod_rule_delete(snowflake guild_id, snowflake rule_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "/auto-moderation/rules/" + std::to_string(rule_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
99
vendor/DPP/src/dpp/cluster/channel.cpp
vendored
Normal file
99
vendor/DPP/src/dpp/cluster/channel.cpp
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::channel_create(const class channel &c, command_completion_event_t callback) {
|
||||
rest_request<channel>(this, API_PATH "/guilds", std::to_string(c.guild_id), "channels", m_post, c.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::channel_delete_permission(const class channel &c, snowflake overwrite_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(c.id), "permissions/" + std::to_string(overwrite_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::channel_delete(snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "", m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::channel_edit_permissions(const class channel &c, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member, command_completion_event_t callback) {
|
||||
channel_edit_permissions(c.id, overwrite_id, allow, deny, member, callback);
|
||||
}
|
||||
|
||||
void cluster::channel_edit_permissions(const snowflake channel_id, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member, command_completion_event_t callback) {
|
||||
json j({ {"allow", std::to_string(allow)}, {"deny", std::to_string(deny)}, {"type", member ? 1 : 0} });
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "permissions/" + std::to_string(overwrite_id), m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::channel_edit_positions(const std::vector<channel> &c, command_completion_event_t callback) {
|
||||
json j = json::array();
|
||||
if (c.empty()) {
|
||||
return;
|
||||
}
|
||||
for (auto & ch : c) {
|
||||
json cj({ {"id", ch.id}, {"position", ch.position} });
|
||||
if (ch.parent_id) {
|
||||
cj["parent_id"] = std::to_string(ch.parent_id);
|
||||
}
|
||||
if (ch.flags & c_lock_permissions) {
|
||||
cj["lock_permissions"] = true;
|
||||
}
|
||||
j.push_back(cj);
|
||||
}
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(c[0].guild_id), "channels/" + std::to_string(c[0].id), m_patch, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::channel_edit(const class channel &c, command_completion_event_t callback) {
|
||||
rest_request<channel>(this, API_PATH "/channels", std::to_string(c.id), "", m_patch, c.build_json(true), callback);
|
||||
}
|
||||
|
||||
void cluster::channel_follow_news(const class channel &c, snowflake target_channel_id, command_completion_event_t callback) {
|
||||
json j({ {"webhook_channel_id", target_channel_id} });
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(c.id), "followers", m_post, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::channel_get(snowflake c, command_completion_event_t callback) {
|
||||
rest_request<channel>(this, API_PATH "/channels", std::to_string(c), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::channel_invite_create(const class channel &c, const class invite &i, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(c.id), "invites", m_post, i.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::channel_invites_get(const class channel &c, command_completion_event_t callback) {
|
||||
rest_request_list<invite>(this, API_PATH "/channels", std::to_string(c.id), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::channel_typing(const class channel &c, command_completion_event_t callback) {
|
||||
channel_typing(c.id, callback);
|
||||
}
|
||||
|
||||
void cluster::channel_typing(snowflake cid, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(cid), "typing", m_post, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::channels_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<channel>(this, API_PATH "/guilds", std::to_string(guild_id), "channels", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
130
vendor/DPP/src/dpp/cluster/confirmation.cpp
vendored
Normal file
130
vendor/DPP/src/dpp/cluster/confirmation.cpp
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
|
||||
confirmation_callback_t::confirmation_callback_t(cluster* creator, const confirmable_t& _value, const http_request_completion_t& _http)
|
||||
: http_info(_http), value(_value), bot(creator)
|
||||
{
|
||||
if (std::holds_alternative<confirmation>(_value)) {
|
||||
confirmation newvalue = std::get<confirmation>(_value);
|
||||
newvalue.success = (http_info.status < 400);
|
||||
value = newvalue;
|
||||
}
|
||||
}
|
||||
|
||||
confirmation_callback_t::confirmation_callback_t(const http_request_completion_t& _http)
|
||||
: http_info(_http), value(), bot(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
confirmation_callback_t::confirmation_callback_t(cluster* creator) : bot(creator) {
|
||||
http_info = {};
|
||||
value = {};
|
||||
}
|
||||
|
||||
bool confirmation_callback_t::is_error() const {
|
||||
if (http_info.status >= 400) {
|
||||
/* Invalid JSON or 4xx/5xx response */
|
||||
return true;
|
||||
}
|
||||
if (http_info.status == 204) {
|
||||
/* Body is empty so we can't parse it but interaction is not an error*/
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
json j = json::parse(this->http_info.body);
|
||||
if (j.find("code") != j.end() && j.find("errors") != j.end() && j.find("message") != j.end()) {
|
||||
if (j["code"].is_number_unsigned() && j["errors"].is_object() && j["message"].is_string()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (const std::exception &) {
|
||||
/* JSON parse error indicates the content is not JSON.
|
||||
* This means that its an empty body e.g. 204 response, and not an actual error.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
error_info confirmation_callback_t::get_error() const {
|
||||
if (is_error()) {
|
||||
json j = json::parse(this->http_info.body);
|
||||
error_info e;
|
||||
|
||||
set_int32_not_null(&j, "code", e.code);
|
||||
set_string_not_null(&j, "message", e.message);
|
||||
json& errors = j["errors"];
|
||||
for (auto obj = errors.begin(); obj != errors.end(); ++obj) {
|
||||
|
||||
if (obj->find("0") != obj->end()) {
|
||||
/* An array of error messages */
|
||||
for (auto index = obj->begin(); index != obj->end(); ++index) {
|
||||
if (index->find("_errors") != index->end()) {
|
||||
for (auto errordetails = (*index)["_errors"].begin(); errordetails != (*index)["_errors"].end(); ++errordetails) {
|
||||
error_detail detail;
|
||||
detail.code = (*errordetails)["code"].get<std::string>();
|
||||
detail.reason = (*errordetails)["message"].get<std::string>();
|
||||
detail.object.clear();
|
||||
detail.field = obj.key();
|
||||
e.errors.emplace_back(detail);
|
||||
}
|
||||
} else {
|
||||
for (auto fields = index->begin(); fields != index->end(); ++fields) {
|
||||
for (auto errordetails = (*fields)["_errors"].begin(); errordetails != (*fields)["_errors"].end(); ++errordetails) {
|
||||
error_detail detail;
|
||||
detail.code = (*errordetails)["code"].get<std::string>();
|
||||
detail.reason = (*errordetails)["message"].get<std::string>();
|
||||
detail.field = fields.key();
|
||||
detail.object = obj.key();
|
||||
e.errors.emplace_back(detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (obj->find("_errors") != obj->end()) {
|
||||
/* An object of error messages */
|
||||
e.errors.reserve((*obj)["_errors"].size());
|
||||
for (auto errordetails = (*obj)["_errors"].begin(); errordetails != (*obj)["_errors"].end(); ++errordetails) {
|
||||
error_detail detail;
|
||||
detail.code = (*errordetails)["code"].get<std::string>();
|
||||
detail.reason = (*errordetails)["message"].get<std::string>();
|
||||
detail.object.clear();
|
||||
detail.field = obj.key();
|
||||
e.errors.emplace_back(detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
return error_info();
|
||||
}
|
||||
|
||||
};
|
||||
66
vendor/DPP/src/dpp/cluster/dm.cpp
vendored
Normal file
66
vendor/DPP/src/dpp/cluster/dm.cpp
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::create_dm_channel(snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<channel>(this, API_PATH "/users", "@me", "channels", m_post, json({{"recipient_id", std::to_string(user_id)}}).dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::current_user_get_dms(command_completion_event_t callback) {
|
||||
rest_request_list<channel>(this, API_PATH "/users", "@me", "channels", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::direct_message_create(snowflake user_id, const message &m, command_completion_event_t callback) {
|
||||
/* Find out if a DM channel already exists */
|
||||
message msg = m;
|
||||
snowflake dm_channel_id = this->get_dm_channel(user_id);
|
||||
if (!dm_channel_id) {
|
||||
this->create_dm_channel(user_id, [user_id, this, msg, callback](const dpp::confirmation_callback_t& completion) {
|
||||
/* NOTE: We are making copies in here for a REASON. Don't try and optimise out these
|
||||
* copies as if we use references, by the time the the thread completes for the callback
|
||||
* the reference is invalid and we get a crash or heap corruption!
|
||||
*/
|
||||
message m2 = msg;
|
||||
dpp::channel c = std::get<channel>(completion.value);
|
||||
m2.channel_id = c.id;
|
||||
this->set_dm_channel(user_id, c.id);
|
||||
message_create(m2, callback);
|
||||
});
|
||||
} else {
|
||||
msg.channel_id = dm_channel_id;
|
||||
message_create(msg, callback);
|
||||
}
|
||||
}
|
||||
|
||||
void cluster::gdm_add(snowflake channel_id, snowflake user_id, const std::string &access_token, const std::string &nick, command_completion_event_t callback) {
|
||||
json params;
|
||||
params["access_token"] = access_token;
|
||||
params["nick"] = nick;
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "recipients/" + std::to_string(user_id), m_put, params.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::gdm_remove(snowflake channel_id, snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "recipients/" + std::to_string(user_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
45
vendor/DPP/src/dpp/cluster/emoji.cpp
vendored
Normal file
45
vendor/DPP/src/dpp/cluster/emoji.cpp
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::guild_emoji_create(snowflake guild_id, const class emoji& newemoji, command_completion_event_t callback) {
|
||||
rest_request<emoji>(this, API_PATH "/guilds", std::to_string(guild_id), "emojis", m_post, newemoji.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_emoji_delete(snowflake guild_id, snowflake emoji_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "emojis/" + std::to_string(emoji_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_emoji_edit(snowflake guild_id, const class emoji& newemoji, command_completion_event_t callback) {
|
||||
rest_request<emoji>(this, API_PATH "/guilds", std::to_string(guild_id), "emojis/" + std::to_string(newemoji.id), m_patch, newemoji.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_emoji_get(snowflake guild_id, snowflake emoji_id, command_completion_event_t callback) {
|
||||
rest_request<emoji>(this, API_PATH "/guilds", std::to_string(guild_id), "emojis/" + std::to_string(emoji_id), m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_emojis_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<emoji>(this, API_PATH "/guilds", std::to_string(guild_id), "emojis", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
29
vendor/DPP/src/dpp/cluster/gateway.cpp
vendored
Normal file
29
vendor/DPP/src/dpp/cluster/gateway.cpp
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::get_gateway_bot(command_completion_event_t callback) {
|
||||
rest_request<gateway>(this, API_PATH "/gateway", "bot", "", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
152
vendor/DPP/src/dpp/cluster/guild.cpp
vendored
Normal file
152
vendor/DPP/src/dpp/cluster/guild.cpp
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/restrequest.h>
|
||||
#include <dpp/once.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::guild_current_member_edit(snowflake guild_id, const std::string &nickname, command_completion_event_t callback) {
|
||||
std::string o = (nickname.empty() ? json({{"nick", json::value_t::null }}) : json({{"nick", nickname }})).dump();
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/@me", m_patch, o, callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_auditlog_get(snowflake guild_id, snowflake user_id, uint32_t action_type, snowflake before, snowflake after, uint32_t limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"user_id", user_id},
|
||||
{"action_type", action_type},
|
||||
{"before", before},
|
||||
{"after", after},
|
||||
{"limit", limit},
|
||||
});
|
||||
rest_request<auditlog>(this, API_PATH "/guilds", std::to_string(guild_id), "audit-logs" + parameters, m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_ban_add(snowflake guild_id, snowflake user_id, uint32_t delete_message_seconds, command_completion_event_t callback) {
|
||||
json j;
|
||||
if (delete_message_seconds) {
|
||||
j["delete_message_seconds"] = delete_message_seconds > 604800 ? 604800 : delete_message_seconds;
|
||||
if (delete_message_seconds >= 1 && delete_message_seconds <= 7) {
|
||||
if (dpp::run_once<struct ban_add_seconds_not_days_t>()) {
|
||||
this->log(ll_warning, "It looks like you may have confused seconds and days in cluster::guild_ban_add - Please double check your parameters!");
|
||||
}
|
||||
}
|
||||
}
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "bans/" + std::to_string(user_id), m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_ban_delete(snowflake guild_id, snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "bans/" + std::to_string(user_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_create(const class guild &g, command_completion_event_t callback) {
|
||||
rest_request<guild>(this, API_PATH "/guilds", "", "", m_post, g.build_json(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_delete(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "", m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_delete_integration(snowflake guild_id, snowflake integration_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "integrations/" + std::to_string(integration_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_edit(const class guild &g, command_completion_event_t callback) {
|
||||
rest_request<guild>(this, API_PATH "/guilds", std::to_string(g.id), "", m_patch, g.build_json(true), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_edit_widget(snowflake guild_id, const class guild_widget &gw, command_completion_event_t callback) {
|
||||
rest_request<guild_widget>(this, API_PATH "/guilds", std::to_string(guild_id), "widget", m_patch, gw.build_json(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_ban(snowflake guild_id, snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<ban>(this, API_PATH "/guilds", std::to_string(guild_id), "bans/" + std::to_string(user_id), m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_bans(snowflake guild_id, snowflake before, snowflake after, snowflake limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"before", before},
|
||||
{"after", after},
|
||||
{"limit", limit},
|
||||
});
|
||||
rest_request_list<ban>(this, API_PATH "/guilds", std::to_string(guild_id), "bans" + parameters, m_get, "", callback, "user_id");
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<guild>(this, API_PATH "/guilds", std::to_string(guild_id), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_integrations(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<integration>(this, API_PATH "/guilds", std::to_string(guild_id), "integrations", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_preview(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<guild>(this, API_PATH "/guilds", std::to_string(guild_id), "preview", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_vanity(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<invite>(this, API_PATH "/guilds", std::to_string(guild_id), "vanity-url", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_widget(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<guild_widget>(this, API_PATH "/guilds", std::to_string(guild_id), "widget", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_modify_integration(snowflake guild_id, const class integration &i, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "integrations/" + std::to_string(i.id), m_patch, i.build_json(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_prune_counts(snowflake guild_id, const struct prune& pruneinfo, command_completion_event_t callback) {
|
||||
rest_request<prune>(this, API_PATH "/guilds", std::to_string(guild_id), "prune", m_get, pruneinfo.build_json(false), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_begin_prune(snowflake guild_id, const struct prune& pruneinfo, command_completion_event_t callback) {
|
||||
rest_request<prune>(this, API_PATH "/guilds", std::to_string(guild_id), "prune", m_post, pruneinfo.build_json(true), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_set_nickname(snowflake guild_id, const std::string &nickname, command_completion_event_t callback) {
|
||||
std::string o = (nickname.empty() ? json({{"nick", json::value_t::null }}) : json({{"nick", nickname }})).dump();
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/@me/nick", m_patch, o, callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_sync_integration(snowflake guild_id, snowflake integration_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "integrations/" + std::to_string(integration_id), m_post, "", callback);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
149
vendor/DPP/src/dpp/cluster/guild_member.cpp
vendored
Normal file
149
vendor/DPP/src/dpp/cluster/guild_member.cpp
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::guild_add_member(const guild_member& gm, const std::string &access_token, command_completion_event_t callback) {
|
||||
json j = json::parse(gm.build_json());
|
||||
j["access_token"] = access_token;
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(gm.guild_id), "members/" + std::to_string(gm.user_id), m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_edit_member(const guild_member& gm, command_completion_event_t callback) {
|
||||
this->post_rest(API_PATH "/guilds", std::to_string(gm.guild_id), "members/" + std::to_string(gm.user_id), m_patch, gm.build_json(), [this, &gm, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, guild_member().fill_from_json(&j, gm.guild_id, gm.user_id), http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_member(snowflake guild_id, snowflake user_id, command_completion_event_t callback) {
|
||||
this->post_rest(API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id), m_get, "", [this, callback, guild_id, user_id](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, guild_member().fill_from_json(&j, guild_id, user_id), http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_members(snowflake guild_id, uint16_t limit, snowflake after, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"limit", std::to_string(limit)},
|
||||
{"after", std::to_string(after)},
|
||||
});
|
||||
this->post_rest(API_PATH "/guilds", std::to_string(guild_id), "members" + parameters, m_get, "", [this, callback, guild_id](json &j, const http_request_completion_t& http) {
|
||||
guild_member_map guild_members;
|
||||
confirmation_callback_t e(this, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
for (auto & curr_member : j) {
|
||||
if (curr_member.find("user") != curr_member.end()) {
|
||||
snowflake user_id = snowflake_not_null(&(curr_member["user"]), "id");
|
||||
guild_members[user_id] = guild_member().fill_from_json(&curr_member, guild_id, user_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, guild_members, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_member_add_role(snowflake guild_id, snowflake user_id, snowflake role_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id) + "/roles/" + std::to_string(role_id), m_put, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_member_delete(snowflake guild_id, snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_member_kick(snowflake guild_id, snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_member_timeout(snowflake guild_id, snowflake user_id, time_t communication_disabled_until, command_completion_event_t callback) {
|
||||
json j;
|
||||
if (communication_disabled_until > 0) {
|
||||
j["communication_disabled_until"] = ts_to_string(communication_disabled_until);
|
||||
} else {
|
||||
j["communication_disabled_until"] = json::value_t::null;
|
||||
}
|
||||
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id), m_patch, j.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_member_delete_role(snowflake guild_id, snowflake user_id, snowflake role_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id) + "/roles/" + std::to_string(role_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_member_remove_role(snowflake guild_id, snowflake user_id, snowflake role_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id) + "/roles/" + std::to_string(role_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_member_move(const snowflake channel_id, const snowflake guild_id, const snowflake user_id, command_completion_event_t callback) {
|
||||
json j;
|
||||
if (channel_id) {
|
||||
j["channel_id"] = channel_id;
|
||||
}
|
||||
else {
|
||||
j["channel_id"] = json::value_t::null;
|
||||
}
|
||||
|
||||
this->post_rest(API_PATH "/guilds", std::to_string(guild_id), "members/" + std::to_string(user_id), m_patch, j.dump(), [this, guild_id, user_id, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, guild_member().fill_from_json(&j, guild_id, user_id), http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_search_members(snowflake guild_id, const std::string& query, uint16_t limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"query", query},
|
||||
{"limit", std::to_string(limit)},
|
||||
});
|
||||
this->post_rest(API_PATH "/guilds", std::to_string(guild_id), "members/search" + parameters, m_get, "", [this, callback, guild_id] (json &j, const http_request_completion_t& http) {
|
||||
guild_member_map guild_members;
|
||||
confirmation_callback_t e(this, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
for (auto & curr_member : j) {
|
||||
if (curr_member.find("user") != curr_member.end()) {
|
||||
snowflake user_id = snowflake_not_null(&(curr_member["user"]), "id");
|
||||
guild_members[user_id] = guild_member().fill_from_json(&curr_member, guild_id, user_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, guild_members, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
38
vendor/DPP/src/dpp/cluster/invite.cpp
vendored
Normal file
38
vendor/DPP/src/dpp/cluster/invite.cpp
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::guild_get_invites(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<invite>(this, API_PATH "/guilds", std::to_string(guild_id), "invites", m_get, "", callback, "code");
|
||||
}
|
||||
|
||||
void cluster::invite_delete(const std::string &invitecode, command_completion_event_t callback) {
|
||||
rest_request<invite>(this, API_PATH "/invites", utility::url_encode(invitecode), "", m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::invite_get(const std::string &invitecode, command_completion_event_t callback) {
|
||||
rest_request<invite>(this, API_PATH "/invites", utility::url_encode(invitecode) + "?with_counts=true&with_expiration=true", "", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
28
vendor/DPP/src/dpp/cluster/json_interface.cpp
vendored
Normal file
28
vendor/DPP/src/dpp/cluster/json_interface.cpp
vendored
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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#include <dpp/json_interface.h>
|
||||
#include <dpp/exception.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
|
||||
};
|
||||
169
vendor/DPP/src/dpp/cluster/message.cpp
vendored
Normal file
169
vendor/DPP/src/dpp/cluster/message.cpp
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::message_add_reaction(const struct message &m, const std::string &reaction, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(m.channel_id), "messages/" + std::to_string(m.id) + "/reactions/" + utility::url_encode(reaction) + "/@me", m_put, "", callback);
|
||||
}
|
||||
|
||||
void cluster::message_add_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction, command_completion_event_t callback) {
|
||||
message m(channel_id, "");
|
||||
m.id = message_id;
|
||||
message_add_reaction(m, reaction, callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void cluster::message_create(const message &m, command_completion_event_t callback) {
|
||||
this->post_rest_multipart(API_PATH "/channels", std::to_string(m.channel_id), "messages", m_post, m.build_json(), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_crosspost(snowflake message_id, snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request<message>(this, API_PATH "/channels", std::to_string(channel_id), "messages/" + std::to_string(message_id) + "/crosspost", m_post, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_delete_all_reactions(const struct message &m, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(m.channel_id), "messages/" + std::to_string(m.id) + "/reactions", m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::message_delete_all_reactions(snowflake message_id, snowflake channel_id, command_completion_event_t callback) {
|
||||
message m(channel_id, "");
|
||||
m.id = message_id;
|
||||
m.owner = this;
|
||||
message_delete_all_reactions(m, callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_delete_bulk(const std::vector<snowflake>& message_ids, snowflake channel_id, command_completion_event_t callback) {
|
||||
json j;
|
||||
for (auto & m : message_ids) {
|
||||
j["messages"].push_back(std::to_string(m));
|
||||
}
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "messages/bulk-delete", m_post, j.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_delete(snowflake message_id, snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "messages/" + std::to_string(message_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_delete_own_reaction(const struct message &m, const std::string &reaction, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(m.channel_id), "messages/" + std::to_string(m.id) + "/reactions/" + utility::url_encode(reaction) + "/@me", m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::message_delete_own_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction, command_completion_event_t callback) {
|
||||
message m(channel_id, "");
|
||||
m.id = message_id;
|
||||
m.owner = this;
|
||||
message_delete_own_reaction(m, reaction, callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_delete_reaction(const struct message &m, snowflake user_id, const std::string &reaction, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(m.channel_id), "messages/" + std::to_string(m.id) + "/reactions/" + utility::url_encode(reaction) + "/" + std::to_string(user_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::message_delete_reaction(snowflake message_id, snowflake channel_id, snowflake user_id, const std::string &reaction, command_completion_event_t callback) {
|
||||
message m(channel_id, "");
|
||||
m.id = message_id;
|
||||
m.owner = this;
|
||||
message_delete_reaction(m, user_id, reaction, callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_delete_reaction_emoji(const struct message &m, const std::string &reaction, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(m.channel_id), "messages/" + std::to_string(m.id) + "/reactions/" + utility::url_encode(reaction), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::message_delete_reaction_emoji(snowflake message_id, snowflake channel_id, const std::string &reaction, command_completion_event_t callback) {
|
||||
message m(channel_id, "");
|
||||
m.id = message_id;
|
||||
m.owner = this;
|
||||
message_delete_reaction_emoji(m, reaction, callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_edit(const message &m, command_completion_event_t callback) {
|
||||
this->post_rest_multipart(API_PATH "/channels", std::to_string(m.channel_id), "messages/" + std::to_string(m.id), m_patch, m.build_json(true), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_get(snowflake message_id, snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request<message>(this, API_PATH "/channels", std::to_string(channel_id), "messages/" + std::to_string(message_id), m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_get_reactions(const struct message &m, const std::string &reaction, snowflake before, snowflake after, snowflake limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"before", before},
|
||||
{"after", after},
|
||||
{"limit", limit},
|
||||
});
|
||||
rest_request_list<user>(this, API_PATH "/channels", std::to_string(m.channel_id), "messages/" + std::to_string(m.id) + "/reactions/" + utility::url_encode(reaction) + parameters, m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::message_get_reactions(snowflake message_id, snowflake channel_id, const std::string &reaction, snowflake before, snowflake after, snowflake limit, command_completion_event_t callback) {
|
||||
message m(channel_id, "");
|
||||
m.id = message_id;
|
||||
m.owner = this;
|
||||
message_get_reactions(m, reaction, before, after, limit, callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_pin(snowflake channel_id, snowflake message_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "pins/" + std::to_string(message_id), m_put, "", callback);
|
||||
}
|
||||
|
||||
void cluster::messages_get(snowflake channel_id, snowflake around, snowflake before, snowflake after, uint64_t limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"around", around},
|
||||
{"before", before},
|
||||
{"after", after},
|
||||
{"limit", limit > 100 ? 100 : limit},
|
||||
});
|
||||
rest_request_list<message>(this, API_PATH "/channels", std::to_string(channel_id), "messages" + parameters, m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::message_unpin(snowflake channel_id, snowflake message_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(channel_id), "pins/" + std::to_string(message_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::channel_pins_get(snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request_list<message>(this, API_PATH "/channels", std::to_string(channel_id), "pins", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
73
vendor/DPP/src/dpp/cluster/role.cpp
vendored
Normal file
73
vendor/DPP/src/dpp/cluster/role.cpp
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/role.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::role_create(const class role &r, command_completion_event_t callback) {
|
||||
rest_request<role>(this, API_PATH "/guilds", std::to_string(r.guild_id), "roles", m_post, r.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::role_delete(snowflake guild_id, snowflake role_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "roles/" + std::to_string(role_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::role_edit(const class role &r, command_completion_event_t callback) {
|
||||
rest_request<role>(this, API_PATH "/guilds", std::to_string(r.guild_id), "roles/" + std::to_string(r.id) , m_patch, r.build_json(true), callback);
|
||||
}
|
||||
|
||||
void cluster::roles_edit_position(snowflake guild_id, const std::vector<role> &roles, command_completion_event_t callback) {
|
||||
if (roles.empty()) {
|
||||
return;
|
||||
}
|
||||
json j = json::array();
|
||||
for (auto & r : roles) {
|
||||
j.push_back({ {"id", r.id}, {"position", r.position} });
|
||||
}
|
||||
rest_request_list<role>(this, API_PATH "/guilds", std::to_string(guild_id), "roles", m_patch, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::roles_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<role>(this, API_PATH "/guilds", std::to_string(guild_id), "roles", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::application_role_connection_get(snowflake application_id, command_completion_event_t callback) {
|
||||
rest_request_vector<application_role_connection_metadata>(this, API_PATH "/applications", std::to_string(application_id), "role-connections/metadata", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::application_role_connection_update(snowflake application_id, const std::vector<application_role_connection_metadata> &connection_metadata, command_completion_event_t callback) {
|
||||
json j = json::array();
|
||||
for (const auto &conn_metadata : connection_metadata) {
|
||||
j.push_back(json::parse(conn_metadata.build_json()));
|
||||
}
|
||||
rest_request_vector<application_role_connection_metadata>(this, API_PATH "/applications", std::to_string(application_id), "role-connections/metadata", m_put, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::user_application_role_connection_get(snowflake application_id, command_completion_event_t callback) {
|
||||
rest_request<application_role_connection>(this, API_PATH "/users/@me/applications", std::to_string(application_id), "role-connection", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::user_application_role_connection_update(snowflake application_id, const application_role_connection &connection, command_completion_event_t callback) {
|
||||
rest_request<application_role_connection>(this, API_PATH "/users/@me/applications", std::to_string(application_id), "role-connection", m_put, connection.build_json(), callback);
|
||||
}
|
||||
|
||||
};
|
||||
71
vendor/DPP/src/dpp/cluster/scheduled_event.cpp
vendored
Normal file
71
vendor/DPP/src/dpp/cluster/scheduled_event.cpp
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/scheduled_event.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::guild_events_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<scheduled_event>(this, API_PATH "/guilds", std::to_string(guild_id), "/scheduled-events?with_user_count=true", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_event_users_get(snowflake guild_id, snowflake event_id, command_completion_event_t callback, uint8_t limit, snowflake before, snowflake after) {
|
||||
std::string append = utility::make_url_parameters({
|
||||
{"before", before},
|
||||
{"after", after},
|
||||
});
|
||||
this->post_rest(API_PATH "/guilds", std::to_string(guild_id), "/scheduled-events/" + std::to_string(event_id) + "/users?with_member=true&limit=" + std::to_string(limit) + append, m_get, "", [this, callback, guild_id](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
event_member_map users;
|
||||
confirmation_callback_t e(this, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
if (j.is_array()) {
|
||||
for (auto & curr_user : j) {
|
||||
event_member e;
|
||||
e.user = user().fill_from_json(&(curr_user["user"]));
|
||||
e.member = guild_member().fill_from_json(&(curr_user["user"]), guild_id, e.user.id);
|
||||
e.guild_scheduled_event_id = snowflake_not_null(&curr_user, "guild_scheduled_event_id");
|
||||
users[e.user.id] = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(confirmation_callback_t(this, users, http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void cluster::guild_event_create(const scheduled_event& event, command_completion_event_t callback) {
|
||||
rest_request<scheduled_event>(this, API_PATH "/guilds", std::to_string(event.guild_id), "/scheduled-events", m_post, event.build_json(false), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_event_delete(snowflake event_id, snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "/scheduled-events/" + std::to_string(event_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_event_edit(const scheduled_event& event, command_completion_event_t callback) {
|
||||
rest_request<scheduled_event>(this, API_PATH "/guilds", std::to_string(event.guild_id), "/scheduled-events/" + std::to_string(event.id), m_patch, event.build_json(true), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_event_get(snowflake guild_id, snowflake event_id, command_completion_event_t callback) {
|
||||
rest_request<scheduled_event>(this, API_PATH "/guilds", std::to_string(guild_id), "/scheduled-events/" + std::to_string(event_id) + "?with_user_count=true", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
42
vendor/DPP/src/dpp/cluster/stage_instance.cpp
vendored
Normal file
42
vendor/DPP/src/dpp/cluster/stage_instance.cpp
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/stage_instance.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::stage_instance_create(const stage_instance& si, command_completion_event_t callback) {
|
||||
rest_request<stage_instance>(this, API_PATH "/stage-instances", "", "", m_post, si.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::stage_instance_get(const snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request<stage_instance>(this, API_PATH "/stage-instances", std::to_string(channel_id), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::stage_instance_edit(const stage_instance& si, command_completion_event_t callback) {
|
||||
rest_request<stage_instance>(this, API_PATH "/stage-instances", std::to_string(si.channel_id), "", m_patch, si.build_json(), callback);
|
||||
}
|
||||
|
||||
void cluster::stage_instance_delete(const snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/stage-instances", std::to_string(channel_id), "", m_delete, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
58
vendor/DPP/src/dpp/cluster/sticker.cpp
vendored
Normal file
58
vendor/DPP/src/dpp/cluster/sticker.cpp
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::guild_sticker_create(sticker &s, command_completion_event_t callback) {
|
||||
this->post_rest(API_PATH "/guilds", std::to_string(s.guild_id), "stickers", m_post, s.build_json(false), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, sticker().fill_from_json(&j), http));
|
||||
}
|
||||
}, s.filename, s.filecontent);
|
||||
}
|
||||
|
||||
void cluster::guild_sticker_delete(snowflake sticker_id, snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "stickers/" + std::to_string(sticker_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_sticker_get(snowflake id, snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<sticker>(this, API_PATH "/guilds", std::to_string(guild_id), "stickers/" + std::to_string(id), m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::guild_sticker_modify(sticker &s, command_completion_event_t callback) {
|
||||
rest_request<sticker>(this, API_PATH "/guilds", std::to_string(s.guild_id), "stickers/" + std::to_string(s.id), m_patch, s.build_json(true), callback);
|
||||
}
|
||||
|
||||
void cluster::guild_stickers_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<sticker>(this, API_PATH "/guilds", std::to_string(guild_id), "stickers", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::nitro_sticker_get(snowflake id, command_completion_event_t callback) {
|
||||
rest_request<sticker>(this, API_PATH "/stickers", std::to_string(id), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::sticker_packs_get(command_completion_event_t callback) {
|
||||
rest_request_list<sticker_pack>(this, API_PATH "/sticker-packs", "", "", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
63
vendor/DPP/src/dpp/cluster/template.cpp
vendored
Normal file
63
vendor/DPP/src/dpp/cluster/template.cpp
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/dtemplate.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::guild_create_from_template(const std::string &code, const std::string &name, command_completion_event_t callback) {
|
||||
json params({{"name", name}});
|
||||
rest_request<guild>(this, API_PATH "/guilds", "templates", code, m_post, params.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_template_create(snowflake guild_id, const std::string &name, const std::string &description, command_completion_event_t callback) {
|
||||
json params({{"name", name}, {"description", description}});
|
||||
rest_request<dtemplate>(this, API_PATH "/guilds", std::to_string(guild_id), "templates", m_post, params.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_template_delete(snowflake guild_id, const std::string &code, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "templates/" + code, m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_template_modify(snowflake guild_id, const std::string &code, const std::string &name, const std::string &description, command_completion_event_t callback) {
|
||||
json params({{"name", name}, {"description", description}});
|
||||
rest_request<dtemplate>(this, API_PATH "/guilds", std::to_string(guild_id), "templates/" + code, m_patch, params.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_templates_get(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<dtemplate>(this, API_PATH "/guilds", std::to_string(guild_id), "templates", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_template_sync(snowflake guild_id, const std::string &code, command_completion_event_t callback) {
|
||||
rest_request<dtemplate>(this, API_PATH "/guilds", std::to_string(guild_id), "templates/" + code, m_put, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::template_get(const std::string &code, command_completion_event_t callback) {
|
||||
rest_request<dtemplate>(this, API_PATH "/guilds", "templates", code, m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
136
vendor/DPP/src/dpp/cluster/thread.cpp
vendored
Normal file
136
vendor/DPP/src/dpp/cluster/thread.cpp
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::current_user_join_thread(snowflake thread_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(thread_id), "/thread-members/@me", m_put, "", callback);
|
||||
}
|
||||
|
||||
void cluster::current_user_leave_thread(snowflake thread_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(thread_id), "/thread-members/@me", m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::threads_get_active(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<thread>(this, API_PATH "/guilds", std::to_string(guild_id), "/threads/active", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::threads_get_joined_private_archived(snowflake channel_id, snowflake before_id, uint16_t limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"before", before_id},
|
||||
{"limit", limit},
|
||||
});
|
||||
rest_request_list<thread>(this, API_PATH "/channels", std::to_string(channel_id), "/users/@me/threads/archived/private" + parameters, m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::threads_get_private_archived(snowflake channel_id, time_t before_timestamp, uint16_t limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"before", before_timestamp},
|
||||
{"limit", limit},
|
||||
});
|
||||
rest_request_list<thread>(this, API_PATH "/channels", std::to_string(channel_id), "/threads/archived/private" + parameters, m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::threads_get_public_archived(snowflake channel_id, time_t before_timestamp, uint16_t limit, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"before", before_timestamp},
|
||||
{"limit", limit},
|
||||
});
|
||||
rest_request_list<thread>(this, API_PATH "/channels", std::to_string(channel_id), "/threads/archived/public" + parameters, m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::thread_member_get(const snowflake thread_id, const snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<thread_member>(this, API_PATH "/channels", std::to_string(thread_id), "/threads-members/" + std::to_string(user_id), m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::thread_members_get(snowflake thread_id, command_completion_event_t callback) {
|
||||
rest_request_list<thread_member>(this, API_PATH "/channels", std::to_string(thread_id), "/threads-members", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::thread_create_in_forum(const std::string& thread_name, snowflake channel_id, const message& msg, auto_archive_duration_t auto_archive_duration, uint16_t rate_limit_per_user, std::vector<snowflake> applied_tags, command_completion_event_t callback)
|
||||
{
|
||||
json j({
|
||||
{"name", thread_name},
|
||||
{"rate_limit_per_user", rate_limit_per_user},
|
||||
{"message", json::parse(msg.build_json())},
|
||||
{"applied_tags", applied_tags},
|
||||
});
|
||||
switch (auto_archive_duration) {
|
||||
case arc_1_hour:
|
||||
j["auto_archive_duration"] = 60;
|
||||
break;
|
||||
case arc_1_day:
|
||||
j["auto_archive_duration"] = 1440;
|
||||
break;
|
||||
case arc_3_days:
|
||||
j["auto_archive_duration"] = 4320;
|
||||
break;
|
||||
case arc_1_week:
|
||||
j["auto_archive_duration"] = 10080;
|
||||
break;
|
||||
}
|
||||
this->post_rest_multipart(API_PATH "/channels", std::to_string(channel_id), "threads", m_post, j.dump(), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
auto t = thread().fill_from_json(&j);
|
||||
confirmation_callback_t e(this, confirmation(), http);
|
||||
if (!e.is_error()) {
|
||||
if (j.contains("message")) {
|
||||
t.msg = message().fill_from_json(&(j["message"]));
|
||||
}
|
||||
}
|
||||
callback(confirmation_callback_t(this, t, http));
|
||||
}
|
||||
}, msg.filename, msg.filecontent);
|
||||
}
|
||||
|
||||
void cluster::thread_create(const std::string& thread_name, snowflake channel_id, uint16_t auto_archive_duration, channel_type thread_type, bool invitable, uint16_t rate_limit_per_user, command_completion_event_t callback)
|
||||
{
|
||||
json j({
|
||||
{"name", thread_name},
|
||||
{"auto_archive_duration", auto_archive_duration},
|
||||
{"type", thread_type},
|
||||
{"invitable", invitable},
|
||||
{"rate_limit_per_user", rate_limit_per_user}
|
||||
});
|
||||
rest_request<thread>(this, API_PATH "/channels", std::to_string(channel_id), "threads", m_post, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::thread_create_with_message(const std::string& thread_name, snowflake channel_id, snowflake message_id, uint16_t auto_archive_duration, uint16_t rate_limit_per_user, command_completion_event_t callback)
|
||||
{
|
||||
json j({
|
||||
{"name", thread_name},
|
||||
{"auto_archive_duration", auto_archive_duration},
|
||||
{"rate_limit_per_user", rate_limit_per_user}
|
||||
});
|
||||
rest_request<thread>(this, API_PATH "/channels", std::to_string(channel_id), "messages/" + std::to_string(message_id) + "/threads", m_post, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::thread_member_add(snowflake thread_id, snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(thread_id), "/thread-members/" + std::to_string(user_id), m_put, "", callback);
|
||||
}
|
||||
|
||||
void cluster::thread_member_remove(snowflake thread_id, snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/channels", std::to_string(thread_id), "/thread-members/" + std::to_string(user_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
127
vendor/DPP/src/dpp/cluster/timer.cpp
vendored
Normal file
127
vendor/DPP/src/dpp/cluster/timer.cpp
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/timer.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
timer lasthandle = 1;
|
||||
std::mutex timer_guard;
|
||||
|
||||
timer cluster::start_timer(timer_callback_t on_tick, uint64_t frequency, timer_callback_t on_stop) {
|
||||
std::lock_guard<std::mutex> l(timer_guard);
|
||||
timer_t* newtimer = new timer_t();
|
||||
|
||||
newtimer->handle = lasthandle++;
|
||||
newtimer->next_tick = time(nullptr) + frequency;
|
||||
newtimer->on_tick = on_tick;
|
||||
newtimer->on_stop = on_stop;
|
||||
newtimer->frequency = frequency;
|
||||
timer_list[newtimer->handle] = newtimer;
|
||||
next_timer.emplace(newtimer->next_tick, newtimer);
|
||||
|
||||
return newtimer->handle;
|
||||
}
|
||||
|
||||
bool cluster::stop_timer(timer t) {
|
||||
std::lock_guard<std::mutex> l(timer_guard);
|
||||
|
||||
auto i = timer_list.find(t);
|
||||
if (i != timer_list.end()) {
|
||||
timer_t* tptr = i->second;
|
||||
if (tptr->on_stop) {
|
||||
/* If there is an on_stop event, call it */
|
||||
tptr->on_stop(t);
|
||||
}
|
||||
timer_list.erase(i);
|
||||
auto j = next_timer.find(tptr->next_tick);
|
||||
if (j != next_timer.end()) {
|
||||
next_timer.erase(j);
|
||||
}
|
||||
delete tptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cluster::timer_reschedule(timer_t* t) {
|
||||
std::lock_guard<std::mutex> l(timer_guard);
|
||||
for (auto i = next_timer.begin(); i != next_timer.end(); ++i) {
|
||||
/* Rescheduling the timer means finding it in the next tick map.
|
||||
* It should be pretty much near the start of the map so this loop
|
||||
* should only be at most a handful of iterations.
|
||||
*/
|
||||
if (i->second->handle == t->handle) {
|
||||
next_timer.erase(i);
|
||||
t->next_tick = time(nullptr) + t->frequency;
|
||||
next_timer.emplace(t->next_tick, t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cluster::tick_timers() {
|
||||
std::vector<timer_t*> scheduled;
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
std::lock_guard<std::mutex> l(timer_guard);
|
||||
for (auto i = next_timer.begin(); i != next_timer.end(); ++i) {
|
||||
if (now >= i->second->next_tick) {
|
||||
scheduled.push_back(i->second);
|
||||
} else {
|
||||
/* The first time we encounter an entry which is not due,
|
||||
* we can bail out, because std::map is ordered storage so
|
||||
* we know at this point no more will match either.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto & t : scheduled) {
|
||||
/* Call handler */
|
||||
t->on_tick(t->handle);
|
||||
/* Reschedule for next tick */
|
||||
timer_reschedule(t);
|
||||
}
|
||||
}
|
||||
|
||||
oneshot_timer::oneshot_timer(class cluster* cl, uint64_t duration, timer_callback_t callback) : owner(cl) {
|
||||
/* Create timer */
|
||||
th = cl->start_timer([callback, this](dpp::timer timer_handle) {
|
||||
callback(this->get_handle());
|
||||
this->owner->stop_timer(this->th);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
timer oneshot_timer::get_handle() {
|
||||
return this->th;
|
||||
}
|
||||
|
||||
void oneshot_timer::cancel() {
|
||||
owner->stop_timer(this->th);
|
||||
}
|
||||
|
||||
oneshot_timer::~oneshot_timer() {
|
||||
cancel();
|
||||
}
|
||||
|
||||
};
|
||||
115
vendor/DPP/src/dpp/cluster/user.cpp
vendored
Normal file
115
vendor/DPP/src/dpp/cluster/user.cpp
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/exception.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::current_user_edit(const std::string &nickname, const std::string& image_blob, const image_type type, command_completion_event_t callback) {
|
||||
json j = json::parse("{\"nickname\": null}");
|
||||
if (!nickname.empty()) {
|
||||
j["nickname"] = nickname;
|
||||
}
|
||||
if (!image_blob.empty()) {
|
||||
static const std::map<image_type, std::string> mimetypes = {
|
||||
{ i_gif, "image/gif" },
|
||||
{ i_jpg, "image/jpeg" },
|
||||
{ i_png, "image/png" },
|
||||
{ i_webp, "image/webp" },
|
||||
};
|
||||
if (image_blob.size() > MAX_EMOJI_SIZE) {
|
||||
throw dpp::length_exception("User icon file exceeds discord limit of 256 kilobytes");
|
||||
}
|
||||
j["avatar"] = "data:" + mimetypes.find(type)->second + ";base64," + base64_encode((unsigned char const*)image_blob.data(), (unsigned int)image_blob.length());
|
||||
}
|
||||
rest_request<user>(this, API_PATH "/users", "@me", "", m_patch, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::current_application_get(command_completion_event_t callback) {
|
||||
rest_request<application>(this, API_PATH "/oauth2/applications", "@me", "", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::current_user_get(command_completion_event_t callback) {
|
||||
rest_request<user_identified>(this, API_PATH "/users", "@me", "", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::current_user_set_voice_state(snowflake guild_id, snowflake channel_id, bool suppress, time_t request_to_speak_timestamp, command_completion_event_t callback) {
|
||||
json j({
|
||||
{"channel_id", channel_id},
|
||||
{"suppress", suppress}
|
||||
});
|
||||
if (request_to_speak_timestamp) {
|
||||
if (request_to_speak_timestamp < time(nullptr)) {
|
||||
throw dpp::logic_exception("Cannot set voice state request to speak timestamp to before current time");
|
||||
}
|
||||
j["request_to_speak_timestamp"] = ts_to_string(request_to_speak_timestamp);
|
||||
} else {
|
||||
j["request_to_speak_timestamp"] = json::value_t::null;
|
||||
}
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "/voice-states/@me", m_patch, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::user_set_voice_state(snowflake user_id, snowflake guild_id, snowflake channel_id, bool suppress, command_completion_event_t callback) {
|
||||
json j({
|
||||
{"channel_id", channel_id},
|
||||
{"suppress", suppress}
|
||||
});
|
||||
rest_request<confirmation>(this, API_PATH "/guilds", std::to_string(guild_id), "/voice-states/" + std::to_string(user_id), m_patch, j.dump(), callback);
|
||||
}
|
||||
|
||||
void cluster::current_user_connections_get(command_completion_event_t callback) {
|
||||
rest_request_list<connection>(this, API_PATH "/users", "@me", "connections", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::current_user_get_guilds(command_completion_event_t callback) {
|
||||
rest_request_list<guild>(this, API_PATH "/users", "@me", "guilds", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::current_user_leave_guild(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/users", "@me", "guilds/" + std::to_string(guild_id), m_delete, "", callback);
|
||||
}
|
||||
|
||||
void cluster::user_get(snowflake user_id, command_completion_event_t callback) {
|
||||
rest_request<user_identified>(this, API_PATH "/users", std::to_string(user_id), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
void cluster::user_get_cached(snowflake user_id, command_completion_event_t callback) {
|
||||
user* u = find_user(user_id);
|
||||
if (u) {
|
||||
/* We can't simply down-cast to user_identified with dynamic_cast,
|
||||
* this will cause a segmentation fault. We have to re-build the more complex
|
||||
* user_identified from a user, by calling a constructor that builds it from
|
||||
* the user object.
|
||||
*/
|
||||
confirmation_callback_t cb(
|
||||
this,
|
||||
user_identified(*u),
|
||||
http_request_completion_t()
|
||||
);
|
||||
callback(cb);
|
||||
return;
|
||||
}
|
||||
/* If the user isn't in the cache, make the API call */
|
||||
rest_request<user_identified>(this, API_PATH "/users", std::to_string(user_id), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
35
vendor/DPP/src/dpp/cluster/voice.cpp
vendored
Normal file
35
vendor/DPP/src/dpp/cluster/voice.cpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/voiceregion.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::get_voice_regions(command_completion_event_t callback) {
|
||||
rest_request_list<voiceregion>(this, "/voice/v9/regions", "", "", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::guild_get_voice_regions(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<voiceregion>(this, API_PATH "/guilds", std::to_string(guild_id), "regions", m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
129
vendor/DPP/src/dpp/cluster/webhook.cpp
vendored
Normal file
129
vendor/DPP/src/dpp/cluster/webhook.cpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/webhook.h>
|
||||
#include <dpp/restrequest.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
void cluster::create_webhook(const class webhook &w, command_completion_event_t callback) {
|
||||
rest_request<webhook>(this, API_PATH "/channels", std::to_string(w.channel_id), "webhooks", m_post, w.build_json(false), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::delete_webhook(snowflake webhook_id, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/webhooks", std::to_string(webhook_id), "", m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::delete_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"thread_id", thread_id},
|
||||
});
|
||||
rest_request<confirmation>(this, API_PATH "/webhooks", std::to_string(wh.id), utility::url_encode(!wh.token.empty() ? wh.token: token) + "/messages/" + std::to_string(message_id) + parameters, m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::delete_webhook_with_token(snowflake webhook_id, const std::string &token, command_completion_event_t callback) {
|
||||
rest_request<confirmation>(this, API_PATH "/webhooks", std::to_string(webhook_id), utility::url_encode(token), m_delete, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::edit_webhook(const class webhook& wh, command_completion_event_t callback) {
|
||||
rest_request<webhook>(this, API_PATH "/webhooks", std::to_string(wh.id), "", m_patch, wh.build_json(false), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::edit_webhook_message(const class webhook &wh, const struct message& m, snowflake thread_id, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"thread_id", thread_id},
|
||||
});
|
||||
this->post_rest_multipart(API_PATH "/webhooks", std::to_string(wh.id), utility::url_encode(!wh.token.empty() ? wh.token: token) + "/messages/" + std::to_string(m.id) + parameters, m_patch, m.build_json(false), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
|
||||
void cluster::edit_webhook_with_token(const class webhook& wh, command_completion_event_t callback) {
|
||||
json jwh = json::parse(wh.build_json(true));
|
||||
if (jwh.find("channel_id") != jwh.end()) {
|
||||
jwh.erase(jwh.find("channel_id"));
|
||||
}
|
||||
rest_request<webhook>(this, API_PATH "/webhooks", std::to_string(wh.id), utility::url_encode(wh.token), m_patch, jwh.dump(), callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::execute_webhook(const class webhook &wh, const struct message& m, bool wait, snowflake thread_id, const std::string& thread_name, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"wait", wait},
|
||||
{"thread_id", thread_id},
|
||||
});
|
||||
std::string body;
|
||||
if (!thread_name.empty() || !wh.avatar.empty() || !wh.name.empty()) { // only use json::parse if thread_name is set
|
||||
json j = json::parse(m.build_json(false));
|
||||
if (!thread_name.empty()) {
|
||||
j["thread_name"] = thread_name;
|
||||
}
|
||||
if (!wh.avatar.empty()) {
|
||||
j["avatar_url"] = wh.avatar;
|
||||
}
|
||||
if (!wh.name.empty()) {
|
||||
j["username"] = wh.name;
|
||||
}
|
||||
body = j.dump();
|
||||
}
|
||||
this->post_rest_multipart(API_PATH "/webhooks", std::to_string(wh.id), utility::url_encode(!wh.token.empty() ? wh.token : token) + parameters, m_post, !body.empty() ? body : m.build_json(false), [this, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
|
||||
void cluster::get_channel_webhooks(snowflake channel_id, command_completion_event_t callback) {
|
||||
rest_request_list<webhook>(this, API_PATH "/channels", std::to_string(channel_id), "webhooks", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::get_guild_webhooks(snowflake guild_id, command_completion_event_t callback) {
|
||||
rest_request_list<webhook>(this, API_PATH "/guilds", std::to_string(guild_id), "webhooks", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::get_webhook(snowflake webhook_id, command_completion_event_t callback) {
|
||||
rest_request<webhook>(this, API_PATH "/webhooks", std::to_string(webhook_id), "", m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::get_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id, command_completion_event_t callback) {
|
||||
std::string parameters = utility::make_url_parameters({
|
||||
{"thread_id", thread_id},
|
||||
});
|
||||
rest_request<message>(this, API_PATH "/webhooks", std::to_string(wh.id), utility::url_encode(!wh.token.empty() ? wh.token: token) + "/messages/" + std::to_string(message_id) + parameters, m_get, "", callback);
|
||||
}
|
||||
|
||||
|
||||
void cluster::get_webhook_with_token(snowflake webhook_id, const std::string &token, command_completion_event_t callback) {
|
||||
rest_request<webhook>(this, API_PATH "/webhooks", std::to_string(webhook_id), utility::url_encode(token), m_get, "", callback);
|
||||
}
|
||||
|
||||
};
|
||||
691
vendor/DPP/src/dpp/cluster_sync_calls.cpp
vendored
Normal file
691
vendor/DPP/src/dpp/cluster_sync_calls.cpp
vendored
Normal file
@@ -0,0 +1,691 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* D++, A Lightweight C++ library for Discord
|
||||
*
|
||||
* Copyright 2022 Craig Edwards and D++ contributors
|
||||
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
|
||||
/* Auto @generated by buildtools/make_sync_struct.php.
|
||||
*
|
||||
* DO NOT EDIT BY HAND!
|
||||
*
|
||||
* To re-generate this header file re-run the script!
|
||||
*/
|
||||
|
||||
#include <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/cluster.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
slashcommand_map cluster::global_bulk_command_create_sync(const std::vector<slashcommand> &commands) {
|
||||
return dpp::sync<slashcommand_map>(this, &cluster::global_bulk_command_create, commands);
|
||||
}
|
||||
|
||||
slashcommand cluster::global_command_create_sync(const slashcommand &s) {
|
||||
return dpp::sync<slashcommand>(this, &cluster::global_command_create, s);
|
||||
}
|
||||
|
||||
slashcommand cluster::global_command_get_sync(snowflake id) {
|
||||
return dpp::sync<slashcommand>(this, &cluster::global_command_get, id);
|
||||
}
|
||||
|
||||
confirmation cluster::global_command_delete_sync(snowflake id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::global_command_delete, id);
|
||||
}
|
||||
|
||||
confirmation cluster::global_command_edit_sync(const slashcommand &s) {
|
||||
return dpp::sync<confirmation>(this, &cluster::global_command_edit, s);
|
||||
}
|
||||
|
||||
slashcommand_map cluster::global_commands_get_sync() {
|
||||
return dpp::sync<slashcommand_map>(this, &cluster::global_commands_get);
|
||||
}
|
||||
|
||||
slashcommand_map cluster::guild_bulk_command_create_sync(const std::vector<slashcommand> &commands, snowflake guild_id) {
|
||||
return dpp::sync<slashcommand_map>(this, &cluster::guild_bulk_command_create, commands, guild_id);
|
||||
}
|
||||
|
||||
guild_command_permissions_map cluster::guild_commands_get_permissions_sync(snowflake guild_id) {
|
||||
return dpp::sync<guild_command_permissions_map>(this, &cluster::guild_commands_get_permissions, guild_id);
|
||||
}
|
||||
|
||||
guild_command_permissions_map cluster::guild_bulk_command_edit_permissions_sync(const std::vector<slashcommand> &commands, snowflake guild_id) {
|
||||
return dpp::sync<guild_command_permissions_map>(this, &cluster::guild_bulk_command_edit_permissions, commands, guild_id);
|
||||
}
|
||||
|
||||
slashcommand cluster::guild_command_create_sync(const slashcommand &s, snowflake guild_id) {
|
||||
return dpp::sync<slashcommand>(this, &cluster::guild_command_create, s, guild_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_command_delete_sync(snowflake id, snowflake guild_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_command_delete, id, guild_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_command_edit_permissions_sync(const slashcommand &s, snowflake guild_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_command_edit_permissions, s, guild_id);
|
||||
}
|
||||
|
||||
slashcommand cluster::guild_command_get_sync(snowflake id, snowflake guild_id) {
|
||||
return dpp::sync<slashcommand>(this, &cluster::guild_command_get, id, guild_id);
|
||||
}
|
||||
|
||||
guild_command_permissions cluster::guild_command_get_permissions_sync(snowflake id, snowflake guild_id) {
|
||||
return dpp::sync<guild_command_permissions>(this, &cluster::guild_command_get_permissions, id, guild_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_command_edit_sync(const slashcommand &s, snowflake guild_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_command_edit, s, guild_id);
|
||||
}
|
||||
|
||||
slashcommand_map cluster::guild_commands_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<slashcommand_map>(this, &cluster::guild_commands_get, guild_id);
|
||||
}
|
||||
|
||||
confirmation cluster::interaction_response_create_sync(snowflake interaction_id, const std::string &token, const interaction_response &r) {
|
||||
return dpp::sync<confirmation>(this, &cluster::interaction_response_create, interaction_id, token, r);
|
||||
}
|
||||
|
||||
confirmation cluster::interaction_response_edit_sync(const std::string &token, const message &m) {
|
||||
return dpp::sync<confirmation>(this, &cluster::interaction_response_edit, token, m);
|
||||
}
|
||||
|
||||
confirmation cluster::interaction_followup_create_sync(const std::string &token, const message &m) {
|
||||
return dpp::sync<confirmation>(this, &cluster::interaction_followup_create, token, m);
|
||||
}
|
||||
|
||||
confirmation cluster::interaction_followup_edit_original_sync(const std::string &token, const message &m) {
|
||||
return dpp::sync<confirmation>(this, &cluster::interaction_followup_edit_original, token, m);
|
||||
}
|
||||
|
||||
confirmation cluster::interaction_followup_delete_sync(const std::string &token) {
|
||||
return dpp::sync<confirmation>(this, &cluster::interaction_followup_delete, token);
|
||||
}
|
||||
|
||||
confirmation cluster::interaction_followup_edit_sync(const std::string &token, const message &m) {
|
||||
return dpp::sync<confirmation>(this, &cluster::interaction_followup_edit, token, m);
|
||||
}
|
||||
|
||||
message cluster::interaction_followup_get_sync(const std::string &token, snowflake message_id) {
|
||||
return dpp::sync<message>(this, &cluster::interaction_followup_get, token, message_id);
|
||||
}
|
||||
|
||||
automod_rule_map cluster::automod_rules_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<automod_rule_map>(this, &cluster::automod_rules_get, guild_id);
|
||||
}
|
||||
|
||||
automod_rule cluster::automod_rule_get_sync(snowflake guild_id, snowflake rule_id) {
|
||||
return dpp::sync<automod_rule>(this, &cluster::automod_rule_get, guild_id, rule_id);
|
||||
}
|
||||
|
||||
automod_rule cluster::automod_rule_create_sync(snowflake guild_id, const automod_rule& r) {
|
||||
return dpp::sync<automod_rule>(this, &cluster::automod_rule_create, guild_id, r);
|
||||
}
|
||||
|
||||
automod_rule cluster::automod_rule_edit_sync(snowflake guild_id, const automod_rule& r) {
|
||||
return dpp::sync<automod_rule>(this, &cluster::automod_rule_edit, guild_id, r);
|
||||
}
|
||||
|
||||
confirmation cluster::automod_rule_delete_sync(snowflake guild_id, snowflake rule_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::automod_rule_delete, guild_id, rule_id);
|
||||
}
|
||||
|
||||
channel cluster::channel_create_sync(const class channel &c) {
|
||||
return dpp::sync<channel>(this, &cluster::channel_create, c);
|
||||
}
|
||||
|
||||
confirmation cluster::channel_delete_permission_sync(const class channel &c, snowflake overwrite_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::channel_delete_permission, c, overwrite_id);
|
||||
}
|
||||
|
||||
confirmation cluster::channel_delete_sync(snowflake channel_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::channel_delete, channel_id);
|
||||
}
|
||||
|
||||
confirmation cluster::channel_edit_positions_sync(const std::vector<channel> &c) {
|
||||
return dpp::sync<confirmation>(this, &cluster::channel_edit_positions, c);
|
||||
}
|
||||
|
||||
channel cluster::channel_edit_sync(const class channel &c) {
|
||||
return dpp::sync<channel>(this, &cluster::channel_edit, c);
|
||||
}
|
||||
|
||||
confirmation cluster::channel_follow_news_sync(const class channel &c, snowflake target_channel_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::channel_follow_news, c, target_channel_id);
|
||||
}
|
||||
|
||||
channel cluster::channel_get_sync(snowflake c) {
|
||||
return dpp::sync<channel>(this, &cluster::channel_get, c);
|
||||
}
|
||||
|
||||
confirmation cluster::channel_invite_create_sync(const class channel &c, const class invite &i) {
|
||||
return dpp::sync<confirmation>(this, &cluster::channel_invite_create, c, i);
|
||||
}
|
||||
|
||||
invite_map cluster::channel_invites_get_sync(const class channel &c) {
|
||||
return dpp::sync<invite_map>(this, &cluster::channel_invites_get, c);
|
||||
}
|
||||
|
||||
channel_map cluster::channels_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<channel_map>(this, &cluster::channels_get, guild_id);
|
||||
}
|
||||
|
||||
channel cluster::create_dm_channel_sync(snowflake user_id) {
|
||||
return dpp::sync<channel>(this, &cluster::create_dm_channel, user_id);
|
||||
}
|
||||
|
||||
channel_map cluster::current_user_get_dms_sync() {
|
||||
return dpp::sync<channel_map>(this, &cluster::current_user_get_dms);
|
||||
}
|
||||
|
||||
message cluster::direct_message_create_sync(snowflake user_id, const message &m) {
|
||||
return dpp::sync<message>(this, &cluster::direct_message_create, user_id, m);
|
||||
}
|
||||
|
||||
confirmation cluster::gdm_add_sync(snowflake channel_id, snowflake user_id, const std::string &access_token, const std::string &nick) {
|
||||
return dpp::sync<confirmation>(this, &cluster::gdm_add, channel_id, user_id, access_token, nick);
|
||||
}
|
||||
|
||||
confirmation cluster::gdm_remove_sync(snowflake channel_id, snowflake user_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::gdm_remove, channel_id, user_id);
|
||||
}
|
||||
|
||||
emoji cluster::guild_emoji_create_sync(snowflake guild_id, const class emoji& newemoji) {
|
||||
return dpp::sync<emoji>(this, &cluster::guild_emoji_create, guild_id, newemoji);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_emoji_delete_sync(snowflake guild_id, snowflake emoji_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_emoji_delete, guild_id, emoji_id);
|
||||
}
|
||||
|
||||
emoji cluster::guild_emoji_edit_sync(snowflake guild_id, const class emoji& newemoji) {
|
||||
return dpp::sync<emoji>(this, &cluster::guild_emoji_edit, guild_id, newemoji);
|
||||
}
|
||||
|
||||
emoji cluster::guild_emoji_get_sync(snowflake guild_id, snowflake emoji_id) {
|
||||
return dpp::sync<emoji>(this, &cluster::guild_emoji_get, guild_id, emoji_id);
|
||||
}
|
||||
|
||||
emoji_map cluster::guild_emojis_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<emoji_map>(this, &cluster::guild_emojis_get, guild_id);
|
||||
}
|
||||
|
||||
gateway cluster::get_gateway_bot_sync() {
|
||||
return dpp::sync<gateway>(this, &cluster::get_gateway_bot);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_current_member_edit_sync(snowflake guild_id, const std::string &nickname) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_current_member_edit, guild_id, nickname);
|
||||
}
|
||||
|
||||
auditlog cluster::guild_auditlog_get_sync(snowflake guild_id, snowflake user_id, uint32_t action_type, snowflake before, snowflake after, uint32_t limit) {
|
||||
return dpp::sync<auditlog>(this, &cluster::guild_auditlog_get, guild_id, user_id, action_type, before, after, limit);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_ban_add_sync(snowflake guild_id, snowflake user_id, uint32_t delete_message_seconds) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_ban_add, guild_id, user_id, delete_message_seconds);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_ban_delete_sync(snowflake guild_id, snowflake user_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_ban_delete, guild_id, user_id);
|
||||
}
|
||||
|
||||
guild cluster::guild_create_sync(const class guild &g) {
|
||||
return dpp::sync<guild>(this, &cluster::guild_create, g);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_delete_sync(snowflake guild_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_delete, guild_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_delete_integration_sync(snowflake guild_id, snowflake integration_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_delete_integration, guild_id, integration_id);
|
||||
}
|
||||
|
||||
guild cluster::guild_edit_sync(const class guild &g) {
|
||||
return dpp::sync<guild>(this, &cluster::guild_edit, g);
|
||||
}
|
||||
|
||||
guild_widget cluster::guild_edit_widget_sync(snowflake guild_id, const class guild_widget &gw) {
|
||||
return dpp::sync<guild_widget>(this, &cluster::guild_edit_widget, guild_id, gw);
|
||||
}
|
||||
|
||||
ban cluster::guild_get_ban_sync(snowflake guild_id, snowflake user_id) {
|
||||
return dpp::sync<ban>(this, &cluster::guild_get_ban, guild_id, user_id);
|
||||
}
|
||||
|
||||
ban_map cluster::guild_get_bans_sync(snowflake guild_id, snowflake before, snowflake after, snowflake limit) {
|
||||
return dpp::sync<ban_map>(this, &cluster::guild_get_bans, guild_id, before, after, limit);
|
||||
}
|
||||
|
||||
guild cluster::guild_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<guild>(this, &cluster::guild_get, guild_id);
|
||||
}
|
||||
|
||||
integration_map cluster::guild_get_integrations_sync(snowflake guild_id) {
|
||||
return dpp::sync<integration_map>(this, &cluster::guild_get_integrations, guild_id);
|
||||
}
|
||||
|
||||
guild cluster::guild_get_preview_sync(snowflake guild_id) {
|
||||
return dpp::sync<guild>(this, &cluster::guild_get_preview, guild_id);
|
||||
}
|
||||
|
||||
invite cluster::guild_get_vanity_sync(snowflake guild_id) {
|
||||
return dpp::sync<invite>(this, &cluster::guild_get_vanity, guild_id);
|
||||
}
|
||||
|
||||
guild_widget cluster::guild_get_widget_sync(snowflake guild_id) {
|
||||
return dpp::sync<guild_widget>(this, &cluster::guild_get_widget, guild_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_modify_integration_sync(snowflake guild_id, const class integration &i) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_modify_integration, guild_id, i);
|
||||
}
|
||||
|
||||
prune cluster::guild_get_prune_counts_sync(snowflake guild_id, const struct prune& pruneinfo) {
|
||||
return dpp::sync<prune>(this, &cluster::guild_get_prune_counts, guild_id, pruneinfo);
|
||||
}
|
||||
|
||||
prune cluster::guild_begin_prune_sync(snowflake guild_id, const struct prune& pruneinfo) {
|
||||
return dpp::sync<prune>(this, &cluster::guild_begin_prune, guild_id, pruneinfo);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_set_nickname_sync(snowflake guild_id, const std::string &nickname) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_set_nickname, guild_id, nickname);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_sync_integration_sync(snowflake guild_id, snowflake integration_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_sync_integration, guild_id, integration_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_add_member_sync(const guild_member& gm, const std::string &access_token) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_add_member, gm, access_token);
|
||||
}
|
||||
|
||||
guild_member cluster::guild_edit_member_sync(const guild_member& gm) {
|
||||
return dpp::sync<guild_member>(this, &cluster::guild_edit_member, gm);
|
||||
}
|
||||
|
||||
guild_member cluster::guild_get_member_sync(snowflake guild_id, snowflake user_id) {
|
||||
return dpp::sync<guild_member>(this, &cluster::guild_get_member, guild_id, user_id);
|
||||
}
|
||||
|
||||
guild_member_map cluster::guild_get_members_sync(snowflake guild_id, uint16_t limit, snowflake after) {
|
||||
return dpp::sync<guild_member_map>(this, &cluster::guild_get_members, guild_id, limit, after);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_member_add_role_sync(snowflake guild_id, snowflake user_id, snowflake role_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_member_add_role, guild_id, user_id, role_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_member_delete_sync(snowflake guild_id, snowflake user_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_member_delete, guild_id, user_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_member_kick_sync(snowflake guild_id, snowflake user_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_member_kick, guild_id, user_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_member_timeout_sync(snowflake guild_id, snowflake user_id, time_t communication_disabled_until) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_member_timeout, guild_id, user_id, communication_disabled_until);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_member_delete_role_sync(snowflake guild_id, snowflake user_id, snowflake role_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_member_delete_role, guild_id, user_id, role_id);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_member_remove_role_sync(snowflake guild_id, snowflake user_id, snowflake role_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_member_remove_role, guild_id, user_id, role_id);
|
||||
}
|
||||
|
||||
guild_member cluster::guild_member_move_sync(const snowflake channel_id, const snowflake guild_id, const snowflake user_id) {
|
||||
return dpp::sync<guild_member>(this, &cluster::guild_member_move, channel_id, guild_id, user_id);
|
||||
}
|
||||
|
||||
guild_member_map cluster::guild_search_members_sync(snowflake guild_id, const std::string& query, uint16_t limit) {
|
||||
return dpp::sync<guild_member_map>(this, &cluster::guild_search_members, guild_id, query, limit);
|
||||
}
|
||||
|
||||
invite_map cluster::guild_get_invites_sync(snowflake guild_id) {
|
||||
return dpp::sync<invite_map>(this, &cluster::guild_get_invites, guild_id);
|
||||
}
|
||||
|
||||
invite cluster::invite_delete_sync(const std::string &invitecode) {
|
||||
return dpp::sync<invite>(this, &cluster::invite_delete, invitecode);
|
||||
}
|
||||
|
||||
invite cluster::invite_get_sync(const std::string &invitecode) {
|
||||
return dpp::sync<invite>(this, &cluster::invite_get, invitecode);
|
||||
}
|
||||
|
||||
message cluster::message_create_sync(const message &m) {
|
||||
return dpp::sync<message>(this, &cluster::message_create, m);
|
||||
}
|
||||
|
||||
message cluster::message_crosspost_sync(snowflake message_id, snowflake channel_id) {
|
||||
return dpp::sync<message>(this, &cluster::message_crosspost, message_id, channel_id);
|
||||
}
|
||||
|
||||
confirmation cluster::message_delete_bulk_sync(const std::vector<snowflake>& message_ids, snowflake channel_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::message_delete_bulk, message_ids, channel_id);
|
||||
}
|
||||
|
||||
confirmation cluster::message_delete_sync(snowflake message_id, snowflake channel_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::message_delete, message_id, channel_id);
|
||||
}
|
||||
|
||||
message cluster::message_edit_sync(const message &m) {
|
||||
return dpp::sync<message>(this, &cluster::message_edit, m);
|
||||
}
|
||||
|
||||
message cluster::message_get_sync(snowflake message_id, snowflake channel_id) {
|
||||
return dpp::sync<message>(this, &cluster::message_get, message_id, channel_id);
|
||||
}
|
||||
|
||||
confirmation cluster::message_pin_sync(snowflake channel_id, snowflake message_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::message_pin, channel_id, message_id);
|
||||
}
|
||||
|
||||
message_map cluster::messages_get_sync(snowflake channel_id, snowflake around, snowflake before, snowflake after, uint64_t limit) {
|
||||
return dpp::sync<message_map>(this, &cluster::messages_get, channel_id, around, before, after, limit);
|
||||
}
|
||||
|
||||
confirmation cluster::message_unpin_sync(snowflake channel_id, snowflake message_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::message_unpin, channel_id, message_id);
|
||||
}
|
||||
|
||||
message_map cluster::channel_pins_get_sync(snowflake channel_id) {
|
||||
return dpp::sync<message_map>(this, &cluster::channel_pins_get, channel_id);
|
||||
}
|
||||
|
||||
role cluster::role_create_sync(const class role &r) {
|
||||
return dpp::sync<role>(this, &cluster::role_create, r);
|
||||
}
|
||||
|
||||
confirmation cluster::role_delete_sync(snowflake guild_id, snowflake role_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::role_delete, guild_id, role_id);
|
||||
}
|
||||
|
||||
role cluster::role_edit_sync(const class role &r) {
|
||||
return dpp::sync<role>(this, &cluster::role_edit, r);
|
||||
}
|
||||
|
||||
role_map cluster::roles_edit_position_sync(snowflake guild_id, const std::vector<role> &roles) {
|
||||
return dpp::sync<role_map>(this, &cluster::roles_edit_position, guild_id, roles);
|
||||
}
|
||||
|
||||
role_map cluster::roles_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<role_map>(this, &cluster::roles_get, guild_id);
|
||||
}
|
||||
|
||||
application_role_connection cluster::user_application_role_connection_get_sync(snowflake application_id) {
|
||||
return dpp::sync<application_role_connection>(this, &cluster::user_application_role_connection_get, application_id);
|
||||
}
|
||||
|
||||
application_role_connection cluster::user_application_role_connection_update_sync(snowflake application_id, const application_role_connection &connection) {
|
||||
return dpp::sync<application_role_connection>(this, &cluster::user_application_role_connection_update, application_id, connection);
|
||||
}
|
||||
|
||||
scheduled_event_map cluster::guild_events_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<scheduled_event_map>(this, &cluster::guild_events_get, guild_id);
|
||||
}
|
||||
|
||||
scheduled_event cluster::guild_event_create_sync(const scheduled_event& event) {
|
||||
return dpp::sync<scheduled_event>(this, &cluster::guild_event_create, event);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_event_delete_sync(snowflake event_id, snowflake guild_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_event_delete, event_id, guild_id);
|
||||
}
|
||||
|
||||
scheduled_event cluster::guild_event_edit_sync(const scheduled_event& event) {
|
||||
return dpp::sync<scheduled_event>(this, &cluster::guild_event_edit, event);
|
||||
}
|
||||
|
||||
scheduled_event cluster::guild_event_get_sync(snowflake guild_id, snowflake event_id) {
|
||||
return dpp::sync<scheduled_event>(this, &cluster::guild_event_get, guild_id, event_id);
|
||||
}
|
||||
|
||||
stage_instance cluster::stage_instance_create_sync(const stage_instance& si) {
|
||||
return dpp::sync<stage_instance>(this, &cluster::stage_instance_create, si);
|
||||
}
|
||||
|
||||
stage_instance cluster::stage_instance_get_sync(const snowflake channel_id) {
|
||||
return dpp::sync<stage_instance>(this, &cluster::stage_instance_get, channel_id);
|
||||
}
|
||||
|
||||
stage_instance cluster::stage_instance_edit_sync(const stage_instance& si) {
|
||||
return dpp::sync<stage_instance>(this, &cluster::stage_instance_edit, si);
|
||||
}
|
||||
|
||||
confirmation cluster::stage_instance_delete_sync(const snowflake channel_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::stage_instance_delete, channel_id);
|
||||
}
|
||||
|
||||
sticker cluster::guild_sticker_create_sync(sticker &s) {
|
||||
return dpp::sync<sticker>(this, &cluster::guild_sticker_create, s);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_sticker_delete_sync(snowflake sticker_id, snowflake guild_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_sticker_delete, sticker_id, guild_id);
|
||||
}
|
||||
|
||||
sticker cluster::guild_sticker_get_sync(snowflake id, snowflake guild_id) {
|
||||
return dpp::sync<sticker>(this, &cluster::guild_sticker_get, id, guild_id);
|
||||
}
|
||||
|
||||
sticker cluster::guild_sticker_modify_sync(sticker &s) {
|
||||
return dpp::sync<sticker>(this, &cluster::guild_sticker_modify, s);
|
||||
}
|
||||
|
||||
sticker_map cluster::guild_stickers_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<sticker_map>(this, &cluster::guild_stickers_get, guild_id);
|
||||
}
|
||||
|
||||
sticker cluster::nitro_sticker_get_sync(snowflake id) {
|
||||
return dpp::sync<sticker>(this, &cluster::nitro_sticker_get, id);
|
||||
}
|
||||
|
||||
sticker_pack_map cluster::sticker_packs_get_sync() {
|
||||
return dpp::sync<sticker_pack_map>(this, &cluster::sticker_packs_get);
|
||||
}
|
||||
|
||||
guild cluster::guild_create_from_template_sync(const std::string &code, const std::string &name) {
|
||||
return dpp::sync<guild>(this, &cluster::guild_create_from_template, code, name);
|
||||
}
|
||||
|
||||
dtemplate cluster::guild_template_create_sync(snowflake guild_id, const std::string &name, const std::string &description) {
|
||||
return dpp::sync<dtemplate>(this, &cluster::guild_template_create, guild_id, name, description);
|
||||
}
|
||||
|
||||
confirmation cluster::guild_template_delete_sync(snowflake guild_id, const std::string &code) {
|
||||
return dpp::sync<confirmation>(this, &cluster::guild_template_delete, guild_id, code);
|
||||
}
|
||||
|
||||
dtemplate cluster::guild_template_modify_sync(snowflake guild_id, const std::string &code, const std::string &name, const std::string &description) {
|
||||
return dpp::sync<dtemplate>(this, &cluster::guild_template_modify, guild_id, code, name, description);
|
||||
}
|
||||
|
||||
dtemplate_map cluster::guild_templates_get_sync(snowflake guild_id) {
|
||||
return dpp::sync<dtemplate_map>(this, &cluster::guild_templates_get, guild_id);
|
||||
}
|
||||
|
||||
dtemplate cluster::guild_template_sync_sync(snowflake guild_id, const std::string &code) {
|
||||
return dpp::sync<dtemplate>(this, &cluster::guild_template_sync, guild_id, code);
|
||||
}
|
||||
|
||||
dtemplate cluster::template_get_sync(const std::string &code) {
|
||||
return dpp::sync<dtemplate>(this, &cluster::template_get, code);
|
||||
}
|
||||
|
||||
confirmation cluster::current_user_join_thread_sync(snowflake thread_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::current_user_join_thread, thread_id);
|
||||
}
|
||||
|
||||
confirmation cluster::current_user_leave_thread_sync(snowflake thread_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::current_user_leave_thread, thread_id);
|
||||
}
|
||||
|
||||
thread_map cluster::threads_get_active_sync(snowflake guild_id) {
|
||||
return dpp::sync<thread_map>(this, &cluster::threads_get_active, guild_id);
|
||||
}
|
||||
|
||||
thread_map cluster::threads_get_joined_private_archived_sync(snowflake channel_id, snowflake before_id, uint16_t limit) {
|
||||
return dpp::sync<thread_map>(this, &cluster::threads_get_joined_private_archived, channel_id, before_id, limit);
|
||||
}
|
||||
|
||||
thread_map cluster::threads_get_private_archived_sync(snowflake channel_id, time_t before_timestamp, uint16_t limit) {
|
||||
return dpp::sync<thread_map>(this, &cluster::threads_get_private_archived, channel_id, before_timestamp, limit);
|
||||
}
|
||||
|
||||
thread_map cluster::threads_get_public_archived_sync(snowflake channel_id, time_t before_timestamp, uint16_t limit) {
|
||||
return dpp::sync<thread_map>(this, &cluster::threads_get_public_archived, channel_id, before_timestamp, limit);
|
||||
}
|
||||
|
||||
thread_member cluster::thread_member_get_sync(const snowflake thread_id, const snowflake user_id) {
|
||||
return dpp::sync<thread_member>(this, &cluster::thread_member_get, thread_id, user_id);
|
||||
}
|
||||
|
||||
thread_member_map cluster::thread_members_get_sync(snowflake thread_id) {
|
||||
return dpp::sync<thread_member_map>(this, &cluster::thread_members_get, thread_id);
|
||||
}
|
||||
|
||||
thread cluster::thread_create_in_forum_sync(const std::string& thread_name, snowflake channel_id, const message& msg, auto_archive_duration_t auto_archive_duration, uint16_t rate_limit_per_user, std::vector<snowflake> applied_tags) {
|
||||
return dpp::sync<thread>(this, &cluster::thread_create_in_forum, thread_name, channel_id, msg, auto_archive_duration, rate_limit_per_user, applied_tags);
|
||||
}
|
||||
|
||||
thread cluster::thread_create_sync(const std::string& thread_name, snowflake channel_id, uint16_t auto_archive_duration, channel_type thread_type, bool invitable, uint16_t rate_limit_per_user) {
|
||||
return dpp::sync<thread>(this, &cluster::thread_create, thread_name, channel_id, auto_archive_duration, thread_type, invitable, rate_limit_per_user);
|
||||
}
|
||||
|
||||
thread cluster::thread_create_with_message_sync(const std::string& thread_name, snowflake channel_id, snowflake message_id, uint16_t auto_archive_duration, uint16_t rate_limit_per_user) {
|
||||
return dpp::sync<thread>(this, &cluster::thread_create_with_message, thread_name, channel_id, message_id, auto_archive_duration, rate_limit_per_user);
|
||||
}
|
||||
|
||||
confirmation cluster::thread_member_add_sync(snowflake thread_id, snowflake user_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::thread_member_add, thread_id, user_id);
|
||||
}
|
||||
|
||||
confirmation cluster::thread_member_remove_sync(snowflake thread_id, snowflake user_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::thread_member_remove, thread_id, user_id);
|
||||
}
|
||||
|
||||
user cluster::current_user_edit_sync(const std::string &nickname, const std::string& image_blob, const image_type type) {
|
||||
return dpp::sync<user>(this, &cluster::current_user_edit, nickname, image_blob, type);
|
||||
}
|
||||
|
||||
application cluster::current_application_get_sync() {
|
||||
return dpp::sync<application>(this, &cluster::current_application_get);
|
||||
}
|
||||
|
||||
user_identified cluster::current_user_get_sync() {
|
||||
return dpp::sync<user_identified>(this, &cluster::current_user_get);
|
||||
}
|
||||
|
||||
confirmation cluster::current_user_set_voice_state_sync(snowflake guild_id, snowflake channel_id, bool suppress, time_t request_to_speak_timestamp) {
|
||||
return dpp::sync<confirmation>(this, &cluster::current_user_set_voice_state, guild_id, channel_id, suppress, request_to_speak_timestamp);
|
||||
}
|
||||
|
||||
confirmation cluster::user_set_voice_state_sync(snowflake user_id, snowflake guild_id, snowflake channel_id, bool suppress) {
|
||||
return dpp::sync<confirmation>(this, &cluster::user_set_voice_state, user_id, guild_id, channel_id, suppress);
|
||||
}
|
||||
|
||||
connection_map cluster::current_user_connections_get_sync() {
|
||||
return dpp::sync<connection_map>(this, &cluster::current_user_connections_get);
|
||||
}
|
||||
|
||||
guild_map cluster::current_user_get_guilds_sync() {
|
||||
return dpp::sync<guild_map>(this, &cluster::current_user_get_guilds);
|
||||
}
|
||||
|
||||
confirmation cluster::current_user_leave_guild_sync(snowflake guild_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::current_user_leave_guild, guild_id);
|
||||
}
|
||||
|
||||
user_identified cluster::user_get_sync(snowflake user_id) {
|
||||
return dpp::sync<user_identified>(this, &cluster::user_get, user_id);
|
||||
}
|
||||
|
||||
user_identified cluster::user_get_cached_sync(snowflake user_id) {
|
||||
return dpp::sync<user_identified>(this, &cluster::user_get_cached, user_id);
|
||||
}
|
||||
|
||||
voiceregion_map cluster::get_voice_regions_sync() {
|
||||
return dpp::sync<voiceregion_map>(this, &cluster::get_voice_regions);
|
||||
}
|
||||
|
||||
voiceregion_map cluster::guild_get_voice_regions_sync(snowflake guild_id) {
|
||||
return dpp::sync<voiceregion_map>(this, &cluster::guild_get_voice_regions, guild_id);
|
||||
}
|
||||
|
||||
webhook cluster::create_webhook_sync(const class webhook &w) {
|
||||
return dpp::sync<webhook>(this, &cluster::create_webhook, w);
|
||||
}
|
||||
|
||||
confirmation cluster::delete_webhook_sync(snowflake webhook_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::delete_webhook, webhook_id);
|
||||
}
|
||||
|
||||
confirmation cluster::delete_webhook_message_sync(const class webhook &wh, snowflake message_id, snowflake thread_id) {
|
||||
return dpp::sync<confirmation>(this, &cluster::delete_webhook_message, wh, message_id, thread_id);
|
||||
}
|
||||
|
||||
confirmation cluster::delete_webhook_with_token_sync(snowflake webhook_id, const std::string &token) {
|
||||
return dpp::sync<confirmation>(this, &cluster::delete_webhook_with_token, webhook_id, token);
|
||||
}
|
||||
|
||||
webhook cluster::edit_webhook_sync(const class webhook& wh) {
|
||||
return dpp::sync<webhook>(this, &cluster::edit_webhook, wh);
|
||||
}
|
||||
|
||||
message cluster::edit_webhook_message_sync(const class webhook &wh, const struct message& m, snowflake thread_id) {
|
||||
return dpp::sync<message>(this, &cluster::edit_webhook_message, wh, m, thread_id);
|
||||
}
|
||||
|
||||
webhook cluster::edit_webhook_with_token_sync(const class webhook& wh) {
|
||||
return dpp::sync<webhook>(this, &cluster::edit_webhook_with_token, wh);
|
||||
}
|
||||
|
||||
message cluster::execute_webhook_sync(const class webhook &wh, const struct message& m, bool wait, snowflake thread_id, const std::string& thread_name) {
|
||||
return dpp::sync<message>(this, &cluster::execute_webhook, wh, m, wait, thread_id, thread_name);
|
||||
}
|
||||
|
||||
webhook_map cluster::get_channel_webhooks_sync(snowflake channel_id) {
|
||||
return dpp::sync<webhook_map>(this, &cluster::get_channel_webhooks, channel_id);
|
||||
}
|
||||
|
||||
webhook_map cluster::get_guild_webhooks_sync(snowflake guild_id) {
|
||||
return dpp::sync<webhook_map>(this, &cluster::get_guild_webhooks, guild_id);
|
||||
}
|
||||
|
||||
webhook cluster::get_webhook_sync(snowflake webhook_id) {
|
||||
return dpp::sync<webhook>(this, &cluster::get_webhook, webhook_id);
|
||||
}
|
||||
|
||||
message cluster::get_webhook_message_sync(const class webhook &wh, snowflake message_id, snowflake thread_id) {
|
||||
return dpp::sync<message>(this, &cluster::get_webhook_message, wh, message_id, thread_id);
|
||||
}
|
||||
|
||||
webhook cluster::get_webhook_with_token_sync(snowflake webhook_id, const std::string &token) {
|
||||
return dpp::sync<webhook>(this, &cluster::get_webhook_with_token, webhook_id, token);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/* End of auto-generated definitions */
|
||||
439
vendor/DPP/src/dpp/commandhandler.cpp
vendored
Normal file
439
vendor/DPP/src/dpp/commandhandler.cpp
vendored
Normal file
@@ -0,0 +1,439 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/commandhandler.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/exception.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
param_info::param_info(parameter_type t, bool o, const std::string &d, const std::map<command_value, std::string> &opts) : type(t), optional(o), description(d), choices(opts)
|
||||
{
|
||||
}
|
||||
|
||||
command_source::command_source(const struct message_create_t& event) : guild_id(event.msg.guild_id), channel_id(event.msg.channel_id), command_id(0), issuer(event.msg.author), message_event(event), interaction_event(std::nullopt)
|
||||
{
|
||||
}
|
||||
|
||||
command_source::command_source(const struct interaction_create_t& event) : guild_id(event.command.guild_id), channel_id(event.command.channel_id), command_id(event.command.id), command_token(event.command.token), issuer(event.command.usr), message_event(std::nullopt), interaction_event(event)
|
||||
{
|
||||
}
|
||||
|
||||
commandhandler::commandhandler(cluster* o, bool auto_hook_events, snowflake application_id) : slash_commands_enabled(false), owner(o), app_id(application_id)
|
||||
{
|
||||
if (!application_id && o->me.id) {
|
||||
app_id = o->me.id;
|
||||
}
|
||||
if (auto_hook_events) {
|
||||
interactions = o->on_slashcommand([this](const dpp::slashcommand_t &event) {
|
||||
this->route(event);
|
||||
});
|
||||
messages = o->on_message_create([this](const dpp::message_create_t & event) {
|
||||
this->route(event);
|
||||
});
|
||||
} else {
|
||||
interactions = messages = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
commandhandler& commandhandler::set_owner(cluster* o)
|
||||
{
|
||||
owner = o;
|
||||
return *this;
|
||||
}
|
||||
|
||||
commandhandler::~commandhandler()
|
||||
{
|
||||
if (messages && interactions) {
|
||||
owner->on_message_create.detach(messages);
|
||||
owner->on_slashcommand.detach(interactions);
|
||||
}
|
||||
}
|
||||
|
||||
commandhandler& commandhandler::add_prefix(const std::string &prefix)
|
||||
{
|
||||
prefixes.emplace_back(prefix);
|
||||
if (prefix == "/") {
|
||||
/* Register existing slash commands */
|
||||
slash_commands_enabled = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
commandhandler& commandhandler::add_command(const std::string &command, const parameter_registration_t ¶meters, command_handler handler, const std::string &description, snowflake guild_id)
|
||||
{
|
||||
command_info_t i;
|
||||
i.func = handler;
|
||||
i.guild_id = guild_id;
|
||||
i.parameters = parameters;
|
||||
commands[lowercase(command)] = i;
|
||||
if (slash_commands_enabled) {
|
||||
if (this->app_id.empty()) {
|
||||
if (owner->me.id.empty()) {
|
||||
throw dpp::logic_exception("Command handler not ready (i don't know my application ID)");
|
||||
} else {
|
||||
this->app_id = owner->me.id;
|
||||
}
|
||||
}
|
||||
dpp::slashcommand newcommand;
|
||||
/* Create a new global command on ready event */
|
||||
newcommand.set_name(lowercase(command)).set_description(description).set_application_id(this->app_id);
|
||||
|
||||
for (auto& parameter : parameters) {
|
||||
command_option_type cot = co_string;
|
||||
switch (parameter.second.type) {
|
||||
case pt_boolean:
|
||||
cot = co_boolean;
|
||||
break;
|
||||
case pt_integer:
|
||||
cot = co_integer;
|
||||
break;
|
||||
case pt_string:
|
||||
cot = co_string;
|
||||
break;
|
||||
case pt_user:
|
||||
cot = co_user;
|
||||
break;
|
||||
case pt_role:
|
||||
cot = co_role;
|
||||
break;
|
||||
case pt_channel:
|
||||
cot = co_channel;
|
||||
break;
|
||||
case pt_double:
|
||||
cot = co_number;
|
||||
break;
|
||||
}
|
||||
|
||||
command_option opt(cot, parameter.first, parameter.second.description, !parameter.second.optional);
|
||||
if (!parameter.second.choices.empty()) {
|
||||
for (auto& c : parameter.second.choices) {
|
||||
opt.add_choice(dpp::command_option_choice(c.second, c.first));
|
||||
}
|
||||
}
|
||||
newcommand.add_option(opt);
|
||||
}
|
||||
/* Register the command */
|
||||
if (guild_id) {
|
||||
if (bulk_registration_list_guild.find(guild_id) == bulk_registration_list_guild.end()) {
|
||||
bulk_registration_list_guild[guild_id] = {};
|
||||
}
|
||||
bulk_registration_list_guild[guild_id].emplace_back(newcommand);
|
||||
} else {
|
||||
bulk_registration_list_global.emplace_back(newcommand);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
commandhandler& commandhandler::register_commands()
|
||||
{
|
||||
for(auto & guild_commands : bulk_registration_list_guild) {
|
||||
owner->guild_bulk_command_create(guild_commands.second, guild_commands.first, [guild_commands, this](const dpp::confirmation_callback_t &callback) {
|
||||
if (callback.is_error()) {
|
||||
this->owner->log(dpp::ll_error, "Failed to register guild slash commands for guild id '" + std::to_string(guild_commands.first) + "': " + callback.http_info.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
owner->global_bulk_command_create(bulk_registration_list_global, [this](const dpp::confirmation_callback_t &callback) {
|
||||
if (callback.is_error()) {
|
||||
this->owner->log(dpp::ll_error, "Failed to register global slash commands: " + callback.http_info.body);
|
||||
}
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool commandhandler::string_has_prefix(std::string &str)
|
||||
{
|
||||
for (auto& p : prefixes) {
|
||||
size_t prefix_length = utility::utf8len(p);
|
||||
if (utility::utf8substr(str, 0, prefix_length) == p) {
|
||||
str.erase(str.begin(), str.begin() + prefix_length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Note that message based command routing relies on cache to resolve ping types (e.g. user, channel ping).
|
||||
* There isn't really a way around this for many things because there is no 'resolved' member for it.
|
||||
* We only get resolved information for the user issuing the command.
|
||||
*/
|
||||
void commandhandler::route(const struct dpp::message_create_t& event)
|
||||
{
|
||||
std::string msg_content = event.msg.content;
|
||||
if (string_has_prefix(msg_content)) {
|
||||
/* Put the string into stringstream to parse parameters at spaces.
|
||||
* We use stringstream as it handles multiple spaces etc nicely.
|
||||
*/
|
||||
std::stringstream ss(msg_content);
|
||||
std::string command;
|
||||
ss >> command;
|
||||
/* Prefixed command, the prefix was removed */
|
||||
auto found_cmd = commands.find(lowercase(command));
|
||||
if (found_cmd != commands.end()) {
|
||||
/* Filter out guild specific commands that are not for the current guild */
|
||||
if (found_cmd->second.guild_id && found_cmd->second.guild_id != event.msg.guild_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
parameter_list_t call_params;
|
||||
|
||||
/* Command found; parse parameters */
|
||||
for (auto& p : found_cmd->second.parameters) {
|
||||
command_parameter param;
|
||||
|
||||
/* Check for end of stream */
|
||||
if (!ss) {
|
||||
/* If it's an optional param, we dont care */
|
||||
if (!p.second.optional) {
|
||||
/* Trigger missing parameter handler? */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (p.second.type) {
|
||||
case pt_string: {
|
||||
std::string x;
|
||||
ss >> x;
|
||||
param = x;
|
||||
}
|
||||
break;
|
||||
case pt_role: {
|
||||
std::string x;
|
||||
ss >> x;
|
||||
if (x.length() > 4 && x[0] == '<' && x[1] == '&') {
|
||||
snowflake rid = from_string<uint64_t>(x.substr(2, x.length() - 1));
|
||||
role* r = dpp::find_role(rid);
|
||||
if (r) {
|
||||
param = *r;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pt_channel: {
|
||||
std::string x;
|
||||
ss >> x;
|
||||
if (x.length() > 4 && x[0] == '<' && x[1] == '#') {
|
||||
snowflake cid = from_string<uint64_t>(x.substr(2, x.length() - 1));
|
||||
channel* c = dpp::find_channel(cid);
|
||||
if (c) {
|
||||
param = *c;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pt_user: {
|
||||
std::string x;
|
||||
ss >> x;
|
||||
if (x.length() > 4 && x[0] == '<' && x[1] == '@') {
|
||||
snowflake uid = from_string<uint64_t>(x.substr(2, x.length() - 1));
|
||||
user* u = dpp::find_user(uid);
|
||||
if (u) {
|
||||
dpp::resolved_user m;
|
||||
m.user = *u;
|
||||
dpp::guild* g = dpp::find_guild(event.msg.guild_id);
|
||||
if (g->members.find(uid) != g->members.end()) {
|
||||
m.member = g->members[uid];
|
||||
}
|
||||
param = m;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pt_integer: {
|
||||
int64_t x = 0;
|
||||
ss >> x;
|
||||
param = x;
|
||||
}
|
||||
break;
|
||||
case pt_double: {
|
||||
double x = 0;
|
||||
ss >> x;
|
||||
param = x;
|
||||
}
|
||||
break;
|
||||
case pt_boolean: {
|
||||
std::string x;
|
||||
bool y = false;
|
||||
ss >> x;
|
||||
x = lowercase(x);
|
||||
if (x == "yes" || x == "1" || x == "true") {
|
||||
y = true;
|
||||
}
|
||||
param = y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add parameter to the list */
|
||||
call_params.emplace_back(p.first, param);
|
||||
}
|
||||
|
||||
/* Call command handler */
|
||||
found_cmd->second.func(command, call_params, command_source(event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void commandhandler::route(const struct slashcommand_t & event)
|
||||
{
|
||||
/* We don't need to check for prefixes here, slash command interactions
|
||||
* dont have prefixes at all.
|
||||
*/
|
||||
command_interaction cmd = std::get<command_interaction>(event.command.data);
|
||||
|
||||
auto found_cmd = commands.find(lowercase(cmd.name));
|
||||
if (found_cmd != commands.end()) {
|
||||
/* Command found; parse parameters */
|
||||
parameter_list_t call_params;
|
||||
for (auto& p : found_cmd->second.parameters) {
|
||||
command_parameter param;
|
||||
const command_value& slash_parameter = event.get_parameter(p.first);
|
||||
dpp::command_resolved res = event.command.resolved;
|
||||
|
||||
if (p.second.optional && slash_parameter.index() == 0 /* std::monostate */) {
|
||||
/* Missing optional parameter, skip this */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (p.second.type) {
|
||||
case pt_string: {
|
||||
std::string s = std::get<std::string>(slash_parameter);
|
||||
param = s;
|
||||
}
|
||||
break;
|
||||
case pt_role: {
|
||||
snowflake rid = std::get<snowflake>(slash_parameter);
|
||||
role* r = dpp::find_role(rid);
|
||||
if (r) {
|
||||
/* Use cache if the role is in the cache */
|
||||
param = *r;
|
||||
} else {
|
||||
/* Otherwise use interaction resolved fields */
|
||||
if (res.roles.find(rid) != res.roles.end()) {
|
||||
param = res.roles[rid];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pt_channel: {
|
||||
snowflake cid = std::get<snowflake>(slash_parameter);
|
||||
channel* c = dpp::find_channel(cid);
|
||||
if (c) {
|
||||
/* Use cache if the channel is in the cache */
|
||||
param = *c;
|
||||
} else {
|
||||
/* Otherwise use interaction resolved fields */
|
||||
if (res.channels.find(cid) != res.channels.end()) {
|
||||
param = res.channels[cid];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pt_user: {
|
||||
snowflake uid = std::get<snowflake>(slash_parameter);
|
||||
/* TODO: Make this used resolved, not cache */
|
||||
user* u = dpp::find_user(uid);
|
||||
if (u) {
|
||||
/* Use the cache if the user is in the cache */
|
||||
dpp::resolved_user m;
|
||||
m.user = *u;
|
||||
dpp::guild* g = dpp::find_guild(event.command.guild_id);
|
||||
if (g->members.find(uid) != g->members.end()) {
|
||||
m.member = g->members[uid];
|
||||
}
|
||||
param = m;
|
||||
} else {
|
||||
/* Otherwise use interaction resolved fields */
|
||||
if (
|
||||
event.command.resolved.users.find(uid) != event.command.resolved.users.end()
|
||||
&&
|
||||
event.command.resolved.members.find(uid) != event.command.resolved.members.end()
|
||||
) {
|
||||
/* Fill in both member and user info */
|
||||
dpp::resolved_user m;
|
||||
m.member = res.members[uid];
|
||||
m.user = res.users[uid];
|
||||
param = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pt_integer: {
|
||||
int64_t i = std::get<int64_t>(slash_parameter);
|
||||
param = i;
|
||||
}
|
||||
break;
|
||||
case pt_boolean: {
|
||||
bool b = std::get<bool>(slash_parameter);
|
||||
param = b;
|
||||
}
|
||||
break;
|
||||
case pt_double: {
|
||||
double b = std::get<double>(slash_parameter);
|
||||
param = b;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add parameter to the list */
|
||||
call_params.emplace_back(p.first, param);
|
||||
}
|
||||
|
||||
/* Call command handler */
|
||||
found_cmd->second.func(cmd.name, call_params, command_source(event));
|
||||
}
|
||||
}
|
||||
|
||||
void commandhandler::reply(const dpp::message &m, command_source source, command_completion_event_t callback)
|
||||
{
|
||||
dpp::message msg = m;
|
||||
msg.owner = this->owner;
|
||||
msg.guild_id = source.guild_id;
|
||||
msg.channel_id = source.channel_id;
|
||||
if (!source.command_token.empty() && source.command_id) {
|
||||
owner->interaction_response_create(source.command_id, source.command_token, dpp::interaction_response(ir_channel_message_with_source, msg), callback);
|
||||
} else {
|
||||
owner->message_create(msg, callback);
|
||||
}
|
||||
}
|
||||
|
||||
void commandhandler::thinking(command_source source, command_completion_event_t callback)
|
||||
{
|
||||
dpp::message msg(this->owner);
|
||||
msg.content = "*";
|
||||
msg.guild_id = source.guild_id;
|
||||
msg.channel_id = source.channel_id;
|
||||
if (!source.command_token.empty() && source.command_id) {
|
||||
owner->interaction_response_create(source.command_id, source.command_token, dpp::interaction_response(ir_deferred_channel_message_with_source, msg), callback);
|
||||
}
|
||||
}
|
||||
|
||||
void commandhandler::thonk(command_source source, command_completion_event_t callback)
|
||||
{
|
||||
thinking(source, callback);
|
||||
}
|
||||
|
||||
};
|
||||
728
vendor/DPP/src/dpp/discordclient.cpp
vendored
Normal file
728
vendor/DPP/src/dpp/discordclient.cpp
vendored
Normal file
@@ -0,0 +1,728 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <dpp/exception.h>
|
||||
#include <dpp/discordclient.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <thread>
|
||||
#include <dpp/json.h>
|
||||
#include <dpp/etf.h>
|
||||
#include <zlib.h>
|
||||
#ifdef _WIN32
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#define PATH_UNCOMPRESSED_JSON "/?v=" DISCORD_API_VERSION "&encoding=json"
|
||||
#define PATH_COMPRESSED_JSON "/?v=" DISCORD_API_VERSION "&encoding=json&compress=zlib-stream"
|
||||
#define PATH_UNCOMPRESSED_ETF "/?v=" DISCORD_API_VERSION "&encoding=etf"
|
||||
#define PATH_COMPRESSED_ETF "/?v=" DISCORD_API_VERSION "&encoding=etf&compress=zlib-stream"
|
||||
#define DECOMP_BUFFER_SIZE 512 * 1024
|
||||
|
||||
#define STRINGIFY(a) STRINGIFY_(a)
|
||||
#define STRINGIFY_(a) #a
|
||||
|
||||
#ifndef DPP_OS
|
||||
#define DPP_OS unknown
|
||||
#endif
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
public:
|
||||
/**
|
||||
* @brief Zlib stream struct
|
||||
*/
|
||||
z_stream d_stream;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Stores the most recent ping message on this shard, which we check for to monitor latency
|
||||
*/
|
||||
thread_local static std::string last_ping_message;
|
||||
|
||||
discord_client::discord_client(dpp::cluster* _cluster, uint32_t _shard_id, uint32_t _max_shards, const std::string &_token, uint32_t _intents, bool comp, websocket_protocol_t ws_proto)
|
||||
: websocket_client(_cluster->default_gateway, "443", comp ? (ws_proto == ws_json ? PATH_COMPRESSED_JSON : PATH_COMPRESSED_ETF) : (ws_proto == ws_json ? PATH_UNCOMPRESSED_JSON : PATH_UNCOMPRESSED_ETF)),
|
||||
terminating(false),
|
||||
runner(nullptr),
|
||||
compressed(comp),
|
||||
decomp_buffer(nullptr),
|
||||
zlib(nullptr),
|
||||
decompressed_total(0),
|
||||
connect_time(0),
|
||||
ping_start(0.0),
|
||||
etf(nullptr),
|
||||
creator(_cluster),
|
||||
heartbeat_interval(0),
|
||||
last_heartbeat(time(nullptr)),
|
||||
shard_id(_shard_id),
|
||||
max_shards(_max_shards),
|
||||
last_seq(0),
|
||||
token(_token),
|
||||
intents(_intents),
|
||||
resumes(0),
|
||||
reconnects(0),
|
||||
websocket_ping(0.0),
|
||||
ready(false),
|
||||
last_heartbeat_ack(time(nullptr)),
|
||||
protocol(ws_proto),
|
||||
resume_gateway_url(_cluster->default_gateway)
|
||||
{
|
||||
try {
|
||||
zlib = new zlibcontext();
|
||||
etf = new etf_parser();
|
||||
}
|
||||
catch (std::bad_alloc&) {
|
||||
delete zlib;
|
||||
delete etf;
|
||||
/* Clean up and rethrow to caller */
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
try {
|
||||
this->connect();
|
||||
}
|
||||
catch (std::exception&) {
|
||||
cleanup();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void discord_client::cleanup()
|
||||
{
|
||||
terminating = true;
|
||||
if (runner) {
|
||||
runner->join();
|
||||
delete runner;
|
||||
}
|
||||
delete etf;
|
||||
delete zlib;
|
||||
}
|
||||
|
||||
discord_client::~discord_client()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
uint64_t discord_client::get_decompressed_bytes_in()
|
||||
{
|
||||
return decompressed_total;
|
||||
}
|
||||
|
||||
void discord_client::setup_zlib()
|
||||
{
|
||||
if (compressed) {
|
||||
zlib->d_stream.zalloc = (alloc_func)0;
|
||||
zlib->d_stream.zfree = (free_func)0;
|
||||
zlib->d_stream.opaque = (voidpf)0;
|
||||
if (inflateInit(&(zlib->d_stream)) != Z_OK) {
|
||||
throw dpp::connection_exception("Can't initialise stream compression!");
|
||||
}
|
||||
this->decomp_buffer = new unsigned char[DECOMP_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void discord_client::end_zlib()
|
||||
{
|
||||
if (compressed) {
|
||||
inflateEnd(&(zlib->d_stream));
|
||||
delete[] this->decomp_buffer;
|
||||
this->decomp_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void discord_client::set_resume_hostname()
|
||||
{
|
||||
hostname = resume_gateway_url;
|
||||
}
|
||||
|
||||
void discord_client::thread_run()
|
||||
{
|
||||
utility::set_thread_name(std::string("shard/") + std::to_string(shard_id));
|
||||
setup_zlib();
|
||||
do {
|
||||
bool error = false;
|
||||
ready = false;
|
||||
message_queue.clear();
|
||||
ssl_client::read_loop();
|
||||
if (!terminating) {
|
||||
ssl_client::close();
|
||||
end_zlib();
|
||||
setup_zlib();
|
||||
do {
|
||||
this->log(ll_debug, "Attempting reconnection of shard " + std::to_string(this->shard_id) + " to wss://" + resume_gateway_url);
|
||||
error = false;
|
||||
try {
|
||||
set_resume_hostname();
|
||||
ssl_client::connect();
|
||||
websocket_client::connect();
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
log(dpp::ll_error, std::string("Error establishing connection, retry in 5 seconds: ") + e.what());
|
||||
ssl_client::close();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
error = true;
|
||||
}
|
||||
} while (error);
|
||||
}
|
||||
} while(!terminating);
|
||||
if (this->sfd != INVALID_SOCKET) {
|
||||
/* Send a graceful termination */
|
||||
this->log(ll_debug, "Graceful shutdown of shard " + std::to_string(this->shard_id) + " succeeded.");
|
||||
this->nonblocking = false;
|
||||
this->send_close_packet();
|
||||
ssl_client::close();
|
||||
} else {
|
||||
this->log(ll_debug, "Graceful shutdown of shard " + std::to_string(this->shard_id) + " not possible, socket already closed.");
|
||||
}
|
||||
end_zlib();
|
||||
}
|
||||
|
||||
void discord_client::run()
|
||||
{
|
||||
this->runner = new std::thread(&discord_client::thread_run, this);
|
||||
this->thread_id = runner->native_handle();
|
||||
}
|
||||
|
||||
bool discord_client::handle_frame(const std::string &buffer)
|
||||
{
|
||||
std::string& data = (std::string&)buffer;
|
||||
|
||||
/* gzip compression is a special case */
|
||||
if (compressed) {
|
||||
/* Check that we have a complete compressed frame */
|
||||
if ((uint8_t)buffer[buffer.size() - 4] == 0x00 && (uint8_t)buffer[buffer.size() - 3] == 0x00 && (uint8_t)buffer[buffer.size() - 2] == 0xFF
|
||||
&& (uint8_t)buffer[buffer.size() - 1] == 0xFF) {
|
||||
/* Decompress buffer */
|
||||
decompressed.clear();
|
||||
zlib->d_stream.next_in = (Bytef *)buffer.c_str();
|
||||
zlib->d_stream.avail_in = (uInt)buffer.size();
|
||||
do {
|
||||
int have = 0;
|
||||
zlib->d_stream.next_out = (Bytef*)decomp_buffer;
|
||||
zlib->d_stream.avail_out = DECOMP_BUFFER_SIZE;
|
||||
int ret = inflate(&(zlib->d_stream), Z_NO_FLUSH);
|
||||
have = DECOMP_BUFFER_SIZE - zlib->d_stream.avail_out;
|
||||
switch (ret)
|
||||
{
|
||||
case Z_NEED_DICT:
|
||||
case Z_STREAM_ERROR:
|
||||
this->error(6000);
|
||||
this->close();
|
||||
return true;
|
||||
break;
|
||||
case Z_DATA_ERROR:
|
||||
this->error(6001);
|
||||
this->close();
|
||||
return true;
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
this->error(6002);
|
||||
this->close();
|
||||
return true;
|
||||
break;
|
||||
case Z_OK:
|
||||
this->decompressed.append((const char*)decomp_buffer, have);
|
||||
this->decompressed_total += have;
|
||||
break;
|
||||
default:
|
||||
/* Stub */
|
||||
break;
|
||||
}
|
||||
} while (zlib->d_stream.avail_out == 0);
|
||||
data = decompressed;
|
||||
} else {
|
||||
/* No complete compressed frame yet */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
json j;
|
||||
|
||||
/**
|
||||
* This section parses the input frames from the websocket after they're decompressed.
|
||||
* Note that both ETF and JSON parsers return an nlohmann::json object, so that the rest
|
||||
* of the library or any user code does not need to be concerned with protocol differences.
|
||||
* Generally, ETF is faster and consumes much less memory, but provides less opportunities
|
||||
* to diagnose if it goes wrong.
|
||||
*/
|
||||
switch (protocol) {
|
||||
case ws_json:
|
||||
try {
|
||||
j = json::parse(data);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
log(dpp::ll_error, "discord_client::handle_frame(JSON): " + std::string(e.what()) + " [" + data + "]");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case ws_etf:
|
||||
try {
|
||||
j = etf->parse(data);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
log(dpp::ll_error, "discord_client::handle_frame(ETF): " + std::string(e.what()) + " len=" + std::to_string(data.size()) + "\n" + dpp::utility::debug_dump((uint8_t*)data.data(), data.size()));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
auto seq = j.find("s");
|
||||
if (seq != j.end() && !seq->is_null()) {
|
||||
last_seq = seq->get<uint64_t>();
|
||||
}
|
||||
|
||||
auto o = j.find("op");
|
||||
if (o != j.end() && !o->is_null()) {
|
||||
uint32_t op = o->get<uint32_t>();
|
||||
|
||||
switch (op) {
|
||||
case 9:
|
||||
/* Reset session state and fall through to 10 */
|
||||
op = 10;
|
||||
log(dpp::ll_debug, "Failed to resume session " + sessionid + ", will reidentify");
|
||||
this->sessionid.clear();
|
||||
this->last_seq = 0;
|
||||
/* No break here, falls through to state 10 to cause a reidentify */
|
||||
[[fallthrough]];
|
||||
case 10:
|
||||
/* Need to check carefully for the existence of this before we try to access it! */
|
||||
if (j.find("d") != j.end() && j["d"].find("heartbeat_interval") != j["d"].end() && !j["d"]["heartbeat_interval"].is_null()) {
|
||||
this->heartbeat_interval = j["d"]["heartbeat_interval"].get<uint32_t>();
|
||||
}
|
||||
|
||||
if (last_seq && !sessionid.empty()) {
|
||||
/* Resume */
|
||||
log(dpp::ll_debug, "Resuming session " + sessionid + " with seq=" + std::to_string(last_seq));
|
||||
json obj = {
|
||||
{ "op", 6 },
|
||||
{ "d", {
|
||||
{"token", this->token },
|
||||
{"session_id", this->sessionid },
|
||||
{"seq", this->last_seq }
|
||||
}
|
||||
}
|
||||
};
|
||||
this->write(jsonobj_to_string(obj));
|
||||
resumes++;
|
||||
} else {
|
||||
/* Full connect */
|
||||
while (time(nullptr) < creator->last_identify + 5) {
|
||||
time_t wait = (creator->last_identify + 5) - time(nullptr);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(wait));
|
||||
}
|
||||
log(dpp::ll_debug, "Connecting new session...");
|
||||
json obj = {
|
||||
{ "op", 2 },
|
||||
{
|
||||
"d",
|
||||
{
|
||||
{ "token", this->token },
|
||||
{ "properties",
|
||||
{
|
||||
{ "os", STRINGIFY(DPP_OS) },
|
||||
{ "browser", "D++" },
|
||||
{ "device", "D++" }
|
||||
}
|
||||
},
|
||||
{ "shard", json::array({ shard_id, max_shards }) },
|
||||
{ "compress", false },
|
||||
{ "large_threshold", 250 },
|
||||
{ "intents", this->intents }
|
||||
}
|
||||
}
|
||||
};
|
||||
this->write(jsonobj_to_string(obj));
|
||||
this->connect_time = creator->last_identify = time(NULL);
|
||||
reconnects++;
|
||||
}
|
||||
this->last_heartbeat_ack = time(nullptr);
|
||||
websocket_ping = 0;
|
||||
break;
|
||||
case 0: {
|
||||
std::string event = j["t"];
|
||||
handle_event(event, j, data);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
log(dpp::ll_debug, "Reconnection requested, closing socket " + sessionid);
|
||||
message_queue.clear();
|
||||
throw dpp::connection_exception("Remote site requested reconnection");
|
||||
break;
|
||||
/* Heartbeat ack */
|
||||
case 11:
|
||||
this->last_heartbeat_ack = time(nullptr);
|
||||
websocket_ping = utility::time_f() - ping_start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
dpp::utility::uptime discord_client::get_uptime()
|
||||
{
|
||||
return dpp::utility::uptime(time(NULL) - connect_time);
|
||||
}
|
||||
|
||||
bool discord_client::is_connected()
|
||||
{
|
||||
return (this->get_state() == CONNECTED) && (this->ready);
|
||||
}
|
||||
|
||||
void discord_client::error(uint32_t errorcode)
|
||||
{
|
||||
const static std::map<uint32_t, std::string> errortext = {
|
||||
{ 1000, "Socket shutdown" },
|
||||
{ 1001, "Client is leaving" },
|
||||
{ 1002, "Endpoint received a malformed frame" },
|
||||
{ 1003, "Endpoint received an unsupported frame" },
|
||||
{ 1004, "Reserved code" },
|
||||
{ 1005, "Expected close status, received none" },
|
||||
{ 1006, "No close code frame has been received" },
|
||||
{ 1007, "Endpoint received inconsistent message (e.g. malformed UTF-8)" },
|
||||
{ 1008, "Generic error" },
|
||||
{ 1009, "Endpoint won't process large frame" },
|
||||
{ 1010, "Client wanted an extension which server did not negotiate" },
|
||||
{ 1011, "Internal server error while operating" },
|
||||
{ 1012, "Server/service is restarting" },
|
||||
{ 1013, "Temporary server condition forced blocking client's request" },
|
||||
{ 1014, "Server acting as gateway received an invalid response" },
|
||||
{ 1015, "Transport Layer Security handshake failure" },
|
||||
{ 4000, "Unknown error" },
|
||||
{ 4001, "Unknown opcode" },
|
||||
{ 4002, "Decode error" },
|
||||
{ 4003, "Not authenticated" },
|
||||
{ 4004, "Authentication failed" },
|
||||
{ 4005, "Already authenticated" },
|
||||
{ 4007, "Invalid seq" },
|
||||
{ 4008, "Rate limited" },
|
||||
{ 4009, "Session timed out" },
|
||||
{ 4010, "Invalid shard" },
|
||||
{ 4011, "Sharding required" },
|
||||
{ 4012, "Invalid API version" },
|
||||
{ 4013, "Invalid intent(s)" },
|
||||
{ 4014, "Disallowed intent(s)" },
|
||||
{ 6000, "ZLib Stream Error" },
|
||||
{ 6001, "ZLib Data Error" },
|
||||
{ 6002, "ZLib Memory Error" },
|
||||
{ 6666, "Hell freezing over" }
|
||||
};
|
||||
std::string error = "Unknown error";
|
||||
auto i = errortext.find(errorcode);
|
||||
if (i != errortext.end()) {
|
||||
error = i->second;
|
||||
}
|
||||
log(dpp::ll_warning, "OOF! Error from underlying websocket: " + std::to_string(errorcode) + ": " + error);
|
||||
}
|
||||
|
||||
void discord_client::log(dpp::loglevel severity, const std::string &msg) const
|
||||
{
|
||||
if (!creator->on_log.empty()) {
|
||||
/* Pass to user if they've hooked the event */
|
||||
dpp::log_t logmsg(nullptr, msg);
|
||||
logmsg.severity = severity;
|
||||
logmsg.message = msg;
|
||||
creator->on_log.call(logmsg);
|
||||
}
|
||||
}
|
||||
|
||||
void discord_client::queue_message(const std::string &j, bool to_front)
|
||||
{
|
||||
std::unique_lock locker(queue_mutex);
|
||||
if (to_front) {
|
||||
message_queue.emplace_front(j);
|
||||
} else {
|
||||
message_queue.emplace_back(j);
|
||||
}
|
||||
}
|
||||
|
||||
discord_client& discord_client::clear_queue()
|
||||
{
|
||||
std::unique_lock locker(queue_mutex);
|
||||
message_queue.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t discord_client::get_queue_size()
|
||||
{
|
||||
std::shared_lock locker(queue_mutex);
|
||||
return message_queue.size();
|
||||
}
|
||||
|
||||
void discord_client::one_second_timer()
|
||||
{
|
||||
if (terminating) {
|
||||
throw dpp::exception("Shard terminating due to cluster shutdown");
|
||||
}
|
||||
|
||||
websocket_client::one_second_timer();
|
||||
|
||||
/* Every minute, rehash all containers from first shard.
|
||||
* We can't just get shard with the id 0 because this won't
|
||||
* work on a clustered environment
|
||||
*/
|
||||
auto shards = creator->get_shards();
|
||||
auto first_iter = shards.begin();
|
||||
if (first_iter != shards.end()) {
|
||||
dpp::discord_client* first_shard = first_iter->second;
|
||||
if (first_shard == this) {
|
||||
creator->tick_timers();
|
||||
|
||||
if ((time(NULL) % 60) == 0) {
|
||||
dpp::garbage_collection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This all only triggers if we are connected (have completed websocket, and received READY or RESUMED) */
|
||||
if (this->is_connected()) {
|
||||
|
||||
/* If we stopped getting heartbeat acknowledgements, this means the connections is dead.
|
||||
* This can happen to TCP connections which is why we have heartbeats in the first place.
|
||||
* Miss two ACKS, forces a reconnection.
|
||||
*/
|
||||
if ((time(nullptr) - this->last_heartbeat_ack) > heartbeat_interval * 2) {
|
||||
log(dpp::ll_warning, "Missed heartbeat ACK, forcing reconnection to session " + sessionid);
|
||||
message_queue.clear();
|
||||
close_socket(sfd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Rate limit outbound messages, 1 every odd second, 2 every even second */
|
||||
for (int x = 0; x < (time(NULL) % 2) + 1; ++x) {
|
||||
std::unique_lock locker(queue_mutex);
|
||||
if (message_queue.size()) {
|
||||
std::string message = message_queue.front();
|
||||
message_queue.pop_front();
|
||||
/* Checking here with .find() saves us having to deserialise the json
|
||||
* to find pings in our queue. The assumption is that the format of the
|
||||
* ping isn't going to change.
|
||||
*/
|
||||
if (!last_ping_message.empty() && message == last_ping_message) {
|
||||
ping_start = utility::time_f();
|
||||
last_ping_message.clear();
|
||||
}
|
||||
this->write(message);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send pings (heartbeat opcodes) before each interval. We send them slightly more regular than expected,
|
||||
* just to be safe.
|
||||
*/
|
||||
if (this->heartbeat_interval && this->last_seq) {
|
||||
/* Check if we're due to emit a heartbeat */
|
||||
if (time(NULL) > last_heartbeat + ((heartbeat_interval / 1000.0) * 0.75)) {
|
||||
last_ping_message = jsonobj_to_string(json({{"op", 1}, {"d", last_seq}}));
|
||||
queue_message(last_ping_message, true);
|
||||
last_heartbeat = time(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t discord_client::get_guild_count() {
|
||||
uint64_t total = 0;
|
||||
dpp::cache<guild>* c = dpp::get_guild_cache();
|
||||
/* IMPORTANT: We must lock the container to iterate it */
|
||||
std::shared_lock l(c->get_mutex());
|
||||
std::unordered_map<snowflake, guild*>& gc = c->get_container();
|
||||
for (auto g = gc.begin(); g != gc.end(); ++g) {
|
||||
dpp::guild* gp = (dpp::guild*)g->second;
|
||||
if (gp->shard_id == this->shard_id) {
|
||||
total++;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
uint64_t discord_client::get_member_count() {
|
||||
uint64_t total = 0;
|
||||
dpp::cache<guild>* c = dpp::get_guild_cache();
|
||||
/* IMPORTANT: We must lock the container to iterate it */
|
||||
std::shared_lock l(c->get_mutex());
|
||||
std::unordered_map<snowflake, guild*>& gc = c->get_container();
|
||||
for (auto g = gc.begin(); g != gc.end(); ++g) {
|
||||
dpp::guild* gp = (dpp::guild*)g->second;
|
||||
if (gp->shard_id == this->shard_id) {
|
||||
if (creator->cache_policy.user_policy == dpp::cp_aggressive) {
|
||||
/* We can use actual member count if we are using full user caching */
|
||||
total += gp->members.size();
|
||||
} else {
|
||||
/* Otherwise we use approximate guild member counts from guild_create */
|
||||
total += gp->member_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
uint64_t discord_client::get_channel_count() {
|
||||
uint64_t total = 0;
|
||||
dpp::cache<guild>* c = dpp::get_guild_cache();
|
||||
/* IMPORTANT: We must lock the container to iterate it */
|
||||
std::shared_lock l(c->get_mutex());
|
||||
std::unordered_map<snowflake, guild*>& gc = c->get_container();
|
||||
for (auto g = gc.begin(); g != gc.end(); ++g) {
|
||||
dpp::guild* gp = (dpp::guild*)g->second;
|
||||
if (gp->shard_id == this->shard_id) {
|
||||
total += gp->channels.size();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
discord_client& discord_client::connect_voice(snowflake guild_id, snowflake channel_id, bool self_mute, bool self_deaf) {
|
||||
#ifdef HAVE_VOICE
|
||||
std::unique_lock lock(voice_mutex);
|
||||
if (connecting_voice_channels.find(guild_id) == connecting_voice_channels.end()) {
|
||||
connecting_voice_channels[guild_id] = new voiceconn(this, channel_id);
|
||||
/* Once sent, this expects two events (in any order) on the websocket:
|
||||
* VOICE_SERVER_UPDATE and VOICE_STATUS_UPDATE
|
||||
*/
|
||||
log(ll_debug, "Sending op 4 to join VC, guild " + std::to_string(guild_id) + " channel " + std::to_string(channel_id));
|
||||
queue_message(jsonobj_to_string(json({
|
||||
{ "op", 4 },
|
||||
{ "d", {
|
||||
{ "guild_id", std::to_string(guild_id) },
|
||||
{ "channel_id", std::to_string(channel_id) },
|
||||
{ "self_mute", self_mute },
|
||||
{ "self_deaf", self_deaf },
|
||||
}
|
||||
}
|
||||
})), false);
|
||||
} else {
|
||||
log(ll_debug, "Requested the bot connect to voice channel " + std::to_string(channel_id) + " on guild " + std::to_string(guild_id) + ", but it seems we are already on this VC");
|
||||
}
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string discord_client::jsonobj_to_string(const nlohmann::json& json) {
|
||||
if (protocol == ws_json) {
|
||||
return json.dump();
|
||||
} else {
|
||||
return etf->build(json);
|
||||
}
|
||||
}
|
||||
|
||||
void discord_client::disconnect_voice_internal(snowflake guild_id, bool emit_json) {
|
||||
#ifdef HAVE_VOICE
|
||||
std::unique_lock lock(voice_mutex);
|
||||
auto v = connecting_voice_channels.find(guild_id);
|
||||
if (v != connecting_voice_channels.end()) {
|
||||
log(ll_debug, "Disconnecting voice, guild: {}" + std::to_string(guild_id));
|
||||
if (emit_json) {
|
||||
queue_message(jsonobj_to_string(json({
|
||||
{ "op", 4 },
|
||||
{ "d", {
|
||||
{ "guild_id", std::to_string(guild_id) },
|
||||
{ "channel_id", json::value_t::null },
|
||||
{ "self_mute", false },
|
||||
{ "self_deaf", false },
|
||||
}
|
||||
}
|
||||
})), false);
|
||||
}
|
||||
delete v->second;
|
||||
v->second = nullptr;
|
||||
connecting_voice_channels.erase(v);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
discord_client& discord_client::disconnect_voice(snowflake guild_id) {
|
||||
disconnect_voice_internal(guild_id, true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
voiceconn* discord_client::get_voice(snowflake guild_id) {
|
||||
#ifdef HAVE_VOICE
|
||||
std::shared_lock lock(voice_mutex);
|
||||
auto v = connecting_voice_channels.find(guild_id);
|
||||
if (v != connecting_voice_channels.end()) {
|
||||
return v->second;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
voiceconn::voiceconn(discord_client* o, snowflake _channel_id) : creator(o), channel_id(_channel_id), voiceclient(nullptr) {
|
||||
}
|
||||
|
||||
bool voiceconn::is_ready() {
|
||||
return (!websocket_hostname.empty() && !session_id.empty() && !token.empty());
|
||||
}
|
||||
|
||||
bool voiceconn::is_active() {
|
||||
return voiceclient != nullptr;
|
||||
}
|
||||
|
||||
voiceconn& voiceconn::disconnect() {
|
||||
if (this->is_active()) {
|
||||
delete voiceclient;
|
||||
voiceclient = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
voiceconn::~voiceconn() {
|
||||
this->disconnect();
|
||||
}
|
||||
|
||||
voiceconn& voiceconn::connect(snowflake guild_id) {
|
||||
if (this->is_ready() && !this->is_active()) {
|
||||
/* This is wrapped in a thread because instantiating discord_voice_client can initiate a blocking SSL_connect() */
|
||||
auto t = std::thread([guild_id, this]() {
|
||||
try {
|
||||
this->creator->log(ll_debug, "Connecting voice for guild " + std::to_string(guild_id) + " channel " + std::to_string(this->channel_id));
|
||||
this->voiceclient = new discord_voice_client(creator->creator, this->channel_id, guild_id, this->token, this->session_id, this->websocket_hostname);
|
||||
/* Note: Spawns thread! */
|
||||
this->voiceclient->run();
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
this->creator->log(ll_debug, "Can't connect to voice websocket (guild_id: " + std::to_string(guild_id) + ", channel_id: " + std::to_string(this->channel_id) + ": " + std::string(e.what()));
|
||||
}
|
||||
});
|
||||
t.detach();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
363
vendor/DPP/src/dpp/discordevents.cpp
vendored
Normal file
363
vendor/DPP/src/dpp/discordevents.cpp
vendored
Normal file
@@ -0,0 +1,363 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE
|
||||
#endif
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <dpp/discordclient.h>
|
||||
#include <dpp/event.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
#include <time.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
char* crossplatform_strptime(const char* s, const char* f, struct tm* tm) {
|
||||
std::istringstream input(s);
|
||||
input.imbue(std::locale(setlocale(LC_ALL, nullptr)));
|
||||
input >> std::get_time(tm, f);
|
||||
if (input.fail()) {
|
||||
return nullptr;
|
||||
}
|
||||
return (char*)(s + input.tellg());
|
||||
}
|
||||
|
||||
namespace dpp {
|
||||
|
||||
std::string ts_to_string(time_t ts) {
|
||||
std::ostringstream ss;
|
||||
struct tm t;
|
||||
#ifdef _WIN32
|
||||
gmtime_s(&t, &ts);
|
||||
#else
|
||||
gmtime_r(&ts, &t);
|
||||
#endif
|
||||
ss << std::put_time(&t, "%FT%TZ");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
uint64_t snowflake_not_null(const json* j, const char *keyname) {
|
||||
/* Snowflakes are a special case. Pun intended.
|
||||
* Because discord drinks the javascript kool-aid, they have to send 64 bit integers as strings as js can't deal with them
|
||||
* even though we can. So, all snowflakes are sent and received wrapped as string values and must be read by nlohmann::json
|
||||
* as string types, then converted from string to uint64_t. Checks for existence of the value, and that it is a string containing
|
||||
* a number. If not, then this function returns 0.
|
||||
*/
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() && k->is_string() ? strtoull(k->get<std::string>().c_str(), nullptr, 10) : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_snowflake_not_null(const json* j, const char *keyname, uint64_t &v) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() && k->is_string() ? strtoull(k->get<std::string>().c_str(), nullptr, 10) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string string_not_null(const json* j, const char *keyname) {
|
||||
/* Returns empty string if the value is not a string, or is null or not defined */
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() && k->is_string() ? k->get<std::string>() : "";
|
||||
} else {
|
||||
return const_cast< char* >("");
|
||||
}
|
||||
}
|
||||
|
||||
void set_string_not_null(const json* j, const char *keyname, std::string &v) {
|
||||
/* Returns empty string if the value is not a string, or is null or not defined */
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() && k->is_string() ? k->get<std::string>() : "";
|
||||
}
|
||||
}
|
||||
|
||||
double double_not_null(const json* j, const char *keyname) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() && !k->is_string() ? k->get<double>() : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_double_not_null(const json* j, const char *keyname, double &v) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() && !k->is_string() ? k->get<double>() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t int64_not_null(const json* j, const char *keyname) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() && !k->is_string() ? k->get<uint64_t>() : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_int64_not_null(const json* j, const char *keyname, uint64_t &v) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() && !k->is_string() ? k->get<uint64_t>() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t int32_not_null(const json* j, const char *keyname) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() && !k->is_string() ? k->get<uint32_t>() : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_int32_not_null(const json* j, const char *keyname, uint32_t &v) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() && !k->is_string() ? k->get<uint32_t>() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t int16_not_null(const json* j, const char *keyname) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() && !k->is_string() ? k->get<uint16_t>() : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_int16_not_null(const json* j, const char *keyname, uint16_t &v) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() && !k->is_string() ? k->get<uint16_t>() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t int8_not_null(const json* j, const char *keyname) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() && !k->is_string() ? k->get<uint8_t>() : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_int8_not_null(const json* j, const char *keyname, uint8_t &v) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() && !k->is_string() ? k->get<uint8_t>() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool bool_not_null(const json* j, const char *keyname) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
return !k->is_null() ? (k->get<bool>() == true) : false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void set_bool_not_null(const json* j, const char *keyname, bool &v) {
|
||||
auto k = j->find(keyname);
|
||||
if (k != j->end()) {
|
||||
v = !k->is_null() ? (k->get<bool>() == true) : false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* buf, unsigned int buffer_length) {
|
||||
/* Quick and dirty base64 encode */
|
||||
static const char to_base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
size_t ret_size = buffer_length + 2;
|
||||
|
||||
ret_size = 4 * ret_size / 3;
|
||||
|
||||
std::string ret;
|
||||
ret.reserve(ret_size);
|
||||
|
||||
for (unsigned int i=0; i<ret_size/4; ++i)
|
||||
{
|
||||
size_t index = i*3;
|
||||
unsigned char b3[3];
|
||||
b3[0] = buf[index+0];
|
||||
b3[1] = buf[index+1];
|
||||
b3[2] = buf[index+2];
|
||||
|
||||
ret.push_back(to_base64[ ((b3[0] & 0xfc) >> 2) ]);
|
||||
ret.push_back(to_base64[ ((b3[0] & 0x03) << 4) + ((b3[1] & 0xf0) >> 4) ]);
|
||||
ret.push_back(to_base64[ ((b3[1] & 0x0f) << 2) + ((b3[2] & 0xc0) >> 6) ]);
|
||||
ret.push_back(to_base64[ ((b3[2] & 0x3f)) ]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_t ts_not_null(const json* j, const char* keyname)
|
||||
{
|
||||
/* Parses discord ISO 8061 timestamps to time_t, accounting for local time adjustment.
|
||||
* Note that discord timestamps contain a decimal seconds part, which time_t and struct tm
|
||||
* can't handle. We strip these out.
|
||||
*/
|
||||
time_t retval = 0;
|
||||
if (j->contains(keyname) && !(*j)[keyname].is_null() && (*j)[keyname].is_string()) {
|
||||
tm timestamp = {};
|
||||
std::string timedate = (*j)[keyname].get<std::string>();
|
||||
if (timedate.find('+') != std::string::npos) {
|
||||
if (timedate.find('.') != std::string::npos) {
|
||||
timedate = timedate.substr(0, timedate.find('.'));
|
||||
}
|
||||
crossplatform_strptime(timedate.substr(0, 19).c_str(), "%Y-%m-%dT%T", ×tamp);
|
||||
timestamp.tm_isdst = 0;
|
||||
retval = mktime(×tamp);
|
||||
} else {
|
||||
crossplatform_strptime(timedate.substr(0, 19).c_str(), "%Y-%m-%d %T", ×tamp);
|
||||
retval = mktime(×tamp);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void set_ts_not_null(const json* j, const char* keyname, time_t &v)
|
||||
{
|
||||
/* Parses discord ISO 8061 timestamps to time_t, accounting for local time adjustment.
|
||||
* Note that discord timestamps contain a decimal seconds part, which time_t and struct tm
|
||||
* can't handle. We strip these out.
|
||||
*/
|
||||
if (j->contains(keyname) && !(*j)[keyname].is_null() && (*j)[keyname].is_string()) {
|
||||
time_t retval = 0;
|
||||
tm timestamp = {};
|
||||
std::string timedate = (*j)[keyname].get<std::string>();
|
||||
if (timedate.find('+') != std::string::npos) {
|
||||
if (timedate.find('.') != std::string::npos) {
|
||||
timedate = timedate.substr(0, timedate.find('.'));
|
||||
}
|
||||
crossplatform_strptime(timedate.substr(0, 19).c_str(), "%Y-%m-%dT%T", ×tamp);
|
||||
timestamp.tm_isdst = 0;
|
||||
retval = mktime(×tamp);
|
||||
} else {
|
||||
crossplatform_strptime(timedate.substr(0, 19).c_str(), "%Y-%m-%d %T", ×tamp);
|
||||
retval = mktime(×tamp);
|
||||
}
|
||||
v = retval;
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<std::string, dpp::events::event*> eventmap = {
|
||||
{ "__LOG__", new dpp::events::logger() },
|
||||
{ "GUILD_CREATE", new dpp::events::guild_create() },
|
||||
{ "GUILD_UPDATE", new dpp::events::guild_update() },
|
||||
{ "GUILD_DELETE", new dpp::events::guild_delete() },
|
||||
{ "GUILD_MEMBER_UPDATE", new dpp::events::guild_member_update() },
|
||||
{ "RESUMED", new dpp::events::resumed() },
|
||||
{ "READY", new dpp::events::ready() },
|
||||
{ "CHANNEL_CREATE", new dpp::events::channel_create() },
|
||||
{ "CHANNEL_UPDATE", new dpp::events::channel_update() },
|
||||
{ "CHANNEL_DELETE", new dpp::events::channel_delete() },
|
||||
{ "PRESENCE_UPDATE", new dpp::events::presence_update() },
|
||||
{ "TYPING_START", new dpp::events::typing_start() },
|
||||
{ "MESSAGE_CREATE", new dpp::events::message_create() },
|
||||
{ "MESSAGE_UPDATE", new dpp::events::message_update() },
|
||||
{ "MESSAGE_DELETE", new dpp::events::message_delete() },
|
||||
{ "MESSAGE_DELETE_BULK", new dpp::events::message_delete_bulk() },
|
||||
{ "MESSAGE_REACTION_ADD", new dpp::events::message_reaction_add() },
|
||||
{ "MESSAGE_REACTION_REMOVE", new dpp::events::message_reaction_remove() },
|
||||
{ "MESSAGE_REACTION_REMOVE_ALL", new dpp::events::message_reaction_remove_all() },
|
||||
{ "MESSAGE_REACTION_REMOVE_EMOJI", new dpp::events::message_reaction_remove_emoji() },
|
||||
{ "CHANNEL_PINS_UPDATE", new dpp::events::channel_pins_update() },
|
||||
{ "GUILD_BAN_ADD", new dpp::events::guild_ban_add() },
|
||||
{ "GUILD_BAN_REMOVE", new dpp::events::guild_ban_remove() },
|
||||
{ "GUILD_EMOJIS_UPDATE", new dpp::events::guild_emojis_update() },
|
||||
{ "GUILD_INTEGRATIONS_UPDATE", new dpp::events::guild_integrations_update() },
|
||||
{ "INTEGRATION_CREATE", new dpp::events::integration_create() },
|
||||
{ "INTEGRATION_UPDATE", new dpp::events::integration_update() },
|
||||
{ "INTEGRATION_DELETE", new dpp::events::integration_delete() },
|
||||
{ "GUILD_MEMBER_ADD", new dpp::events::guild_member_add() },
|
||||
{ "GUILD_MEMBER_REMOVE", new dpp::events::guild_member_remove() },
|
||||
{ "GUILD_MEMBERS_CHUNK", new dpp::events::guild_members_chunk() },
|
||||
{ "GUILD_ROLE_CREATE", new dpp::events::guild_role_create() },
|
||||
{ "GUILD_ROLE_UPDATE", new dpp::events::guild_role_update() },
|
||||
{ "GUILD_ROLE_DELETE", new dpp::events::guild_role_delete() },
|
||||
{ "VOICE_STATE_UPDATE", new dpp::events::voice_state_update() },
|
||||
{ "VOICE_SERVER_UPDATE", new dpp::events::voice_server_update() },
|
||||
{ "WEBHOOKS_UPDATE", new dpp::events::webhooks_update() },
|
||||
{ "INVITE_CREATE", new dpp::events::invite_create() },
|
||||
{ "INVITE_DELETE", new dpp::events::invite_delete() },
|
||||
{ "INTERACTION_CREATE", new dpp::events::interaction_create() },
|
||||
{ "USER_UPDATE", new dpp::events::user_update() },
|
||||
{ "GUILD_JOIN_REQUEST_DELETE", new dpp::events::guild_join_request_delete() },
|
||||
{ "GUILD_JOIN_REQUEST_UPDATE", nullptr },
|
||||
{ "STAGE_INSTANCE_CREATE", new dpp::events::stage_instance_create() },
|
||||
{ "STAGE_INSTANCE_UPDATE", new dpp::events::stage_instance_update() },
|
||||
{ "STAGE_INSTANCE_DELETE", new dpp::events::stage_instance_delete() },
|
||||
{ "THREAD_CREATE", new dpp::events::thread_create() },
|
||||
{ "THREAD_UPDATE", new dpp::events::thread_update() },
|
||||
{ "THREAD_DELETE", new dpp::events::thread_delete() },
|
||||
{ "THREAD_LIST_SYNC", new dpp::events::thread_list_sync() },
|
||||
{ "THREAD_MEMBER_UPDATE", new dpp::events::thread_member_update() },
|
||||
{ "THREAD_MEMBERS_UPDATE", new dpp::events::thread_members_update() },
|
||||
{ "GUILD_STICKERS_UPDATE", new dpp::events::guild_stickers_update() },
|
||||
{ "GUILD_APPLICATION_COMMAND_COUNTS_UPDATE", nullptr },
|
||||
{ "APPLICATION_COMMAND_PERMISSIONS_UPDATE", nullptr },
|
||||
{ "EMBEDDED_ACTIVITY_UPDATE", nullptr },
|
||||
{ "GUILD_APPLICATION_COMMAND_INDEX_UPDATE", nullptr },
|
||||
{ "GUILD_SCHEDULED_EVENT_CREATE", new dpp::events::guild_scheduled_event_create() },
|
||||
{ "GUILD_SCHEDULED_EVENT_UPDATE", new dpp::events::guild_scheduled_event_update() },
|
||||
{ "GUILD_SCHEDULED_EVENT_DELETE", new dpp::events::guild_scheduled_event_delete() },
|
||||
{ "GUILD_SCHEDULED_EVENT_USER_ADD", new dpp::events::guild_scheduled_event_user_add() },
|
||||
{ "GUILD_SCHEDULED_EVENT_USER_REMOVE", new dpp::events::guild_scheduled_event_user_remove() },
|
||||
{ "AUTO_MODERATION_RULE_CREATE", new dpp::events::automod_rule_create() },
|
||||
{ "AUTO_MODERATION_RULE_UPDATE", new dpp::events::automod_rule_update() },
|
||||
{ "AUTO_MODERATION_RULE_DELETE", new dpp::events::automod_rule_delete() },
|
||||
{ "AUTO_MODERATION_ACTION_EXECUTION", new dpp::events::automod_rule_execute() },
|
||||
{ "GUILD_AUDIT_LOG_ENTRY_CREATE", nullptr }, /* TODO: Implement this event */
|
||||
};
|
||||
|
||||
void discord_client::handle_event(const std::string &event, json &j, const std::string &raw)
|
||||
{
|
||||
auto ev_iter = eventmap.find(event);
|
||||
if (ev_iter != eventmap.end()) {
|
||||
/* A handler with nullptr is silently ignored. We don't plan to make a handler for it
|
||||
* so this usually some user-only thing that's crept into the API and shown to bots
|
||||
* that we dont care about.
|
||||
*/
|
||||
if (ev_iter->second != nullptr) {
|
||||
ev_iter->second->handle(this, j, raw);
|
||||
}
|
||||
} else {
|
||||
log(dpp::ll_debug, "Unhandled event: " + event + ", " + j.dump());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
1282
vendor/DPP/src/dpp/discordvoiceclient.cpp
vendored
Normal file
1282
vendor/DPP/src/dpp/discordvoiceclient.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
315
vendor/DPP/src/dpp/dispatcher.cpp
vendored
Normal file
315
vendor/DPP/src/dpp/dispatcher.cpp
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/appcommand.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/discordclient.h>
|
||||
#include <dpp/dispatcher.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <variant>
|
||||
|
||||
#define event_ctor(a, b) a::a(discord_client* client, const std::string &raw) : b(client, raw) {}
|
||||
|
||||
namespace dpp {
|
||||
|
||||
thread_local bool stop_event = false;
|
||||
|
||||
event_dispatch_t::event_dispatch_t(discord_client* client, const std::string &raw) : raw_event(raw), from(client)
|
||||
{
|
||||
/* NOTE: This is thread_local because the event_dispatch_t sent to the event is const and cannot itself be modified,
|
||||
* so there's no const-safe way to set an object variable to true later!
|
||||
*/
|
||||
stop_event = false;
|
||||
}
|
||||
|
||||
const event_dispatch_t& event_dispatch_t::cancel_event() const
|
||||
{
|
||||
/* NOTE: This is thread_local because the event_dispatch_t sent to the event is const and cannot itself be modified,
|
||||
* so there's no const-safe way to have this as an object property!
|
||||
*/
|
||||
stop_event = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool event_dispatch_t::is_cancelled() const
|
||||
{
|
||||
return stop_event;
|
||||
}
|
||||
|
||||
context_menu_t::context_menu_t(class discord_client* client, const std::string& raw) : interaction_create_t(client, raw) {
|
||||
}
|
||||
|
||||
message_context_menu_t::message_context_menu_t(class discord_client* client, const std::string& raw) : context_menu_t(client, raw) {
|
||||
}
|
||||
|
||||
message message_context_menu_t::get_message() const {
|
||||
return ctx_message;
|
||||
}
|
||||
|
||||
message_context_menu_t& message_context_menu_t::set_message(const message& m) {
|
||||
ctx_message = m;
|
||||
return *this;
|
||||
}
|
||||
|
||||
user_context_menu_t::user_context_menu_t(class discord_client* client, const std::string& raw) : context_menu_t(client, raw) {
|
||||
}
|
||||
|
||||
user user_context_menu_t::get_user() const {
|
||||
return ctx_user;
|
||||
}
|
||||
|
||||
user_context_menu_t& user_context_menu_t::set_user(const user& u) {
|
||||
ctx_user = u;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void message_create_t::send(const std::string& m, command_completion_event_t callback) const
|
||||
{
|
||||
this->send(dpp::message(m), callback);
|
||||
}
|
||||
|
||||
void message_create_t::send(message& msg, command_completion_event_t callback) const
|
||||
{
|
||||
msg.channel_id = this->msg.channel_id;
|
||||
this->from->creator->message_create(msg, callback);
|
||||
}
|
||||
|
||||
void message_create_t::send(message&& msg, command_completion_event_t callback) const
|
||||
{
|
||||
msg.channel_id = this->msg.channel_id;
|
||||
this->from->creator->message_create(msg, callback);
|
||||
}
|
||||
|
||||
void message_create_t::reply(const std::string& m, bool mention_replied_user, command_completion_event_t callback) const
|
||||
{
|
||||
this->reply(dpp::message(m), mention_replied_user, callback);
|
||||
}
|
||||
|
||||
void message_create_t::reply(message& msg, bool mention_replied_user, command_completion_event_t callback) const
|
||||
{
|
||||
msg.set_reference(this->msg.id);
|
||||
msg.channel_id = this->msg.channel_id;
|
||||
if (mention_replied_user) {
|
||||
msg.allowed_mentions.replied_user = mention_replied_user;
|
||||
msg.allowed_mentions.users.push_back(this->msg.author.id);
|
||||
}
|
||||
this->from->creator->message_create(msg, callback);
|
||||
}
|
||||
|
||||
void message_create_t::reply(message&& msg, bool mention_replied_user, command_completion_event_t callback) const
|
||||
{
|
||||
msg.set_reference(this->msg.id);
|
||||
msg.channel_id = this->msg.channel_id;
|
||||
if (mention_replied_user) {
|
||||
msg.allowed_mentions.replied_user = mention_replied_user;
|
||||
msg.allowed_mentions.users.push_back(this->msg.author.id);
|
||||
}
|
||||
this->from->creator->message_create(msg, callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::reply(interaction_response_type t, const message & m, command_completion_event_t callback) const
|
||||
{
|
||||
from->creator->interaction_response_create(this->command.id, this->command.token, dpp::interaction_response(t, m), callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::reply(const message & m, command_completion_event_t callback) const
|
||||
{
|
||||
from->creator->interaction_response_create(
|
||||
this->command.id,
|
||||
this->command.token,
|
||||
dpp::interaction_response(ir_channel_message_with_source, m),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
void interaction_create_t::thinking(bool ephemeral, command_completion_event_t callback) const {
|
||||
message msg;
|
||||
msg.content = "*";
|
||||
msg.guild_id = this->command.guild_id;
|
||||
msg.channel_id = this->command.channel_id;
|
||||
if (ephemeral) {
|
||||
msg.set_flags(dpp::m_ephemeral);
|
||||
}
|
||||
this->reply(ir_deferred_channel_message_with_source, msg, callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::reply(command_completion_event_t callback) const
|
||||
{
|
||||
this->reply(ir_deferred_update_message, message(), callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::dialog(const interaction_modal_response& mr, command_completion_event_t callback) const
|
||||
{
|
||||
from->creator->interaction_response_create(this->command.id, this->command.token, mr, callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::reply(interaction_response_type t, const std::string & mt, command_completion_event_t callback) const
|
||||
{
|
||||
this->reply(t, dpp::message(this->command.channel_id, mt, mt_application_command), callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::reply(const std::string & mt, command_completion_event_t callback) const
|
||||
{
|
||||
this->reply(ir_channel_message_with_source, dpp::message(this->command.channel_id, mt, mt_application_command), callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::edit_response(const message & m, command_completion_event_t callback) const
|
||||
{
|
||||
from->creator->interaction_response_edit(this->command.token, m, callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::edit_response(const std::string & mt, command_completion_event_t callback) const
|
||||
{
|
||||
this->edit_response(dpp::message(this->command.channel_id, mt, mt_application_command), callback);
|
||||
}
|
||||
|
||||
void interaction_create_t::get_original_response(command_completion_event_t callback) const
|
||||
{
|
||||
from->creator->post_rest(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_get, "", [creator = this->from->creator, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(creator, message().fill_from_json(&j), http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void interaction_create_t::edit_original_response(const message & m, command_completion_event_t callback) const
|
||||
{
|
||||
from->creator->post_rest_multipart(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_patch, m.build_json(), [creator = this->from->creator, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(creator, message().fill_from_json(&j), http));
|
||||
}
|
||||
}, m.filename, m.filecontent);
|
||||
}
|
||||
|
||||
void interaction_create_t::delete_original_response(command_completion_event_t callback) const
|
||||
{
|
||||
from->creator->post_rest(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_delete, "", [creator = this->from->creator, callback](json &j, const http_request_completion_t& http) {
|
||||
if (callback) {
|
||||
callback(confirmation_callback_t(creator, confirmation(), http));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const command_value& interaction_create_t::get_parameter(const std::string& name) const
|
||||
{
|
||||
/* Dummy STATIC return value for unknown options so we aren't returning a value off the stack */
|
||||
static command_value dummy_value = {};
|
||||
const command_interaction& ci = std::get<command_interaction>(command.data);
|
||||
for (auto i = ci.options.begin(); i != ci.options.end(); ++i) {
|
||||
if (i->name == name) {
|
||||
return i->value;
|
||||
}
|
||||
}
|
||||
return dummy_value;
|
||||
}
|
||||
|
||||
voice_receive_t::voice_receive_t(class discord_client* client, const std::string &raw, class discord_voice_client* vc, snowflake _user_id, uint8_t* pcm, size_t length) : event_dispatch_t(client, raw), voice_client(vc), user_id(_user_id) {
|
||||
reassign(vc, _user_id, pcm, length);
|
||||
}
|
||||
|
||||
void voice_receive_t::reassign(class discord_voice_client* vc, snowflake _user_id, uint8_t* pcm, size_t length) {
|
||||
voice_client = vc;
|
||||
user_id = _user_id;
|
||||
|
||||
audio_data.assign(pcm, length);
|
||||
|
||||
// for backwards compatibility; remove soon
|
||||
audio = audio_data.data();
|
||||
audio_size = audio_data.length();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Standard default constructors that call the parent constructor, for events */
|
||||
event_ctor(guild_join_request_delete_t, event_dispatch_t);
|
||||
event_ctor(stage_instance_create_t, event_dispatch_t);
|
||||
event_ctor(stage_instance_update_t, event_dispatch_t);
|
||||
event_ctor(stage_instance_delete_t, event_dispatch_t);
|
||||
event_ctor(log_t, event_dispatch_t);
|
||||
event_ctor(voice_state_update_t, event_dispatch_t);
|
||||
event_ctor(interaction_create_t, event_dispatch_t);
|
||||
event_ctor(button_click_t, interaction_create_t);
|
||||
event_ctor(autocomplete_t, interaction_create_t);
|
||||
event_ctor(select_click_t, interaction_create_t);
|
||||
event_ctor(form_submit_t, interaction_create_t);
|
||||
event_ctor(slashcommand_t, interaction_create_t);
|
||||
event_ctor(guild_delete_t, event_dispatch_t);
|
||||
event_ctor(channel_delete_t, event_dispatch_t);
|
||||
event_ctor(channel_update_t, event_dispatch_t);
|
||||
event_ctor(ready_t, event_dispatch_t);
|
||||
event_ctor(message_delete_t, event_dispatch_t);
|
||||
event_ctor(resumed_t, event_dispatch_t);
|
||||
event_ctor(guild_role_create_t, event_dispatch_t);
|
||||
event_ctor(typing_start_t, event_dispatch_t);
|
||||
event_ctor(message_reaction_add_t, event_dispatch_t);
|
||||
event_ctor(message_reaction_remove_t, event_dispatch_t);
|
||||
event_ctor(guild_create_t, event_dispatch_t);
|
||||
event_ctor(channel_create_t, event_dispatch_t);
|
||||
event_ctor(message_reaction_remove_emoji_t, event_dispatch_t);
|
||||
event_ctor(message_delete_bulk_t, event_dispatch_t);
|
||||
event_ctor(guild_role_update_t, event_dispatch_t);
|
||||
event_ctor(guild_role_delete_t, event_dispatch_t);
|
||||
event_ctor(channel_pins_update_t, event_dispatch_t);
|
||||
event_ctor(message_reaction_remove_all_t, event_dispatch_t);
|
||||
event_ctor(voice_server_update_t, event_dispatch_t);
|
||||
event_ctor(guild_emojis_update_t, event_dispatch_t);
|
||||
event_ctor(presence_update_t, event_dispatch_t);
|
||||
event_ctor(webhooks_update_t, event_dispatch_t);
|
||||
event_ctor(guild_member_add_t, event_dispatch_t);
|
||||
event_ctor(invite_delete_t, event_dispatch_t);
|
||||
event_ctor(guild_update_t, event_dispatch_t);
|
||||
event_ctor(guild_integrations_update_t, event_dispatch_t);
|
||||
event_ctor(guild_member_update_t, event_dispatch_t);
|
||||
event_ctor(invite_create_t, event_dispatch_t);
|
||||
event_ctor(message_update_t, event_dispatch_t);
|
||||
event_ctor(user_update_t, event_dispatch_t);
|
||||
event_ctor(message_create_t, event_dispatch_t);
|
||||
event_ctor(guild_ban_add_t, event_dispatch_t);
|
||||
event_ctor(guild_ban_remove_t, event_dispatch_t);
|
||||
event_ctor(integration_create_t, event_dispatch_t);
|
||||
event_ctor(integration_update_t, event_dispatch_t);
|
||||
event_ctor(integration_delete_t, event_dispatch_t);
|
||||
event_ctor(guild_member_remove_t, event_dispatch_t);
|
||||
event_ctor(guild_members_chunk_t, event_dispatch_t);
|
||||
event_ctor(thread_create_t, event_dispatch_t);
|
||||
event_ctor(thread_update_t, event_dispatch_t);
|
||||
event_ctor(thread_delete_t, event_dispatch_t);
|
||||
event_ctor(thread_list_sync_t, event_dispatch_t);
|
||||
event_ctor(thread_member_update_t, event_dispatch_t);
|
||||
event_ctor(thread_members_update_t, event_dispatch_t);
|
||||
event_ctor(voice_buffer_send_t, event_dispatch_t);
|
||||
event_ctor(voice_user_talking_t, event_dispatch_t);
|
||||
event_ctor(voice_ready_t, event_dispatch_t);
|
||||
event_ctor(voice_receive_t, event_dispatch_t);
|
||||
event_ctor(voice_client_speaking_t, event_dispatch_t);
|
||||
event_ctor(voice_client_disconnect_t, event_dispatch_t);
|
||||
event_ctor(voice_track_marker_t, event_dispatch_t);
|
||||
event_ctor(guild_stickers_update_t, event_dispatch_t);
|
||||
event_ctor(guild_scheduled_event_create_t, event_dispatch_t);
|
||||
event_ctor(guild_scheduled_event_update_t, event_dispatch_t);
|
||||
event_ctor(guild_scheduled_event_delete_t, event_dispatch_t);
|
||||
event_ctor(guild_scheduled_event_user_add_t, event_dispatch_t);
|
||||
event_ctor(guild_scheduled_event_user_remove_t, event_dispatch_t);
|
||||
event_ctor(automod_rule_create_t, event_dispatch_t);
|
||||
event_ctor(automod_rule_delete_t, event_dispatch_t);
|
||||
event_ctor(automod_rule_update_t, event_dispatch_t);
|
||||
event_ctor(automod_rule_execute_t, event_dispatch_t);
|
||||
};
|
||||
108
vendor/DPP/src/dpp/dns.cpp
vendored
Normal file
108
vendor/DPP/src/dpp/dns.cpp
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#include <dpp/dns.h>
|
||||
#include <cerrno>
|
||||
#include <exception>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <dpp/exception.h>
|
||||
|
||||
namespace dpp
|
||||
{
|
||||
/* One hour in seconds */
|
||||
constexpr time_t one_hour = 60 * 60;
|
||||
|
||||
/* Thread safety mutex for dns cache */
|
||||
std::shared_mutex dns_cache_mutex;
|
||||
|
||||
/* Cache container */
|
||||
dns_cache_t dns_cache;
|
||||
|
||||
const dns_cache_entry* resolve_hostname(const std::string& hostname, const std::string& port)
|
||||
{
|
||||
addrinfo hints, *addrs;
|
||||
dns_cache_t::const_iterator iter;
|
||||
time_t now = time(nullptr);
|
||||
int error;
|
||||
bool exists = false;
|
||||
|
||||
/* Thread safety scope */
|
||||
{
|
||||
/* Check cache for existing DNS record. This can use a shared lock. */
|
||||
std::shared_lock dns_cache_lock(dns_cache_mutex);
|
||||
iter = dns_cache.find(hostname);
|
||||
if (iter != dns_cache.end()) {
|
||||
exists = true;
|
||||
if (now < iter->second->expire_timestamp) {
|
||||
/* there is a cached entry that is still valid, return it */
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exists) {
|
||||
/* there is a cached entry, but it has expired,
|
||||
* delete and free it, and fall through to a new lookup.
|
||||
* We must use a unique lock here as we modify the cache.
|
||||
*/
|
||||
std::unique_lock dns_cache_lock(dns_cache_mutex);
|
||||
iter = dns_cache.find(hostname);
|
||||
if (iter != dns_cache.end()) { /* re-validate iter */
|
||||
delete iter->second;
|
||||
dns_cache.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
/* The hints indicate what sort of DNS results we are interested in.
|
||||
* To change this to support IPv6, one change we need to make here is
|
||||
* to change AF_INET to AF_UNSPEC. Everything else should just work fine.
|
||||
*/
|
||||
memset(&hints, 0, sizeof(addrinfo));
|
||||
hints.ai_family = AF_INET; // IPv6 explicitly unsupported by Discord
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
if ((error = getaddrinfo(hostname.c_str(), port.c_str(), &hints, &addrs))) {
|
||||
throw dpp::connection_exception(std::string("getaddrinfo error: ") + gai_strerror(error));
|
||||
}
|
||||
|
||||
/* Thread safety scope */
|
||||
{
|
||||
/* Update cache, requires unique lock */
|
||||
std::unique_lock dns_cache_lock(dns_cache_mutex);
|
||||
dns_cache_entry* cache_entry = new dns_cache_entry();
|
||||
|
||||
/* The sockaddr struct contains a bunch of raw pointers that we
|
||||
* must copy to the cache, before freeing it with freeaddrinfo().
|
||||
* Icky icky C APIs.
|
||||
*/
|
||||
memcpy(&cache_entry->addr, addrs, sizeof(addrinfo));
|
||||
memcpy(&cache_entry->ai_addr, addrs->ai_addr, addrs->ai_addrlen);
|
||||
cache_entry->expire_timestamp = now + one_hour;
|
||||
dns_cache[hostname] = cache_entry;
|
||||
|
||||
/* Now we're done with this horrible struct, free it and return */
|
||||
freeaddrinfo(addrs);
|
||||
return cache_entry;
|
||||
}
|
||||
}
|
||||
};
|
||||
59
vendor/DPP/src/dpp/dpp.rc.in
vendored
Normal file
59
vendor/DPP/src/dpp/dpp.rc.in
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#include <Winver.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION @DPP_VERSION_MAJOR@,@DPP_VERSION_MINOR@,@DPP_VERSION_PATCH@
|
||||
PRODUCTVERSION @DPP_VERSION_MAJOR@,@DPP_VERSION_MINOR@,@DPP_VERSION_PATCH@
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Brainbox.cc"
|
||||
VALUE "FileDescription", "D++ - The lightweight C++ Discord API Library"
|
||||
VALUE "FileVersion", "@DPP_VERSION@"
|
||||
VALUE "ProductVersion", "@DPP_VERSION@"
|
||||
VALUE "ProductName", "D++ Discord API Library"
|
||||
VALUE "InternalName", "DPP"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021 D++ contributors - Licensed under the Apache 2.0 License."
|
||||
VALUE "OriginalFilename", "dpp.dll"
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
61
vendor/DPP/src/dpp/dtemplate.cpp
vendored
Normal file
61
vendor/DPP/src/dpp/dtemplate.cpp
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/dtemplate.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp {
|
||||
|
||||
dtemplate::dtemplate() : code(""), name(""), description(""), usage_count(0), creator_id(0), source_guild_id(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
dtemplate& dtemplate::fill_from_json(nlohmann::json* j) {
|
||||
code = string_not_null(j, "code");
|
||||
name = string_not_null(j, "name");
|
||||
description = string_not_null(j, "description");
|
||||
usage_count = int32_not_null(j, "usage_count");
|
||||
creator_id = snowflake_not_null(j, "creator_id");
|
||||
created_at = ts_not_null(j, "created_at");
|
||||
updated_at = ts_not_null(j, "updated_at");
|
||||
source_guild_id = snowflake_not_null(j, "source_guild_id");
|
||||
is_dirty = bool_not_null(j, "is_dirty");
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string dtemplate::build_json(bool with_id) const {
|
||||
json j({
|
||||
{"code", code},
|
||||
{"name", name},
|
||||
{"description", description},
|
||||
{"usage_count", usage_count},
|
||||
{"creator_id", creator_id},
|
||||
{"updated_at", updated_at},
|
||||
{"source_guild_id", source_guild_id,
|
||||
"is_dirty", is_dirty}
|
||||
});
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
};
|
||||
122
vendor/DPP/src/dpp/emoji.cpp
vendored
Normal file
122
vendor/DPP/src/dpp/emoji.cpp
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/emoji.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/json.h>
|
||||
#include <dpp/exception.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
emoji::emoji() : managed(), user_id(0), flags(0), image_data(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
emoji::emoji(const std::string n, const snowflake i, const uint8_t f) : managed(i), name(n), user_id(0), flags(f), image_data(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
emoji::~emoji() {
|
||||
delete image_data;
|
||||
}
|
||||
|
||||
std::string emoji::get_mention(const std::string &name, const snowflake &id, bool is_animated) {
|
||||
return utility::emoji_mention(name,id,is_animated);
|
||||
}
|
||||
|
||||
emoji& emoji::fill_from_json(nlohmann::json* j) {
|
||||
id = snowflake_not_null(j, "id");
|
||||
name = string_not_null(j, "name");
|
||||
if (j->contains("user")) {
|
||||
json & user = (*j)["user"];
|
||||
user_id = snowflake_not_null(&user, "id");
|
||||
}
|
||||
if (bool_not_null(j, "require_colons"))
|
||||
flags |= e_require_colons;
|
||||
if (bool_not_null(j, "managed"))
|
||||
flags |= e_managed;
|
||||
if (bool_not_null(j, "animated"))
|
||||
flags |= e_animated;
|
||||
if (bool_not_null(j, "available"))
|
||||
flags |= e_available;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string emoji::build_json(bool with_id) const {
|
||||
json j;
|
||||
if (with_id) {
|
||||
j["id"] = std::to_string(id);
|
||||
}
|
||||
j["name"] = name;
|
||||
if (image_data) {
|
||||
j["image"] = *image_data;
|
||||
}
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
bool emoji::requires_colons() const {
|
||||
return flags & e_require_colons;
|
||||
}
|
||||
|
||||
bool emoji::is_managed() const {
|
||||
return flags & e_managed;
|
||||
}
|
||||
|
||||
bool emoji::is_animated() const {
|
||||
return flags & e_animated;
|
||||
}
|
||||
|
||||
bool emoji::is_available() const {
|
||||
return flags & e_available;
|
||||
}
|
||||
|
||||
emoji& emoji::load_image(const std::string &image_blob, const image_type type) {
|
||||
static const std::map<image_type, std::string> mimetypes = {
|
||||
{ i_gif, "image/gif" },
|
||||
{ i_jpg, "image/jpeg" },
|
||||
{ i_png, "image/png" },
|
||||
{ i_webp, "image/webp" },
|
||||
};
|
||||
if (image_blob.size() > MAX_EMOJI_SIZE) {
|
||||
throw dpp::length_exception("Emoji file exceeds discord limit of 256 kilobytes");
|
||||
}
|
||||
|
||||
/* If there's already image data defined, free the old data, to prevent a memory leak */
|
||||
delete image_data;
|
||||
|
||||
image_data = new std::string("data:" + mimetypes.find(type)->second + ";base64," + base64_encode((unsigned char const*)image_blob.data(), (unsigned int)image_blob.length()));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string emoji::format() const
|
||||
{
|
||||
return id ? ((is_animated() ? "a:" : "") + name + ":" + std::to_string(id)) : name;
|
||||
}
|
||||
|
||||
std::string emoji::get_mention() const {
|
||||
return utility::emoji_mention(name,id,is_animated());
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
727
vendor/DPP/src/dpp/etf.cpp
vendored
Normal file
727
vendor/DPP/src/dpp/etf.cpp
vendored
Normal file
@@ -0,0 +1,727 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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").
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/etf.h>
|
||||
#include <dpp/sysdep.h>
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/exception.h>
|
||||
#include <dpp/json.h>
|
||||
#include <zlib.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
void etf_parser::buffer_write(etf_buffer *pk, const char *bytes, size_t l) {
|
||||
|
||||
if (pk->length + l > pk->buf.size()) {
|
||||
// Grow buffer 2x to avoid excessive re-allocations.
|
||||
pk->buf.resize((pk->length + l) * 2);
|
||||
}
|
||||
|
||||
memcpy(pk->buf.data() + pk->length, bytes, l);
|
||||
pk->length += l;
|
||||
}
|
||||
|
||||
void etf_parser::append_version(etf_buffer *b) {
|
||||
static unsigned char buf[1] = {FORMAT_VERSION};
|
||||
buffer_write(b, (const char *)buf, 1);
|
||||
}
|
||||
|
||||
void etf_parser::append_nil(etf_buffer *b) {
|
||||
static unsigned char buf[5] = {ett_atom_small, 3, 'n', 'i', 'l'};
|
||||
buffer_write(b, (const char *)buf, 5);
|
||||
}
|
||||
|
||||
void etf_parser::append_false(etf_buffer *b) {
|
||||
static unsigned char buf[7] = {ett_atom_small, 5, 'f', 'a', 'l', 's', 'e'};
|
||||
buffer_write(b, (const char *)buf, 7);
|
||||
}
|
||||
|
||||
void etf_parser::append_true(etf_buffer *b) {
|
||||
static unsigned char buf[6] = {ett_atom_small, 4, 't', 'r', 'u', 'e'};
|
||||
buffer_write(b, (const char *)buf, 6);
|
||||
}
|
||||
|
||||
void etf_parser::append_small_integer(etf_buffer *b, unsigned char d) {
|
||||
unsigned char buf[2] = {ett_smallint, d};
|
||||
buffer_write(b, (const char *)buf, 2);
|
||||
}
|
||||
|
||||
void etf_parser::append_integer(etf_buffer *b, int32_t d) {
|
||||
unsigned char buf[5];
|
||||
buf[0] = ett_integer;
|
||||
store_32_bits(buf + 1, d);
|
||||
buffer_write(b, (const char *)buf, 5);
|
||||
}
|
||||
|
||||
void etf_parser::append_unsigned_long_long(etf_buffer *b, unsigned long long d) {
|
||||
unsigned char buf[1 + 2 + sizeof(unsigned long long)];
|
||||
buf[0] = ett_bigint_small;
|
||||
|
||||
unsigned char bytes_enc = 0;
|
||||
while (d > 0) {
|
||||
buf[3 + bytes_enc] = d & 0xFF;
|
||||
d >>= 8;
|
||||
bytes_enc++;
|
||||
}
|
||||
buf[1] = bytes_enc;
|
||||
buf[2] = 0;
|
||||
|
||||
buffer_write(b, (const char *)buf, 1 + 2 + bytes_enc);
|
||||
}
|
||||
|
||||
void etf_parser::append_long_long(etf_buffer *b, long long d) {
|
||||
unsigned char buf[1 + 2 + sizeof(unsigned long long)];
|
||||
buf[0] = ett_bigint_small;
|
||||
buf[2] = d < 0 ? 1 : 0;
|
||||
unsigned long long ull = d < 0 ? -d : d;
|
||||
unsigned char bytes_enc = 0;
|
||||
while (ull > 0) {
|
||||
buf[3 + bytes_enc] = ull & 0xFF;
|
||||
ull >>= 8;
|
||||
bytes_enc++;
|
||||
}
|
||||
buf[1] = bytes_enc;
|
||||
buffer_write(b, (const char *)buf, 1 + 2 + bytes_enc);
|
||||
}
|
||||
|
||||
void etf_parser::append_double(etf_buffer *b, double f) {
|
||||
unsigned char buf[1 + 8] = {0};
|
||||
buf[0] = ett_new_float;
|
||||
type_punner p;
|
||||
p.df = f;
|
||||
store_64_bits(buf + 1, p.ui64);
|
||||
buffer_write(b, (const char *)buf, 1 + 8);
|
||||
}
|
||||
|
||||
void etf_parser::append_atom(etf_buffer *b, const char *bytes, size_t size) {
|
||||
if (size < 255) {
|
||||
unsigned char buf[2] = {ett_atom_small, (unsigned char)size};
|
||||
buffer_write(b, (const char *)buf, 2);
|
||||
buffer_write(b, (const char *)bytes, size);
|
||||
} else {
|
||||
unsigned char buf[3];
|
||||
buf[0] = ett_atom;
|
||||
|
||||
if (size > 0xFFFF) {
|
||||
throw dpp::parse_exception("ETF: Atom too large");
|
||||
}
|
||||
|
||||
store_16_bits(buf + 1, size);
|
||||
buffer_write(b, (const char *)buf, 3);
|
||||
buffer_write(b, (const char *)bytes, size);
|
||||
}
|
||||
}
|
||||
|
||||
void etf_parser::append_atom_utf8(etf_buffer *b, const char *bytes, size_t size) {
|
||||
if (size < 255) {
|
||||
unsigned char buf[2] = {ett_atom_utf8_small, (unsigned char)size};
|
||||
buffer_write(b, (const char *)buf, 2);
|
||||
buffer_write(b, (const char *)bytes, size);
|
||||
} else {
|
||||
unsigned char buf[3];
|
||||
buf[0] = ett_atom_utf8;
|
||||
|
||||
if (size > 0xFFFF) {
|
||||
throw dpp::parse_exception("ETF: Atom too large");
|
||||
}
|
||||
|
||||
store_16_bits(buf + 1, size);
|
||||
buffer_write(b, (const char *)buf, 3);
|
||||
buffer_write(b, (const char *)bytes, size);
|
||||
}
|
||||
}
|
||||
|
||||
void etf_parser::append_binary(etf_buffer *b, const char *bytes, size_t size) {
|
||||
unsigned char buf[5];
|
||||
buf[0] = ett_binary;
|
||||
|
||||
store_32_bits(buf + 1, size);
|
||||
buffer_write(b, (const char *)buf, 5);
|
||||
buffer_write(b, (const char *)bytes, size);
|
||||
}
|
||||
|
||||
void etf_parser::append_string(etf_buffer *b, const char *bytes, size_t size) {
|
||||
unsigned char buf[3];
|
||||
buf[0] = ett_string;
|
||||
|
||||
store_16_bits(buf + 1, size);
|
||||
buffer_write(b, (const char *)buf, 3);
|
||||
buffer_write(b, (const char *)bytes, size);
|
||||
}
|
||||
|
||||
void etf_parser::append_tuple_header(etf_buffer *b, size_t size) {
|
||||
if (size < 256) {
|
||||
unsigned char buf[2];
|
||||
buf[0] = ett_small_tuple;
|
||||
buf[1] = (unsigned char)size;
|
||||
buffer_write(b, (const char *)buf, 2);
|
||||
} else {
|
||||
unsigned char buf[5];
|
||||
buf[0] = ett_large_tuple;
|
||||
store_32_bits(buf + 1, size);
|
||||
buffer_write(b, (const char *)buf, 5);
|
||||
}
|
||||
}
|
||||
|
||||
void etf_parser::append_nil_ext(etf_buffer *b) {
|
||||
static unsigned char buf[1] = {ett_nil};
|
||||
buffer_write(b, (const char *)buf, 1);
|
||||
}
|
||||
|
||||
void etf_parser::append_list_header(etf_buffer *b, size_t size) {
|
||||
unsigned char buf[5];
|
||||
buf[0] = ett_list;
|
||||
store_32_bits(buf + 1, size);
|
||||
buffer_write(b, (const char *)buf, 5);
|
||||
}
|
||||
|
||||
void etf_parser::append_map_header(etf_buffer *b, size_t size) {
|
||||
unsigned char buf[5];
|
||||
buf[0] = ett_map;
|
||||
store_32_bits(buf + 1, size);
|
||||
buffer_write(b, (const char *)buf, 5);
|
||||
}
|
||||
|
||||
etf_parser::etf_parser()
|
||||
{
|
||||
}
|
||||
|
||||
etf_parser::~etf_parser() = default;
|
||||
|
||||
|
||||
uint8_t etf_parser::read_8_bits() {
|
||||
if (offset + sizeof(uint8_t) > size) {
|
||||
throw dpp::parse_exception("ETF: read_8_bits() past end of buffer");
|
||||
}
|
||||
auto val = *reinterpret_cast<const uint8_t*>(data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
return val;
|
||||
}
|
||||
|
||||
uint16_t etf_parser::read_16_bits() {
|
||||
if (offset + sizeof(uint16_t) > size) {
|
||||
throw dpp::parse_exception("ETF: read_16_bits() past end of buffer");
|
||||
}
|
||||
uint16_t val = etf_byte_order_16(*reinterpret_cast<const uint16_t*>(data + offset));
|
||||
offset += sizeof(uint16_t);
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t etf_parser::read_32_bits() {
|
||||
if (offset + sizeof(uint32_t) > size) {
|
||||
throw dpp::parse_exception("ETF: read_32_bits() past end of buffer");
|
||||
}
|
||||
uint32_t val = etf_byte_order_32(*reinterpret_cast<const uint32_t*>(data + offset));
|
||||
offset += sizeof(uint32_t);
|
||||
return val;
|
||||
}
|
||||
|
||||
uint64_t etf_parser::read_64_bits() {
|
||||
if (offset + sizeof(uint64_t) > size) {
|
||||
throw dpp::parse_exception("ETF: read_64_bits() past end of buffer");
|
||||
}
|
||||
uint64_t val = etf_byte_order_64(*reinterpret_cast<const uint64_t*>(data + offset));
|
||||
offset += sizeof(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
const char* etf_parser::read_string(uint32_t length) {
|
||||
if (offset + length > size) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const uint8_t* str = data + offset;
|
||||
offset += length;
|
||||
return (const char*)str;
|
||||
}
|
||||
|
||||
static const char* atom_null = "null";
|
||||
static const char* atom_true = "true";
|
||||
static const char* atom_false = "false";
|
||||
|
||||
json etf_parser::process_atom(const char* atom, uint16_t length) {
|
||||
json j;
|
||||
|
||||
if (atom == NULL) {
|
||||
return j;
|
||||
}
|
||||
|
||||
if (length >= 3 && length <= 5) {
|
||||
if (length == 4 && *((uint32_t*)atom) == *((uint32_t*)atom_null)) { // "null"
|
||||
return j;
|
||||
}
|
||||
else if(length == 4 && *((uint32_t*)atom) == *((uint32_t*)atom_true)) { // "true"
|
||||
return true;
|
||||
}
|
||||
else if (length == 3 && atom[0] == 'n' && atom[1] == 'i' && atom[2] == 'l') { // "nil"
|
||||
return j;
|
||||
}
|
||||
else if (length == 5 && *((uint32_t*)atom) == *((uint32_t*)atom_false) && atom[4] == 'e') { // "fals","e"
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
j = std::string(atom, length);
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_atom() {
|
||||
auto length = read_16_bits();
|
||||
const char* atom = read_string(length);
|
||||
return process_atom(atom, length);
|
||||
}
|
||||
|
||||
json etf_parser::decode_small_atom() {
|
||||
auto length = read_8_bits();
|
||||
const char* atom = read_string(length);
|
||||
return process_atom(atom, length);
|
||||
}
|
||||
|
||||
json etf_parser::decode_small_integer() {
|
||||
json j;
|
||||
j = (uint8_t)read_8_bits();
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_integer() {
|
||||
json j;
|
||||
j = (int32_t)read_32_bits();
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_array(uint32_t length) {
|
||||
json array = json::array();
|
||||
for(uint32_t i = 0; i < length; ++i) {
|
||||
array.emplace_back(inner_parse());
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
json etf_parser::decode_list() {
|
||||
const uint32_t length = read_32_bits();
|
||||
auto array = decode_array(length);
|
||||
|
||||
const auto tailMarker = read_8_bits();
|
||||
if (tailMarker != ett_nil) {
|
||||
return json();
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
json etf_parser::decode_tuple(uint32_t length) {
|
||||
return decode_array(length);
|
||||
}
|
||||
|
||||
json etf_parser::decode_nil() {
|
||||
return json::array();
|
||||
}
|
||||
|
||||
json etf_parser::decode_map() {
|
||||
const uint32_t length = read_32_bits();
|
||||
json map;
|
||||
for(uint32_t i = 0; i < length; ++i) {
|
||||
auto key = inner_parse();
|
||||
if (key.is_number()) {
|
||||
map.emplace(std::to_string(key.get<uint64_t>()), inner_parse());
|
||||
} else {
|
||||
map.emplace(key.get<std::string>(), inner_parse());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
json etf_parser::decode_float() {
|
||||
|
||||
const uint8_t FLOAT_LENGTH = 31;
|
||||
const char* floatStr = read_string(FLOAT_LENGTH);
|
||||
|
||||
if (floatStr == NULL) {
|
||||
return json();
|
||||
}
|
||||
|
||||
double number;
|
||||
char null_terminated[FLOAT_LENGTH + 1] = {0};
|
||||
|
||||
memcpy(null_terminated, floatStr, FLOAT_LENGTH);
|
||||
|
||||
auto count = sscanf(null_terminated, "%lf", &number);
|
||||
|
||||
if (count != 1) {
|
||||
return json();
|
||||
}
|
||||
|
||||
json j = number;
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_new_float() {
|
||||
union {
|
||||
uint64_t ui64;
|
||||
double df;
|
||||
} val;
|
||||
val.ui64 = read_64_bits();
|
||||
json j = val.df;
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_bigint(uint32_t digits) {
|
||||
const uint8_t sign = read_8_bits();
|
||||
|
||||
if (digits > 8) {
|
||||
throw dpp::parse_exception("ETF: big integer larger than 8 bytes unsupported");
|
||||
}
|
||||
|
||||
uint64_t value = 0;
|
||||
uint64_t b = 1;
|
||||
for(uint32_t i = 0; i < digits; ++i) {
|
||||
uint64_t digit = read_8_bits();
|
||||
value += digit * b;
|
||||
b <<= 8;
|
||||
}
|
||||
|
||||
if (digits <= 4) {
|
||||
if (sign == 0) {
|
||||
json j = std::to_string(static_cast<uint32_t>(value));
|
||||
return j;
|
||||
}
|
||||
|
||||
const bool isSignBitAvailable = (value & (1 << 31)) == 0;
|
||||
if (isSignBitAvailable) {
|
||||
int32_t negativeValue = -static_cast<int32_t>(value);
|
||||
json j = std::to_string(negativeValue);
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
if (sign == 0) {
|
||||
json j = std::to_string(value);
|
||||
return j;
|
||||
} else {
|
||||
json j = std::to_string(-((int64_t)value));
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
json etf_parser::decode_bigint_small() {
|
||||
const auto bytes = read_8_bits();
|
||||
return decode_bigint(bytes);
|
||||
}
|
||||
|
||||
json etf_parser::decode_bigint_large() {
|
||||
const auto bytes = read_32_bits();
|
||||
return decode_bigint(bytes);
|
||||
}
|
||||
|
||||
json etf_parser::decode_binary() {
|
||||
const auto length = read_32_bits();
|
||||
const char* str = read_string(length);
|
||||
if (str == NULL) {
|
||||
return json();
|
||||
}
|
||||
json j = std::string(str, length);
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_string() {
|
||||
const auto length = read_16_bits();
|
||||
const char* str = read_string(length);
|
||||
if (str == NULL) {
|
||||
return json();
|
||||
}
|
||||
json j = std::string(str, length);
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_string_as_list() {
|
||||
const auto length = read_16_bits();
|
||||
json array = json::array();
|
||||
if (offset + length > size) {
|
||||
throw dpp::parse_exception("String list past end of buffer");
|
||||
}
|
||||
for(uint16_t i = 0; i < length; ++i) {
|
||||
array.emplace_back(decode_small_integer());
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
json etf_parser::decode_tuple_small() {
|
||||
return decode_tuple(read_8_bits());
|
||||
}
|
||||
|
||||
json etf_parser::decode_tuple_large() {
|
||||
return decode_tuple(read_32_bits());
|
||||
}
|
||||
|
||||
json etf_parser::decode_compressed() {
|
||||
const uint32_t uncompressedSize = read_32_bits();
|
||||
unsigned long sourceSize = uncompressedSize;
|
||||
std::vector<uint8_t> outBuffer;
|
||||
outBuffer.reserve(uncompressedSize);
|
||||
const int ret = uncompress((Bytef*)outBuffer.data(), &sourceSize, (const unsigned char*)(data + offset), (uLong)(size - offset));
|
||||
|
||||
offset += sourceSize;
|
||||
if (ret != Z_OK) {
|
||||
throw dpp::parse_exception("ETF compressed value: decompresson error");
|
||||
}
|
||||
|
||||
uint8_t* old_data = data;
|
||||
size_t old_size = size;
|
||||
size_t old_offset = offset;
|
||||
data = outBuffer.data();
|
||||
size = uncompressedSize;
|
||||
offset = 0;
|
||||
json j = inner_parse();
|
||||
data = old_data;
|
||||
size = old_size;
|
||||
offset = old_offset;
|
||||
return j;
|
||||
}
|
||||
|
||||
json etf_parser::decode_reference() {
|
||||
json reference;
|
||||
|
||||
reference["node"] = inner_parse();
|
||||
|
||||
std::vector<int32_t> ids;
|
||||
ids.emplace_back(read_32_bits());
|
||||
reference["id"] = ids;
|
||||
|
||||
reference["creation"] = read_8_bits();
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
json etf_parser::decode_new_reference() {
|
||||
json reference;
|
||||
|
||||
uint16_t len = read_16_bits();
|
||||
reference["node"] = inner_parse();
|
||||
reference["creation"] = read_8_bits();
|
||||
|
||||
std::vector<int32_t> ids;
|
||||
for(uint16_t i = 0; i < len; ++i) {
|
||||
ids.emplace_back(read_32_bits());
|
||||
}
|
||||
reference["id"] = ids;
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
json etf_parser::decode_port() {
|
||||
json port;
|
||||
port["node"] = inner_parse();
|
||||
port["id"] = read_32_bits();
|
||||
port["creation"] = read_8_bits();
|
||||
return port;
|
||||
}
|
||||
|
||||
json etf_parser::decode_pid() {
|
||||
json pid;
|
||||
pid["node"] = inner_parse();
|
||||
pid["id"] = read_32_bits();
|
||||
pid["serial"] = read_32_bits();
|
||||
pid["creation"] = read_8_bits();
|
||||
return pid;
|
||||
}
|
||||
|
||||
json etf_parser::decode_export() {
|
||||
json exp;
|
||||
exp["mod"] = inner_parse();
|
||||
exp["fun"] = inner_parse();
|
||||
exp["arity"] = inner_parse();
|
||||
return exp;
|
||||
}
|
||||
|
||||
json etf_parser::inner_parse() {
|
||||
/* Decode one value into json from ETF */
|
||||
if(offset >= size) {
|
||||
throw dpp::parse_exception("Read past end of ETF buffer");
|
||||
}
|
||||
|
||||
const uint8_t type = read_8_bits();
|
||||
|
||||
switch(type) {
|
||||
case ett_distribution:
|
||||
throw dpp::parse_exception("Distribution headers are not supported");
|
||||
case ett_smallint:
|
||||
return decode_small_integer();
|
||||
case ett_integer:
|
||||
return decode_integer();
|
||||
case ett_float:
|
||||
return decode_float();
|
||||
case ett_new_float:
|
||||
return decode_new_float();
|
||||
case ett_atom:
|
||||
return decode_atom();
|
||||
case ett_atom_small:
|
||||
return decode_small_atom();
|
||||
case ett_small_tuple:
|
||||
return decode_tuple_small();
|
||||
case ett_large_tuple:
|
||||
return decode_tuple_large();
|
||||
case ett_nil:
|
||||
return decode_nil();
|
||||
case ett_string:
|
||||
return decode_string_as_list();
|
||||
case ett_list:
|
||||
return decode_list();
|
||||
case ett_map:
|
||||
return decode_map();
|
||||
case ett_binary:
|
||||
return decode_binary();
|
||||
case ett_bigint_small:
|
||||
return decode_bigint_small();
|
||||
case ett_bigint_large:
|
||||
return decode_bigint_large();
|
||||
case ett_reference:
|
||||
return decode_reference();
|
||||
case ett_new_reference:
|
||||
return decode_new_reference();
|
||||
case ett_port:
|
||||
return decode_port();
|
||||
case ett_pid:
|
||||
return decode_pid();
|
||||
case ett_export:
|
||||
return decode_export();
|
||||
case ett_compressed:
|
||||
return decode_compressed();
|
||||
default:
|
||||
throw dpp::parse_exception("Unknown data type in ETF");
|
||||
}
|
||||
}
|
||||
|
||||
json etf_parser::parse(const std::string& in) {
|
||||
/* Recursively decode multiple values from ETF to JSON */
|
||||
offset = 0;
|
||||
size = in.size();
|
||||
data = (uint8_t*)in.data();
|
||||
const uint8_t version = read_8_bits();
|
||||
if (version == FORMAT_VERSION) {
|
||||
return inner_parse();
|
||||
} else {
|
||||
throw dpp::parse_exception("Incorrect ETF version");
|
||||
}
|
||||
}
|
||||
|
||||
void etf_parser::inner_build(const json* i, etf_buffer* b)
|
||||
{
|
||||
if (i->is_number_integer()) {
|
||||
/* Numeric integer types by size */
|
||||
int64_t number = i->get<int64_t>();
|
||||
if (number >= 0 && number <= 127) {
|
||||
unsigned char num = (unsigned char)number;
|
||||
append_small_integer(b, num);
|
||||
}
|
||||
else if (number >= std::numeric_limits<uint32_t>::max() - 1) {
|
||||
append_unsigned_long_long(b, number);
|
||||
}
|
||||
else {
|
||||
int32_t num32 = (int32_t)number;
|
||||
append_integer(b, num32);
|
||||
}
|
||||
}
|
||||
else if (i->is_number_float()) {
|
||||
/* Floating point (double) types */
|
||||
double decimal = i->get<double>();
|
||||
append_double(b, decimal);
|
||||
}
|
||||
else if (i->is_null()) {
|
||||
/* NULL type */
|
||||
append_nil(b);
|
||||
}
|
||||
else if (i->is_boolean()) {
|
||||
/* Boolean types */
|
||||
bool truthy = i->get<bool>();
|
||||
if (truthy) {
|
||||
append_true(b);
|
||||
} else {
|
||||
append_false(b);
|
||||
}
|
||||
}
|
||||
else if (i->is_string()) {
|
||||
/* String types */
|
||||
const std::string s = i->get<std::string>();
|
||||
append_binary(b, s.c_str(), s.length());
|
||||
}
|
||||
else if (i->is_array()) {
|
||||
/* Array types (can contain any other type, recursively) */
|
||||
const size_t length = i->size();
|
||||
if (length == 0) {
|
||||
append_nil_ext(b);
|
||||
} else {
|
||||
if (length > std::numeric_limits<uint32_t>::max() - 1) {
|
||||
throw dpp::parse_exception("ETF encode: List too large for ETF");
|
||||
}
|
||||
}
|
||||
|
||||
append_list_header(b, length);
|
||||
for(size_t index = 0; index < length; ++index) {
|
||||
inner_build(&((*i)[index]), b);
|
||||
}
|
||||
append_nil_ext(b);
|
||||
}
|
||||
else if (i->is_object()) {
|
||||
/* Object types (can contain any other type, recursively, but nlohmann::json only supports string keys) */
|
||||
const size_t length = i->size();
|
||||
if (length > std::numeric_limits<uint32_t>::max() - 1) {
|
||||
throw dpp::parse_exception("ETF encode: Map too large for ETF");
|
||||
}
|
||||
append_map_header(b, length);
|
||||
for (auto n = i->begin(); n != i->end(); ++n) {
|
||||
json jstr = n.key();
|
||||
inner_build(&jstr, b);
|
||||
inner_build(&(n.value()), b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string etf_parser::build(const json& j) {
|
||||
etf_buffer pk(1024 * 1024);
|
||||
append_version(&pk);
|
||||
inner_build(&j, &pk);
|
||||
return std::string(pk.buf.data(), pk.length);
|
||||
}
|
||||
|
||||
etf_buffer::etf_buffer(size_t initial) {
|
||||
buf.resize(initial);
|
||||
length = 0;
|
||||
}
|
||||
|
||||
etf_buffer::~etf_buffer() = default;
|
||||
|
||||
};
|
||||
|
||||
48
vendor/DPP/src/dpp/events/automod_rule_create.cpp
vendored
Normal file
48
vendor/DPP/src/dpp/events/automod_rule_create.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/automod.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void automod_rule_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_automod_rule_create.empty()) {
|
||||
json& d = j["d"];
|
||||
automod_rule_create_t arc(client, raw);
|
||||
arc.created = automod_rule().fill_from_json(&d);
|
||||
client->creator->on_automod_rule_create.call(arc);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
48
vendor/DPP/src/dpp/events/automod_rule_delete.cpp
vendored
Normal file
48
vendor/DPP/src/dpp/events/automod_rule_delete.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/automod.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void automod_rule_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_automod_rule_create.empty()) {
|
||||
json& d = j["d"];
|
||||
automod_rule_delete_t ard(client, raw);
|
||||
ard.deleted = automod_rule().fill_from_json(&d);
|
||||
client->creator->on_automod_rule_delete.call(ard);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
58
vendor/DPP/src/dpp/events/automod_rule_execute.cpp
vendored
Normal file
58
vendor/DPP/src/dpp/events/automod_rule_execute.cpp
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/automod.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void automod_rule_execute::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_automod_rule_execute.empty()) {
|
||||
json& d = j["d"];
|
||||
automod_rule_execute_t are(client, raw);
|
||||
are.guild_id = snowflake_not_null(&d, "guild_id");
|
||||
are.action = dpp::automod_action().fill_from_json(&(d["action"]));
|
||||
are.rule_id = snowflake_not_null(&d, "rule_id");
|
||||
are.rule_trigger_type = (automod_trigger_type)int8_not_null(&d, "rule_trigger_type");
|
||||
are.user_id = snowflake_not_null(&d, "user_id");
|
||||
are.channel_id = snowflake_not_null(&d, "channel_id");
|
||||
are.message_id = snowflake_not_null(&d, "message_id");
|
||||
are.alert_system_message_id = snowflake_not_null(&d, "alert_system_message_id");
|
||||
are.content = string_not_null(&d, "content");
|
||||
are.matched_keyword = string_not_null(&d, "matched_keyword");
|
||||
are.matched_content = string_not_null(&d, "matched_content");
|
||||
client->creator->on_automod_rule_execute.call(are);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
48
vendor/DPP/src/dpp/events/automod_rule_update.cpp
vendored
Normal file
48
vendor/DPP/src/dpp/events/automod_rule_update.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/automod.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void automod_rule_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_automod_rule_update.empty()) {
|
||||
json& d = j["d"];
|
||||
automod_rule_update_t aru(client, raw);
|
||||
aru.updated = automod_rule().fill_from_json(&d);
|
||||
client->creator->on_automod_rule_update.call(aru);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
66
vendor/DPP/src/dpp/events/channel_create.cpp
vendored
Normal file
66
vendor/DPP/src/dpp/events/channel_create.cpp
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void channel_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
|
||||
dpp::channel* c = dpp::find_channel(snowflake_not_null(&d, "id"));
|
||||
if (!c) {
|
||||
c = new dpp::channel();
|
||||
}
|
||||
c->fill_from_json(&d);
|
||||
dpp::get_channel_cache()->store(c);
|
||||
if (c->recipients.size()) {
|
||||
for (auto & u : c->recipients) {
|
||||
client->creator->set_dm_channel(u, c->id);
|
||||
}
|
||||
}
|
||||
dpp::guild* g = dpp::find_guild(c->guild_id);
|
||||
if (g) {
|
||||
g->channels.push_back(c->id);
|
||||
|
||||
if (!client->creator->on_channel_create.empty()) {
|
||||
dpp::channel_create_t cc(client, raw);
|
||||
cc.created = c;
|
||||
cc.creating_guild = g;
|
||||
client->creator->on_channel_create.call(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
63
vendor/DPP/src/dpp/events/channel_delete.cpp
vendored
Normal file
63
vendor/DPP/src/dpp/events/channel_delete.cpp
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void channel_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::channel* c = dpp::find_channel(snowflake_not_null(&d, "id"));
|
||||
if (c) {
|
||||
dpp::guild* g = dpp::find_guild(c->guild_id);
|
||||
if (g) {
|
||||
auto gc = std::find(g->channels.begin(), g->channels.end(), c->id);
|
||||
if (gc != g->channels.end()) {
|
||||
g->channels.erase(gc);
|
||||
}
|
||||
|
||||
if (!client->creator->on_channel_delete.empty()) {
|
||||
dpp::channel_delete_t cd(client, raw);
|
||||
cd.deleted = c;
|
||||
cd.deleting_guild = g;
|
||||
client->creator->on_channel_delete.call(cd);
|
||||
}
|
||||
}
|
||||
dpp::get_channel_cache()->remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
54
vendor/DPP/src/dpp/events/channel_pins_update.cpp
vendored
Normal file
54
vendor/DPP/src/dpp/events/channel_pins_update.cpp
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void channel_pins_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
|
||||
if (!client->creator->on_channel_pins_update.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::channel_pins_update_t cpu(client, raw);
|
||||
cpu.pin_channel = dpp::find_channel(snowflake_not_null(&d, "channel_id"));
|
||||
cpu.pin_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
cpu.timestamp = ts_not_null(&d, "last_pin_timestamp");
|
||||
|
||||
client->creator->on_channel_pins_update.call(cpu);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}};
|
||||
54
vendor/DPP/src/dpp/events/channel_update.cpp
vendored
Normal file
54
vendor/DPP/src/dpp/events/channel_update.cpp
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void channel_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::channel* c = dpp::find_channel(from_string<uint64_t>(d["id"].get<std::string>()));
|
||||
if (c) {
|
||||
c->fill_from_json(&d);
|
||||
if (!client->creator->on_channel_update.empty()) {
|
||||
dpp::channel_update_t cu(client, raw);
|
||||
cu.updated = c;
|
||||
cu.updating_guild = dpp::find_guild(c->guild_id);
|
||||
client->creator->on_channel_update.call(cu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
52
vendor/DPP/src/dpp/events/guild_ban_add.cpp
vendored
Normal file
52
vendor/DPP/src/dpp/events/guild_ban_add.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/ban.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_ban_add::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_guild_ban_add.empty()) {
|
||||
json &d = j["d"];
|
||||
dpp::guild_ban_add_t gba(client, raw);
|
||||
gba.banning_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
gba.banned = dpp::user().fill_from_json(&(d["user"]));
|
||||
client->creator->on_guild_ban_add.call(gba);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
52
vendor/DPP/src/dpp/events/guild_ban_remove.cpp
vendored
Normal file
52
vendor/DPP/src/dpp/events/guild_ban_remove.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/ban.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_ban_remove::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_guild_ban_remove.empty()) {
|
||||
json &d = j["d"];
|
||||
dpp::guild_ban_remove_t gbr(client, raw);
|
||||
gbr.unbanning_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
gbr.unbanned = dpp::user().fill_from_json(&(d["user"]));
|
||||
client->creator->on_guild_ban_remove.call(gbr);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
199
vendor/DPP/src/dpp/events/guild_create.cpp
vendored
Normal file
199
vendor/DPP/src/dpp/events/guild_create.cpp
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
bool newguild = false;
|
||||
if (snowflake_not_null(&d, "id") == 0)
|
||||
return;
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "id"));
|
||||
if (!g) {
|
||||
g = new dpp::guild();
|
||||
newguild = true;
|
||||
}
|
||||
g->fill_from_json(client, &d);
|
||||
g->shard_id = client->shard_id;
|
||||
if (!g->is_unavailable() && newguild) {
|
||||
if (client->creator->cache_policy.role_policy != dpp::cp_none) {
|
||||
/* Store guild roles */
|
||||
g->roles.clear();
|
||||
g->roles.reserve(d["roles"].size());
|
||||
for (auto & role : d["roles"]) {
|
||||
dpp::role *r = dpp::find_role(snowflake_not_null(&role, "id"));
|
||||
if (!r) {
|
||||
r = new dpp::role();
|
||||
}
|
||||
r->fill_from_json(g->id, &role);
|
||||
dpp::get_role_cache()->store(r);
|
||||
g->roles.push_back(r->id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store guild channels */
|
||||
g->channels.clear();
|
||||
g->channels.reserve(d["channels"].size());
|
||||
for (auto & channel : d["channels"]) {
|
||||
dpp::channel* c = dpp::find_channel(snowflake_not_null(&channel, "id"));
|
||||
if (!c) {
|
||||
c = new dpp::channel();
|
||||
}
|
||||
c->fill_from_json(&channel);
|
||||
c->guild_id = g->id;
|
||||
dpp::get_channel_cache()->store(c);
|
||||
g->channels.push_back(c->id);
|
||||
}
|
||||
|
||||
/* Store guild threads */
|
||||
g->threads.clear();
|
||||
g->threads.reserve(d["threads"].size());
|
||||
for (auto & channel : d["threads"]) {
|
||||
g->threads.push_back(snowflake_not_null(&channel, "id"));
|
||||
}
|
||||
|
||||
/* Store guild members */
|
||||
if (client->creator->cache_policy.user_policy == cp_aggressive) {
|
||||
g->members.reserve(d["members"].size());
|
||||
for (auto & user : d["members"]) {
|
||||
snowflake userid = snowflake_not_null(&(user["user"]), "id");
|
||||
/* Only store ones we don't have already otherwise gm will leak */
|
||||
if (g->members.find(userid) == g->members.end()) {
|
||||
dpp::user* u = dpp::find_user(userid);
|
||||
if (!u) {
|
||||
u = new dpp::user();
|
||||
u->fill_from_json(&(user["user"]));
|
||||
dpp::get_user_cache()->store(u);
|
||||
} else {
|
||||
u->refcount++;
|
||||
}
|
||||
dpp::guild_member gm;
|
||||
gm.fill_from_json(&user, g->id, userid);
|
||||
g->members[userid] = gm;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (client->creator->cache_policy.emoji_policy != dpp::cp_none) {
|
||||
/* Store emojis */
|
||||
g->emojis.reserve(d["emojis"].size());
|
||||
g->emojis = {};
|
||||
for (auto & emoji : d["emojis"]) {
|
||||
dpp::emoji* e = dpp::find_emoji(snowflake_not_null(&emoji, "id"));
|
||||
if (!e) {
|
||||
e = new dpp::emoji();
|
||||
e->fill_from_json(&emoji);
|
||||
dpp::get_emoji_cache()->store(e);
|
||||
}
|
||||
g->emojis.push_back(e->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
dpp::get_guild_cache()->store(g);
|
||||
if (newguild && g->id && (client->intents & dpp::i_guild_members)) {
|
||||
if (client->creator->cache_policy.user_policy == cp_aggressive) {
|
||||
json chunk_req = json({{"op", 8}, {"d", {{"guild_id",std::to_string(g->id)},{"query",""},{"limit",0}}}});
|
||||
if (client->intents & dpp::i_guild_presences) {
|
||||
chunk_req["d"]["presences"] = true;
|
||||
}
|
||||
client->queue_message(client->jsonobj_to_string(chunk_req));
|
||||
}
|
||||
}
|
||||
|
||||
if (!client->creator->on_guild_create.empty()) {
|
||||
dpp::guild_create_t gc(client, raw);
|
||||
gc.created = g;
|
||||
|
||||
/* Fill presences if there are any */
|
||||
if (d.find("presences") != d.end()) {
|
||||
for (auto & p : d["presences"]) {
|
||||
try {
|
||||
snowflake user_id = std::stoull(p["user"]["id"].get<std::string>());
|
||||
gc.presences.emplace(user_id, presence().fill_from_json(&p));
|
||||
}
|
||||
catch (std::exception&) {
|
||||
/*
|
||||
* std::invalid_argument if no conversion could be performed
|
||||
* std::out_of_range if the converted value would fall out of the range of
|
||||
* the result type or if the underlying function (std::strtoul or std::strtoull)
|
||||
* sets errno to ERANGE.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in scheduled events, if there are any */
|
||||
if (d.find("guild_scheduled_events") != d.end()) {
|
||||
for (auto & p : d["guild_scheduled_events"]) {
|
||||
scheduled_event s;
|
||||
s.fill_from_json(&p);
|
||||
gc.scheduled_events.emplace(s.id, s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in stage instances, if there are any */
|
||||
if (d.find("stage_instances") != d.end()) {
|
||||
for (auto & p : d["stage_instances"]) {
|
||||
stage_instance s;
|
||||
s.fill_from_json(&p);
|
||||
gc.stage_instances.emplace(s.id, s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in threads, if there are any */
|
||||
if (d.find("threads") != d.end()) {
|
||||
for (auto & p : d["threads"]) {
|
||||
dpp::thread t;
|
||||
t.fill_from_json(&p);
|
||||
gc.threads.emplace(t.id, t);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in stickers, if there are any */
|
||||
if (d.find("stickers") != d.end()) {
|
||||
for (auto & p : d["stickers"]) {
|
||||
sticker st;
|
||||
st.fill_from_json(&p);
|
||||
gc.stickers.emplace(st.id, st);
|
||||
}
|
||||
}
|
||||
|
||||
client->creator->on_guild_create.call(gc);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
93
vendor/DPP/src/dpp/events/guild_delete.cpp
vendored
Normal file
93
vendor/DPP/src/dpp/events/guild_delete.cpp
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "id"));
|
||||
if (g) {
|
||||
if (!bool_not_null(&d, "unavailable")) {
|
||||
dpp::get_guild_cache()->remove(g);
|
||||
if (client->creator->cache_policy.emoji_policy != dpp::cp_none) {
|
||||
for (auto & ee : g->emojis) {
|
||||
dpp::emoji* fe = dpp::find_emoji(ee);
|
||||
if (fe) {
|
||||
dpp::get_emoji_cache()->remove(fe);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (client->creator->cache_policy.role_policy != dpp::cp_none) {
|
||||
for (auto & rr : g->roles) {
|
||||
dpp::role* role = dpp::find_role(rr);
|
||||
if (role) {
|
||||
dpp::get_role_cache()->remove(role);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto & cc : g->channels) {
|
||||
dpp::channel* ch = dpp::find_channel(cc);
|
||||
if (ch) {
|
||||
dpp::get_channel_cache()->remove(ch);
|
||||
}
|
||||
}
|
||||
if (client->creator->cache_policy.user_policy != dpp::cp_none) {
|
||||
for (auto gm = g->members.begin(); gm != g->members.end(); ++gm) {
|
||||
dpp::user* u = dpp::find_user(gm->second.user_id);
|
||||
if (u) {
|
||||
u->refcount--;
|
||||
if (u->refcount < 1) {
|
||||
dpp::get_user_cache()->remove(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g->members.clear();
|
||||
} else {
|
||||
g->flags |= dpp::g_unavailable;
|
||||
}
|
||||
|
||||
if (!client->creator->on_guild_delete.empty()) {
|
||||
dpp::guild_delete_t gd(client, raw);
|
||||
gd.deleted = g;
|
||||
client->creator->on_guild_delete.call(gd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
74
vendor/DPP/src/dpp/events/guild_emojis_update.cpp
vendored
Normal file
74
vendor/DPP/src/dpp/events/guild_emojis_update.cpp
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/emoji.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_emojis_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
if (client->creator->cache_policy.emoji_policy != dpp::cp_none) {
|
||||
for (auto & ee : g->emojis) {
|
||||
dpp::emoji* fe = dpp::find_emoji(ee);
|
||||
if (fe) {
|
||||
dpp::get_emoji_cache()->remove(fe);
|
||||
}
|
||||
}
|
||||
g->emojis.clear();
|
||||
for (auto & emoji : d["emojis"]) {
|
||||
dpp::emoji* e = dpp::find_emoji(snowflake_not_null(&emoji, "id"));
|
||||
if (!e) {
|
||||
e = new dpp::emoji();
|
||||
e->fill_from_json(&emoji);
|
||||
dpp::get_emoji_cache()->store(e);
|
||||
}
|
||||
g->emojis.push_back(e->id);
|
||||
}
|
||||
}
|
||||
if (!client->creator->on_guild_emojis_update.empty()) {
|
||||
dpp::guild_emojis_update_t geu(client, raw);
|
||||
geu.emojis = g->emojis;
|
||||
geu.updating_guild = g;
|
||||
client->creator->on_guild_emojis_update.call(geu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
50
vendor/DPP/src/dpp/events/guild_integrations_update.cpp
vendored
Normal file
50
vendor/DPP/src/dpp/events/guild_integrations_update.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/integration.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_integrations_update::handle(class discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_guild_integrations_update.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::guild_integrations_update_t giu(client, raw);
|
||||
giu.updating_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
client->creator->on_guild_integrations_update.call(giu);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/guild_join_request_delete.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/guild_join_request_delete.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_join_request_delete::handle(class discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_guild_join_request_delete.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::guild_join_request_delete_t grd(client, raw);
|
||||
grd.user_id = snowflake_not_null(&d, "user_id");
|
||||
grd.guild_id = snowflake_not_null(&d, "guild_id");
|
||||
client->creator->on_guild_join_request_delete.call(grd);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
80
vendor/DPP/src/dpp/events/guild_member_add.cpp
vendored
Normal file
80
vendor/DPP/src/dpp/events/guild_member_add.cpp
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_member_add::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json d = j["d"];
|
||||
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
dpp::guild_member_add_t gmr(client, raw);
|
||||
if (g) {
|
||||
if (client->creator->cache_policy.user_policy == dpp::cp_none) {
|
||||
dpp::guild_member gm;
|
||||
gm.fill_from_json(&d, g->id, snowflake_not_null(&(d["user"]), "id"));
|
||||
gmr.added = gm;
|
||||
if (!client->creator->on_guild_member_add.empty()) {
|
||||
gmr.adding_guild = g;
|
||||
client->creator->on_guild_member_add.call(gmr);
|
||||
}
|
||||
} else {
|
||||
dpp::user* u = dpp::find_user(snowflake_not_null(&(d["user"]), "id"));
|
||||
if (!u) {
|
||||
u = new dpp::user();
|
||||
u->fill_from_json(&(d["user"]));
|
||||
dpp::get_user_cache()->store(u);
|
||||
} else {
|
||||
u->refcount++;
|
||||
}
|
||||
dpp::guild_member gm;
|
||||
gmr.added = {};
|
||||
if (u && u->id && g->members.find(u->id) == g->members.end()) {
|
||||
gm.fill_from_json(&d, g->id, u->id);
|
||||
g->members[u->id] = gm;
|
||||
gmr.added = gm;
|
||||
} else if (u && u->id) {
|
||||
gmr.added = g->members.find(u->id)->second;
|
||||
}
|
||||
if (!client->creator->on_guild_member_add.empty()) {
|
||||
gmr.adding_guild = g;
|
||||
client->creator->on_guild_member_add.call(gmr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
79
vendor/DPP/src/dpp/events/guild_member_remove.cpp
vendored
Normal file
79
vendor/DPP/src/dpp/events/guild_member_remove.cpp
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_member_remove::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json d = j["d"];
|
||||
|
||||
dpp::guild_member_remove_t gmr(client, raw);
|
||||
|
||||
gmr.removing_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
|
||||
if (client->creator->cache_policy.user_policy == dpp::cp_none) {
|
||||
dpp::user u;
|
||||
u.fill_from_json(&(d["user"]));
|
||||
gmr.removed = &u;
|
||||
if (!client->creator->on_guild_member_remove.empty()) {
|
||||
client->creator->on_guild_member_remove.call(gmr);
|
||||
}
|
||||
} else {
|
||||
|
||||
gmr.removed = dpp::find_user(snowflake_not_null(&(d["user"]), "id"));
|
||||
|
||||
if (!client->creator->on_guild_member_remove.empty()) {
|
||||
client->creator->on_guild_member_remove.call(gmr);
|
||||
}
|
||||
|
||||
if (gmr.removing_guild && gmr.removed) {
|
||||
auto i = gmr.removing_guild->members.find(gmr.removed->id);
|
||||
if (i != gmr.removing_guild->members.end()) {
|
||||
dpp::user* u = dpp::find_user(gmr.removed->id);
|
||||
if (u) {
|
||||
u->refcount--;
|
||||
if (u->refcount < 1) {
|
||||
dpp::get_user_cache()->remove(u);
|
||||
}
|
||||
}
|
||||
gmr.removing_guild->members.erase(i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
73
vendor/DPP/src/dpp/events/guild_member_update.cpp
vendored
Normal file
73
vendor/DPP/src/dpp/events/guild_member_update.cpp
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_member_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(from_string<uint64_t>(d["guild_id"].get<std::string>()));
|
||||
if (client->creator->cache_policy.user_policy == dpp::cp_none) {
|
||||
dpp::user u;
|
||||
u.fill_from_json(&(d["user"]));
|
||||
if (g && !client->creator->on_guild_member_update.empty()) {
|
||||
dpp::guild_member_update_t gmu(client, raw);
|
||||
gmu.updating_guild = g;
|
||||
guild_member m;
|
||||
auto& user = d;//d["user"]; // d contains roles and other member stuff already
|
||||
m.fill_from_json(&user, g->id, u.id);
|
||||
gmu.updated = m;
|
||||
client->creator->on_guild_member_update.call(gmu);
|
||||
}
|
||||
} else {
|
||||
dpp::user* u = dpp::find_user(from_string<uint64_t>(d["user"]["id"].get<std::string>()));
|
||||
if (g && u) {
|
||||
auto& user = d;//d["user"]; // d contains roles and other member stuff already
|
||||
guild_member m;
|
||||
m.fill_from_json(&user, g->id, u->id);
|
||||
g->members[u->id] = m;
|
||||
|
||||
if (!client->creator->on_guild_member_update.empty()) {
|
||||
dpp::guild_member_update_t gmu(client, raw);
|
||||
gmu.updating_guild = g;
|
||||
gmu.updated = m;
|
||||
client->creator->on_guild_member_update.call(gmu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
75
vendor/DPP/src/dpp/events/guild_members_chunk.cpp
vendored
Normal file
75
vendor/DPP/src/dpp/events/guild_members_chunk.cpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_members_chunk::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json &d = j["d"];
|
||||
dpp::guild_member_map um;
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
/* Store guild members */
|
||||
if (client->creator->cache_policy.user_policy == cp_aggressive) {
|
||||
for (auto & userrec : d["members"]) {
|
||||
json & userspart = userrec["user"];
|
||||
dpp::user* u = dpp::find_user(snowflake_not_null(&userspart, "id"));
|
||||
if (!u) {
|
||||
u = new dpp::user();
|
||||
u->fill_from_json(&userspart);
|
||||
dpp::get_user_cache()->store(u);
|
||||
}
|
||||
if (g->members.find(u->id) == g->members.end()) {
|
||||
dpp::guild_member gm;
|
||||
gm.fill_from_json(&userrec, g->id, u->id);
|
||||
g->members[u->id] = gm;
|
||||
if (!client->creator->on_guild_members_chunk.empty()) {
|
||||
um[u->id] = gm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!client->creator->on_guild_members_chunk.empty()) {
|
||||
dpp::guild_members_chunk_t gmc(client, raw);
|
||||
gmc.adding = g;
|
||||
gmc.members = &um;
|
||||
client->creator->on_guild_members_chunk.call(gmc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
74
vendor/DPP/src/dpp/events/guild_role_create.cpp
vendored
Normal file
74
vendor/DPP/src/dpp/events/guild_role_create.cpp
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/role.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_role_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json &d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
if (client->creator->cache_policy.role_policy == dpp::cp_none) {
|
||||
json &role = d["role"];
|
||||
dpp::role r;
|
||||
r.fill_from_json(g->id, &role);
|
||||
if (!client->creator->on_guild_role_create.empty()) {
|
||||
dpp::guild_role_create_t grc(client, raw);
|
||||
grc.creating_guild = g;
|
||||
grc.created = &r;
|
||||
client->creator->on_guild_role_create.call(grc);
|
||||
}
|
||||
} else {
|
||||
json &role = d["role"];
|
||||
dpp::role *r = dpp::find_role(snowflake_not_null(&role, "id"));
|
||||
if (!r) {
|
||||
r = new dpp::role();
|
||||
}
|
||||
r->fill_from_json(g->id, &role);
|
||||
dpp::get_role_cache()->store(r);
|
||||
g->roles.push_back(r->id);
|
||||
if (!client->creator->on_guild_role_create.empty()) {
|
||||
dpp::guild_role_create_t grc(client, raw);
|
||||
grc.creating_guild = g;
|
||||
grc.created = r;
|
||||
client->creator->on_guild_role_create.call(grc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
74
vendor/DPP/src/dpp/events/guild_role_delete.cpp
vendored
Normal file
74
vendor/DPP/src/dpp/events/guild_role_delete.cpp
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/role.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_role_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json &d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
if (client->creator->cache_policy.role_policy == dpp::cp_none) {
|
||||
dpp::role r;
|
||||
r.fill_from_json(g->id, &d);
|
||||
if (!client->creator->on_guild_role_delete.empty()) {
|
||||
dpp::guild_role_delete_t grd(client, raw);
|
||||
grd.deleting_guild = g;
|
||||
grd.deleted = &r;
|
||||
client->creator->on_guild_role_delete.call(grd);
|
||||
}
|
||||
} else {
|
||||
json& role = d["role"];
|
||||
dpp::snowflake id = snowflake_not_null(&role, "id");
|
||||
dpp::role *r = dpp::find_role(id);
|
||||
if (!client->creator->on_guild_role_delete.empty()) {
|
||||
dpp::guild_role_delete_t grd(client, raw);
|
||||
grd.deleting_guild = g;
|
||||
grd.deleted = r ? r : nullptr;
|
||||
grd.role_id = id;
|
||||
client->creator->on_guild_role_delete.call(grd);
|
||||
}
|
||||
if (r) {
|
||||
auto i = std::find(g->roles.begin(), g->roles.end(), r->id);
|
||||
if (i != g->roles.end()) {
|
||||
g->roles.erase(i);
|
||||
}
|
||||
dpp::get_role_cache()->remove(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
70
vendor/DPP/src/dpp/events/guild_role_update.cpp
vendored
Normal file
70
vendor/DPP/src/dpp/events/guild_role_update.cpp
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/role.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_role_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json &d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
if (client->creator->cache_policy.role_policy == dpp::cp_none) {
|
||||
dpp::role r;
|
||||
r.fill_from_json(g->id, &d);
|
||||
if (!client->creator->on_guild_role_update.empty()) {
|
||||
dpp::guild_role_update_t gru(client, raw);
|
||||
gru.updating_guild = g;
|
||||
gru.updated = &r;
|
||||
client->creator->on_guild_role_update.call(gru);
|
||||
}
|
||||
} else {
|
||||
json& role = d["role"];
|
||||
dpp::role *r = dpp::find_role(snowflake_not_null(&role, "id"));
|
||||
if (r) {
|
||||
r->fill_from_json(g->id, &role);
|
||||
if (!client->creator->on_guild_role_update.empty()) {
|
||||
dpp::guild_role_update_t gru(client, raw);
|
||||
gru.updating_guild = g;
|
||||
gru.updated = r;
|
||||
client->creator->on_guild_role_update.call(gru);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
50
vendor/DPP/src/dpp/events/guild_scheduled_event_create.cpp
vendored
Normal file
50
vendor/DPP/src/dpp/events/guild_scheduled_event_create.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/scheduled_event.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_scheduled_event_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
if (!client->creator->on_guild_scheduled_event_create.empty()) {
|
||||
dpp::guild_scheduled_event_create_t ec(client, raw);
|
||||
ec.created.fill_from_json(&d);
|
||||
client->creator->on_guild_scheduled_event_create.call(ec);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
50
vendor/DPP/src/dpp/events/guild_scheduled_event_delete.cpp
vendored
Normal file
50
vendor/DPP/src/dpp/events/guild_scheduled_event_delete.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/scheduled_event.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_scheduled_event_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
if (!client->creator->on_guild_scheduled_event_delete.empty()) {
|
||||
dpp::guild_scheduled_event_delete_t ed(client, raw);
|
||||
ed.deleted.fill_from_json(&d);
|
||||
client->creator->on_guild_scheduled_event_delete.call(ed);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
50
vendor/DPP/src/dpp/events/guild_scheduled_event_update.cpp
vendored
Normal file
50
vendor/DPP/src/dpp/events/guild_scheduled_event_update.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/scheduled_event.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_scheduled_event_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
if (!client->creator->on_guild_scheduled_event_update.empty()) {
|
||||
dpp::guild_scheduled_event_update_t eu(client, raw);
|
||||
eu.updated.fill_from_json(&d);
|
||||
client->creator->on_guild_scheduled_event_update.call(eu);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
51
vendor/DPP/src/dpp/events/guild_scheduled_event_user_add.cpp
vendored
Normal file
51
vendor/DPP/src/dpp/events/guild_scheduled_event_user_add.cpp
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_scheduled_event_user_add::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
if (!client->creator->on_guild_scheduled_event_user_add.empty()) {
|
||||
dpp::guild_scheduled_event_user_add_t eua(client, raw);
|
||||
eua.guild_id = snowflake_not_null(&d, "guild_id");
|
||||
eua.user_id = snowflake_not_null(&d, "user_id");
|
||||
eua.event_id = snowflake_not_null(&d, "guild_scheduled_event_id");
|
||||
client->creator->on_guild_scheduled_event_user_add.call(eua);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
51
vendor/DPP/src/dpp/events/guild_scheduled_event_user_remove.cpp
vendored
Normal file
51
vendor/DPP/src/dpp/events/guild_scheduled_event_user_remove.cpp
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_scheduled_event_user_remove::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
if (!client->creator->on_guild_scheduled_event_user_remove.empty()) {
|
||||
dpp::guild_scheduled_event_user_remove_t eur(client, raw);
|
||||
eur.guild_id = snowflake_not_null(&d, "guild_id");
|
||||
eur.user_id = snowflake_not_null(&d, "user_id");
|
||||
eur.event_id = snowflake_not_null(&d, "guild_scheduled_event_id");
|
||||
client->creator->on_guild_scheduled_event_user_remove.call(eur);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
58
vendor/DPP/src/dpp/events/guild_stickers_update.cpp
vendored
Normal file
58
vendor/DPP/src/dpp/events/guild_stickers_update.cpp
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_stickers_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
if (!client->creator->on_guild_stickers_update.empty()) {
|
||||
dpp::guild_stickers_update_t gsu(client, raw);
|
||||
for (auto & sticker : d["stickers"]) {
|
||||
dpp::sticker s;
|
||||
s.fill_from_json(&sticker);
|
||||
gsu.stickers.emplace_back(s);
|
||||
}
|
||||
gsu.updating_guild = g;
|
||||
client->creator->on_guild_stickers_update.call(gsu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
69
vendor/DPP/src/dpp/events/guild_update.cpp
vendored
Normal file
69
vendor/DPP/src/dpp/events/guild_update.cpp
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void guild_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::guild* g = dpp::find_guild(from_string<uint64_t>(d["id"].get<std::string>()));
|
||||
if (g) {
|
||||
g->fill_from_json(client, &d);
|
||||
if (!g->is_unavailable()) {
|
||||
if (client->creator->cache_policy.role_policy != dpp::cp_none && d.find("roles") != d.end()) {
|
||||
for (size_t rc = 0; rc < g->roles.size(); ++rc) {
|
||||
dpp::role* oldrole = dpp::find_role(g->roles[rc]);
|
||||
dpp::get_role_cache()->remove(oldrole);
|
||||
}
|
||||
g->roles.clear();
|
||||
for (auto & role : d["roles"]) {
|
||||
dpp::role *r = new dpp::role();
|
||||
r->fill_from_json(g->id, &role);
|
||||
dpp::get_role_cache()->store(r);
|
||||
g->roles.push_back(r->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!client->creator->on_guild_update.empty()) {
|
||||
dpp::guild_update_t gu(client, raw);
|
||||
gu.updated = g;
|
||||
client->creator->on_guild_update.call(gu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
50
vendor/DPP/src/dpp/events/integration_create.cpp
vendored
Normal file
50
vendor/DPP/src/dpp/events/integration_create.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/integration.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void integration_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_integration_create.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::integration_create_t ic(client, raw);
|
||||
ic.created_integration = dpp::integration().fill_from_json(&d);
|
||||
client->creator->on_integration_create.call(ic);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/integration_delete.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/integration_delete.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/integration.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void integration_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_integration_delete.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::integration_delete_t id(client, raw);
|
||||
id.deleted_integration = dpp::integration().fill_from_json(&d);
|
||||
client->creator->on_integration_delete.call(id);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/integration_update.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/integration_update.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/integration.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void integration_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_integration_update.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::integration_update_t iu(client, raw);
|
||||
iu.updated_integration = dpp::integration().fill_from_json(&d);
|
||||
client->creator->on_integration_update.call(iu);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
162
vendor/DPP/src/dpp/events/interaction_create.cpp
vendored
Normal file
162
vendor/DPP/src/dpp/events/interaction_create.cpp
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/appcommand.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void interaction_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
dpp::interaction i;
|
||||
/* We must set here because we cant pass it through the nlohmann from_json() */
|
||||
i.cache_policy = client->creator->cache_policy;
|
||||
i.fill_from_json(&d);
|
||||
/* There are several types of interactions, component interactions,
|
||||
* auto complete interactions, dialog interactions and slash command
|
||||
* interactions. Both fire different library events so ensure they are
|
||||
* dispatched properly.
|
||||
*/
|
||||
if (i.type == it_application_command) {
|
||||
/* Slash command is split again into chat input, and the two context menu types */
|
||||
command_interaction cmd_data = i.get_command_interaction();
|
||||
if (cmd_data.type == ctxm_message && !client->creator->on_message_context_menu.empty()) {
|
||||
if (i.resolved.messages.size()) {
|
||||
/* Message right-click context menu */
|
||||
message_context_menu_t mcm(client, raw);
|
||||
mcm.command = i;
|
||||
mcm.set_message(i.resolved.messages.begin()->second);
|
||||
client->creator->on_message_context_menu.call(mcm);
|
||||
}
|
||||
} else if (cmd_data.type == ctxm_user && !client->creator->on_user_context_menu.empty()) {
|
||||
if (i.resolved.users.size()) {
|
||||
/* User right-click context menu */
|
||||
user_context_menu_t ucm(client, raw);
|
||||
ucm.command = i;
|
||||
ucm.set_user(i.resolved.users.begin()->second);
|
||||
client->creator->on_user_context_menu.call(ucm);
|
||||
}
|
||||
} else if (cmd_data.type == ctxm_chat_input && !client->creator->on_slashcommand.empty()) {
|
||||
dpp::slashcommand_t sc(client, raw);
|
||||
sc.command = i;
|
||||
client->creator->on_slashcommand.call(sc);
|
||||
}
|
||||
if (!client->creator->on_interaction_create.empty()) {
|
||||
/* Standard chat input. Note that for backwards compatibility, context menu
|
||||
* events still find their way here. At some point in the future, receiving
|
||||
* ctxm_user and ctxm_message inputs to this event will be depreciated.
|
||||
*/
|
||||
dpp::interaction_create_t ic(client, raw);
|
||||
ic.command = i;
|
||||
client->creator->on_interaction_create.call(ic);
|
||||
}
|
||||
} else if (i.type == it_modal_submit) {
|
||||
if (!client->creator->on_form_submit.empty()) {
|
||||
dpp::form_submit_t fs(client, raw);
|
||||
fs.custom_id = string_not_null(&(d["data"]), "custom_id");
|
||||
fs.command = i;
|
||||
for (auto & c : d["data"]["components"]) {
|
||||
fs.components.push_back(dpp::component().fill_from_json(&c));
|
||||
}
|
||||
client->creator->on_form_submit.call(fs);
|
||||
}
|
||||
} else if (i.type == it_autocomplete) {
|
||||
// "data":{"id":"903319628816728104","name":"blep","options":[{"focused":true,"name":"animal","type":3,"value":"a"}],"type":1}
|
||||
if (!client->creator->on_autocomplete.empty()) {
|
||||
dpp::autocomplete_t ac(client, raw);
|
||||
ac.id = snowflake_not_null(&(d["data"]), "id");
|
||||
ac.name = string_not_null(&(d["data"]), "name");
|
||||
for (auto & o : d["data"]["options"]) {
|
||||
dpp::command_option opt;
|
||||
opt.name = string_not_null(&o, "name");
|
||||
opt.type = (dpp::command_option_type)int8_not_null(&o, "type");
|
||||
if (o.contains("value") && !o.at("value").is_null()) {
|
||||
switch (opt.type) {
|
||||
case co_boolean:
|
||||
opt.value = o.at("value").get<bool>();
|
||||
break;
|
||||
case co_channel:
|
||||
case co_role:
|
||||
case co_user:
|
||||
case co_attachment:
|
||||
case co_mentionable:
|
||||
opt.value = dpp::snowflake(snowflake_not_null(&o, "value"));
|
||||
break;
|
||||
case co_integer:
|
||||
opt.value = o.at("value").get<int64_t>();
|
||||
break;
|
||||
case co_string:
|
||||
opt.value = o.at("value").get<std::string>();
|
||||
break;
|
||||
case co_number:
|
||||
opt.value = o.at("value").get<double>();
|
||||
break;
|
||||
case co_sub_command:
|
||||
case co_sub_command_group:
|
||||
/* Silences warning on clang, handled elsewhere */
|
||||
break;
|
||||
}
|
||||
}
|
||||
opt.focused = bool_not_null(&o, "focused");
|
||||
ac.options.emplace_back(opt);
|
||||
}
|
||||
ac.command = i;
|
||||
client->creator->on_autocomplete.call(ac);
|
||||
}
|
||||
} else if (i.type == it_component_button) {
|
||||
dpp::component_interaction bi = std::get<component_interaction>(i.data);
|
||||
if (bi.component_type == cot_button) {
|
||||
if (!client->creator->on_button_click.empty()) {
|
||||
dpp::button_click_t ic(client, raw);
|
||||
ic.command = i;
|
||||
ic.custom_id = bi.custom_id;
|
||||
ic.component_type = bi.component_type;
|
||||
client->creator->on_button_click.call(ic);
|
||||
}
|
||||
} else if (bi.component_type == cot_selectmenu || bi.component_type == cot_user_selectmenu ||
|
||||
bi.component_type == cot_role_selectmenu || bi.component_type == cot_mentionable_selectmenu ||
|
||||
bi.component_type == cot_channel_selectmenu) {
|
||||
if (!client->creator->on_select_click.empty()) {
|
||||
dpp::select_click_t ic(client, raw);
|
||||
ic.command = i;
|
||||
ic.custom_id = bi.custom_id;
|
||||
ic.component_type = bi.component_type;
|
||||
ic.values = bi.values;
|
||||
client->creator->on_select_click.call(ic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/invite_create.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/invite_create.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/invite.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void invite_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_invite_create.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::invite_create_t ci(client, raw);
|
||||
ci.created_invite = dpp::invite().fill_from_json(&d);
|
||||
client->creator->on_invite_create.call(ci);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/invite_delete.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/invite_delete.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/invite.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void invite_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_invite_delete.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::invite_delete_t cd(client, raw);
|
||||
cd.deleted_invite = dpp::invite().fill_from_json(&d);
|
||||
client->creator->on_invite_delete.call(cd);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
48
vendor/DPP/src/dpp/events/logger.cpp
vendored
Normal file
48
vendor/DPP/src/dpp/events/logger.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void logger::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_log.empty()) {
|
||||
dpp::log_t logmsg(client, raw);
|
||||
logmsg.severity = (dpp::loglevel)from_string<uint32_t>(raw.substr(0, raw.find(';')));
|
||||
logmsg.message = raw.substr(raw.find(';') + 1, raw.length());
|
||||
client->creator->on_log.call(logmsg);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
51
vendor/DPP/src/dpp/events/message_create.cpp
vendored
Normal file
51
vendor/DPP/src/dpp/events/message_create.cpp
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
|
||||
if (!client->creator->on_message_create.empty()) {
|
||||
json d = j["d"];
|
||||
dpp::message_create_t msg(client, raw);
|
||||
msg.msg.fill_from_json(&d, client->creator->cache_policy);
|
||||
msg.msg.owner = client->creator;
|
||||
client->creator->on_message_create.call(msg);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
52
vendor/DPP/src/dpp/events/message_delete.cpp
vendored
Normal file
52
vendor/DPP/src/dpp/events/message_delete.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_message_delete.empty()) {
|
||||
json d = j["d"];
|
||||
dpp::message_delete_t msg(client, raw);
|
||||
dpp::message m(client->creator);
|
||||
m.fill_from_json(&d);
|
||||
msg.deleted = &m;
|
||||
client->creator->on_message_delete.call(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}};
|
||||
55
vendor/DPP/src/dpp/events/message_delete_bulk.cpp
vendored
Normal file
55
vendor/DPP/src/dpp/events/message_delete_bulk.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_delete_bulk::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_message_delete_bulk.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::message_delete_bulk_t msg(client, raw);
|
||||
msg.deleting_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
msg.deleting_channel = dpp::find_channel(snowflake_not_null(&d, "channel_id"));
|
||||
msg.deleting_user = dpp::find_user(snowflake_not_null(&d, "user_id"));
|
||||
for (auto& m : d["ids"]) {
|
||||
msg.deleted.push_back(from_string<uint64_t>(m.get<std::string>()));
|
||||
}
|
||||
client->creator->on_message_delete_bulk.call(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}};
|
||||
57
vendor/DPP/src/dpp/events/message_reaction_add.cpp
vendored
Normal file
57
vendor/DPP/src/dpp/events/message_reaction_add.cpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_reaction_add::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_message_reaction_add.empty()) {
|
||||
json &d = j["d"];
|
||||
dpp::message_reaction_add_t mra(client, raw);
|
||||
dpp::snowflake guild_id = snowflake_not_null(&d, "guild_id");
|
||||
mra.reacting_guild = dpp::find_guild(guild_id);
|
||||
mra.reacting_user = dpp::user().fill_from_json(&(d["member"]["user"]));
|
||||
mra.reacting_member = dpp::guild_member().fill_from_json(&(d["member"]), guild_id, mra.reacting_user.id);
|
||||
mra.reacting_channel = dpp::find_channel(snowflake_not_null(&d, "channel_id"));
|
||||
mra.message_id = snowflake_not_null(&d, "message_id");
|
||||
mra.reacting_emoji = dpp::emoji().fill_from_json(&(d["emoji"]));
|
||||
if (mra.reacting_channel && mra.message_id) {
|
||||
client->creator->on_message_reaction_add.call(mra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
56
vendor/DPP/src/dpp/events/message_reaction_remove.cpp
vendored
Normal file
56
vendor/DPP/src/dpp/events/message_reaction_remove.cpp
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_reaction_remove::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_message_reaction_remove.empty()) {
|
||||
json &d = j["d"];
|
||||
dpp::message_reaction_remove_t mrr(client, raw);
|
||||
dpp::snowflake guild_id = snowflake_not_null(&d, "guild_id");
|
||||
mrr.reacting_guild = dpp::find_guild(guild_id);
|
||||
mrr.reacting_user_id = snowflake_not_null(&d, "user_id");
|
||||
mrr.reacting_channel = dpp::find_channel(snowflake_not_null(&d, "channel_id"));
|
||||
mrr.message_id = snowflake_not_null(&d, "message_id");
|
||||
mrr.reacting_emoji = dpp::emoji().fill_from_json(&(d["emoji"]));
|
||||
if (mrr.reacting_channel && mrr.message_id) {
|
||||
client->creator->on_message_reaction_remove.call(mrr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
53
vendor/DPP/src/dpp/events/message_reaction_remove_all.cpp
vendored
Normal file
53
vendor/DPP/src/dpp/events/message_reaction_remove_all.cpp
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_reaction_remove_all::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_message_reaction_remove_all.empty()) {
|
||||
json &d = j["d"];
|
||||
dpp::message_reaction_remove_all_t mrra(client, raw);
|
||||
mrra.reacting_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
mrra.reacting_channel = dpp::find_channel(snowflake_not_null(&d, "channel_id"));
|
||||
mrra.message_id = snowflake_not_null(&d, "message_id");
|
||||
if (mrra.reacting_channel && mrra.message_id) {
|
||||
client->creator->on_message_reaction_remove_all.call(mrra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
55
vendor/DPP/src/dpp/events/message_reaction_remove_emoji.cpp
vendored
Normal file
55
vendor/DPP/src/dpp/events/message_reaction_remove_emoji.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_reaction_remove_emoji::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_message_reaction_remove_emoji.empty()) {
|
||||
json &d = j["d"];
|
||||
dpp::message_reaction_remove_emoji_t mrre(client, raw);
|
||||
mrre.reacting_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
mrre.reacting_channel = dpp::find_channel(snowflake_not_null(&d, "channel_id"));
|
||||
mrre.message_id = snowflake_not_null(&d, "message_id");
|
||||
mrre.reacting_emoji = dpp::emoji().fill_from_json(&(d["emoji"]));
|
||||
if (mrre.reacting_channel && mrre.message_id) {
|
||||
client->creator->on_message_reaction_remove_emoji.call(mrre);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}};
|
||||
52
vendor/DPP/src/dpp/events/message_update.cpp
vendored
Normal file
52
vendor/DPP/src/dpp/events/message_update.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/presence.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void message_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_message_update.empty()) {
|
||||
json d = j["d"];
|
||||
dpp::message_update_t msg(client, raw);
|
||||
dpp::message m(client->creator);
|
||||
m.fill_from_json(&d);
|
||||
msg.msg = m;
|
||||
client->creator->on_message_update.call(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}};
|
||||
48
vendor/DPP/src/dpp/events/presence_update.cpp
vendored
Normal file
48
vendor/DPP/src/dpp/events/presence_update.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void presence_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_presence_update.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::presence_update_t pu(client, raw);
|
||||
pu.rich_presence = dpp::presence().fill_from_json(&d);
|
||||
client->creator->on_presence_update.call(pu);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
80
vendor/DPP/src/dpp/events/ready.cpp
vendored
Normal file
80
vendor/DPP/src/dpp/events/ready.cpp
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/dns.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
#ifndef _DOXYGEN_
|
||||
std::mutex protect_the_loot;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void ready::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
client->log(dpp::ll_info, "Shard id " + std::to_string(client->shard_id) + " (" + std::to_string(client->shard_id + 1) + "/" + std::to_string(client->max_shards) + ") ready!");
|
||||
client->sessionid = j["d"]["session_id"].get<std::string>();
|
||||
/* Session-specific gateway resume url
|
||||
* https://discord.com/developers/docs/change-log#sessionspecific-gateway-resume-urls
|
||||
*
|
||||
* Discord give us the hostname wrapped in wss://crap/ like we're going to pass it to
|
||||
* some top-heavy lib. Let's strip all this out if given to us so we just have a
|
||||
* hostname.
|
||||
*/
|
||||
std::string ugly(j["d"]["resume_gateway_url"]);
|
||||
if (ugly.substr(0, 6) == "wss://") {
|
||||
client->resume_gateway_url = ugly.substr(6, ugly.length() - (*ugly.rbegin() == '/' ? 7 : 6));
|
||||
} else {
|
||||
client->resume_gateway_url = ugly;
|
||||
}
|
||||
/* Pre-resolve it into our cache so that we aren't waiting on this when we need it later */
|
||||
static_cast<void>(resolve_hostname(client->resume_gateway_url, "443"));
|
||||
client->log(ll_debug, "Resume URL for session " + client->sessionid + " is " + ugly + " (host: " + client->resume_gateway_url + ")");
|
||||
|
||||
client->ready = true;
|
||||
|
||||
/* Mutex this to make sure multiple threads don't change it at the same time */
|
||||
{
|
||||
std::lock_guard<std::mutex> lockit(protect_the_loot);
|
||||
client->creator->me.fill_from_json(&(j["d"]["user"]));
|
||||
}
|
||||
|
||||
if (!client->creator->on_ready.empty()) {
|
||||
dpp::ready_t r(client, raw);
|
||||
r.session_id = client->sessionid;
|
||||
r.shard_id = client->shard_id;
|
||||
client->creator->on_ready.call(r);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
52
vendor/DPP/src/dpp/events/resumed.cpp
vendored
Normal file
52
vendor/DPP/src/dpp/events/resumed.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void resumed::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
client->log(dpp::ll_debug, std::string("Successfully resumed session id ") + client->sessionid);
|
||||
|
||||
client->ready = true;
|
||||
|
||||
if (!client->creator->on_resumed.empty()) {
|
||||
dpp::resumed_t r(client, raw);
|
||||
r.session_id = client->sessionid;
|
||||
r.shard_id = client->shard_id;
|
||||
client->creator->on_resumed.call(r);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/stage_instance_create.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/stage_instance_create.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/message.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void stage_instance_create::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_stage_instance_create.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::stage_instance_create_t sic(client, raw);
|
||||
sic.created.fill_from_json(&d);
|
||||
client->creator->on_stage_instance_create.call(sic);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/stage_instance_delete.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/stage_instance_delete.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stage_instance.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void stage_instance_delete::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_stage_instance_delete.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::stage_instance_delete_t sid(client, raw);
|
||||
sid.deleted.fill_from_json(&d);
|
||||
client->creator->on_stage_instance_delete.call(sid);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
49
vendor/DPP/src/dpp/events/stage_instance_update.cpp
vendored
Normal file
49
vendor/DPP/src/dpp/events/stage_instance_update.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stage_instance.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void stage_instance_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_stage_instance_update.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::stage_instance_update_t siu(client, raw);
|
||||
siu.updated.fill_from_json(&d);
|
||||
client->creator->on_stage_instance_update.call(siu);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
48
vendor/DPP/src/dpp/events/thread_create.cpp
vendored
Normal file
48
vendor/DPP/src/dpp/events/thread_create.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
void thread_create::handle(discord_client* client, json& j, const std::string& raw) {
|
||||
json& d = j["d"];
|
||||
|
||||
dpp::thread t;
|
||||
t.fill_from_json(&d);
|
||||
dpp::guild* g = dpp::find_guild(t.guild_id);
|
||||
if (g) {
|
||||
g->threads.push_back(t.id);
|
||||
if (!client->creator->on_thread_create.empty()) {
|
||||
dpp::thread_create_t tc(client, raw);
|
||||
tc.created = t;
|
||||
tc.creating_guild = g;
|
||||
client->creator->on_thread_create.call(tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
51
vendor/DPP/src/dpp/events/thread_delete.cpp
vendored
Normal file
51
vendor/DPP/src/dpp/events/thread_delete.cpp
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
void thread_delete::handle(discord_client* client, json& j, const std::string& raw) {
|
||||
json& d = j["d"];
|
||||
|
||||
dpp::thread t;
|
||||
t.fill_from_json(&d);
|
||||
dpp::guild* g = dpp::find_guild(t.guild_id);
|
||||
if (g) {
|
||||
auto gt = std::find(g->threads.begin(), g->threads.end(), t.id);
|
||||
if (gt != g->threads.end()) {
|
||||
g->threads.erase(gt);
|
||||
}
|
||||
if (!client->creator->on_thread_delete.empty()) {
|
||||
dpp::thread_delete_t td(client, raw);
|
||||
td.deleted = t;
|
||||
td.deleting_guild = g;
|
||||
client->creator->on_thread_delete.call(td);
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
59
vendor/DPP/src/dpp/events/thread_list_sync.cpp
vendored
Normal file
59
vendor/DPP/src/dpp/events/thread_list_sync.cpp
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
void thread_list_sync::handle(discord_client* client, json& j, const std::string& raw) {
|
||||
json& d = j["d"];
|
||||
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
/** Store thread IDs*/
|
||||
if (d.find("threads") != d.end()) {
|
||||
for (auto& t : d["threads"]) {
|
||||
g->threads.push_back(snowflake_not_null(&t, "id"));
|
||||
}
|
||||
}
|
||||
if (!client->creator->on_thread_list_sync.empty()) {
|
||||
dpp::thread_list_sync_t tls(client, raw);
|
||||
if (d.find("threads") != d.end()) {
|
||||
for (auto& t : d["threads"]) {
|
||||
tls.threads.push_back(thread().fill_from_json(&t));
|
||||
}
|
||||
}
|
||||
if (d.find("members") != d.end()) {
|
||||
for (auto& tm : d["members"]) {
|
||||
tls.members.push_back(thread_member().fill_from_json(&tm));
|
||||
}
|
||||
}
|
||||
client->creator->on_thread_list_sync.call(tls);
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
40
vendor/DPP/src/dpp/events/thread_member_update.cpp
vendored
Normal file
40
vendor/DPP/src/dpp/events/thread_member_update.cpp
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
void thread_member_update::handle(discord_client* client, json& j, const std::string& raw) {
|
||||
if (!client->creator->on_thread_member_update.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::thread_member_update_t tm(client, raw);
|
||||
tm.updated = thread_member().fill_from_json(&d);
|
||||
client->creator->on_thread_member_update.call(tm);
|
||||
}
|
||||
}
|
||||
}};
|
||||
60
vendor/DPP/src/dpp/events/thread_members_update.cpp
vendored
Normal file
60
vendor/DPP/src/dpp/events/thread_members_update.cpp
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
void thread_members_update::handle(discord_client* client, json& j, const std::string& raw) {
|
||||
json& d = j["d"];
|
||||
|
||||
dpp::guild* g = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
if (g) {
|
||||
if (!client->creator->on_thread_members_update.empty()) {
|
||||
dpp::thread_members_update_t tms(client, raw);
|
||||
tms.updating_guild = g;
|
||||
set_snowflake_not_null(&d, "id", tms.thread_id);
|
||||
set_int8_not_null(&d, "member_count", tms.member_count);
|
||||
if (d.find("added_members") != d.end()) {
|
||||
for (auto& tm : d["added_members"]) {
|
||||
tms.added.emplace_back(thread_member().fill_from_json(&tm));
|
||||
}
|
||||
}
|
||||
if (d.find("removed_member_ids") != d.end()) {
|
||||
try {
|
||||
for (auto& rm : d["removed_member_ids"]) {
|
||||
tms.removed_ids.push_back(std::stoull(static_cast<std::string>(rm)));
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
client->creator->log(dpp::ll_error, std::string("thread_members_update: {}") + e.what());
|
||||
}
|
||||
}
|
||||
client->creator->on_thread_members_update.call(tms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
47
vendor/DPP/src/dpp/events/thread_update.cpp
vendored
Normal file
47
vendor/DPP/src/dpp/events/thread_update.cpp
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/channel.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
void thread_update::handle(discord_client* client, json& j, const std::string& raw) {
|
||||
json& d = j["d"];
|
||||
|
||||
dpp::thread t;
|
||||
t.fill_from_json(&d);
|
||||
dpp::guild* g = dpp::find_guild(t.guild_id);
|
||||
if (g) {
|
||||
if (!client->creator->on_thread_update.empty()) {
|
||||
dpp::thread_update_t tu(client, raw);
|
||||
tu.updated = t;
|
||||
tu.updating_guild = g;
|
||||
client->creator->on_thread_update.call(tu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
52
vendor/DPP/src/dpp/events/typing_start.cpp
vendored
Normal file
52
vendor/DPP/src/dpp/events/typing_start.cpp
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void typing_start::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
if (!client->creator->on_typing_start.empty()) {
|
||||
json& d = j["d"];
|
||||
dpp::typing_start_t ts(client, raw);
|
||||
ts.typing_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
|
||||
ts.typing_channel = dpp::find_channel(snowflake_not_null(&d, "channel_id"));
|
||||
ts.user_id = snowflake_not_null(&d, "user_id");
|
||||
ts.typing_user = dpp::find_user(ts.user_id);
|
||||
ts.timestamp = ts_not_null(&d, "timestamp");
|
||||
client->creator->on_typing_start.call(ts);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
68
vendor/DPP/src/dpp/events/user_update.cpp
vendored
Normal file
68
vendor/DPP/src/dpp/events/user_update.cpp
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/cache.h>
|
||||
#include <dpp/user.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void user_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
json& d = j["d"];
|
||||
|
||||
dpp::snowflake user_id = snowflake_not_null(&d, "id");
|
||||
if (user_id) {
|
||||
if (client->creator->cache_policy.user_policy != dpp::cp_none) {
|
||||
dpp::user* u = dpp::find_user(user_id);
|
||||
if (u) {
|
||||
u->fill_from_json(&d);
|
||||
}
|
||||
if (!client->creator->on_user_update.empty()) {
|
||||
dpp::user_update_t uu(client, raw);
|
||||
uu.updated = *u;
|
||||
client->creator->on_user_update.call(uu);
|
||||
}
|
||||
} else {
|
||||
if (!client->creator->on_user_update.empty()) {
|
||||
dpp::user u;
|
||||
u.fill_from_json(&d);
|
||||
dpp::user_update_t uu(client, raw);
|
||||
uu.updated = u;
|
||||
client->creator->on_user_update.call(uu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
69
vendor/DPP/src/dpp/events/voice_server_update.cpp
vendored
Normal file
69
vendor/DPP/src/dpp/events/voice_server_update.cpp
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/voicestate.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void voice_server_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
|
||||
json &d = j["d"];
|
||||
dpp::voice_server_update_t vsu(client, raw);
|
||||
vsu.guild_id = snowflake_not_null(&d, "guild_id");
|
||||
vsu.token = string_not_null(&d, "token");
|
||||
vsu.endpoint = string_not_null(&d, "endpoint");
|
||||
|
||||
{
|
||||
std::shared_lock lock(client->voice_mutex);
|
||||
auto v = client->connecting_voice_channels.find(vsu.guild_id);
|
||||
/* Check to see if there is a connection in progress for a voice channel on this guild */
|
||||
if (v != client->connecting_voice_channels.end()) {
|
||||
if (!v->second->is_ready()) {
|
||||
v->second->token = vsu.token;
|
||||
v->second->websocket_hostname = vsu.endpoint;
|
||||
if (!v->second->is_active()) {
|
||||
v->second->connect(vsu.guild_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!client->creator->on_voice_server_update.empty()) {
|
||||
client->creator->on_voice_server_update.call(vsu);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
94
vendor/DPP/src/dpp/events/voice_state_update.cpp
vendored
Normal file
94
vendor/DPP/src/dpp/events/voice_state_update.cpp
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/************************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
#include <dpp/discordevents.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/discordvoiceclient.h>
|
||||
#include <dpp/guild.h>
|
||||
#include <dpp/voicestate.h>
|
||||
#include <dpp/stringops.h>
|
||||
#include <dpp/json.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace dpp { namespace events {
|
||||
|
||||
using namespace dpp;
|
||||
|
||||
/**
|
||||
* @brief Handle event
|
||||
*
|
||||
* @param client Websocket client (current shard)
|
||||
* @param j JSON data for the event
|
||||
* @param raw Raw JSON string
|
||||
*/
|
||||
void voice_state_update::handle(discord_client* client, json &j, const std::string &raw) {
|
||||
|
||||
json& d = j["d"];
|
||||
dpp::voice_state_update_t vsu(client, raw);
|
||||
vsu.state = dpp::voicestate().fill_from_json(&d);
|
||||
vsu.state.shard = client;
|
||||
|
||||
/* Update guild voice states */
|
||||
dpp::guild* g = dpp::find_guild(vsu.state.guild_id);
|
||||
if (g) {
|
||||
if (vsu.state.channel_id.empty()) {
|
||||
auto ve = g->voice_members.find(vsu.state.user_id);
|
||||
if (ve != g->voice_members.end()) {
|
||||
g->voice_members.erase(ve);
|
||||
}
|
||||
} else {
|
||||
g->voice_members[vsu.state.user_id] = vsu.state;
|
||||
}
|
||||
|
||||
if (client->creator->cache_policy.user_policy != dpp::cp_none) {
|
||||
if (d.contains("member")) {
|
||||
auto& member = d["member"];
|
||||
guild_member m;
|
||||
m.fill_from_json(&member, g->id, vsu.state.user_id);
|
||||
g->members[m.user_id] = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vsu.state.user_id == client->creator->me.id)
|
||||
{
|
||||
if (vsu.state.channel_id.empty()) {
|
||||
/* Instruction to disconnect from vc */
|
||||
client->disconnect_voice_internal(vsu.state.guild_id, false);
|
||||
} else {
|
||||
std::shared_lock lock(client->voice_mutex);
|
||||
auto v = client->connecting_voice_channels.find(vsu.state.guild_id);
|
||||
/* Check to see if we have a connection to a voice channel in progress on this guild */
|
||||
if (v != client->connecting_voice_channels.end()) {
|
||||
v->second->session_id = vsu.state.session_id;
|
||||
if (v->second->is_ready() && !v->second->is_active()) {
|
||||
v->second->connect(vsu.state.guild_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!client->creator->on_voice_state_update.empty()) {
|
||||
client->creator->on_voice_state_update.call(vsu);
|
||||
}
|
||||
}
|
||||
|
||||
}};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user