diff options
author | George Hazan <ghazan@miranda.im> | 2023-03-23 19:24:19 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2023-03-23 19:24:19 +0300 |
commit | a1284729b31119dc50d95f73e2ffe7fed4a20ac8 (patch) | |
tree | a657e9c43b4cf4e79c7ae4ada525b3c35996e541 /src/mir_app | |
parent | 94250c7e15a5f10628ecd405d64605189d4afffc (diff) |
chat serialization
Diffstat (limited to 'src/mir_app')
-rw-r--r-- | src/mir_app/src/chat.h | 3 | ||||
-rw-r--r-- | src/mir_app/src/chat_svc.cpp | 64 | ||||
-rw-r--r-- | src/mir_app/src/chat_tools.cpp | 49 | ||||
-rw-r--r-- | src/mir_app/src/chat_ui.cpp | 2 | ||||
-rw-r--r-- | src/mir_app/src/stdafx.h | 5 |
5 files changed, 108 insertions, 15 deletions
diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index bf406fe434..c41c5344a8 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -130,4 +130,7 @@ CSrmmLogWindow *Srmm_GetLogWindow(CMsgDialog *pDlg); void Chat_RemoveContact(MCONTACT hContact);
+CMStringW Chat_GetFolderName(SESSION_INFO *si = nullptr);
+void Chat_Serialize(SESSION_INFO *si);
+
#pragma comment(lib,"comctl32.lib")
diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index 0898e91402..9fd2d559ba 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -187,6 +187,7 @@ MIR_APP_DLL(int) Chat_Register(const GCREGISTER *gcr) mi->bAckMsg = (gcr->dwFlags & GC_ACKMSG) != 0;
mi->bChanMgr = (gcr->dwFlags & GC_CHANMGR) != 0;
mi->bDatabase = (gcr->dwFlags & GC_DATABASE) != 0;
+ mi->bPersistent = (gcr->dwFlags & GC_PERSISTENT) != 0;
mi->iMaxText = gcr->iMaxText;
mi->pszHeader = g_chatApi.Log_CreateRtfHeader();
@@ -418,22 +419,18 @@ MIR_APP_DLL(int) Chat_Terminate(SESSION_INFO *si) /////////////////////////////////////////////////////////////////////////////////////////
// handles chat event
-static void AddUser(GCEVENT *gce)
+static void AddUser(SESSION_INFO *si, GCEVENT &gce)
{
- SESSION_INFO *si = gce->si;
- if (si == nullptr)
- return;
-
- uint16_t status = TM_StringToWord(si->pStatuses, gce->pszStatus.w);
+ uint16_t status = TM_StringToWord(si->pStatuses, gce.pszStatus.w);
- USERINFO *ui = g_chatApi.UM_AddUser(si, gce->pszUID.w, gce->pszNick.w, status);
+ USERINFO *ui = g_chatApi.UM_AddUser(si, gce.pszUID.w, gce.pszNick.w, status);
if (ui == nullptr)
return;
if (g_chatApi.OnAddUser)
g_chatApi.OnAddUser(si, ui);
- if (gce->bIsMe)
+ if (gce.bIsMe)
si->pMe = ui;
ui->Status = status;
ui->Status |= si->pStatuses->iStatus;
@@ -465,6 +462,7 @@ static BOOL HandleChatEvent(GCEVENT &gce, int bManyFix) if (!mir_wstrcmp(si->ptszTopic, pwszNew)) // nothing changed? exiting
return 0;
+ si->bIsDirty = true;
replaceStrW(si->ptszTopic, pwszNew);
if (pwszNew != nullptr)
db_set_ws(si->hContact, si->pszModule, "Topic", si->ptszTopic);
@@ -501,6 +499,7 @@ static BOOL HandleChatEvent(GCEVENT &gce, int bManyFix) break;
case GC_EVENT_NICK:
+ si->bIsDirty = true;
SM_ChangeNick(si, &gce);
bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
break;
@@ -509,13 +508,15 @@ static BOOL HandleChatEvent(GCEVENT &gce, int bManyFix) return SM_UserTyping(&gce);
case GC_EVENT_JOIN:
- AddUser(&gce);
+ si->bIsDirty = true;
+ AddUser(si, gce);
bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
break;
case GC_EVENT_PART:
case GC_EVENT_QUIT:
case GC_EVENT_KICK:
+ si->bIsDirty = true;
bRemoveFlag = TRUE;
bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
break;
@@ -617,8 +618,10 @@ MIR_APP_DLL(int) Chat_AddGroup(SESSION_INFO *si, const wchar_t *wszText) mir_cslock lck(csChat);
STATUSINFO *ti = TM_AddStatus(&si->pStatuses, wszText, &si->iStatusCount);
- if (ti)
+ if (ti) {
si->iStatusCount++;
+ si->bIsDirty = true;
+ }
if (g_chatApi.OnAddStatus)
g_chatApi.OnAddStatus(si, ti);
@@ -634,6 +637,7 @@ MIR_APP_DLL(int) Chat_ChangeSessionName(SESSION_INFO *si, const wchar_t *wszNewN if (!mir_wstrcmp(si->ptszName, wszNewName))
return 0;
+ si->bIsDirty = true;
replaceStrW(si->ptszName, wszNewName);
db_set_ws(si->hContact, si->pszModule, "Nick", wszNewName);
if (si->pDlg)
@@ -650,8 +654,10 @@ MIR_APP_DLL(int) Chat_ChangeUserId(const char *szModule, const wchar_t *wszOldId mir_cslock lck(csChat);
for (auto &si : g_arSessions)
- if (!mir_strcmpi(si->pszModule, szModule))
+ if (!mir_strcmpi(si->pszModule, szModule)) {
Chat_ChangeUserId(si, wszOldId, wszNewId);
+ si->bIsDirty = true;
+ }
return 0;
}
@@ -665,6 +671,7 @@ MIR_APP_DLL(int) Chat_ChangeUserId(SESSION_INFO *si, const wchar_t *wszOldId, co if (ui) {
replaceStrW(ui->pszUID, wszNewId);
UM_SortKeys(si);
+ si->bIsDirty = true;
}
return 0;
}
@@ -723,6 +730,8 @@ MIR_APP_DLL(int) Chat_SetStatusEx(SESSION_INFO *si, int flags, const wchar_t *ws UM_SetStatusEx(si, wszText, flags);
if (si->pDlg)
RedrawWindow(GetDlgItem(si->pDlg->GetHwnd(), IDC_LIST), nullptr, nullptr, RDW_INVALIDATE);
+
+ si->bIsDirty = true;
return 0;
}
@@ -984,6 +993,34 @@ static IconItem iconList[] = static bool bInited = false;
+class ChatGlobals
+{
+ CTimer timerChat;
+
+ void onTimer(CTimer *)
+ {
+ mir_cslock lck(csChat);
+
+ for (auto &it : g_arSessions)
+ if (it->bIsDirty)
+ Chat_Serialize(it);
+ }
+
+public:
+ ChatGlobals() :
+ timerChat(Miranda_GetSystemWindow(), (LPARAM)this)
+ {
+ timerChat.OnEvent = Callback(this, &ChatGlobals::onTimer);
+ timerChat.Start(10000);
+ }
+
+ ~ChatGlobals()
+ {
+ timerChat.Stop();
+ }
+}
+static *pChatGlobals = nullptr;
+
int LoadChatModule(void)
{
HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
@@ -992,6 +1029,9 @@ int LoadChatModule(void) HookEvent(ME_SKIN_ICONSCHANGED, IconsChanged);
HookEvent(ME_FONT_RELOAD, FontsChanged);
+ pChatGlobals = new ChatGlobals();
+ CreateDirectoryTreeW(Chat_GetFolderName());
+
g_hWindowList = WindowList_Create();
hHookEvent = CreateHookableEvent(ME_GC_HOOK_EVENT);
hevMuteChat = CreateHookableEvent(ME_GC_MUTE);
@@ -1023,6 +1063,8 @@ void UnloadChatModule(void) if (!bInited)
return;
+ delete pChatGlobals;
+
FreeMsgLogBitmaps();
OptionsUnInit();
diff --git a/src/mir_app/src/chat_tools.cpp b/src/mir_app/src/chat_tools.cpp index 4b101c4c66..744797f205 100644 --- a/src/mir_app/src/chat_tools.cpp +++ b/src/mir_app/src/chat_tools.cpp @@ -837,3 +837,52 @@ MIR_APP_DLL(int) Chat_GetTextPixelSize(const wchar_t *pszText, HFONT hFont, bool ReleaseDC(nullptr, hdc);
return bWidth ? rc.right - rc.left : rc.bottom - rc.top;
}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Chat serialization
+
+CMStringW Chat_GetFolderName(SESSION_INFO *si)
+{
+ CMStringW ret(VARSW(L"%miranda_userdata%\\ChatCache"));
+ if (si)
+ ret.AppendFormat(L"\\%d.json", si->hContact);
+
+ return ret;
+}
+
+void Chat_Serialize(SESSION_INFO *si)
+{
+ si->bIsDirty = false;
+
+ if (!si->pMI->bPersistent)
+ return;
+
+ JSONNode pRoleList(JSON_ARRAY); pRoleList.set_name("roles");
+ for (auto *p = si->pStatuses; p; p = p->next) {
+ JSONNode role;
+ role << JSONNode("id", p->iStatus) << JSONNode("name", T2Utf(p->pszGroup).get());
+ pRoleList << role;
+ }
+
+ JSONNode pUserList(JSON_ARRAY); pUserList.set_name("users");
+ for (auto &it : si->arUsers) {
+ JSONNode user;
+ user << JSONNode("id", T2Utf(it->pszUID).get()) << JSONNode("nick", T2Utf(it->pszNick).get()) << JSONNode("role", it->Status);
+ pUserList << user;
+ }
+
+ JSONNode root;
+ root << pRoleList << pUserList;
+ if (si->ptszName)
+ root << JSONNode("name", T2Utf(si->ptszName).get());
+ if (si->ptszTopic)
+ root << JSONNode("topic", T2Utf(si->ptszTopic).get());
+
+ ptrW wszText(json_write(&root));
+ if (wszText) {
+ if (FILE *out = _wfopen(Chat_GetFolderName(si), L"w")) {
+ fputs(T2Utf(wszText), out);
+ fclose(out);
+ }
+ }
+}
diff --git a/src/mir_app/src/chat_ui.cpp b/src/mir_app/src/chat_ui.cpp index 8b08092f8a..aacb22bf8a 100644 --- a/src/mir_app/src/chat_ui.cpp +++ b/src/mir_app/src/chat_ui.cpp @@ -129,8 +129,6 @@ public: };
/////////////////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////////////////
// Popup options
class COptPopupDlg : public CDlgBase
diff --git a/src/mir_app/src/stdafx.h b/src/mir_app/src/stdafx.h index cbb17fac19..caf3f20342 100644 --- a/src/mir_app/src/stdafx.h +++ b/src/mir_app/src/stdafx.h @@ -71,16 +71,17 @@ typedef struct SslHandle *HSSL; #include <m_extraicons.h>
#include <m_file.h>
#include <m_findadd.h>
+#include <m_fontservice.h>
#include <m_gui.h>
#include <m_history.h>
+#include <m_hotkeys.h>
#include <m_hpp.h>
#include <m_icolib.h>
#include <m_idle.h>
#include <m_ieview.h>
#include <m_ignore.h>
#include <m_imgsrvc.h>
-#include <m_hotkeys.h>
-#include <m_fontservice.h>
+#include <m_json.h>
#include <m_langpack.h>
#include <m_metacontacts.h>
#include <m_netlib.h>
|