handle role mentions

This commit is contained in:
ouwou
2023-03-16 20:27:59 -04:00
parent 0e1e15eaeb
commit b83bf2a622
6 changed files with 68 additions and 5 deletions

View File

@@ -1646,7 +1646,7 @@ void DiscordClient::HandleGatewayMessageCreate(const GatewayMessage &msg) {
m_last_message_id[data.ChannelID] = data.ID;
if (data.Author.ID != GetUserData().ID)
m_unread[data.ChannelID];
if (data.DoesMentionEveryoneOrUser(GetUserData().ID)) {
if (data.DoesMention(GetUserData().ID)) {
m_unread[data.ChannelID]++;
}
m_signal_message_create.emit(data);

View File

@@ -197,7 +197,7 @@ void from_json(const nlohmann::json &j, Message &m) {
JS_D("tts", m.IsTTS);
JS_D("mention_everyone", m.DoesMentionEveryone);
JS_D("mentions", m.Mentions);
// JS_D("mention_roles", m.MentionRoles);
JS_D("mention_roles", m.MentionRoles);
// JS_O("mention_channels", m.MentionChannels);
JS_D("attachments", m.Attachments);
JS_D("embeds", m.Embeds);
@@ -235,6 +235,7 @@ void Message::from_json_edited(const nlohmann::json &j) {
JS_O("tts", IsTTS);
JS_O("mention_everyone", DoesMentionEveryone);
JS_O("mentions", Mentions);
JS_O("mention_roles", MentionRoles);
JS_O("embeds", Embeds);
JS_O("nonce", Nonce);
JS_O("pinned", IsPinned);
@@ -270,3 +271,11 @@ bool Message::DoesMentionEveryoneOrUser(Snowflake id) const noexcept {
return user.ID == id;
});
}
bool Message::DoesMention(Snowflake id) const noexcept {
if (DoesMentionEveryoneOrUser(id)) return true;
if (!GuildID.has_value()) return false; // nothing left to check
const auto member = Abaddon::Get().GetDiscordClient().GetMember(id, *GuildID);
if (!member.has_value()) return false;
return std::find_first_of(MentionRoles.begin(), MentionRoles.end(), member->Roles.begin(), member->Roles.end()) != MentionRoles.end();
}

View File

@@ -183,7 +183,7 @@ struct Message {
bool IsTTS;
bool DoesMentionEveryone;
std::vector<UserData> Mentions; // full user accessible
// std::vector<RoleData> MentionRoles;
std::vector<Snowflake> MentionRoles;
// std::optional<std::vector<ChannelMentionData>> MentionChannels;
std::vector<AttachmentData> Attachments;
std::vector<EmbedData> Embeds;
@@ -213,6 +213,7 @@ struct Message {
[[nodiscard]] bool IsEdited() const;
[[nodiscard]] bool DoesMentionEveryoneOrUser(Snowflake id) const noexcept;
[[nodiscard]] bool DoesMention(Snowflake id) const noexcept;
private:
bool m_deleted = false;

View File

@@ -346,6 +346,15 @@ void Store::SetMessage(Snowflake id, const Message &message) {
s->Reset();
}
for (const auto &r : message.MentionRoles) {
auto &s = m_stmt_set_role_mention;
s->Bind(1, id);
s->Bind(2, r);
if (!s->Insert())
fprintf(stderr, "message role mention insert failed for %" PRIu64 "/%" PRIu64 ": %s\n", static_cast<uint64_t>(id), static_cast<uint64_t>(r), m_db.ErrStr());
s->Reset();
}
for (const auto &a : message.Attachments) {
auto &s = m_stmt_set_attachment;
s->Bind(1, id);
@@ -987,6 +996,17 @@ Message Store::GetMessageBound(std::unique_ptr<Statement> &s) const {
s->Reset();
}
{
auto &s = m_stmt_get_role_mentions;
s->Bind(1, r.ID);
while (s->FetchOne()) {
Snowflake id;
s->Get(0, id);
r.MentionRoles.push_back(id);
}
s->Reset();
}
{
auto &s = m_stmt_get_reactions;
s->Bind(1, r.ID);
@@ -1437,6 +1457,14 @@ bool Store::CreateTables() {
)
)";
const char *create_mention_roles = R"(
CREATE TABLE IF NOT EXISTS mention_roles (
message INTEGER NOT NULL,
role INTEGER NOT NULL,
PRIMARY KEY(message, role)
)
)";
const char *create_attachments = R"(
CREATE TABLE IF NOT EXISTS attachments (
message INTEGER NOT NULL,
@@ -1556,6 +1584,11 @@ bool Store::CreateTables() {
return false;
}
if (m_db.Execute(create_mention_roles) != SQLITE_OK) {
fprintf(stderr, "failed to create role mentions table: %s\n", m_db.ErrStr());
return false;
}
if (m_db.Execute(create_attachments) != SQLITE_OK) {
fprintf(stderr, "failed to create attachments table: %s\n", m_db.ErrStr());
return false;
@@ -2119,6 +2152,24 @@ bool Store::CreateStatements() {
return false;
}
m_stmt_set_role_mention = std::make_unique<Statement>(m_db, R"(
REPLACE INTO mention_roles VALUES (
?, ?
)
)");
if (!m_stmt_set_role_mention->OK()) {
fprintf(stderr, "failed to prepare set role mention statement: %s\n", m_db.ErrStr());
return false;
}
m_stmt_get_role_mentions = std::make_unique<Statement>(m_db, R"(
SELECT role FROM mention_roles WHERE message = ?
)");
if (!m_stmt_get_role_mentions->OK()) {
fprintf(stderr, "failed to prepare get role mentions statement: %s\n", m_db.ErrStr());
return false;
}
m_stmt_set_attachment = std::make_unique<Statement>(m_db, R"(
REPLACE INTO attachments VALUES (
?, ?, ?, ?, ?, ?, ?, ?

View File

@@ -299,6 +299,8 @@ private:
STMT(get_emoji_roles);
STMT(set_mention);
STMT(get_mentions);
STMT(set_role_mention);
STMT(get_role_mentions);
STMT(set_attachment);
STMT(get_attachments);
STMT(set_recipient);

View File

@@ -22,7 +22,7 @@ bool CheckGuildMessage(const Message &message) {
case DefaultNotificationLevel::ALL_MESSAGES:
return true;
case DefaultNotificationLevel::ONLY_MENTIONS:
return message.DoesMentionEveryoneOrUser(discord.GetUserData().ID);
return message.DoesMention(discord.GetUserData().ID);
default:
return false;
}
@@ -78,7 +78,7 @@ bool CheckGuildMessage(const Message &message) {
case NotificationLevel::ALL_MESSAGES:
return true;
case NotificationLevel::ONLY_MENTIONS:
return message.DoesMentionEveryoneOrUser(discord.GetUserData().ID);
return message.DoesMention(discord.GetUserData().ID);
case NotificationLevel::NO_MESSAGES:
return false;
default: