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
46 changes: 27 additions & 19 deletions src/dpp/events/channel_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,36 @@ 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);
} else {
c = dpp::find_channel(snowflake_not_null(&d, "id"));
if (!c) {
c = new dpp::channel();
}
}
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);
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(from_string<uint64_t>(d["id"].get<std::string>()));
braindigitalis marked this conversation as resolved.
Show resolved Hide resolved
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);
}
}

}};
164 changes: 86 additions & 78 deletions src/dpp/events/guild_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,97 +42,105 @@ 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)
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();
dpp::guild newguild;
dpp::guild* g = nullptr;

if (client->creator->cache_policy.guild_policy == cp_none) {
newguild.fill_from_json(client, &d);
g = &newguild;
} else {
bool newguild = false;
braindigitalis marked this conversation as resolved.
Show resolved Hide resolved
if (snowflake_not_null(&d, "id") == 0)
return;
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);
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 (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));
}
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
Loading