diff options
40 files changed, 174 insertions, 130 deletions
diff --git a/include/delphi/m_database.inc b/include/delphi/m_database.inc index 892f5740d0..43691bc9c6 100644 --- a/include/delphi/m_database.inc +++ b/include/delphi/m_database.inc @@ -46,6 +46,7 @@ type cbBlob : dword; // size in bytes of pBlob^
pBlob : PByte; // pointer to buffer containing the module defined event data
szId : PAnsiChar; // server id of event
+ szUserId : PAnsiChar; // user id of event
end;
(******************************************************************************
diff --git a/include/delphi/m_protosvc.inc b/include/delphi/m_protosvc.inc index 69d9435a4e..2d60e9327f 100644 --- a/include/delphi/m_protosvc.inc +++ b/include/delphi/m_protosvc.inc @@ -182,6 +182,7 @@ type timestamp : dword;
szMessage : TChar;
lParam : LPARAM;
+ szUserId : PAnsiChar; // user id of event
end;
const
diff --git a/include/m_database.h b/include/m_database.h index ad0e16e60b..0a31bc68fc 100644 --- a/include/m_database.h +++ b/include/m_database.h @@ -188,7 +188,8 @@ struct DBEVENTINFO uint16_t eventType; // module-defined event type field
int cbBlob; // size of pBlob in bytes
uint8_t *pBlob; // pointer to buffer containing module-defined event data
- const char *szId; // server id
+ const char *szId; // server message id
+ const char *szUserId; // user id (for group chats only)
bool __forceinline markedRead() const {
return (flags & (DBEF_SENT | DBEF_READ)) != 0;
diff --git a/include/m_protosvc.h b/include/m_protosvc.h index e6f1df3ab2..031622a3a5 100644 --- a/include/m_protosvc.h +++ b/include/m_protosvc.h @@ -735,12 +735,13 @@ struct PROTOFILERESUME struct PROTORECVEVENT
{
- uint32_t flags; // combination of PREF_*
- uint32_t timestamp; // unix time
- char* szMessage; // message body in utf8
- LPARAM lParam; // extra space for the network level protocol module
- const char* szMsgId; // server message id, optional, should be NULL otherwise
- // ignored for protocols without PF4_SERVERMSGID in GetCaps()
+ uint32_t flags; // combination of PREF_*
+ uint32_t timestamp; // unix time
+ char* szMessage; // message body in utf8
+ LPARAM lParam; // extra space for the network level protocol module
+ const char* szMsgId; // server message id, optional, should be NULL otherwise
+ // ignored for protocols without PF4_SERVERMSGID in GetCaps()
+ const char *szUserId; // user id, for group chats stored in the database
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/include/m_srmm_int.h b/include/m_srmm_int.h index c9ac8c14b7..876c31dbaf 100644 --- a/include/m_srmm_int.h +++ b/include/m_srmm_int.h @@ -204,6 +204,7 @@ protected: bool ProcessHotkeys(int key, bool bShift, bool bCtrl, bool bAlt);
void RefreshButtonStatus(void);
void RunUserMenu(HWND hwndOwner, struct USERINFO *ui, const POINT &pt);
+ void UpdateChatLog(void);
protected:
CSrmmLogWindow *m_pLog = nullptr;
@@ -233,6 +234,7 @@ protected: public:
MCONTACT m_hContact;
+ MEVENT m_hDbEventFirst, m_hDbEventLast;
int m_iLogFilterFlags;
bool m_bFilterEnabled, m_bNicklistEnabled;
bool m_bFGSet, m_bBGSet;
@@ -246,6 +248,7 @@ public: virtual void AddLog();
virtual void CloseTab() {}
+ virtual bool GetFirstEvent() PURE;
virtual bool IsActive() const PURE;
virtual void LoadSettings() PURE;
virtual void SetStatusText(const wchar_t *, HICON) {}
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib Binary files differindex 2fdd599d80..5b29f95fd8 100644 --- a/libs/win32/mir_app.lib +++ b/libs/win32/mir_app.lib diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib Binary files differindex f416cbf44a..fc28af6423 100644 --- a/libs/win64/mir_app.lib +++ b/libs/win64/mir_app.lib diff --git a/plugins/Dbx_sqlite/src/dbevents.cpp b/plugins/Dbx_sqlite/src/dbevents.cpp index 605090c2eb..0dadafa834 100644 --- a/plugins/Dbx_sqlite/src/dbevents.cpp +++ b/plugins/Dbx_sqlite/src/dbevents.cpp @@ -104,7 +104,9 @@ MEVENT CDbxSQLite::AddEvent(MCONTACT hContact, const DBEVENTINFO *dbei) }
mir_cslockfull lock(m_csDbAccess);
- sqlite3_stmt *stmt = InitQuery("INSERT INTO events(contact_id, module, timestamp, type, flags, data, server_id, is_read) VALUES (?, ?, ?, ?, ?, ?, ?, ?);", qEvAdd);
+ sqlite3_stmt *stmt = InitQuery(
+ "INSERT INTO events(contact_id, module, timestamp, type, flags, data, server_id, user_id, is_read) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", qEvAdd);
sqlite3_bind_int64(stmt, 1, hContact);
sqlite3_bind_text(stmt, 2, tmp.szModule, (int)mir_strlen(tmp.szModule), nullptr);
sqlite3_bind_int64(stmt, 3, tmp.timestamp);
@@ -112,7 +114,8 @@ MEVENT CDbxSQLite::AddEvent(MCONTACT hContact, const DBEVENTINFO *dbei) sqlite3_bind_int64(stmt, 5, tmp.flags);
sqlite3_bind_blob(stmt, 6, tmp.pBlob, tmp.cbBlob, nullptr);
sqlite3_bind_text(stmt, 7, szEventId, (int)mir_strlen(szEventId), nullptr);
- sqlite3_bind_int(stmt, 8, tmp.markedRead());
+ sqlite3_bind_text(stmt, 8, tmp.szUserId, (int)mir_strlen(tmp.szUserId), nullptr);
+ sqlite3_bind_int(stmt, 9, tmp.markedRead());
int rc = sqlite3_step(stmt);
logError(rc, __FILE__, __LINE__);
sqlite3_reset(stmt);
@@ -287,7 +290,7 @@ int CDbxSQLite::GetBlobSize(MEVENT hDbEvent) return res;
}
-static char g_szId[100];
+static char g_szId[100], g_szUserId[100];
BOOL CDbxSQLite::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei)
{
@@ -303,7 +306,7 @@ BOOL CDbxSQLite::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei) }
mir_cslock lock(m_csDbAccess);
- sqlite3_stmt *stmt = InitQuery("SELECT module, timestamp, type, flags, server_id, length(data), data FROM events WHERE id = ? LIMIT 1;", qEvGet);
+ sqlite3_stmt *stmt = InitQuery("SELECT module, timestamp, type, flags, server_id, user_id, length(data), data FROM events WHERE id = ? LIMIT 1;", qEvGet);
sqlite3_bind_int64(stmt, 1, hDbEvent);
int rc = sqlite3_step(stmt);
logError(rc, __FILE__, __LINE__);
@@ -328,7 +331,14 @@ BOOL CDbxSQLite::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei) }
else dbei->szId = nullptr;
- int32_t cbBlob = sqlite3_column_int64(stmt, 5);
+ char *pszUserId = (char *)sqlite3_column_text(stmt, 5);
+ if (mir_strlen(pszUserId)) {
+ mir_strncpy(g_szUserId, pszUserId, sizeof(g_szUserId));
+ dbei->szUserId = g_szUserId;
+ }
+ else dbei->szUserId = nullptr;
+
+ int32_t cbBlob = sqlite3_column_int64(stmt, 6);
size_t bytesToCopy = cbBlob;
if (dbei->cbBlob == -1)
dbei->pBlob = (uint8_t*)mir_calloc(cbBlob + 2);
@@ -337,7 +347,7 @@ BOOL CDbxSQLite::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei) dbei->cbBlob = cbBlob;
if (bytesToCopy && dbei->pBlob) {
- uint8_t *data = (uint8_t *)sqlite3_column_blob(stmt, 6);
+ uint8_t *data = (uint8_t *)sqlite3_column_blob(stmt, 7);
if (dbei->flags & DBEF_ENCRYPTED) {
dbei->flags &= ~DBEF_ENCRYPTED;
diff --git a/plugins/Dbx_sqlite/src/dbintf.cpp b/plugins/Dbx_sqlite/src/dbintf.cpp index 035a651ccf..95855925f5 100644 --- a/plugins/Dbx_sqlite/src/dbintf.cpp +++ b/plugins/Dbx_sqlite/src/dbintf.cpp @@ -46,7 +46,7 @@ int CDbxSQLite::Create() logError(rc, __FILE__, __LINE__);
rc = sqlite3_exec(m_db, "CREATE TABLE events (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, contact_id INTEGER NOT NULL, module TEXT NOT NULL,"
- "timestamp INTEGER NOT NULL, type INTEGER NOT NULL, flags INTEGER NOT NULL, data BLOB, server_id TEXT, is_read INTEGER NOT NULL DEFAULT 0);", nullptr, nullptr, nullptr);
+ "timestamp INTEGER NOT NULL, type INTEGER NOT NULL, flags INTEGER NOT NULL, data BLOB, server_id TEXT NULL, user_id TEXT NULL, is_read INTEGER NOT NULL DEFAULT 0);", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
rc = sqlite3_exec(m_db, "CREATE INDEX idx_events_contactid_timestamp ON events(contact_id, timestamp);", nullptr, nullptr, nullptr);
@@ -67,6 +67,9 @@ int CDbxSQLite::Create() rc = sqlite3_exec(m_db, "CREATE INDEX idx_settings_module ON settings(module);", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
+
+ DBVARIANT dbv = { DBVT_BYTE, 2 };
+ WriteContactSetting(0, "Compatibility", "Sqlite", &dbv);
return 0;
}
diff --git a/plugins/Dbx_sqlite/src/dbsettings.cpp b/plugins/Dbx_sqlite/src/dbsettings.cpp index c4bd196cb4..249a8bc059 100644 --- a/plugins/Dbx_sqlite/src/dbsettings.cpp +++ b/plugins/Dbx_sqlite/src/dbsettings.cpp @@ -59,7 +59,7 @@ void CDbxSQLite::InitSettings() FillContactSettings();
- DBVARIANT dbv; dbv.type = DBVT_BYTE;
+ DBVARIANT dbv = { DBVT_BYTE };
if (GetContactSetting(0, "Compatibility", "Sqlite", &dbv))
dbv.bVal = 0;
@@ -73,8 +73,14 @@ void CDbxSQLite::InitSettings() rc = sqlite3_exec(m_db, "UPDATE events SET is_read=1 WHERE (flags & 6) <> 0;", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- dbv.type = DBVT_BYTE;
- dbv.dVal = 1;
+ dbv.bVal = 1;
+ }
+
+ if (dbv.bVal < 2) {
+ int rc = sqlite3_exec(m_db, "ALTER TABLE events ADD COLUMN user_id TEXT NULL;", 0, 0, 0);
+ logError(rc, __FILE__, __LINE__);
+
+ dbv.bVal = 2;
WriteContactSetting(0, "Compatibility", "Sqlite", &dbv);
}
}
diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp index 3618b9a1aa..8f7a405723 100644 --- a/plugins/Scriver/src/msgdialog.cpp +++ b/plugins/Scriver/src/msgdialog.cpp @@ -236,20 +236,16 @@ bool CMsgDialog::OnInitDialog() UpdateStatusBar();
UpdateTitle();
UpdateNickList();
+ UpdateChatLog();
m_pParent->AddChild(this);
PopupWindow(false);
-
- if (m_si->pMI->bDatabase) {
- FindFirstEvent();
- SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
- }
}
else {
m_nickList.Hide();
m_splitterX.Hide();
- bool notifyUnread = FindFirstEvent();
+ bool notifyUnread = GetFirstEvent();
m_pParent->AddChild(this);
@@ -1170,7 +1166,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) break;
case HM_DBEVENTADDED:
- if (wParam == m_hContact) {
+ if (wParam == m_hContact && !isChat()) {
MEVENT hDbEvent = lParam;
DBEVENTINFO dbei = {};
db_event_get(hDbEvent, &dbei);
@@ -1194,7 +1190,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) PopupWindow(true);
}
- if (isChat() || (hDbEvent != m_hDbEventFirst && db_event_next(m_hContact, hDbEvent) == 0))
+ if (hDbEvent != m_hDbEventFirst && db_event_next(m_hContact, hDbEvent) == 0)
m_pLog->LogEvents(hDbEvent, 1, 1);
else
SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
diff --git a/plugins/Scriver/src/msgs.cpp b/plugins/Scriver/src/msgs.cpp index ffb08f4e3c..01ffec8586 100644 --- a/plugins/Scriver/src/msgs.cpp +++ b/plugins/Scriver/src/msgs.cpp @@ -109,6 +109,7 @@ static int MessageEventAdded(WPARAM hContact, LPARAM lParam) return 0;
}
}
+
if (hwnd == nullptr || !IsWindowVisible(GetParent(hwnd))) {
wchar_t toolTip[256];
mir_snwprintf(toolTip, TranslateT("Message from %s"), Clist_GetContactDisplayName(hContact));
diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h index 0a2d30257e..7b92e8ce24 100644 --- a/plugins/Scriver/src/msgs.h +++ b/plugins/Scriver/src/msgs.h @@ -88,7 +88,6 @@ class CMsgDialog : public CSrmmBaseDialog friend INT_PTR CALLBACK InfobarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void ClearLog(void);
- bool FindFirstEvent(void);
HICON GetTabIcon(void);
void GetTitlebarIcon(struct TitleBarData *tbd);
void Init(void);
@@ -110,7 +109,7 @@ class CMsgDialog : public CSrmmBaseDialog bool m_bIncoming, m_bWindowCascaded;
- MEVENT m_hDbEventFirst, m_hDbEventLast, m_hDbUnreadEventFirst;
+ MEVENT m_hDbUnreadEventFirst;
int m_minLogBoxHeight, m_minEditBoxHeight;
int m_iShowUnread;
uint16_t m_wStatus;
@@ -173,6 +172,7 @@ public: void onType(CTimer *);
void CloseTab() override;
+ bool GetFirstEvent() override;
void LoadSettings() override;
void SetStatusText(const wchar_t *, HICON) override;
void ShowFilterMenu() override;
diff --git a/plugins/Scriver/src/msgutils.cpp b/plugins/Scriver/src/msgutils.cpp index 68eaf56b40..01210cdcbd 100644 --- a/plugins/Scriver/src/msgutils.cpp +++ b/plugins/Scriver/src/msgutils.cpp @@ -36,7 +36,7 @@ void CMsgDialog::CloseTab() Close(); } -bool CMsgDialog::FindFirstEvent() +bool CMsgDialog::GetFirstEvent() { bool notifyUnread = false; diff --git a/plugins/TabSRMM/src/generic_msghandlers.cpp b/plugins/TabSRMM/src/generic_msghandlers.cpp index f704717da6..ad5df5726d 100644 --- a/plugins/TabSRMM/src/generic_msghandlers.cpp +++ b/plugins/TabSRMM/src/generic_msghandlers.cpp @@ -1081,7 +1081,7 @@ void CMsgDialog::DM_EventAdded(WPARAM, LPARAM lParam) }
m_cache->updateStats(TSessionStats::UPDATE_WITH_LAST_RCV, 0);
- if (hDbEvent != m_hDbEventFirst || isChat())
+ if (hDbEvent != m_hDbEventFirst)
StreamEvents(hDbEvent, 1, 1);
else
RemakeLog();
diff --git a/plugins/TabSRMM/src/mim.cpp b/plugins/TabSRMM/src/mim.cpp index ca1e9c3272..9b776b88ab 100644 --- a/plugins/TabSRMM/src/mim.cpp +++ b/plugins/TabSRMM/src/mim.cpp @@ -416,7 +416,7 @@ int CMimAPI::MessageEventAdded(WPARAM hContact, LPARAM hDbEvent) if (pTargetContainer == nullptr || !g_plugin.bHideOnClose || IsWindowVisible(pTargetContainer->m_hwnd))
return 0;
- WINDOWPLACEMENT wp = { 0 };
+ WINDOWPLACEMENT wp = {};
wp.length = sizeof(wp);
GetWindowPlacement(pTargetContainer->m_hwnd, &wp);
diff --git a/plugins/TabSRMM/src/msgdialog.cpp b/plugins/TabSRMM/src/msgdialog.cpp index 0ea8c25470..67d48d5545 100644 --- a/plugins/TabSRMM/src/msgdialog.cpp +++ b/plugins/TabSRMM/src/msgdialog.cpp @@ -573,14 +573,10 @@ bool CMsgDialog::OnInitDialog() m_hTabIcon = m_hTabStatusIcon;
UpdateNickList();
-
- if (m_si->pMI->bDatabase) {
- FindFirstEvent();
- RemakeLog();
- }
+ UpdateChatLog();
}
else {
- FindFirstEvent();
+ GetFirstEvent();
DM_OptionsApplied();
@@ -2494,7 +2490,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case HM_DBEVENTADDED:
// this is called whenever a new event has been added to the database.
// this CAN be posted (some sanity checks required).
- if (this)
+ if (this && !isChat())
DM_EventAdded(m_hContact, lParam);
return 0;
diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp index f2045b77df..06501884f7 100644 --- a/plugins/TabSRMM/src/msgdlgother.cpp +++ b/plugins/TabSRMM/src/msgdlgother.cpp @@ -452,7 +452,7 @@ void CMsgDialog::EnableSending(bool bMode) const /////////////////////////////////////////////////////////////////////////////////////////
-void CMsgDialog::FindFirstEvent()
+bool CMsgDialog::GetFirstEvent()
{
int historyMode = g_plugin.getByte(m_hContact, SRMSGSET_LOADHISTORY, -1);
if (historyMode == -1)
@@ -506,6 +506,7 @@ void CMsgDialog::FindFirstEvent() }
break;
}
+ return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/TabSRMM/src/msgs.h b/plugins/TabSRMM/src/msgs.h index 382ad1f54d..01ad889666 100644 --- a/plugins/TabSRMM/src/msgs.h +++ b/plugins/TabSRMM/src/msgs.h @@ -456,7 +456,6 @@ class CMsgDialog : public CSrmmBaseDialog void CalcDynamicAvatarSize(BITMAP *bminfo);
void DetermineMinHeight(void);
BOOL DoRtfToTags(CMStringW &pszText) const;
- void FindFirstEvent(void);
int FindRTLLocale(void);
void FlashOnClist(MEVENT hEvent, DBEVENTINFO *dbei);
void FlashTab(bool bInvertMode);
@@ -558,7 +557,6 @@ public: uint32_t m_dwUnread;
HANDLE m_hTheme, m_hThemeIP, m_hThemeToolbar;
HICON m_hXStatusIcon, m_hTabStatusIcon, m_hTabIcon, m_iFlashIcon, m_hTaskbarIcon, m_hClientIcon;
- MEVENT m_hDbEventFirst, m_hDbEventLast;
HANDLE m_hTimeZone;
MEVENT* m_hHistoryEvents;
time_t m_lastEventTime;
@@ -635,6 +633,7 @@ public: void AddLog() override;
void CloseTab() override;
+ bool GetFirstEvent() override;
bool IsActive() const override;
void LoadSettings() override;
void SetStatusText(const wchar_t *, HICON) override;
diff --git a/protocols/Facebook/src/proto.cpp b/protocols/Facebook/src/proto.cpp index b773e6b7b0..f594a7ad91 100644 --- a/protocols/Facebook/src/proto.cpp +++ b/protocols/Facebook/src/proto.cpp @@ -112,7 +112,7 @@ FacebookProto::FacebookProto(const char *proto_name, const wchar_t *username) : // Group chats
GCREGISTER gcr = {};
- gcr.dwFlags = GC_TYPNOTIF;
+ gcr.dwFlags = GC_TYPNOTIF | GC_DATABASE;
gcr.ptszDispName = m_tszUserName;
gcr.pszModule = m_szModuleName;
Chat_Register(&gcr);
diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp index 8a3aa1819d..cae092fcbd 100644 --- a/protocols/Facebook/src/server.cpp +++ b/protocols/Facebook/src/server.cpp @@ -863,36 +863,17 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root) }
// if that's a group chat, send it to the room
- CMStringW wszActorFbId(metadata["actorFbId"].as_mstring());
- __int64 actorFbId = _wtoi64(wszActorFbId);
-
- if (pUser->bIsChat) {
- szBody.Replace("%", "%%");
- ptrW wszText(mir_utf8decodeW(szBody));
-
- // TODO: GC_EVENT_JOIN for chat participants which are missing (for example added later during group chat)
-
- GCEVENT gce = { pUser->si, GC_EVENT_MESSAGE };
- gce.dwFlags = GCEF_ADDTOLOG;
- gce.pszUID.w = wszActorFbId;
- gce.pszText.w = wszText;
- gce.time = time(0);
- gce.bIsMe = actorFbId == m_uid;
- Chat_Event(&gce);
-
- debugLogA("New channel %lld message from %S: %s", pUser->id, gce.pszUID.w, gce.pszText.w);
- }
- else { // otherwise store a private message
- PROTORECVEVENT pre = {};
- pre.timestamp = uint32_t(_wtoi64(metadata["timestamp"].as_mstring()) / 1000);
- pre.szMessage = (char *)szBody.c_str();
- pre.szMsgId = (char *)szId.c_str();
-
- if (m_uid == actorFbId)
- pre.flags |= PREF_SENT;
-
- ProtoChainRecvMsg(pUser->hContact, &pre);
- }
+ auto szActorFbId(metadata["actorFbId"].as_string());
+
+ PROTORECVEVENT pre = {};
+ pre.timestamp = uint32_t(_wtoi64(metadata["timestamp"].as_mstring()) / 1000);
+ pre.szMessage = (char *)szBody.c_str();
+ pre.szMsgId = (char *)szId.c_str();
+ if (m_uid == _atoi64(szActorFbId.c_str()))
+ pre.flags |= PREF_SENT;
+ if (pUser->bIsChat)
+ pre.szUserId = szActorFbId.c_str();
+ ProtoChainRecvMsg(pUser->hContact, &pre);
}
// changing thread name
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp index f1ff831f63..ec3dd49ce6 100644 --- a/protocols/ICQ-WIM/src/proto.cpp +++ b/protocols/ICQ-WIM/src/proto.cpp @@ -83,7 +83,7 @@ CIcqProto::CIcqProto(const char *aProtoName, const wchar_t *aUserName) : // group chats
GCREGISTER gcr = {};
- gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR;
+ gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR | GC_DATABASE;
gcr.ptszDispName = m_tszUserName;
gcr.pszModule = m_szModuleName;
Chat_Register(&gcr);
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp index d8f203dfc9..562cdbaa8e 100644 --- a/protocols/ICQ-WIM/src/server.cpp +++ b/protocols/ICQ-WIM/src/server.cpp @@ -486,32 +486,6 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo }
}
- if (isChatRoom(hContact)) {
- CMStringA reqId(it["reqId"].as_mstring());
- CheckOwnMessage(reqId, szMsgId, true);
-
- CMStringW wszSender(it["chat"]["sender"].as_mstring());
- CMStringW wszChatId(GetUserId(hContact));
-
- if (bIsFileTransfer) {
- wszText = pFileInfo->szUrl;
- if (!pFileInfo->wszDescr)
- wszText.AppendFormat(L"\r\n%s", pFileInfo->wszDescr.c_str());
- delete pFileInfo;
- }
-
- if (auto *si = Chat_Find(wszChatId, m_szModuleName)) {
- GCEVENT gce = { si, GC_EVENT_MESSAGE};
- gce.dwFlags = GCEF_ADDTOLOG;
- gce.pszUID.w = wszSender;
- gce.pszText.w = wszText;
- gce.time = iMsgTime;
- gce.bIsMe = wszSender == m_szOwnId;
- Chat_Event(&gce);
- }
- return;
- }
-
// skip own messages, just set the server msgid
CMStringA reqId(it["reqId"].as_mstring());
if (CheckOwnMessage(reqId, szMsgId, true)) {
@@ -555,13 +529,18 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo debugLogA("Adding message %d:%lld (CR=%d)", hContact, msgId, bCreateRead);
ptrA szUtf(mir_utf8encodeW(wszText));
+ CMStringA szSender(it["chat"]["sender"].as_mstring());
PROTORECVEVENT pre = {};
- if (bIsOutgoing) pre.flags |= PREF_SENT;
- if (bCreateRead) pre.flags |= PREF_CREATEREAD;
pre.szMsgId = szMsgId;
pre.timestamp = iMsgTime;
pre.szMessage = szUtf;
+ if (bIsOutgoing)
+ pre.flags |= PREF_SENT;
+ if (bCreateRead)
+ pre.flags |= PREF_CREATEREAD;
+ if (isChatRoom(hContact))
+ pre.szUserId = szSender;
ProtoChainRecvMsg(hContact, &pre);
}
diff --git a/protocols/IRCG/src/commandmonitor.cpp b/protocols/IRCG/src/commandmonitor.cpp index 5e0705dfe8..9eb66f8aaa 100644 --- a/protocols/IRCG/src/commandmonitor.cpp +++ b/protocols/IRCG/src/commandmonitor.cpp @@ -688,7 +688,7 @@ bool CIrcProto::OnIrc_PRIVMSG(const CIrcMessage *pmsg) MCONTACT hContact = CList_AddContact(&user, false, true);
- PROTORECVEVENT pre = { 0 };
+ PROTORECVEVENT pre = {};
pre.timestamp = (uint32_t)time(0);
pre.szMessage = mir_utf8encodeW(mess);
setWString(hContact, "User", pmsg->prefix.sUser);
diff --git a/protocols/IRCG/src/irclib.cpp b/protocols/IRCG/src/irclib.cpp index aedbe97af5..cad89607c5 100644 --- a/protocols/IRCG/src/irclib.cpp +++ b/protocols/IRCG/src/irclib.cpp @@ -1274,7 +1274,7 @@ void CDccSession::DoChatReceive() if (*pStart) { // send it off to some messaging module - PROTORECVEVENT pre = { 0 }; + PROTORECVEVENT pre = {}; pre.timestamp = (uint32_t)time(0); pre.szMessage = pStart; ProtoChainRecvMsg(di->hContact, &pre); diff --git a/protocols/Sametime/src/messaging.cpp b/protocols/Sametime/src/messaging.cpp index c8c3cb64cb..4def7ca30d 100644 --- a/protocols/Sametime/src/messaging.cpp +++ b/protocols/Sametime/src/messaging.cpp @@ -81,7 +81,7 @@ void mwIm_conversation_recv(mwConversation* conv, mwImSendType type, gconstpoint if (type != mwImSend_PLAIN)
return;
- PROTORECVEVENT pre = { 0 };
+ PROTORECVEVENT pre = {};
time_t t = time(0);
pre.timestamp = t;
pre.szMessage = (char*)msg;
diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp index 29dc9157f2..33b108f036 100644 --- a/protocols/SkypeWeb/src/skype_contacts.cpp +++ b/protocols/SkypeWeb/src/skype_contacts.cpp @@ -130,7 +130,7 @@ void CSkypeProto::LoadContactsAuth(NETLIBHTTPREQUEST *response, AsyncHttpRequest DB::AUTH_BLOB blob(hContact, displayName.c_str(), nullptr, nullptr, skypeId.c_str(), reason.c_str());
- PROTORECVEVENT pre = { 0 };
+ PROTORECVEVENT pre = {};
pre.timestamp = time(0);
pre.lParam = blob.size();
pre.szMessage = blob;
diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index a31a3c47c8..ec95703156 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -232,7 +232,7 @@ void CToxProto::OnFriendRequest(Tox*, const uint8_t *pubKey, const uint8_t *mess DB::AUTH_BLOB blob(hContact, nullptr, nullptr, nullptr, (LPCSTR)address, (LPCSTR)message);
- PROTORECVEVENT pre = { 0 };
+ PROTORECVEVENT pre = {};
pre.timestamp = now();
pre.lParam = blob.size();
pre.szMessage = blob;
diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index 67401eea28..84ba0e1ca1 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -139,17 +139,13 @@ bool CMsgDialog::OnInitDialog() UpdateOptions();
UpdateStatusBar();
UpdateTitle();
-
- if (m_si->pMI->bDatabase) {
- FindFirstEvent();
- RemakeLog();
- }
+ UpdateChatLog();
}
else {
m_nickList.Hide();
m_splitterX.Hide();
- FindFirstEvent();
+ GetFirstEvent();
bool bUpdate = false;
DB::ECPTR pCursor(DB::EventsRev(m_hContact));
@@ -594,7 +590,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) return TRUE;
case HM_DBEVENTADDED:
- if (wParam == m_hContact) {
+ if (wParam == m_hContact && !isChat()) {
MEVENT hDbEvent = lParam;
if (m_hDbEventFirst == 0)
m_hDbEventFirst = hDbEvent;
@@ -1300,7 +1296,7 @@ void CMsgDialog::CloseTab() else SendMessage(m_hwndParent, WM_CLOSE, 0, 0);
}
-void CMsgDialog::FindFirstEvent()
+bool CMsgDialog::GetFirstEvent()
{
// This finds the first message to display, it works like shit
m_hDbEventFirst = db_event_firstUnread(m_hContact);
@@ -1339,6 +1335,7 @@ void CMsgDialog::FindFirstEvent() }
break;
}
+ return true;
}
void CMsgDialog::NotifyTyping(int mode)
diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h index 0e9f38dead..8234296277 100644 --- a/src/core/stdmsg/src/msgs.h +++ b/src/core/stdmsg/src/msgs.h @@ -55,7 +55,6 @@ class CMsgDialog : public CSrmmBaseDialog friend class CTabbedWindow;
typedef CSrmmBaseDialog CSuper;
- void FindFirstEvent();
void Init(void);
void NotifyTyping(int mode);
void SetButtonsPos(void);
@@ -141,8 +140,6 @@ public: return ((CLogWindow *)m_pLog);
}
- MEVENT m_hDbEventFirst, m_hDbEventLast;
-
int m_avatarWidth = 0, m_avatarHeight = 0;
bool m_bIsAutoRTL = false;
@@ -156,6 +153,7 @@ public: }
void CloseTab() override;
+ bool GetFirstEvent() override;
bool IsActive() const override;
void LoadSettings() override;
void SetStatusText(const wchar_t *, HICON) override;
diff --git a/src/mir_app/mir_app.vcxproj b/src/mir_app/mir_app.vcxproj index f1be852b29..f2cc3c4900 100644 --- a/src/mir_app/mir_app.vcxproj +++ b/src/mir_app/mir_app.vcxproj @@ -215,7 +215,4 @@ <None Include="src\mir_app.def" />
<None Include="src\mir_app64.def" />
</ItemGroup>
- <ItemGroup>
- <Text Include="..\docs\contributors.txt" />
- </ItemGroup>
</Project>
\ No newline at end of file diff --git a/src/mir_app/mir_app.vcxproj.filters b/src/mir_app/mir_app.vcxproj.filters index b32a67a380..d7960c2ea2 100644 --- a/src/mir_app/mir_app.vcxproj.filters +++ b/src/mir_app/mir_app.vcxproj.filters @@ -508,7 +508,4 @@ <UniqueIdentifier>{2f5b2fe9-25c8-4029-8a52-f34a11f984a7}</UniqueIdentifier>
</Filter>
</ItemGroup>
- <ItemGroup>
- <Text Include="..\docs\contributors.txt" />
- </ItemGroup>
</Project>
\ No newline at end of file diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index b8580e1b51..a128e612be 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -80,6 +80,7 @@ BOOL SM_SetStatus(const char *pszModule, SESSION_INFO *si, int wStatus) BOOL SM_TakeStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszStatus);
BOOL SM_UserTyping(GCEVENT* gce);
+SESSION_INFO* SM_FindSessionByContact(MCONTACT hContact);
SESSION_INFO* SM_FindSessionByIndex(const char *pszModule, int iItem);
STATUSINFO* TM_AddStatus(STATUSINFO **ppStatusList, const wchar_t *pszStatus, int *iCount);
diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp index 014c092322..61eb35d9ff 100644 --- a/src/mir_app/src/chat_manager.cpp +++ b/src/mir_app/src/chat_manager.cpp @@ -453,6 +453,16 @@ static int SM_GetCount(const char *pszModule) return count;
}
+SESSION_INFO* SM_FindSessionByContact(MCONTACT hContact)
+{
+ mir_cslock lck(csChat);
+ for (auto &si : g_arSessions)
+ if (si->hContact == hContact)
+ return si;
+
+ return nullptr;
+}
+
SESSION_INFO* SM_FindSessionByIndex(const char *pszModule, int iItem)
{
int count = 0;
diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index 7dd1c64498..a1bf16f53c 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -517,11 +517,9 @@ static BOOL HandleChatEvent(GCEVENT &gce, int bManyFix) return 0;
if (si && (si->bInitDone || gce.iType == GC_EVENT_TOPIC || (gce.iType == GC_EVENT_JOIN && gce.bIsMe))) {
- if (gce.pszNick.w == nullptr && gce.pszUID.w != nullptr) {
- USERINFO *ui = g_chatApi.UM_FindUser(si, gce.pszUID.w);
- if (ui != nullptr)
+ if (gce.pszNick.w == nullptr && gce.pszUID.w != nullptr)
+ if (USERINFO *ui = g_chatApi.UM_FindUser(si, gce.pszUID.w))
gce.pszNick.w = ui->pszNick;
- }
int isOk = SM_AddEvent(si, &gce, bIsHighlighted);
if (si->pDlg) {
@@ -776,6 +774,32 @@ static INT_PTR LeaveChat(WPARAM hContact, LPARAM) return 0;
}
+static int OnEventAdded(WPARAM hContact, LPARAM hDbEvent)
+{
+ if (Contact::IsGroupChat(hContact)) {
+ if (auto *si = SM_FindSessionByContact(hContact)) {
+ DB::EventInfo dbei;
+ dbei.cbBlob = -1;
+ if (!db_event_get(hDbEvent, &dbei)) {
+ auto *szProto = Proto_GetBaseAccountName(si->hContact);
+ if (si && !mir_strcmp(szProto, dbei.szModule) && dbei.eventType == EVENTTYPE_MESSAGE && dbei.szUserId) {
+ CMStringA szText((char *)dbei.pBlob);
+ szText.Replace("%", "%%");
+
+ GCEVENT gce = { si, GC_EVENT_MESSAGE };
+ gce.dwFlags = GCEF_ADDTOLOG | GCEF_UTF8;
+ gce.pszUID.a = dbei.szUserId;
+ gce.pszText.a = szText;
+ gce.time = dbei.timestamp;
+ Chat_Event(&gce);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
static int OnContactDeleted(WPARAM hContact, LPARAM)
{
char *szProto = Proto_GetBaseAccountName(hContact);
@@ -914,6 +938,7 @@ int LoadChatModule(void) {
HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
+ HookEvent(ME_DB_EVENT_ADDED, OnEventAdded);
HookEvent(ME_DB_CONTACT_DELETED, OnContactDeleted);
HookEvent(ME_SKIN_ICONSCHANGED, IconsChanged);
HookEvent(ME_FONT_RELOAD, FontsChanged);
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 8150a19b26..81f0512e7f 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -817,3 +817,4 @@ Srmm_CreateHotkey @886 NONAME ?Chat_Terminate@@YGHPAUSESSION_INFO@@_N@Z @932 NONAME
?Chat_Terminate@@YGHPBD_N@Z @933 NONAME
?Chat_Control@@YGHPBDH@Z @934 NONAME
+?UpdateChatLog@CSrmmBaseDialog@@IAEXXZ @935 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 520d097e19..901fc10164 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -817,3 +817,4 @@ Srmm_CreateHotkey @886 NONAME ?Chat_Terminate@@YAHPEAUSESSION_INFO@@_N@Z @932 NONAME
?Chat_Terminate@@YAHPEBD_N@Z @933 NONAME
?Chat_Control@@YAHPEBDH@Z @934 NONAME
+?UpdateChatLog@CSrmmBaseDialog@@IEAAXXZ @935 NONAME
diff --git a/src/mir_app/src/proto_interface.cpp b/src/mir_app/src/proto_interface.cpp index 09cf67f845..801442d8fa 100644 --- a/src/mir_app/src/proto_interface.cpp +++ b/src/mir_app/src/proto_interface.cpp @@ -195,9 +195,6 @@ MEVENT PROTO_INTERFACE::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) if (pre->szMessage == nullptr)
return 0;
- ptrA pszTemp;
- mir_ptr<uint8_t> pszBlob;
-
DBEVENTINFO dbei = {};
dbei.flags = DBEF_UTF;
dbei.szModule = Proto_GetBaseAccountName(hContact);
@@ -205,6 +202,7 @@ MEVENT PROTO_INTERFACE::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) dbei.eventType = EVENTTYPE_MESSAGE;
dbei.cbBlob = (uint32_t)mir_strlen(pre->szMessage) + 1;
dbei.pBlob = (uint8_t*)pre->szMessage;
+ dbei.szUserId = pre->szUserId;
if (pre->flags & PREF_CREATEREAD)
dbei.flags |= DBEF_READ;
diff --git a/src/mir_app/src/srmm_base.cpp b/src/mir_app/src/srmm_base.cpp index fd1d564a8a..1a83d7aa86 100644 --- a/src/mir_app/src/srmm_base.cpp +++ b/src/mir_app/src/srmm_base.cpp @@ -636,6 +636,46 @@ void CSrmmBaseDialog::RedrawLog() else ClearLog();
}
+void CSrmmBaseDialog::UpdateChatLog()
+{
+ if (!m_si->pMI->bDatabase)
+ return;
+
+ GetFirstEvent();
+
+ SESSION_INFO *tmp = g_chatApi.SM_CreateSession();
+
+ auto *szProto = Proto_GetBaseAccountName(m_hContact);
+ for (MEVENT hDbEvent = m_hDbEventFirst; hDbEvent; hDbEvent = db_event_next(m_hContact, hDbEvent)) {
+ DB::EventInfo dbei;
+ dbei.cbBlob = -1;
+ if (!db_event_get(hDbEvent, &dbei)) {
+ if (!mir_strcmp(szProto, dbei.szModule) && dbei.eventType == EVENTTYPE_MESSAGE && dbei.szUserId) {
+ auto *pUser = g_chatApi.UM_FindUser(m_si, Utf2T(dbei.szUserId));
+ if (pUser == nullptr)
+ continue;
+
+ Utf2T wszUserId(dbei.szUserId);
+ CMStringW wszText(Utf2T((char*)dbei.pBlob));
+ wszText.Replace(L"%", L"%%");
+
+ GCEVENT gce = { m_si, GC_EVENT_MESSAGE };
+ gce.dwFlags = GCEF_ADDTOLOG;
+ gce.pszUserInfo.w = wszUserId;
+ gce.pszText.w = wszText;
+ gce.time = dbei.timestamp;
+ if (USERINFO *ui = g_chatApi.UM_FindUser(m_si, wszUserId))
+ gce.pszNick.w = ui->pszNick;
+ SM_AddEvent(tmp, &gce, false);
+ }
+ }
+ }
+
+ m_pLog->LogEvents(tmp->pLogEnd, false);
+ g_chatApi.LM_RemoveAll(&tmp->pLog, &tmp->pLogEnd);
+ delete tmp;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
void CSrmmBaseDialog::onClick_Color(CCtrlButton *pButton)
diff --git a/src/mir_app/src/srmm_util.cpp b/src/mir_app/src/srmm_util.cpp index 2ca887a54a..080ff4ae5d 100644 --- a/src/mir_app/src/srmm_util.cpp +++ b/src/mir_app/src/srmm_util.cpp @@ -28,7 +28,7 @@ const char *g_pszHotkeySection; /////////////////////////////////////////////////////////////////////////////////////////
-MIR_APP_DLL(DWORD) CALLBACK Srmm_LogStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb)
+MIR_APP_DLL(DWORD) CALLBACK Srmm_LogStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
LOGSTREAMDATA *lstrdat = (LOGSTREAMDATA*)dwCookie;
if (lstrdat) {
|