Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow disabling of guild and channel caches #895

Merged
merged 8 commits into from
Sep 27, 2023
78 changes: 75 additions & 3 deletions include/dpp/cluster.h

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions include/dpp/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,38 @@ struct DPP_EXPORT cache_policy_t {
* @brief Caching policy for roles
*/
cache_policy_setting_t role_policy = cp_aggressive;

/**
* @brief Caching policy for roles
*/
cache_policy_setting_t channel_policy = cp_aggressive;

/**
* @brief Caching policy for roles
*/
cache_policy_setting_t guild_policy = cp_aggressive;
};

/**
* @brief Contains a set of predefined cache policies for use when constructing a dpp::cluster
*/
namespace cache_policy {

/**
* @brief A shortcut constant for all caching enabled for use in dpp::cluster constructor
*/
inline constexpr cache_policy_t cpol_default = { cp_aggressive, cp_aggressive, cp_aggressive, cp_aggressive, cp_aggressive };

/**
* @brief A shortcut constant for a more balanced caching policy for use in dpp::cluster constructor
*/
inline constexpr cache_policy_t cpol_balanced = { cp_lazy, cp_lazy, cp_lazy, cp_aggressive, cp_aggressive };

/**
* @brief A shortcut constant for all caching disabled for use in dpp::cluster constructor
*/
inline constexpr cache_policy_t cpol_none = { cp_none, cp_none, cp_none, cp_none, cp_none };

};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/dpp/discordvoiceclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ discord_voice_client::discord_voice_client(dpp::cluster* _cluster, snowflake _ch
: websocket_client(_host.substr(0, _host.find(":")), _host.substr(_host.find(":") + 1, _host.length()), "/?v=4", OP_TEXT),
runner(nullptr),
connect_time(0),
port(0),
mixer(std::make_unique<audio_mixer>()),
port(0),
ssrc(0),
timescale(1000000),
paused(false),
Expand Down
51 changes: 32 additions & 19 deletions src/dpp/events/channel_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,41 @@ using namespace dpp;
*/
void channel_create::handle(discord_client* client, json &j, const std::string &raw) {
json& d = j["d"];
dpp::channel newchannel;
dpp::channel* c = nullptr;
dpp::guild* g = nullptr;

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);
if (client->creator->cache_policy.channel_policy == cp_none) {
newchannel.fill_from_json(&d);
c = &newchannel;
g = dpp::find_guild(c->guild_id);
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);
} else {
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);
}
}
g = dpp::find_guild(c->guild_id);
if (g) {
g->channels.push_back(c->id);
}
braindigitalis marked this conversation as resolved.
Show resolved Hide resolved
}
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);
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/dpp/events/channel_delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,24 @@ using namespace dpp;
*/
void channel_delete::handle(discord_client* client, json &j, const std::string &raw) {
json& d = j["d"];
dpp::guild* g = nullptr;
dpp::channel* c = dpp::find_channel(snowflake_not_null(&d, "id"));
if (c) {
dpp::guild* g = dpp::find_guild(c->guild_id);
g = dpp::find_guild(c->guild_id);
braindigitalis marked this conversation as resolved.
Show resolved Hide resolved
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);
}
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);
}
}

}};
23 changes: 15 additions & 8 deletions src/dpp/events/channel_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,23 @@ using namespace dpp;
*/
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);
channel newchannel;
channel* c = nullptr;
if (client->creator->cache_policy.channel_policy == cp_none) {
newchannel.fill_from_json(&d);
c = &newchannel;
} else {
c = dpp::find_channel(snowflake_not_null(&d, "id"));
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);
}
}

}};
165 changes: 89 additions & 76 deletions src/dpp/events/guild_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,97 +42,110 @@ using namespace dpp;
*/
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)
dpp::guild newguild;
dpp::guild* g = nullptr;

if (snowflake_not_null(&d, "id") == 0) {
/* This shouldnt ever happen, but it has been seen in the wild i guess?
* Either way a guild with invalid or missing ID doesnt want to cause events.
*/
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();

if (client->creator->cache_policy.guild_policy == cp_none) {
newguild.fill_from_json(client, &d);
g = &newguild;
} else {
bool is_new_guild = false;
g = dpp::find_guild(snowflake_not_null(&d, "id"));
if (!g) {
g = new dpp::guild();
is_new_guild = true;
}
g->fill_from_json(client, &d);
g->shard_id = client->shard_id;
if (!g->is_unavailable() && is_new_guild) {
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);
braindigitalis marked this conversation as resolved.
Show resolved Hide resolved
}
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();
/* 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);
}
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 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++;
/* 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;
}
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);
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);
}
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;
dpp::get_guild_cache()->store(g);
if (is_new_guild && 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));
}
client->queue_message(client->jsonobj_to_string(chunk_req));
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/dpp/events/guild_delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ void guild_delete::handle(discord_client* client, json &j, const std::string &ra
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);
}
}

if (!client->creator->on_guild_delete.empty()) {
dpp::guild_delete_t gd(client, raw);
gd.deleted = g;
client->creator->on_guild_delete.call(gd);
}
}

Expand Down
Loading