Skip to content

Commit

Permalink
make event.from safe in threads
Browse files Browse the repository at this point in the history
  • Loading branch information
braindigitalis committed Dec 14, 2024
1 parent 06113a4 commit 2190cf6
Show file tree
Hide file tree
Showing 77 changed files with 141 additions and 128 deletions.
34 changes: 22 additions & 12 deletions include/dpp/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,13 @@ struct DPP_EXPORT event_dispatch_t {

/**
* @brief Shard the event came from.
* Note that for some events, notably voice events, this may be nullptr.
*/
discord_client* from = nullptr;
uint32_t shard = 0;

/**
* @brief Cluster owning the event dispatch
*/
dpp::cluster* owner = nullptr;

/**
* @brief Whether the event was cancelled using cancel_event().
Expand Down Expand Up @@ -116,18 +120,24 @@ struct DPP_EXPORT event_dispatch_t {
/**
* @brief Construct a new event_dispatch_t object
*
* @param client The shard the event originated on. May be a nullptr, e.g. for voice events
* @param shard_id The shard the event originated on.
* @param raw Raw event data as JSON or ETF
*/
event_dispatch_t(discord_client* client, const std::string& raw);
event_dispatch_t(dpp::cluster* creator, uint32_t shard_id, const std::string& raw);

/**
* @brief Returns the shard object for the events shard id
* @return discord client object
*/
discord_client* from() const;

/**
* @brief Construct a new event_dispatch_t object
*
* @param client The shard the event originated on. May be a nullptr, e.g. for voice events
* @param shard_id The shard the event originated on.
* @param raw Raw event data as JSON or ETF
*/
event_dispatch_t(discord_client* client, std::string&& raw);
event_dispatch_t(dpp::cluster* creator, uint32_t shard_id, std::string&& raw);

/**
* @brief Copy another event_dispatch_t object
Expand Down Expand Up @@ -2018,28 +2028,28 @@ struct DPP_EXPORT voice_receive_t : public event_dispatch_t {
/**
* @brief Construct a new voice receive t object
*
* @param client The shard the event originated on.
* WILL ALWAYS be NULL.
* @param creator The creating cluster
* @param shard_id Shard the voice channel exists on
* @param raw Raw event text as UDP packet.
* @param vc owning voice client pointer
* @param _user_id user id who is speaking, 0 for a mix of all user audio
* @param pcm user audio to set
* @param length length of user audio in bytes
*/
voice_receive_t(discord_client* client, const std::string& raw, class discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length);
voice_receive_t(dpp::cluster* creator, uint32_t shard_id, const std::string& raw, class discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length);

/**
* @brief Construct a new voice receive t object
*
* @param client The shard the event originated on.
* WILL ALWAYS be NULL.
* @param creator The creating cluster
* @param shard_id Shard the voice channel exists on
* @param raw Raw event text as UDP packet.
* @param vc owning voice client pointer
* @param _user_id user id who is speaking, 0 for a mix of all user audio
* @param pcm user audio to set
* @param length length of user audio in bytes
*/
voice_receive_t(discord_client* client, std::string&& raw, class discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length);
voice_receive_t(dpp::cluster* creator, uint32_t shard_id, std::string&& raw, class discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length);

/**
* @brief Voice client
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void cluster::queue_work(int priority, work_unit task) {
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);
dpp::log_t logmsg(nullptr, 0, msg);
logmsg.severity = severity;
logmsg.message = msg;
size_t pos{0};
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/discordclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ 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);
dpp::log_t logmsg(creator, shard_id, msg);
logmsg.severity = severity;
logmsg.message = msg;
size_t pos{0};
Expand Down
40 changes: 22 additions & 18 deletions src/dpp/dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@

namespace dpp {

event_dispatch_t::event_dispatch_t(discord_client* client, const std::string& raw) : raw_event(raw), from(client) {}
event_dispatch_t::event_dispatch_t(dpp::cluster* creator, uint32_t shard_id, const std::string& raw) : raw_event(raw), shard(shard_id), owner(creator) {}

event_dispatch_t::event_dispatch_t(discord_client* client, std::string&& raw) : raw_event(std::move(raw)), from(client) {}
event_dispatch_t::event_dispatch_t(dpp::cluster* creator, uint32_t shard_id, std::string&& raw) : raw_event(std::move(raw)), shard(shard_id), owner(creator) {}

discord_client* event_dispatch_t::from() const {
return owner->get_shard(shard);
}

const event_dispatch_t& event_dispatch_t::cancel_event() const {
cancelled = true;
Expand Down Expand Up @@ -73,12 +77,12 @@ void message_create_t::send(const std::string& m, command_completion_event_t cal
}

void message_create_t::send(const message& msg, command_completion_event_t callback) const {
this->from->creator->message_create(std::move(message{msg}.set_channel_id(this->msg.channel_id)), std::move(callback));
owner->message_create(std::move(message{msg}.set_channel_id(this->msg.channel_id)), std::move(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(std::move(msg), std::move(callback));
owner->message_create(std::move(msg), std::move(callback));
}

void message_create_t::reply(const std::string& m, bool mention_replied_user, command_completion_event_t callback) const {
Expand All @@ -94,7 +98,7 @@ void message_create_t::reply(const message& msg, bool mention_replied_user, comm
msg_to_send.allowed_mentions.replied_user = mention_replied_user;
msg_to_send.allowed_mentions.users.push_back(this->msg.author.id);
}
this->from->creator->message_create(std::move(msg_to_send), std::move(callback));
owner->message_create(std::move(msg_to_send), std::move(callback));
}

void message_create_t::reply(message&& msg, bool mention_replied_user, command_completion_event_t callback) const {
Expand All @@ -104,15 +108,15 @@ void message_create_t::reply(message&& msg, bool mention_replied_user, command_c
msg.allowed_mentions.replied_user = mention_replied_user;
msg.allowed_mentions.users.push_back(this->msg.author.id);
}
this->from->creator->message_create(std::move(msg), std::move(callback));
owner->message_create(std::move(msg), std::move(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), std::move(callback));
owner->interaction_response_create(this->command.id, this->command.token, dpp::interaction_response(t, m), std::move(callback));
}

void interaction_create_t::reply(const message& m, command_completion_event_t callback) const {
from->creator->interaction_response_create(
owner->interaction_response_create(
this->command.id,
this->command.token,
dpp::interaction_response(ir_channel_message_with_source, m),
Expand All @@ -134,7 +138,7 @@ void interaction_create_t::reply(command_completion_event_t callback) const {
}

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, std::move(callback));
owner->interaction_response_create(this->command.id, this->command.token, mr, std::move(callback));
}

void interaction_create_t::reply(interaction_response_type t, const std::string& mt, command_completion_event_t callback) const {
Expand All @@ -146,17 +150,17 @@ void interaction_create_t::reply(const std::string& mt, command_completion_event
}

void interaction_create_t::edit_response(const message& m, command_completion_event_t callback) const {
from->creator->interaction_response_edit(this->command.token, m, std::move(callback));
owner->interaction_response_edit(this->command.token, m, std::move(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), std::move(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, cb = std::move(callback)](json& j, const http_request_completion_t& http) {
owner->post_rest(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_get, "", [owner = this->owner, cb = std::move(callback)](json& j, const http_request_completion_t& http) {
if (cb) {
cb(confirmation_callback_t(creator, message().fill_from_json(&j), http));
cb(confirmation_callback_t(owner, message().fill_from_json(&j), http));
}
});
}
Expand All @@ -172,17 +176,17 @@ void interaction_create_t::edit_original_response(const message& m, command_comp
file_mimetypes.push_back(data.mimetype);
}

from->creator->post_rest_multipart(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_patch, m.build_json(), [creator = this->from->creator, cb = std::move(callback)](json& j, const http_request_completion_t& http) {
owner->post_rest_multipart(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_patch, m.build_json(), [owner = this->owner, cb = std::move(callback)](json& j, const http_request_completion_t& http) {
if (cb) {
cb(confirmation_callback_t(creator, message().fill_from_json(&j), http));
cb(confirmation_callback_t(owner, message().fill_from_json(&j), http));
}
}, m.file_data);
}

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, cb = std::move(callback)](const json &, const http_request_completion_t& http) {
owner->post_rest(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_delete, "", [owner = this->owner, cb = std::move(callback)](const json &, const http_request_completion_t& http) {
if (cb) {
cb(confirmation_callback_t(creator, confirmation(), http));
cb(confirmation_callback_t(owner, confirmation(), http));
}
});
}
Expand Down Expand Up @@ -267,11 +271,11 @@ command_value interaction_create_t::get_parameter(const std::string& name) const
return {};
}

voice_receive_t::voice_receive_t(discord_client* client, const std::string& raw, discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length) : event_dispatch_t(client, raw), voice_client(vc), user_id(_user_id) {
voice_receive_t::voice_receive_t(dpp::cluster* creator, uint32_t shard_id, const std::string& raw, discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length) : event_dispatch_t(owner, shard_id, std::move(raw)), voice_client(vc), user_id(_user_id) {
reassign(vc, _user_id, pcm, length);
}

voice_receive_t::voice_receive_t(discord_client* client, std::string&& raw, discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length) : event_dispatch_t(client, std::move(raw)), voice_client(vc), user_id(_user_id) {
voice_receive_t::voice_receive_t(dpp::cluster* creator, uint32_t shard_id, std::string&& raw, discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length) : event_dispatch_t(owner, shard_id, std::move(raw)), voice_client(vc), user_id(_user_id) {
reassign(vc, _user_id, pcm, length);
}

Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/automod_rule_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace dpp::events {
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);
automod_rule_create_t arc(client->owner, client->shard_id, raw);
arc.created = automod_rule().fill_from_json(&d);
client->creator->queue_work(0, [c = client->creator, arc]() {
c->on_automod_rule_create.call(arc);
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/automod_rule_delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace dpp::events {
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);
automod_rule_delete_t ard(client->owner, client->shard_id, raw);
ard.deleted = automod_rule().fill_from_json(&d);
client->creator->queue_work(0, [c = client->creator, ard]() {
c->on_automod_rule_delete.call(ard);
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/automod_rule_execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace dpp::events {
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);
automod_rule_execute_t are(client->owner, client->shard_id, 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");
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/automod_rule_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace dpp::events {
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);
automod_rule_update_t aru(client->owner, client->shard_id, raw);
aru.updated = automod_rule().fill_from_json(&d);
client->creator->queue_work(0, [c = client->creator, aru]() {
c->on_automod_rule_update.call(aru);
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/channel_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void channel_create::handle(discord_client* client, json &j, const std::string &
}
}
if (!client->creator->on_channel_create.empty()) {
dpp::channel_create_t cc(client, raw);
dpp::channel_create_t cc(client->owner, client->shard_id, raw);
cc.created = c;
cc.creating_guild = g;
client->creator->queue_work(1, [c = client->creator, cc]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/channel_delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void channel_delete::handle(discord_client* client, json &j, const std::string &
get_channel_cache()->remove(find_channel(c.id));
}
if (!client->creator->on_channel_delete.empty()) {
channel_delete_t cd(client, raw);
channel_delete_t cd(client->owner, client->shard_id, raw);
cd.deleted = c;
cd.deleting_guild = g;
client->creator->queue_work(1, [c = client->creator, cd]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/channel_pins_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void channel_pins_update::handle(discord_client* client, json &j, const std::str

if (!client->creator->on_channel_pins_update.empty()) {
json& d = j["d"];
dpp::channel_pins_update_t cpu(client, raw);
dpp::channel_pins_update_t cpu(client->owner, client->shard_id, 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");
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/channel_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void channel_update::handle(discord_client* client, json &j, const std::string &
}
}
if (!client->creator->on_channel_update.empty()) {
dpp::channel_update_t cu(client, raw);
dpp::channel_update_t cu(client->owner, client->shard_id, raw);
cu.updated = c;
cu.updating_guild = dpp::find_guild(c->guild_id);
client->creator->queue_work(1, [c = client->creator, cu]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/entitlement_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void entitlement_create::handle(discord_client* client, json &j, const std::stri
json& d = j["d"];
ent.fill_from_json(&d);

dpp::entitlement_create_t entitlement_event(client, raw);
dpp::entitlement_create_t entitlement_event(client->owner, client->shard_id, raw);
entitlement_event.created = ent;

client->creator->queue_work(0, [c = client->creator, entitlement_event]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/entitlement_delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void entitlement_delete::handle(discord_client* client, json &j, const std::stri
json& d = j["d"];
ent.fill_from_json(&d);

dpp::entitlement_delete_t entitlement_event(client, raw);
dpp::entitlement_delete_t entitlement_event(client->owner, client->shard_id, raw);
entitlement_event.deleted = ent;

client->creator->queue_work(0, [c = client->creator, entitlement_event]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/entitlement_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void entitlement_update::handle(discord_client* client, json &j, const std::stri
json& d = j["d"];
ent.fill_from_json(&d);

dpp::entitlement_update_t entitlement_event(client, raw);
dpp::entitlement_update_t entitlement_event(client->owner, client->shard_id, raw);
entitlement_event.updating_entitlement = ent;

client->creator->queue_work(0, [c = client->creator, entitlement_event]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/guild_audit_log_entry_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace dpp::events {
void guild_audit_log_entry_create::handle(discord_client* client, json &j, const std::string &raw) {
json& d = j["d"];
if (!client->creator->on_guild_audit_log_entry_create.empty()) {
dpp::guild_audit_log_entry_create_t ec(client, raw);
dpp::guild_audit_log_entry_create_t ec(client->owner, client->shard_id, raw);
ec.entry.fill_from_json(&d);
client->creator->queue_work(2, [c = client->creator, ec]() {
c->on_guild_audit_log_entry_create.call(ec);
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/guild_ban_add.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace dpp::events {
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);
dpp::guild_ban_add_t gba(client->owner, client->shard_id, raw);
gba.banning_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
gba.banned = dpp::user().fill_from_json(&(d["user"]));
client->creator->queue_work(1, [c = client->creator, gba]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/guild_ban_remove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace dpp::events {
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);
dpp::guild_ban_remove_t gbr(client->owner, client->shard_id, raw);
gbr.unbanning_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
gbr.unbanned = dpp::user().fill_from_json(&(d["user"]));
client->creator->queue_work(1, [c = client->creator, gbr]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/guild_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void guild_create::handle(discord_client* client, json &j, const std::string &ra
}

if (!client->creator->on_guild_create.empty()) {
dpp::guild_create_t gc(client, raw);
dpp::guild_create_t gc(client->owner, client->shard_id, raw);
gc.created = g;

/* Fill presences if there are any */
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/guild_delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void guild_delete::handle(discord_client* client, json &j, const std::string &ra
}

if (!client->creator->on_guild_delete.empty()) {
dpp::guild_delete_t gd(client, raw);
dpp::guild_delete_t gd(client->owner, client->shard_id, raw);
gd.deleted = guild_del;
gd.guild_id = guild_del.id;
client->creator->queue_work(0, [c = client->creator, gd]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/guild_emojis_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void guild_emojis_update::handle(discord_client* client, json &j, const std::str
}
}
if (!client->creator->on_guild_emojis_update.empty()) {
dpp::guild_emojis_update_t geu(client, raw);
dpp::guild_emojis_update_t geu(client->owner, client->shard_id, raw);
geu.emojis = emojis;
geu.updating_guild = g;
client->creator->queue_work(1, [c = client->creator, geu]() {
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/events/guild_integrations_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace dpp::events {
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);
dpp::guild_integrations_update_t giu(client->owner, client->shard_id, raw);
giu.updating_guild = dpp::find_guild(snowflake_not_null(&d, "guild_id"));
client->creator->queue_work(1, [c = client->creator, giu]() {
c->on_guild_integrations_update.call(giu);
Expand Down
Loading

0 comments on commit 2190cf6

Please sign in to comment.