diff options
author | George Hazan <george.hazan@gmail.com> | 2024-06-06 15:00:35 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2024-06-06 15:00:35 +0300 |
commit | cf9398bf479f55b792fc932f1fdadfe7d1deb3c3 (patch) | |
tree | 18d7fd7fee1ef8642d2b09b7b82e05043cd58ac5 | |
parent | 9c960060136f193ff4f336adcd2c4fac7b604547 (diff) |
Discord: ability to disable database histories for a certain guild
-rw-r--r-- | protocols/Discord/src/dispatch.cpp | 70 | ||||
-rw-r--r-- | protocols/Discord/src/guilds.cpp | 3 | ||||
-rw-r--r-- | protocols/Discord/src/menus.cpp | 40 | ||||
-rw-r--r-- | protocols/Discord/src/proto.cpp | 4 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 8 | ||||
-rw-r--r-- | protocols/Discord/src/stdafx.h | 27 | ||||
-rw-r--r-- | protocols/Discord/src/utils.cpp | 9 |
7 files changed, 108 insertions, 53 deletions
diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp index 3d886f3eb2..cab63a8d44 100644 --- a/protocols/Discord/src/dispatch.cpp +++ b/protocols/Discord/src/dispatch.cpp @@ -474,6 +474,7 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot, bool bIsNew) }
// shift & store LastMsgId field
+ bool bIsChat = Contact::IsGroupChat(pUser->hContact);
pUser->lastMsgId = msgId;
SnowFlake lastId = getId(pUser->hContact, DB_KEY_LASTMSGID); // as stored in a database
@@ -485,7 +486,7 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot, bool bIsNew) COwnMessage ownMsg(::getId(pRoot["nonce"]), 0);
COwnMessage *p = arOwnMessages.find(&ownMsg);
- if (p != nullptr && !Contact::IsGroupChat(pUser->hContact)) { // own message? skip it
+ if (p != nullptr && !bIsChat) { // own message? skip it
ProtoBroadcastAck(pUser->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)p->reqId, (LPARAM)szMsgId);
debugLogA("skipping own message with nonce=%lld, id=%lld", ownMsg.nonce, msgId);
}
@@ -494,42 +495,53 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot, bool bIsNew) if (wszText.IsEmpty())
return;
- else {
- // old message? try to restore it from database
- bool bOurMessage = userId == m_ownId;
- MEVENT hOldEvent = (bIsNew) ? 0 : db_event_getById(m_szModuleName, szMsgId);
+ // if we don't store guild's messages, simply push it to a chat
+ if (bIsChat && pUser->pGuild && !pUser->pGuild->m_bEnableHistory) {
+ _A2T wszUID(szUserId);
+
+ GCEVENT gce = { pUser->si, GC_EVENT_MESSAGE };
+ gce.dwFlags = GCEF_ADDTOLOG;
+ gce.pszUID.w = wszUID;
+ gce.pszText.w = wszText;
+ gce.time = time(0);
+ gce.bIsMe = userId == m_ownId;
+ Chat_Event(&gce);
+ return;
+ }
- const JSONNode &edited = pRoot["edited_timestamp"];
- if (!edited.isnull())
- wszText.AppendFormat(L" (%s %s)", TranslateT("edited at"), edited.as_mstring().c_str());
+ // old message? try to restore it from database
+ MEVENT hOldEvent = (bIsNew) ? 0 : db_event_getById(m_szModuleName, szMsgId);
- // if a message has myself as an author, add some flags
- DB::EventInfo dbei(hOldEvent);
- if (bOurMessage)
- dbei.flags |= DBEF_READ | DBEF_SENT;
+ const JSONNode &edited = pRoot["edited_timestamp"];
+ if (!edited.isnull())
+ wszText.AppendFormat(L" (%s %s)", TranslateT("edited at"), edited.as_mstring().c_str());
- if (auto &nReply = pRoot["message_reference"]) {
- _i64toa(::getId(nReply["message_id"]), szReplyId, 10);
- dbei.szReplyId = szReplyId;
- }
+ // if a message has myself as an author, add some flags
+ DB::EventInfo dbei(hOldEvent);
+ if (userId == m_ownId)
+ dbei.flags |= DBEF_READ | DBEF_SENT;
- debugLogA("store a message from private user %lld, channel id %lld", pUser->id, pUser->channelId);
+ if (auto &nReply = pRoot["message_reference"]) {
+ _i64toa(::getId(nReply["message_id"]), szReplyId, 10);
+ dbei.szReplyId = szReplyId;
+ }
- dbei.timestamp = (uint32_t)StringToDate(pRoot["timestamp"].as_mstring());
- dbei.szId = szMsgId;
- replaceStr(dbei.pBlob, mir_utf8encodeW(wszText));
- dbei.cbBlob = (int)mir_strlen(dbei.pBlob);
+ debugLogA("store a message from private user %lld, channel id %lld", pUser->id, pUser->channelId);
- if (!pUser->bIsPrivate || pUser->bIsGroup) {
- dbei.szUserId = szUserId;
- ProcessChatUser(pUser, userId, pRoot);
- }
+ dbei.timestamp = (uint32_t)StringToDate(pRoot["timestamp"].as_mstring());
+ dbei.szId = szMsgId;
+ replaceStr(dbei.pBlob, mir_utf8encodeW(wszText));
+ dbei.cbBlob = (int)mir_strlen(dbei.pBlob);
- if (dbei)
- db_event_edit(dbei.getEvent(), &dbei, true);
- else
- ProtoChainRecvMsg(pUser->hContact, dbei);
+ if (!pUser->bIsPrivate || pUser->bIsGroup) {
+ dbei.szUserId = szUserId;
+ ProcessChatUser(pUser, userId, pRoot);
}
+
+ if (dbei)
+ db_event_edit(dbei.getEvent(), &dbei, true);
+ else
+ ProtoChainRecvMsg(pUser->hContact, dbei);
}
}
diff --git a/protocols/Discord/src/guilds.cpp b/protocols/Discord/src/guilds.cpp index 0972518154..35b1cd18fc 100644 --- a/protocols/Discord/src/guilds.cpp +++ b/protocols/Discord/src/guilds.cpp @@ -138,6 +138,7 @@ void CDiscordProto::ProcessGuild(const JSONNode &pRoot) pGuild->pParentSi = (SESSION_INFO*)si;
pGuild->m_hContact = si->hContact;
setId(pGuild->m_hContact, DB_KEY_CHANNELID, guildId);
+ pGuild->m_bEnableHistory = surelyGetBool(pGuild->m_hContact, DB_KEY_ENABLE_HIST);
Chat_Control(si, WINDOW_HIDDEN);
Chat_Control(si, SESSION_ONLINE);
@@ -147,7 +148,7 @@ void CDiscordProto::ProcessGuild(const JSONNode &pRoot) BuildStatusList(pGuild, si);
- if (!pGuild->m_bSynced && getByte(si->hContact, "EnableSync"))
+ if (!pGuild->m_bSynced && getByte(si->hContact, DB_KEY_ENABLE_SYNC))
GatewaySendGuildInfo(pGuild);
// store all guild members
diff --git a/protocols/Discord/src/menus.cpp b/protocols/Discord/src/menus.cpp index cc928221f3..1c248df24e 100644 --- a/protocols/Discord/src/menus.cpp +++ b/protocols/Discord/src/menus.cpp @@ -40,6 +40,19 @@ INT_PTR CDiscordProto::OnMenuCreateChannel(WPARAM hContact, LPARAM) /////////////////////////////////////////////////////////////////////////////////////////
+INT_PTR CDiscordProto::OnMenuDatabaseHistory(WPARAM hContact, LPARAM)
+{
+ bool bEnable = !getBool(hContact, DB_KEY_ENABLE_HIST);
+ setByte(hContact, DB_KEY_ENABLE_HIST, bEnable);
+
+ if (auto *pGuild = FindGuild(getId(hContact, DB_KEY_CHANNELID)))
+ pGuild->m_bEnableHistory = bEnable;
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
INT_PTR CDiscordProto::OnMenuJoinGuild(WPARAM, LPARAM)
{
ENTER_STRING es = { m_szModuleName, "guild_name", TranslateT("Enter invitation code you received"), nullptr, ESF_COMBO, 5 };
@@ -78,8 +91,8 @@ INT_PTR CDiscordProto::OnMenuLoadHistory(WPARAM hContact, LPARAM) INT_PTR CDiscordProto::OnMenuToggleSync(WPARAM hContact, LPARAM)
{
- bool bEnabled = !getBool(hContact, "EnableSync");
- setByte(hContact, "EnableSync", bEnabled);
+ bool bEnabled = !getBool(hContact, DB_KEY_ENABLE_SYNC);
+ setByte(hContact, DB_KEY_ENABLE_SYNC, bEnabled);
if (bEnabled)
if (auto *pGuild = FindGuild(getId(hContact, DB_KEY_CHANNELID)))
@@ -99,11 +112,16 @@ int CDiscordProto::OnMenuPrebuild(WPARAM hContact, LPARAM) if (!bIsGuild && getWord(hContact, "ApparentMode") != 0)
Menu_ShowItem(GetMenuItem(PROTO_MENU_REQ_AUTH), true);
-
- if (getByte(hContact, "EnableSync"))
+
+ if (getByte(hContact, DB_KEY_ENABLE_SYNC))
Menu_ModifyItem(m_hMenuToggleSync, LPGENW("Disable sync"), Skin_GetIconHandle(SKINICON_CHAT_LEAVE));
else
Menu_ModifyItem(m_hMenuToggleSync, LPGENW("Enable sync"), Skin_GetIconHandle(SKINICON_CHAT_JOIN));
+
+ if (getByte(hContact, DB_KEY_ENABLE_HIST))
+ Menu_ModifyItem(m_hMenuDatabaseHistory, LPGENW("Disable database history for a guild"), Skin_GetIconHandle(SKINICON_CHAT_LEAVE));
+ else
+ Menu_ModifyItem(m_hMenuDatabaseHistory, LPGENW("Enable database history for a guild"), Skin_GetIconHandle(SKINICON_CHAT_JOIN));
return 0;
}
@@ -149,14 +167,14 @@ void CDiscordProto::InitMenus() CreateProtoService(mi.pszService, &CDiscordProto::OnMenuCreateChannel);
SET_UID(mi, 0x6EF11AD6, 0x6111, 0x4E29, 0xBA, 0x8B, 0xA7, 0xB2, 0xE0, 0x22, 0xE1, 0x8D);
mi.name.a = LPGEN("Create new channel");
- mi.position = -200001001;
+ mi.position++;
mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_ADDCONTACT);
m_hMenuCreateChannel = Menu_AddContactMenuItem(&mi, m_szModuleName);
SET_UID(mi, 0x6EF11AD6, 0x6111, 0x4E29, 0xBA, 0x8B, 0xA7, 0xB2, 0xE0, 0x22, 0xE1, 0x8E);
mi.pszService = "/CopyId";
mi.name.a = LPGEN("Copy ID");
- mi.position = -200001002;
+ mi.position++;
mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_USERONLINE);
Menu_AddContactMenuItem(&mi, m_szModuleName);
@@ -164,9 +182,17 @@ void CDiscordProto::InitMenus() CreateProtoService(mi.pszService, &CDiscordProto::OnMenuToggleSync);
SET_UID(mi, 0x6EF11AD6, 0x6111, 0x4E29, 0xBA, 0x8B, 0xA7, 0xB2, 0xE0, 0x22, 0xE1, 0x8F);
mi.name.a = LPGEN("Enable guild sync");
- mi.position = -200001003;
+ mi.position++;
mi.hIcolibItem = Skin_GetIconHandle(SKINICON_CHAT_JOIN);
m_hMenuToggleSync = Menu_AddContactMenuItem(&mi, m_szModuleName);
+ mi.pszService = "/DatabaseHistory";
+ CreateProtoService(mi.pszService, &CDiscordProto::OnMenuDatabaseHistory);
+ SET_UID(mi, 0x6EF11AD6, 0x6111, 0x4E29, 0xBA, 0x8B, 0xA7, 0xB2, 0xE0, 0x22, 0xE1, 0x90);
+ mi.name.a = LPGEN("Enable database history for a guild");
+ mi.position++;
+ mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_HISTORY);
+ m_hMenuDatabaseHistory = Menu_AddContactMenuItem(&mi, m_szModuleName);
+
HookProtoEvent(ME_CLIST_PREBUILDCONTACTMENU, &CDiscordProto::OnMenuPrebuild);
}
diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index cea528e5b7..32ad2f6c01 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -150,8 +150,8 @@ void CDiscordProto::OnModulesLoaded() switch (getByte(hContact, "ChatRoom")) {
case 2: // guild
delSetting(hContact, DB_KEY_CHANNELID);
- if (getDword(hContact, "EnableSync", -1) == -1)
- setDword(hContact, "EnableSync", 1);
+ surelyGetBool(hContact, DB_KEY_ENABLE_HIST);
+ surelyGetBool(hContact, DB_KEY_ENABLE_SYNC);
break;
case 1: // group chat
diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index 117e7a90ba..98a3b1343b 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -212,7 +212,8 @@ struct CDiscordGuild : public MZeroedObject MCONTACT m_hContact;
MGROUP m_groupId;
bool m_bSynced = false;
-
+ bool m_bEnableHistory = true;
+
SESSION_INFO *pParentSi;
LIST<CDiscordUser> arChannels;
OBJLIST<CDiscordGuildMember> arChatUsers;
@@ -383,12 +384,13 @@ class CDiscordProto : public PROTO<CDiscordProto> INT_PTR __cdecl OnMenuCopyId(WPARAM, LPARAM);
INT_PTR __cdecl OnMenuCreateChannel(WPARAM, LPARAM);
+ INT_PTR __cdecl OnMenuDatabaseHistory(WPARAM, LPARAM);
INT_PTR __cdecl OnMenuJoinGuild(WPARAM, LPARAM);
INT_PTR __cdecl OnMenuLeaveGuild(WPARAM, LPARAM);
INT_PTR __cdecl OnMenuLoadHistory(WPARAM, LPARAM);
INT_PTR __cdecl OnMenuToggleSync(WPARAM, LPARAM);
- HGENMENU m_hMenuLeaveGuild, m_hMenuCreateChannel, m_hMenuToggleSync;
+ HGENMENU m_hMenuLeaveGuild, m_hMenuCreateChannel, m_hMenuToggleSync, m_hMenuDatabaseHistory;
//////////////////////////////////////////////////////////////////////////////////////
// guilds
@@ -463,6 +465,8 @@ class CDiscordProto : public PROTO<CDiscordProto> void setId(const char *szName, SnowFlake iValue);
void setId(MCONTACT hContact, const char *szName, SnowFlake iValue);
+ bool surelyGetBool(MCONTACT hContact, const char *szSetting);
+
public:
CDiscordProto(const char*,const wchar_t*);
~CDiscordProto();
diff --git a/protocols/Discord/src/stdafx.h b/protocols/Discord/src/stdafx.h index 1623cbafa6..9987d6a256 100644 --- a/protocols/Discord/src/stdafx.h +++ b/protocols/Discord/src/stdafx.h @@ -54,18 +54,21 @@ extern IconItem g_iconList[];
-#define DB_KEY_ID "id"
-#define DB_KEY_TOKEN "AccessToken"
-#define DB_KEY_PASSWORD "Password"
-#define DB_KEY_DISCR "Discriminator"
-#define DB_KEY_MFA "MfaEnabled"
-#define DB_KEY_NICK "Nick"
-#define DB_KEY_OWNERID "OwnerID"
-#define DB_KEY_AVHASH "AvatarHash"
-#define DB_KEY_CHANNELID "ChannelID"
-#define DB_KEY_LASTMSGID "LastMessageID"
-#define DB_KEY_REQAUTH "ReqAuth"
-#define DB_KEY_DONT_FETCH "DontFetch"
+#define DB_KEY_ID "id"
+#define DB_KEY_TOKEN "AccessToken"
+#define DB_KEY_PASSWORD "Password"
+#define DB_KEY_DISCR "Discriminator"
+#define DB_KEY_MFA "MfaEnabled"
+#define DB_KEY_NICK "Nick"
+#define DB_KEY_OWNERID "OwnerID"
+#define DB_KEY_AVHASH "AvatarHash"
+#define DB_KEY_CHANNELID "ChannelID"
+#define DB_KEY_LASTMSGID "LastMessageID"
+#define DB_KEY_REQAUTH "ReqAuth"
+#define DB_KEY_DONT_FETCH "DontFetch"
+
+#define DB_KEY_ENABLE_SYNC "EnableSync"
+#define DB_KEY_ENABLE_HIST "EnableDbHistory"
#define DB_KEYVAL_GROUP L"Discord"
diff --git a/protocols/Discord/src/utils.cpp b/protocols/Discord/src/utils.cpp index e8480c80e2..983cd6201b 100644 --- a/protocols/Discord/src/utils.cpp +++ b/protocols/Discord/src/utils.cpp @@ -135,6 +135,15 @@ void CDiscordProto::setId(MCONTACT hContact, const char *szSetting, SnowFlake iV db_set_blob(hContact, m_szModuleName, szSetting, &iValue, sizeof(iValue));
}
+bool CDiscordProto::surelyGetBool(MCONTACT hContact, const char *szSetting)
+{
+ int iValue = getDword(hContact, szSetting, -1);
+ if (iValue == -1)
+ setByte(hContact, szSetting, iValue = 1);
+
+ return iValue != 0;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
void CopyId(const CMStringW &nick)
|