From 1ba1e51fc6fa7e30b0a627a141348f515ffaba76 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 13 Oct 2018 21:29:05 +0300 Subject: chat api: - GC_SHAREDUSERS flag added to share the same array of users for all group chats; - USERINFO.next removed; - MODULEINFO.arUsers & SESSION_INFO.arUsers introduced to maintain user lists; - MM_AddModule removed; - memory allocation model changed for MODULEINFO & SESSION_INFO - MM_CreateModule & SM_CreateSession members are added to g_chatApi --- include/m_chat.h | 1 + include/m_chat_int.h | 69 +++++--- libs/win32/mir_app.lib | Bin 183264 -> 184756 bytes libs/win64/mir_app.lib | Bin 178462 -> 179984 bytes plugins/Scriver/src/chat_main.cpp | 6 + plugins/Scriver/src/chat_window.cpp | 73 ++++---- plugins/Scriver/src/input.cpp | 1 - plugins/TabSRMM/src/chat.h | 2 +- plugins/TabSRMM/src/chat_log.cpp | 4 +- plugins/TabSRMM/src/chat_main.cpp | 12 ++ plugins/TabSRMM/src/chat_manager.cpp | 17 +- plugins/TabSRMM/src/chat_tools.cpp | 2 +- plugins/TabSRMM/src/chat_window.cpp | 44 ++--- plugins/TabSRMM/src/msgdlgutils.cpp | 2 +- plugins/TabSRMM/src/taskbar.cpp | 61 ++++--- protocols/Discord/src/dispatch.cpp | 17 +- protocols/Discord/src/guilds.cpp | 49 +++--- protocols/Discord/src/proto.cpp | 2 +- protocols/Discord/src/proto.h | 3 +- protocols/Discord/src/utils.cpp | 2 +- protocols/JabberG/src/stdafx.h | 2 - src/core/stdmsg/src/chat_manager.cpp | 6 + src/core/stdmsg/src/chat_window.cpp | 34 ++-- src/mir_app/src/chat.h | 117 +++++++------ src/mir_app/src/chat_log.cpp | 2 +- src/mir_app/src/chat_manager.cpp | 320 +++++++++++++++-------------------- src/mir_app/src/chat_svc.cpp | 22 +-- src/mir_app/src/mir_app.def | 5 + src/mir_app/src/mir_app64.def | 5 + src/mir_app/src/srmm_base.cpp | 49 +++--- 30 files changed, 440 insertions(+), 489 deletions(-) diff --git a/include/m_chat.h b/include/m_chat.h index 978e1e1860..d6d2e398ae 100644 --- a/include/m_chat.h +++ b/include/m_chat.h @@ -133,6 +133,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define GC_ACKMSG 0x0020 // the protocol must acknowlege messages sent #define GC_TYPNOTIF 0x0040 // enable typing notifications. #define GC_CHANMGR 0x0080 // enable the 'channel settings' button +#define GC_SHAREDUSERS 0x0100 // array of users is the same for all group chats // Error messages #define GC_ERROR 1 // An internal error occurred. diff --git a/include/m_chat_int.h b/include/m_chat_int.h index 4e69c9f4e4..154edc854e 100644 --- a/include/m_chat_int.h +++ b/include/m_chat_int.h @@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef M_CHAT_INT_H__ #define M_CHAT_INT_H__ 1 -#pragma warning(disable:4512) +#pragma warning(disable:4512 4275) #include @@ -83,17 +83,31 @@ struct LOGSTREAMDATA; class CChatRoomDlg; -struct GCModuleInfoBase +struct USERINFO : public MZeroedObject, public MNonCopyable { + wchar_t* pszNick; + wchar_t* pszUID; + WORD Status; + int iStatusEx; + WORD ContactStatus; +}; + +struct MIR_APP_EXPORT GCModuleInfoBase : public MZeroedObject, public MNonCopyable +{ + GCModuleInfoBase(); + ~GCModuleInfoBase(); + char *pszModule; wchar_t *ptszModDispName; char *pszHeader; bool bBold, bItalics, bUnderline; bool bColor, bBkgColor; - bool bChanMgr, bAckMsg; + bool bChanMgr, bAckMsg, bSharedUsers; int iMaxText; + + OBJLIST arUsers; // for shared list of users }; struct COMMANDINFO @@ -131,18 +145,11 @@ struct STATUSINFO STATUSINFO *next; }; -struct USERINFO +struct MIR_APP_EXPORT GCSessionInfoBase : public MZeroedObject, public MNonCopyable { - wchar_t* pszNick; - wchar_t* pszUID; - WORD Status; - int iStatusEx; - WORD ContactStatus; - USERINFO *next; -}; + GCSessionInfoBase(); + ~GCSessionInfoBase(); -struct GCSessionInfoBase -{ MCONTACT hContact; bool bInitDone; @@ -156,7 +163,6 @@ struct GCSessionInfoBase wchar_t* ptszTopic; int iType; - int nUsersInNicklist; int iEventCount; int iStatusCount; @@ -171,10 +177,19 @@ struct GCSessionInfoBase CChatRoomDlg *pDlg; COMMANDINFO *lpCommands, *lpCurrentCommand; LOGINFO *pLog, *pLogEnd; - USERINFO *pUsers, *pMe; + USERINFO *pMe; STATUSINFO *pStatuses; + MODULEINFO *pMI; + + OBJLIST arUsers; wchar_t pszLogFileName[MAX_PATH]; + + __forceinline OBJLIST& getUserList() + { + GCModuleInfoBase *mi = (GCModuleInfoBase*)pMI; + return (mi->bSharedUsers) ? mi->arUsers : arUsers; + } }; struct GCLogStreamDataBase @@ -260,6 +275,7 @@ struct CHAT_MANAGER void (*SetActiveSession)(SESSION_INFO *si); SESSION_INFO* (*GetActiveSession)(void); + SESSION_INFO* (*SM_CreateSession)(void); SESSION_INFO* (*SM_FindSession)(const wchar_t *pszID, const char *pszModule); HICON (*SM_GetStatusIcon)(SESSION_INFO *si, USERINFO * ui); BOOL (*SM_PostMessage)(const wchar_t *pszID, const char *pszModule, UINT msg, WPARAM wParam, LPARAM lParam); @@ -272,7 +288,7 @@ struct CHAT_MANAGER USERINFO* (*SM_GetUserFromIndex)(const wchar_t *pszID, const char *pszModule, int index); void (*SM_InvalidateLogDirectories)(void); - MODULEINFO* (*MM_AddModule)(const char *pszModule); + MODULEINFO* (*MM_CreateModule)(void); MODULEINFO* (*MM_FindModule)(const char *pszModule); void (*MM_FontsChanged)(void); void (*MM_IconsChanged)(void); @@ -282,18 +298,15 @@ struct CHAT_MANAGER wchar_t* (*TM_WordToString)(STATUSINFO *pStatusList, WORD Status); BOOL (*TM_RemoveAll)(STATUSINFO** pStatusList); - BOOL (*UM_SetStatusEx)(USERINFO *pUserList, const wchar_t* pszText, int onlyMe); - USERINFO* (*UM_AddUser)(STATUSINFO *pStatusList, USERINFO **pUserList, const wchar_t *pszUID, const wchar_t *pszNick, WORD wStatus); - USERINFO* (*UM_SortUser)(USERINFO **ppUserList, const wchar_t *pszUID); - USERINFO* (*UM_FindUser)(USERINFO *pUserList, const wchar_t *pszUID); - USERINFO* (*UM_FindUserFromIndex)(USERINFO *pUserList, int index); - USERINFO* (*UM_GiveStatus)(USERINFO *pUserList, const wchar_t *pszUID, WORD status); - USERINFO* (*UM_SetContactStatus)(USERINFO *pUserList, const wchar_t *pszUID, WORD status); - USERINFO* (*UM_TakeStatus)(USERINFO *pUserList, const wchar_t *pszUID, WORD status); - wchar_t* (*UM_FindUserAutoComplete)(USERINFO *pUserList, const wchar_t* pszOriginal, const wchar_t* pszCurrent); - BOOL (*UM_RemoveUser)(USERINFO **pUserList, const wchar_t *pszUID); - BOOL (*UM_RemoveAll)(USERINFO **ppUserList); - int (*UM_CompareItem)(USERINFO *u1, const wchar_t *pszNick, WORD wStatus); + int (*UM_CompareItem)(const USERINFO *u1, const USERINFO *u2); + USERINFO* (*UM_AddUser)(STATUSINFO *pStatusList, SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszNick, WORD wStatus); + USERINFO* (*UM_FindUser)(SESSION_INFO *si, const wchar_t *pszUID); + USERINFO* (*UM_FindUserFromIndex)(SESSION_INFO *si, int index); + USERINFO* (*UM_GiveStatus)(SESSION_INFO *si, const wchar_t *pszUID, WORD status); + USERINFO* (*UM_SetContactStatus)(SESSION_INFO *si, const wchar_t *pszUID, WORD status); + USERINFO* (*UM_TakeStatus)(SESSION_INFO *si, const wchar_t *pszUID, WORD status); + wchar_t* (*UM_FindUserAutoComplete)(SESSION_INFO *si, const wchar_t* pszOriginal, const wchar_t* pszCurrent); + BOOL (*UM_RemoveUser)(SESSION_INFO *si, const wchar_t *pszUID); LOGINFO* (*LM_AddEvent)(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd); BOOL (*LM_TrimLog)(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd, int iCount); diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib index ebf0b05285..24c1bd4901 100644 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index a4f8cecf3c..74d05788f8 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib differ diff --git a/plugins/Scriver/src/chat_main.cpp b/plugins/Scriver/src/chat_main.cpp index 191bd75ffd..9bd5f5b4f2 100644 --- a/plugins/Scriver/src/chat_main.cpp +++ b/plugins/Scriver/src/chat_main.cpp @@ -80,6 +80,11 @@ static void OnDestroyModule(MODULEINFO *mi) if (mi->hOfflineTalkIcon) DestroyIcon(mi->hOfflineTalkIcon); } +static MODULEINFO* MM_CreateModule() +{ + return new MODULEINFO(); +} + static void OnCreateModule(MODULEINFO *mi) { HIMAGELIST hList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 0); @@ -130,6 +135,7 @@ int Chat_Load() CHAT_MANAGER_INITDATA data = { &g_Settings, sizeof(MODULEINFO), sizeof(SESSION_INFO), LPGENW("Messaging") L"/" LPGENW("Group chats"), FONTMODE_SKIP, &g_plugin }; Chat_CustomizeApi(&data); + g_chatApi.MM_CreateModule = MM_CreateModule; g_chatApi.OnCreateModule = OnCreateModule; g_chatApi.OnDestroyModule = OnDestroyModule; g_chatApi.OnLoadSettings = OnLoadSettings; diff --git a/plugins/Scriver/src/chat_window.cpp b/plugins/Scriver/src/chat_window.cpp index 005c5e1114..ead6d34283 100644 --- a/plugins/Scriver/src/chat_window.cpp +++ b/plugins/Scriver/src/chat_window.cpp @@ -83,7 +83,7 @@ LBL_SkipEnd: if (m_pLastSession != nullptr) pszName = m_pLastSession->ptszName; } - else pszName = g_chatApi.UM_FindUserAutoComplete(m_si->pUsers, m_wszSearchQuery, m_wszSearchResult); + else pszName = g_chatApi.UM_FindUserAutoComplete(m_si, m_wszSearchQuery, m_wszSearchResult); mir_free(pszText); replaceStrW(m_wszSearchResult, nullptr); @@ -116,9 +116,9 @@ void CChatRoomDlg::FixTabIcons() HICON hIcon; if (!(m_si->wState & GC_EVENT_HIGHLIGHT)) { if (m_si->wState & STATE_TALK) - hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? g_chatApi.MM_FindModule(m_si->pszModule)->hOnlineTalkIcon : g_chatApi.MM_FindModule(m_si->pszModule)->hOfflineTalkIcon; + hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? m_si->pMI->hOnlineTalkIcon : m_si->pMI->hOfflineTalkIcon; else - hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? g_chatApi.MM_FindModule(m_si->pszModule)->hOnlineIcon : g_chatApi.MM_FindModule(m_si->pszModule)->hOfflineIcon; + hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? m_si->pMI->hOnlineIcon : m_si->pMI->hOfflineIcon; } else hIcon = g_dat.hMsgIcon; @@ -157,7 +157,7 @@ void CChatRoomDlg::MessageDialogResize(int w, int h) m_btnNickList.Enable(true); m_btnFilter.Enable(true); if (m_si->iType == GCW_CHATROOM) - m_btnChannelMgr.Enable(g_chatApi.MM_FindModule(m_si->pszModule)->bChanMgr); + m_btnChannelMgr.Enable(m_si->pMI->bChanMgr); } int toolbarTopY = bToolbar ? h - m_pParent->iSplitterY - toolbarHeight : h - m_pParent->iSplitterY; @@ -310,10 +310,6 @@ void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) if (!pButton->Enabled()) return; - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - if (mi == nullptr) - return; - char *pszRtf = m_message.GetRichTextRtf(); if (pszRtf == nullptr) return; @@ -332,7 +328,7 @@ void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) ptszText.Trim(); ptszText.Replace(L"%", L"%%"); - if (mi->bAckMsg) { + if (m_si->pMI->bAckMsg) { EnableWindow(m_message.GetHwnd(), FALSE); m_message.SendMsg(EM_SETREADONLY, TRUE, 0); } @@ -437,17 +433,14 @@ void CChatRoomDlg::UpdateNickList() { m_nickList.SendMsg(WM_SETREDRAW, FALSE, 0); m_nickList.SendMsg(LB_RESETCONTENT, 0, 0); - for (int index = 0; index < m_si->nUsersInNicklist; index++) { - USERINFO *ui = g_chatApi.SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, index); - if (ui) { - char szIndicator = SM_GetStatusIndicator(m_si, ui); - if (szIndicator > '\0') { - static wchar_t ptszBuf[128]; - mir_snwprintf(ptszBuf, L"%c%s", szIndicator, ui->pszNick); - m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ptszBuf); - } - else m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ui->pszNick); + for (auto &ui : m_si->getUserList()) { + char szIndicator = SM_GetStatusIndicator(m_si, ui); + if (szIndicator > '\0') { + static wchar_t ptszBuf[128]; + mir_snwprintf(ptszBuf, L"%c%s", szIndicator, ui->pszNick); + m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ptszBuf); } + else m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ui->pszNick); } m_nickList.SendMsg(WM_SETREDRAW, TRUE, 0); InvalidateRect(m_nickList.GetHwnd(), nullptr, FALSE); @@ -459,18 +452,14 @@ void CChatRoomDlg::UpdateOptions() { m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2")); m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bFilterEnabled ? "chat_filter" : "chat_filter2")); - { - MODULEINFO *pInfo = g_chatApi.MM_FindModule(m_si->pszModule); - if (pInfo) { - m_btnBold.Enable(pInfo->bBold); - m_btnItalic.Enable(pInfo->bItalics); - m_btnUnderline.Enable(pInfo->bUnderline); - m_btnColor.Enable(pInfo->bColor); - m_btnBkColor.Enable(pInfo->bBkgColor); - if (m_si->iType == GCW_CHATROOM) - m_btnChannelMgr.Enable(pInfo->bChanMgr); - } - } + + m_btnBold.Enable(m_si->pMI->bBold); + m_btnItalic.Enable(m_si->pMI->bItalics); + m_btnUnderline.Enable(m_si->pMI->bUnderline); + m_btnColor.Enable(m_si->pMI->bColor); + m_btnBkColor.Enable(m_si->pMI->bBkgColor); + if (m_si->iType == GCW_CHATROOM) + m_btnChannelMgr.Enable(m_si->pMI->bChanMgr); UpdateStatusBar(); UpdateTitle(); @@ -511,14 +500,13 @@ void CChatRoomDlg::UpdateOptions() void CChatRoomDlg::UpdateStatusBar() { - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); wchar_t szTemp[512]; - mir_snwprintf(szTemp, L"%s : %s", mi->ptszModDispName, m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L""); + mir_snwprintf(szTemp, L"%s : %s", m_si->pMI->ptszModDispName, m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L""); StatusBarData sbd; sbd.iItem = 0; sbd.iFlags = SBDF_TEXT | SBDF_ICON; - sbd.hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; + sbd.hIcon = m_si->wStatus == ID_STATUS_ONLINE ? m_si->pMI->hOnlineIcon : m_si->pMI->hOfflineIcon; sbd.pszText = szTemp; SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd); @@ -534,24 +522,23 @@ void CChatRoomDlg::UpdateStatusBar() void CChatRoomDlg::UpdateTitle() { - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - TitleBarData tbd = {}; - tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon; - tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig; + tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? m_si->pMI->hOnlineIcon : m_si->pMI->hOfflineIcon; + tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? m_si->pMI->hOnlineIconBig : m_si->pMI->hOfflineIconBig; tbd.hIconNot = (m_si->wState & (GC_EVENT_HIGHLIGHT | STATE_TALK)) ? GetCachedIcon("chat_overlay") : nullptr; + int nUsers = m_si->getUserList().getCount(); wchar_t szTemp[512]; switch (m_si->iType) { case GCW_CHATROOM: mir_snwprintf(szTemp, - (m_si->nUsersInNicklist == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"), - m_si->ptszName, m_si->nUsersInNicklist); + (nUsers == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"), + m_si->ptszName, nUsers); break; case GCW_PRIVMESS: mir_snwprintf(szTemp, - (m_si->nUsersInNicklist == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"), - m_si->ptszName, m_si->nUsersInNicklist); + (nUsers == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"), + m_si->ptszName, nUsers); break; case GCW_SERVER: mir_snwprintf(szTemp, L"%s: Server", m_si->ptszName); @@ -845,7 +832,7 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) // string we have int iItems = m_nickList.SendMsg(LB_GETCOUNT, 0, 0); for (int i = 0; i < iItems; i++) { - USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si->pUsers, i); + USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, i); if (ui) { if (!wcsnicmp(ui->pszNick, m_wszSearch, mir_wstrlen(m_wszSearch))) { m_nickList.SendMsg(LB_SETCURSEL, i, 0); diff --git a/plugins/Scriver/src/input.cpp b/plugins/Scriver/src/input.cpp index 620db9d6b1..048e2adcde 100644 --- a/plugins/Scriver/src/input.cpp +++ b/plugins/Scriver/src/input.cpp @@ -116,7 +116,6 @@ bool CScriverWindow::CheckSend() { BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; - BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; if (!isShift && !isCtrl && g_dat.sendMode == SEND_ON_ENTER) { PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); diff --git a/plugins/TabSRMM/src/chat.h b/plugins/TabSRMM/src/chat.h index 56a0b742b8..d5d928b135 100644 --- a/plugins/TabSRMM/src/chat.h +++ b/plugins/TabSRMM/src/chat.h @@ -117,7 +117,7 @@ SESSION_INFO* SM_FindSessionAutoComplete(const char* pszModule, SESSION_INFO* cu BOOL SM_ReconfigureFilters(); -int UM_CompareItem(USERINFO *u1, const wchar_t* pszNick, WORD wStatus); +int UM_CompareItem(const USERINFO *u1, const USERINFO *u2); // tools.c BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight, int bManyFix); diff --git a/plugins/TabSRMM/src/chat_log.cpp b/plugins/TabSRMM/src/chat_log.cpp index d65b6a0e1f..4bce806bb2 100644 --- a/plugins/TabSRMM/src/chat_log.cpp +++ b/plugins/TabSRMM/src/chat_log.cpp @@ -78,7 +78,7 @@ static int Log_AppendIEView(LOGSTREAMDATA* streamData, BOOL simpleMode, wchar_t int lineLen, textCharsCount = 0; wchar_t* line = (wchar_t*)_alloca(8001 * sizeof(wchar_t)); wchar_t* d; - MODULEINFO *mi = g_chatApi.MM_FindModule(streamData->si->pszModule); + MODULEINFO *mi = streamData->si->pMI; va_start(va, fmt); lineLen = mir_vsnwprintf(line, 8000, fmt, va); @@ -697,8 +697,8 @@ char* Log_CreateRtfHeader(void) char* Log_CreateRTF(LOGSTREAMDATA *streamData) { LOGINFO *lin = streamData->lin; - MODULEINFO *mi = g_chatApi.MM_FindModule(streamData->si->pszModule); SESSION_INFO *si = streamData->si; + MODULEINFO *mi = si->pMI; // ### RTF HEADER diff --git a/plugins/TabSRMM/src/chat_main.cpp b/plugins/TabSRMM/src/chat_main.cpp index 1dc5e20f7e..73611ef337 100644 --- a/plugins/TabSRMM/src/chat_main.cpp +++ b/plugins/TabSRMM/src/chat_main.cpp @@ -209,6 +209,16 @@ static void stubShowRoom(SESSION_INFO *si) ShowRoom(nullptr, si); } +static MODULEINFO* MM_CreateModule() +{ + return new MODULEINFO(); +} + +static SESSION_INFO* SM_CreateSession() +{ + return new SESSION_INFO(); +} + // load the module int Chat_Load() { @@ -218,11 +228,13 @@ int Chat_Load() CHAT_MANAGER_INITDATA data = { &g_Settings, sizeof(MODULEINFO), sizeof(SESSION_INFO), LPGENW("Message sessions") L"/" LPGENW("Group chats"), FONTMODE_ALTER, &g_plugin }; Chat_CustomizeApi(&data); + g_chatApi.MM_CreateModule = MM_CreateModule; g_chatApi.OnCreateModule = OnCreateModule; g_chatApi.OnNewUser = OnNewUser; g_chatApi.OnSetTopic = OnSetTopic; + g_chatApi.SM_CreateSession = SM_CreateSession; g_chatApi.OnCreateSession = OnCreateSession; g_chatApi.OnReplaceSession = OnReplaceSession; diff --git a/plugins/TabSRMM/src/chat_manager.cpp b/plugins/TabSRMM/src/chat_manager.cpp index c40ed9e821..e2232e6050 100644 --- a/plugins/TabSRMM/src/chat_manager.cpp +++ b/plugins/TabSRMM/src/chat_manager.cpp @@ -44,29 +44,26 @@ static int sttCompareNicknames(const wchar_t *s1, const wchar_t *s2) return mir_wstrcmpi(s1, s2); } -int UM_CompareItem(USERINFO *u1, const wchar_t* pszNick, WORD wStatus) +int UM_CompareItem(const USERINFO *u1, const USERINFO *u2) { WORD dw1 = u1->Status; - WORD dw2 = wStatus; + WORD dw2 = u2->Status; for (int i = 0; i < 8; i++) { if ((dw1 & 1) && !(dw2 & 1)) return -1; if ((dw2 & 1) && !(dw1 & 1)) return 1; - if ((dw1 & 1) && (dw2 & 1)) { - if (g_Settings.bAlternativeSorting) - return sttCompareNicknames(u1->pszNick, pszNick); - else - return mir_wstrcmp(u1->pszNick, pszNick); - } + if ((dw1 & 1) && (dw2 & 1)) + break; + dw1 = dw1 >> 1; dw2 = dw2 >> 1; } if (g_Settings.bAlternativeSorting) - return sttCompareNicknames(u1->pszNick, pszNick); - return mir_wstrcmp(u1->pszNick, pszNick); + return sttCompareNicknames(u1->pszNick, u2->pszNick); + return mir_wstrcmp(u1->pszNick, u2->pszNick); } //--------------------------------------------------- diff --git a/plugins/TabSRMM/src/chat_tools.cpp b/plugins/TabSRMM/src/chat_tools.cpp index cebe7cb32c..0fd56c7b0d 100644 --- a/plugins/TabSRMM/src/chat_tools.cpp +++ b/plugins/TabSRMM/src/chat_tools.cpp @@ -534,7 +534,7 @@ char GetIndicator(SESSION_INFO *si, LPCTSTR ptszNick, int *iNickIndex) if (iNickIndex) *iNickIndex = 0; - for (USERINFO *ui = si->pUsers; ui; ui = ui->next) { + for (auto &ui : si->getUserList()) { if (!mir_wstrcmp(ui->pszNick, ptszNick)) { STATUSINFO *ti = g_chatApi.TM_FindStatus(si->pStatuses, g_chatApi.TM_WordToString(si->pStatuses, ui->Status)); if (ti) { diff --git a/plugins/TabSRMM/src/chat_window.cpp b/plugins/TabSRMM/src/chat_window.cpp index 4b2381cb64..e554a73c3b 100644 --- a/plugins/TabSRMM/src/chat_window.cpp +++ b/plugins/TabSRMM/src/chat_window.cpp @@ -254,11 +254,8 @@ int CChatRoomDlg::Resizer(UTILRESIZECONTROL *urc) m_btnNickList.Enable(true); m_btnFilter.Enable(true); - if (m_si->iType == GCW_CHATROOM) { - MODULEINFO *tmp = g_chatApi.MM_FindModule(m_si->pszModule); - if (tmp) - m_btnChannelMgr.Enable(tmp->bChanMgr); - } + if (m_si->iType == GCW_CHATROOM) + m_btnChannelMgr.Enable(m_si->pMI->bChanMgr); } else { m_nickList.Hide(); @@ -421,7 +418,7 @@ LBL_SkipEnd: if (m_pLastSession != nullptr) pszName = m_pLastSession->ptszName; } - else pszName = g_chatApi.UM_FindUserAutoComplete(m_si->pUsers, m_wszSearchQuery, m_wszSearchResult); + else pszName = g_chatApi.UM_FindUserAutoComplete(m_si, m_wszSearchQuery, m_wszSearchResult); replaceStrW(m_wszSearchResult, nullptr); @@ -623,10 +620,6 @@ void CChatRoomDlg::onClick_OK(CCtrlButton*) if (GetSendButtonState(m_hwnd) == PBS_DISABLED) return; - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - if (mi == nullptr) - return; - ptrA pszRtf(m_message.GetRichTextRtf()); g_chatApi.SM_AddCommand(m_si->ptszID, m_si->pszModule, pszRtf); @@ -637,7 +630,7 @@ void CChatRoomDlg::onClick_OK(CCtrlButton*) DoRtfToTags(ptszText); ptszText.Trim(); - if (mi->bAckMsg) { + if (m_si->pMI->bAckMsg) { m_message.Enable(false); m_message.SendMsg(EM_SETREADONLY, TRUE, 0); } @@ -654,7 +647,7 @@ void CChatRoomDlg::onClick_OK(CCtrlButton*) if (ptszText[0] == '/' || m_si->iType == GCW_SERVER) fSound = false; Chat_DoEventHook(m_si, GC_USER_MESSAGE, nullptr, ptszText, 0); - mi->idleTimeStamp = time(0); + m_si->pMI->idleTimeStamp = time(0); UpdateStatusBar(); if (m_pContainer) if (fSound && !nen_options.iNoSounds && !(m_pContainer->dwFlags & CNT_NOSOUND)) @@ -831,7 +824,7 @@ void CChatRoomDlg::ShowFilterMenu() void CChatRoomDlg::UpdateNickList() { int i = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); - m_nickList.SendMsg(LB_SETCOUNT, m_si->nUsersInNicklist, 0); + m_nickList.SendMsg(LB_SETCOUNT, m_si->getUserList().getCount(), 0); m_nickList.SendMsg(LB_SETTOPINDEX, i, 0); UpdateTitle(); m_hTabIcon = m_hTabStatusIcon; @@ -839,7 +832,7 @@ void CChatRoomDlg::UpdateNickList() void CChatRoomDlg::UpdateOptions() { - MODULEINFO *pInfo = m_si ? g_chatApi.MM_FindModule(m_si->pszModule) : nullptr; + MODULEINFO *pInfo = m_si ? m_si->pMI : nullptr; if (pInfo) { m_btnBold.Enable(pInfo->bBold); m_btnItalic.Enable(pInfo->bItalics); @@ -871,10 +864,7 @@ void CChatRoomDlg::UpdateStatusBar() return; //Mad: strange rare crash here... - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - if (!mi) - return; - + MODULEINFO *mi = m_si->pMI; if (!mi->ptszModDispName) return; @@ -927,20 +917,21 @@ void CChatRoomDlg::UpdateTitle() wchar_t szTemp[100]; HICON hIcon = nullptr; + int nUsers = m_si->getUserList().getCount(); switch (m_si->iType) { case GCW_CHATROOM: hIcon = Skin_LoadProtoIcon(m_si->pszModule, (m_wStatus <= ID_STATUS_OFFLINE) ? ID_STATUS_OFFLINE : m_wStatus); mir_snwprintf(szTemp, - (m_si->nUsersInNicklist == 1) ? TranslateT("%s: chat room (%u user%s)") : TranslateT("%s: chat room (%u users%s)"), - szNick, m_si->nUsersInNicklist, m_bFilterEnabled ? TranslateT(", event filter active") : L""); + (nUsers == 1) ? TranslateT("%s: chat room (%u user%s)") : TranslateT("%s: chat room (%u users%s)"), + szNick, nUsers, m_bFilterEnabled ? TranslateT(", event filter active") : L""); break; case GCW_PRIVMESS: hIcon = Skin_LoadProtoIcon(m_si->pszModule, (m_wStatus <= ID_STATUS_OFFLINE) ? ID_STATUS_OFFLINE : m_wStatus); - if (m_si->nUsersInNicklist == 1) + if (nUsers == 1) mir_snwprintf(szTemp, TranslateT("%s: message session"), szNick); else - mir_snwprintf(szTemp, TranslateT("%s: message session (%u users)"), szNick, m_si->nUsersInNicklist); + mir_snwprintf(szTemp, TranslateT("%s: message session (%u users)"), szNick, nUsers); break; case GCW_SERVER: mir_snwprintf(szTemp, L"%s: Server", szNick); @@ -1092,8 +1083,7 @@ LRESULT CChatRoomDlg::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) RemoveMenu(hSubMenu, 8, MF_BYPOSITION); RemoveMenu(hSubMenu, 4, MF_BYPOSITION); - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | ((mi && mi->bBold) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | (m_si->pMI->bBold ? MF_ENABLED : MF_GRAYED)); TranslateMenu(hSubMenu); CHARRANGE sel, all = { 0, -1 }; @@ -1500,7 +1490,7 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) // string we have int i, iItems = m_nickList.SendMsg(LB_GETCOUNT, 0, 0); for (i = 0; i < iItems; i++) { - USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si->pUsers, i); + USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, i); if (ui) { if (!wcsnicmp(ui->pszNick, m_wszSearch, mir_wstrlen(m_wszSearch))) { m_nickList.SendMsg(LB_SETSEL, FALSE, -1); @@ -1765,7 +1755,7 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) int x_offset = 0; int index = dis->itemID; - USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si->pUsers, index); + USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, index); if (ui == nullptr) return TRUE; @@ -2047,7 +2037,7 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) // clicked a nick name if (g_Settings.bClickableNicks) { if (msg == WM_RBUTTONDOWN) { - for (USERINFO *ui = m_si->pUsers; ui; ui = ui->next) { + for (auto &ui : m_si->getUserList()) { if (mir_wstrcmp(ui->pszNick, tr.lpstrText)) continue; diff --git a/plugins/TabSRMM/src/msgdlgutils.cpp b/plugins/TabSRMM/src/msgdlgutils.cpp index 7de395df5e..b870db669d 100644 --- a/plugins/TabSRMM/src/msgdlgutils.cpp +++ b/plugins/TabSRMM/src/msgdlgutils.cpp @@ -862,7 +862,7 @@ BOOL CTabBaseDlg::DoRtfToTags(CMStringW &pszText) const } else idx += 5; - MODULEINFO *mi = (isChat()) ? g_chatApi.MM_FindModule(m_si->pszModule) : nullptr; + MODULEINFO *mi = (isChat()) ? m_si->pMI : nullptr; bool bInsideColor = false, bInsideUl = false; CMStringW res; diff --git a/plugins/TabSRMM/src/taskbar.cpp b/plugins/TabSRMM/src/taskbar.cpp index 42acd42c6d..88c7c38328 100644 --- a/plugins/TabSRMM/src/taskbar.cpp +++ b/plugins/TabSRMM/src/taskbar.cpp @@ -840,39 +840,37 @@ void CThumbMUC::renderContent() if (si == nullptr) return; - const MODULEINFO *mi = g_chatApi.MM_FindModule(si->pszModule); - if (mi) { - wchar_t szTemp[250]; - if (m_dat->m_dwUnread) { - mir_snwprintf(szTemp, TranslateT("%d unread"), m_dat->m_dwUnread); - CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); - m_rcIcon.top += m_sz.cy; + const MODULEINFO *mi = si->pMI; + wchar_t szTemp[250]; + if (m_dat->m_dwUnread) { + mir_snwprintf(szTemp, TranslateT("%d unread"), m_dat->m_dwUnread); + CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); + m_rcIcon.top += m_sz.cy; + } + if (si->iType != GCW_SERVER) { + wchar_t* _p = nullptr; + if (si->ptszStatusbarText) + _p = wcschr(si->ptszStatusbarText, ']'); + if (_p) { + _p++; + wchar_t _t = *_p; + *_p = 0; + mir_snwprintf(szTemp, TranslateT("Chat room %s"), si->ptszStatusbarText); + *_p = _t; } - if (si->iType != GCW_SERVER) { - wchar_t* _p = nullptr; - if (si->ptszStatusbarText) - _p = wcschr(si->ptszStatusbarText, ']'); - if (_p) { - _p++; - wchar_t _t = *_p; - *_p = 0; - mir_snwprintf(szTemp, TranslateT("Chat room %s"), si->ptszStatusbarText); - *_p = _t; - } - else - mir_snwprintf(szTemp, TranslateT("Chat room %s"), L""); - CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); + else + mir_snwprintf(szTemp, TranslateT("Chat room %s"), L""); + CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); + m_rcIcon.top += m_sz.cy; + mir_snwprintf(szTemp, TranslateT("%d user(s)"), si->getUserList().getCount()); + CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); + } + else { + mir_snwprintf(szTemp, TranslateT("Server window")); + CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); + if (mi->tszIdleMsg[0] && mir_wstrlen(mi->tszIdleMsg) > 2) { m_rcIcon.top += m_sz.cy; - mir_snwprintf(szTemp, TranslateT("%d user(s)"), si->nUsersInNicklist); - CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); - } - else { - mir_snwprintf(szTemp, TranslateT("Server window")); - CSkin::RenderText(m_hdc, m_dat->m_hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); - if (mi->tszIdleMsg[0] && mir_wstrlen(mi->tszIdleMsg) > 2) { - m_rcIcon.top += m_sz.cy; - CSkin::RenderText(m_hdc, m_dat->m_hTheme, &mi->tszIdleMsg[2], &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); - } + CSkin::RenderText(m_hdc, m_dat->m_hTheme, &mi->tszIdleMsg[2], &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true); } } @@ -887,7 +885,6 @@ void CThumbMUC::renderContent() szStatusMsg = TranslateT("no topic set."); } else if (mi) { - wchar_t szTemp[250]; mir_snwprintf(szTemp, TranslateT("%s on %s%s"), m_dat->m_wszMyNickname, mi->ptszModDispName, L""); szStatusMsg = szTemp; } diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp index dbb30f382c..fa301ee37c 100644 --- a/protocols/Discord/src/dispatch.cpp +++ b/protocols/Discord/src/dispatch.cpp @@ -88,15 +88,10 @@ void CDiscordProto::OnCommandChannelCreated(const JSONNode &pRoot) } } else { - CDiscordGuild *pGuild = FindGuild(guildId); - if (pGuild == nullptr) - return; - // group channel for a guild - CDiscordUser *pUser = ProcessGuildChannel(pGuild, pRoot); - if (pUser != nullptr) - for (auto &it : pGuild->arChatUsers) - AddUserToChannel(*pUser, *it); + CDiscordGuild *pGuild = FindGuild(guildId); + if (pGuild) + ProcessGuildChannel(pGuild, pRoot); } } @@ -254,7 +249,7 @@ void CDiscordProto::OnCommandGuildMemberUpdated(const JSONNode &pRoot) CMStringW wszOldNick; SESSION_INFO *si = g_chatApi.SM_FindSession(it->wszUsername, m_szModuleName); if (si != nullptr) { - USERINFO *ui = g_chatApi.UM_FindUser(si->pUsers, wszUserId); + USERINFO *ui = g_chatApi.UM_FindUser(si, wszUserId); if (ui != nullptr) wszOldNick = ui->pszNick; } @@ -382,9 +377,7 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot) pm->wszNick = pRoot["user"]["username"].as_mstring() + L"#" + pRoot["user"]["discriminator"].as_mstring(); pGuild->arChatUsers.insert(pm); - for (auto &it : arUsers) - if (it->guildId == pGuild->id) - AddUserToChannel(*it, *pm); + AddGuildUser(pGuild->id, *pm); } ParseSpecialChars(si, wszText); diff --git a/protocols/Discord/src/guilds.cpp b/protocols/Discord/src/guilds.cpp index 0bb61ed52a..1d0a137fea 100644 --- a/protocols/Discord/src/guilds.cpp +++ b/protocols/Discord/src/guilds.cpp @@ -98,9 +98,8 @@ CDiscordUser* CDiscordProto::ProcessGuildChannel(CDiscordGuild *pGuild, const JS CMStringW wszChannelName = pGuild->wszName + L"#" + pch["name"].as_mstring(); // filter our all channels but the text ones - if (pch["type"].as_int() != 0) { + if (pch["type"].as_int() != 0) return nullptr; - } CMStringW wszTopic = pch["topic"].as_mstring(); @@ -139,18 +138,34 @@ CDiscordUser* CDiscordProto::ProcessGuildChannel(CDiscordGuild *pGuild, const JS SnowFlake oldMsgId = getId(pUser->hContact, DB_KEY_LASTMSGID); if (oldMsgId != 0 && pUser->lastMsg.id > oldMsgId) RetrieveHistory(pUser->hContact, MSG_AFTER, oldMsgId, 99); - - for (auto &it : pGuild->arChatUsers) - AddUserToChannel(*pUser, *it); - return pUser; } ///////////////////////////////////////////////////////////////////////////////////////// -void CDiscordProto::AddUserToChannel(const CDiscordUser &pChannel, const CDiscordGuildMember &pUser) +void CDiscordProto::AddGuildUser(SnowFlake guildId, const CDiscordGuildMember &pUser) { - GCEVENT gce = { m_szModuleName, pChannel.wszUsername, GC_EVENT_JOIN }; + const CDiscordUser *pChannel = nullptr; + for (auto &it : arUsers) + if (it->guildId == guildId) { + pChannel = it; + break; + } + + if (pChannel == nullptr) + return; + + int flags = GC_SSE_ONLYLISTED; + switch (pUser.iStatus) { + case ID_STATUS_ONLINE: case ID_STATUS_NA: case ID_STATUS_DND: + flags += GC_SSE_ONLINE; + break; + + default: + return; + } + + GCEVENT gce = { m_szModuleName, pChannel->wszUsername, GC_EVENT_JOIN }; gce.time = time(0); gce.dwFlags = GCEF_SILENT; @@ -163,15 +178,7 @@ void CDiscordProto::AddUserToChannel(const CDiscordUser &pChannel, const CDiscor gce.ptszNick = pUser.wszNick; Chat_Event(&gce); - int flags = GC_SSE_ONLYLISTED; - switch (pUser.iStatus) { - case ID_STATUS_ONLINE: case ID_STATUS_NA: case ID_STATUS_DND: - flags += GC_SSE_ONLINE; - break; - default: - flags += GC_SSE_OFFLINE; - } - Chat_SetStatusEx(m_szModuleName, pChannel.wszUsername, flags, wszUserId); + Chat_SetStatusEx(m_szModuleName, pChannel->wszUsername, flags, wszUserId); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -222,10 +229,6 @@ void CDiscordProto::ParseGuildContents(CDiscordGuild *pGuild, const JSONNode &pR gm->iStatus = StrToStatus(s["status"].as_mstring()); } - for (auto &pm : newMembers) { - for (auto &pUser : arUsers) { - if (pUser->guildId == pGuild->id) - AddUserToChannel(*pUser, *pm); - } - } + for (auto &pm : newMembers) + AddGuildUser(pGuild->id, *pm); } diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index 574bd2be53..f6a91aca67 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -108,7 +108,7 @@ void CDiscordProto::OnModulesLoaded() } GCREGISTER gcr = {}; - gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR; + gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR | GC_SHAREDUSERS; gcr.ptszDispName = m_tszUserName; gcr.pszModule = m_szModuleName; Chat_Register(&gcr); diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index 7874a8ffb6..5e6d537b24 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -196,6 +196,7 @@ class CDiscordProto : public PROTO OBJLIST arUsers; OBJLIST arOwnMessages; + CDiscordUser* FindUser(SnowFlake id); CDiscordUser* FindUser(const wchar_t *pwszUsername, int iDiscriminator); CDiscordUser* FindUserByChannel(SnowFlake channelId); @@ -226,7 +227,7 @@ class CDiscordProto : public PROTO } void ProcessGuild(const JSONNode&); - void AddUserToChannel(const CDiscordUser &pChannel, const CDiscordGuildMember &pUser); + void AddGuildUser(SnowFlake guildId, const CDiscordGuildMember &pUser); void ParseGuildContents(CDiscordGuild *guild, const JSONNode &); CDiscordUser* ProcessGuildChannel(CDiscordGuild *guild, const JSONNode&); void ProcessRole(CDiscordGuild *guild, const JSONNode&); diff --git a/protocols/Discord/src/utils.cpp b/protocols/Discord/src/utils.cpp index e1867992db..d4e35b4090 100644 --- a/protocols/Discord/src/utils.cpp +++ b/protocols/Discord/src/utils.cpp @@ -265,7 +265,7 @@ void CDiscordProto::ParseSpecialChars(SESSION_INFO *si, CMStringW &str) if (wszWord[1] == '!') iStart++; - USERINFO *ui = g_chatApi.UM_FindUser(si->pUsers, wszWord.c_str() + iStart); + USERINFO *ui = g_chatApi.UM_FindUser(si, wszWord.c_str() + iStart); if (ui != nullptr) str.Replace(L"<" + wszWord + L">", CMStringW('@') + ui->pszNick); } diff --git a/protocols/JabberG/src/stdafx.h b/protocols/JabberG/src/stdafx.h index 7120057218..bd420ce718 100755 --- a/protocols/JabberG/src/stdafx.h +++ b/protocols/JabberG/src/stdafx.h @@ -106,8 +106,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "jabber_byte.h" #include "jabber_ibb.h" -struct SESSION_INFO : public GCSessionInfoBase {}; - struct CJabberProto; struct CMPlugin : public ACCPROTOPLUGIN diff --git a/src/core/stdmsg/src/chat_manager.cpp b/src/core/stdmsg/src/chat_manager.cpp index 18626e3f28..a4e82c1d98 100644 --- a/src/core/stdmsg/src/chat_manager.cpp +++ b/src/core/stdmsg/src/chat_manager.cpp @@ -59,6 +59,11 @@ HMENU g_hMenu = nullptr; GlobalLogSettings g_Settings; +static MODULEINFO* MM_CreateModule() +{ + return new MODULEINFO(); +} + static void OnDestroyModule(MODULEINFO *mi) { if (mi->hOnlineIcon) @@ -231,6 +236,7 @@ void Load_ChatModule() CHAT_MANAGER_INITDATA data = { &g_Settings, sizeof(MODULEINFO), sizeof(SESSION_INFO), LPGENW("Message sessions") L"/" LPGENW("Chat module"), FONTMODE_USE, &g_plugin }; Chat_CustomizeApi(&data); + g_chatApi.MM_CreateModule = MM_CreateModule; g_chatApi.OnCreateModule = OnCreateModule; g_chatApi.OnDestroyModule = OnDestroyModule; g_chatApi.OnReplaceSession = OnReplaceSession; diff --git a/src/core/stdmsg/src/chat_window.cpp b/src/core/stdmsg/src/chat_window.cpp index 3f513be937..3f2750bdb7 100644 --- a/src/core/stdmsg/src/chat_window.cpp +++ b/src/core/stdmsg/src/chat_window.cpp @@ -141,10 +141,6 @@ void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) if (pszRtf == nullptr) return; - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - if (mi == nullptr) - return; - g_chatApi.SM_AddCommand(m_si->ptszID, m_si->pszModule, pszRtf); CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf))); @@ -152,7 +148,7 @@ void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) ptszText.Trim(); ptszText.Replace(L"%", L"%%"); - if (mi->bAckMsg) { + if (m_si->pMI->bAckMsg) { EnableWindow(m_message.GetHwnd(), FALSE); m_message.SendMsg(EM_SETREADONLY, TRUE, 0); } @@ -201,8 +197,7 @@ int CChatRoomDlg::GetImageId() const if ((m_si->wState & GC_EVENT_HIGHLIGHT) && (m_nFlash & 1)) return 0; - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - return (m_si->wStatus == ID_STATUS_ONLINE) ? mi->OnlineIconIndex : mi->OfflineIconIndex; + return (m_si->wStatus == ID_STATUS_ONLINE) ? m_si->pMI->OnlineIconIndex : m_si->pMI->OfflineIconIndex; } void CChatRoomDlg::LoadSettings() @@ -268,7 +263,7 @@ void CChatRoomDlg::ShowFilterMenu() void CChatRoomDlg::UpdateNickList() { int i = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); - m_nickList.SendMsg(LB_SETCOUNT, m_si->nUsersInNicklist, 0); + m_nickList.SendMsg(LB_SETCOUNT, m_si->getUserList().getCount(), 0); m_nickList.SendMsg(LB_SETTOPINDEX, i, 0); UpdateTitle(); @@ -279,7 +274,7 @@ void CChatRoomDlg::UpdateOptions() m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bNicklistEnabled ? "nicklist" : "nicklist2", FALSE)); m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bFilterEnabled ? "filter" : "filter2", FALSE)); - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); + MODULEINFO *mi = m_si->pMI; EnableWindow(m_btnBold.GetHwnd(), mi->bBold); EnableWindow(m_btnItalic.GetHwnd(), mi->bItalics); EnableWindow(m_btnUnderline.GetHwnd(), mi->bUnderline); @@ -330,8 +325,7 @@ void CChatRoomDlg::UpdateOptions() void CChatRoomDlg::UpdateStatusBar() { - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - wchar_t *ptszDispName = mi->ptszModDispName; + wchar_t *ptszDispName = m_si->pMI->ptszModDispName; int x = 12; x += Chat_GetTextPixelSize(ptszDispName, (HFONT)SendMessage(m_pOwner->m_hwndStatus, WM_GETFONT, 0, 0), TRUE); x += GetSystemMetrics(SM_CXSMICON); @@ -339,10 +333,10 @@ void CChatRoomDlg::UpdateStatusBar() SendMessage(m_pOwner->m_hwndStatus, SB_SETPARTS, 2, (LPARAM)&iStatusbarParts); // stupid hack to make icons show. I dunno why this is needed currently - HICON hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; + HICON hIcon = m_si->wStatus == ID_STATUS_ONLINE ? m_si->pMI->hOnlineIcon : m_si->pMI->hOfflineIcon; if (!hIcon) { g_chatApi.MM_IconsChanged(); - hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; + hIcon = m_si->wStatus == ID_STATUS_ONLINE ? m_si->pMI->hOnlineIcon : m_si->pMI->hOfflineIcon; } SendMessage(m_pOwner->m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); @@ -353,17 +347,19 @@ void CChatRoomDlg::UpdateStatusBar() void CChatRoomDlg::UpdateTitle() { + int nUsers = m_si->getUserList().getCount(); + wchar_t szTemp[100]; switch (m_si->iType) { case GCW_CHATROOM: mir_snwprintf(szTemp, - (m_si->nUsersInNicklist == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"), - m_si->ptszName, m_si->nUsersInNicklist); + (nUsers == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"), + m_si->ptszName, nUsers); break; case GCW_PRIVMESS: mir_snwprintf(szTemp, - (m_si->nUsersInNicklist == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"), - m_si->ptszName, m_si->nUsersInNicklist); + (nUsers == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"), + m_si->ptszName, nUsers); break; case GCW_SERVER: mir_snwprintf(szTemp, L"%s: Server", m_si->ptszName); @@ -740,7 +736,7 @@ LRESULT CChatRoomDlg::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) wchar_t *pszSelName = (wchar_t *)mir_alloc(sizeof(wchar_t)*(end - start + 1)); mir_wstrncpy(pszSelName, pszText + start, end - start + 1); - wchar_t *pszName = g_chatApi.UM_FindUserAutoComplete(m_si->pUsers, szTabSave, pszSelName); + wchar_t *pszName = g_chatApi.UM_FindUserAutoComplete(m_si, szTabSave, pszSelName); if (pszName == nullptr) { pszName = szTabSave; m_message.SendMsg(EM_SETSEL, start, end); @@ -1019,7 +1015,7 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) m_btnNickList.Enable(true); m_btnFilter.Enable(true); if (m_si->iType == GCW_CHATROOM) - m_btnChannelMgr.Enable(g_chatApi.MM_FindModule(m_si->pszModule)->bChanMgr); + m_btnChannelMgr.Enable(m_si->pMI->bChanMgr); } CSuper::DlgProc(uMsg, wParam, lParam); // call built-in resizer diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index 401adb6139..2172a014b9 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -29,8 +29,8 @@ void Srmm_CreateToolbarIcons(HWND hwndDlg, int flags); void Srmm_ProcessToolbarHotkey(MCONTACT hContact, INT_PTR iButtonFrom, HWND hwndDlg); struct MODULEINFO : public GCModuleInfoBase {}; -struct SESSION_INFO : public GCSessionInfoBase {}; struct LOGSTREAMDATA : public GCLogStreamDataBase {}; +struct SESSION_INFO : public GCSessionInfoBase {}; class CChatRoomDlg : public CSrmmBaseDialog { @@ -52,74 +52,79 @@ extern MWindowList g_hWindowList; extern HANDLE hevSendEvent, hevBuildMenuEvent; // log.c -void LoadMsgLogBitmaps(void); -void FreeMsgLogBitmaps(void); -void ValidateFilename (wchar_t *filename); -wchar_t* MakeTimeStamp(wchar_t *pszStamp, time_t time); -wchar_t* GetChatLogsFilename(SESSION_INFO *si, time_t tTime); -char* Log_CreateRtfHeader(); -char* Log_CreateRTF(LOGSTREAMDATA *streamData); -char* Log_SetStyle(int style); +void LoadMsgLogBitmaps(void); +void FreeMsgLogBitmaps(void); +void ValidateFilename (wchar_t *filename); +wchar_t* MakeTimeStamp(wchar_t *pszStamp, time_t time); +wchar_t* GetChatLogsFilename(SESSION_INFO *si, time_t tTime); +char* Log_CreateRtfHeader(); +char* Log_CreateRTF(LOGSTREAMDATA *streamData); +char* Log_SetStyle(int style); // chat_manager.cpp -BOOL SM_AddEvent(const wchar_t *pszID, const char *pszModule, GCEVENT *gce, bool bIsHighlighted); -BOOL SM_ChangeNick(const wchar_t *pszID, const char *pszModule, GCEVENT *gce); -char* SM_GetUsers(SESSION_INFO *si); -BOOL SM_GiveStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, const wchar_t *pszStatus); -BOOL SM_MoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID); -void SM_RemoveAll(void); -int SM_RemoveSession(const wchar_t *pszID, const char *pszModule, bool removeContact); -BOOL SM_RemoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID); -BOOL SM_SetContactStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, WORD wStatus); -BOOL SM_SetOffline(const char *pszModule, SESSION_INFO *si); -BOOL SM_SetStatus(const char *pszModule, SESSION_INFO *si, int wStatus); -BOOL SM_TakeStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, const wchar_t *pszStatus); +MODULEINFO* MM_AddModule(const char *pszModule); + +BOOL SM_AddEvent(const wchar_t *pszID, const char *pszModule, GCEVENT *gce, bool bIsHighlighted); +BOOL SM_ChangeNick(const wchar_t *pszID, const char *pszModule, GCEVENT *gce); +char* SM_GetUsers(SESSION_INFO *si); +BOOL SM_GiveStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, const wchar_t *pszStatus); +void SM_RemoveAll(void); +int SM_RemoveSession(const wchar_t *pszID, const char *pszModule, bool removeContact); +BOOL SM_RemoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID); +BOOL SM_SetContactStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, WORD wStatus); +BOOL SM_SetOffline(const char *pszModule, SESSION_INFO *si); +BOOL SM_SetStatus(const char *pszModule, SESSION_INFO *si, int wStatus); +BOOL SM_TakeStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, const wchar_t *pszStatus); SESSION_INFO* SM_FindSession(const wchar_t *pszID, const char *pszModule); SESSION_INFO* SM_FindSessionByIndex(const char *pszModule, int iItem); -STATUSINFO* TM_AddStatus(STATUSINFO **ppStatusList, const wchar_t *pszStatus, int *iCount); -WORD TM_StringToWord(STATUSINFO *pStatusList, const wchar_t *pszStatus); +STATUSINFO* TM_AddStatus(STATUSINFO **ppStatusList, const wchar_t *pszStatus, int *iCount); +WORD TM_StringToWord(STATUSINFO *pStatusList, const wchar_t *pszStatus); -// clist.c -BOOL AddEvent(MCONTACT hContact, HICON hIcon, MEVENT hEvent, int type, wchar_t* fmt, ...); -MCONTACT AddRoom(const char *pszModule, const wchar_t *pszRoom, const wchar_t *pszDisplayName, int iType); -MCONTACT FindRoom(const char *pszModule, const wchar_t *pszRoom); -BOOL SetAllOffline(BOOL bHide, const char *pszModule); -BOOL SetOffline(MCONTACT hContact, BOOL bHide); +BOOL UM_RemoveAll(SESSION_INFO *si); +BOOL UM_SetStatusEx(SESSION_INFO *si, const wchar_t* pszText, int flags); +bool UM_SortUser(SESSION_INFO *si, const wchar_t *pszUID); -int RoomDoubleclicked(WPARAM wParam,LPARAM lParam); -INT_PTR JoinChat(WPARAM wParam, LPARAM lParam); -INT_PTR LeaveChat(WPARAM wParam, LPARAM lParam); -int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); +// clist.c +BOOL AddEvent(MCONTACT hContact, HICON hIcon, MEVENT hEvent, int type, wchar_t* fmt, ...); +MCONTACT AddRoom(const char *pszModule, const wchar_t *pszRoom, const wchar_t *pszDisplayName, int iType); +MCONTACT FindRoom(const char *pszModule, const wchar_t *pszRoom); +BOOL SetAllOffline(BOOL bHide, const char *pszModule); +BOOL SetOffline(MCONTACT hContact, BOOL bHide); + +int RoomDoubleclicked(WPARAM wParam,LPARAM lParam); +INT_PTR JoinChat(WPARAM wParam, LPARAM lParam); +INT_PTR LeaveChat(WPARAM wParam, LPARAM lParam); +int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); // options.c -int OptionsInit(void); -int OptionsUnInit(void); -void LoadMsgDlgFont(int i, LOGFONT * lf, COLORREF * colour); -void LoadGlobalSettings(void); -HICON LoadIconEx(char* pszIcoLibName, bool big); -void LoadLogFonts(void); -void SetIndentSize(void); -void RegisterFonts(void); +int OptionsInit(void); +int OptionsUnInit(void); +void LoadMsgDlgFont(int i, LOGFONT * lf, COLORREF * colour); +void LoadGlobalSettings(void); +HICON LoadIconEx(char* pszIcoLibName, bool big); +void LoadLogFonts(void); +void SetIndentSize(void); +void RegisterFonts(void); // services.c -void LoadChatIcons(void); -int LoadChatModule(void); -void UnloadChatModule(void); +void LoadChatIcons(void); +int LoadChatModule(void); +void UnloadChatModule(void); // tools.c -int DoRtfToTags(CMStringW &pszText, int iNumColors, COLORREF *pColors); -wchar_t *RemoveFormatting(const wchar_t* pszText); -BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight, int bManyFix); -int GetRichTextLength(HWND hwnd); -bool IsHighlighted(SESSION_INFO *si, GCEVENT *pszText); -BOOL IsEventSupported(int eventType); -BOOL LogToFile(SESSION_INFO *si, GCEVENT *gce); -BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce); -BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce); -int ShowPopup(MCONTACT hContact, SESSION_INFO *si, HICON hIcon, char* pszProtoName, wchar_t* pszRoomName, COLORREF crBkg, const wchar_t* fmt, ...); - -const wchar_t* my_strstri(const wchar_t* s1, const wchar_t* s2); +int DoRtfToTags(CMStringW &pszText, int iNumColors, COLORREF *pColors); +wchar_t* RemoveFormatting(const wchar_t* pszText); +BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight, int bManyFix); +int GetRichTextLength(HWND hwnd); +bool IsHighlighted(SESSION_INFO *si, GCEVENT *pszText); +BOOL IsEventSupported(int eventType); +BOOL LogToFile(SESSION_INFO *si, GCEVENT *gce); +BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce); +BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce); +int ShowPopup(MCONTACT hContact, SESSION_INFO *si, HICON hIcon, char* pszProtoName, wchar_t* pszRoomName, COLORREF crBkg, const wchar_t* fmt, ...); + +const wchar_t* my_strstri(const wchar_t* s1, const wchar_t* s2); #pragma comment(lib,"comctl32.lib") diff --git a/src/mir_app/src/chat_log.cpp b/src/mir_app/src/chat_log.cpp index 5c0f4aed89..32dd87f67c 100644 --- a/src/mir_app/src/chat_log.cpp +++ b/src/mir_app/src/chat_log.cpp @@ -294,7 +294,7 @@ wchar_t* MakeTimeStamp(wchar_t *pszStamp, time_t time) char* Log_CreateRTF(LOGSTREAMDATA *streamData) { SESSION_INFO *si = streamData->si; - MODULEINFO *mi = g_chatApi.MM_FindModule(si->pszModule); + MODULEINFO *mi = si->pMI; // guesstimate amount of memory for the RTF CMStringA buf; diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp index f28d82768e..4abff39ba8 100644 --- a/src/mir_app/src/chat_manager.cpp +++ b/src/mir_app/src/chat_manager.cpp @@ -26,6 +26,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define WINDOWS_COMMANDS_MAX 30 +static int CompareUser(const USERINFO *u1, const USERINFO *u2) +{ + return g_chatApi.UM_CompareItem(u1, u2); +} + static int compareSessions(const SESSION_INFO *p1, const SESSION_INFO *p2) { int res = mir_strcmpi(p1->pszModule, p2->pszModule); @@ -74,6 +79,18 @@ static SESSION_INFO* GetActiveSession(void) // Session Manager functions // Keeps track of all sessions and its windows +GCSessionInfoBase::GCSessionInfoBase() : + arUsers(10, CompareUser) +{} + +GCSessionInfoBase::~GCSessionInfoBase() +{} + +static SESSION_INFO* SM_CreateSession(void) +{ + return new SESSION_INFO(); +} + static void SM_FreeSession(SESSION_INFO *si, bool bRemoveContact = false) { if (g_clistApi.pfnGetEvent(si->hContact, 0)) @@ -98,12 +115,11 @@ static void SM_FreeSession(SESSION_INFO *si, bool bRemoveContact = false) db_unset(si->hContact, "CList", "StatusMsg"); } - g_chatApi.UM_RemoveAll(&si->pUsers); + UM_RemoveAll(si); g_chatApi.TM_RemoveAll(&si->pStatuses); g_chatApi.LM_RemoveAll(&si->pLog, &si->pLogEnd); si->iStatusCount = 0; - si->nUsersInNicklist = 0; mir_free(si->pszModule); mir_free(si->ptszID); @@ -118,7 +134,7 @@ static void SM_FreeSession(SESSION_INFO *si, bool bRemoveContact = false) si->lpCommands = pNext; } - mir_free(si); + delete si; } int SM_RemoveSession(const wchar_t *pszID, const char *pszModule, bool removeContact) @@ -172,9 +188,9 @@ BOOL SM_SetOffline(const char *pszModule, SESSION_INFO *si) return TRUE; } - g_chatApi.UM_RemoveAll(&si->pUsers); + UM_RemoveAll(si); si->pMe = nullptr; - si->nUsersInNicklist = 0; + if (si->iType != GCW_SERVER) si->bInitDone = false; if (g_chatApi.OnOfflineSession) @@ -222,19 +238,6 @@ BOOL SM_AddEvent(const wchar_t *pszID, const char *pszModule, GCEVENT *gce, bool return TRUE; } -BOOL SM_MoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID) -{ - if (!pszUID) - return FALSE; - - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == nullptr) - return FALSE; - - g_chatApi.UM_SortUser(&si->pUsers, pszUID); - return TRUE; -} - BOOL SM_RemoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID) { if (!pszModule || !pszUID) @@ -244,15 +247,14 @@ BOOL SM_RemoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *p if ((pszID && mir_wstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) continue; - USERINFO *ui = g_chatApi.UM_FindUser(si->pUsers, pszUID); + USERINFO *ui = g_chatApi.UM_FindUser(si, pszUID); if (ui) { - si->nUsersInNicklist--; if (g_chatApi.OnRemoveUser) g_chatApi.OnRemoveUser(si, ui); if (si->pMe == ui) si->pMe = nullptr; - g_chatApi.UM_RemoveUser(&si->pUsers, pszUID); + g_chatApi.UM_RemoveUser(si, pszUID); if (si->pDlg) si->pDlg->UpdateNickList(); @@ -268,7 +270,7 @@ BOOL SM_RemoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *p static USERINFO* SM_GetUserFromIndex(const wchar_t *pszID, const char *pszModule, int index) { SESSION_INFO *si = SM_FindSession(pszID, pszModule); - return (si == nullptr) ? nullptr : g_chatApi.UM_FindUserFromIndex(si->pUsers, index); + return (si == nullptr) ? nullptr : g_chatApi.UM_FindUserFromIndex(si, index); } BOOL SM_GiveStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, const wchar_t *pszStatus) @@ -277,9 +279,9 @@ BOOL SM_GiveStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *p if (si == nullptr) return FALSE; - USERINFO *ui = g_chatApi.UM_GiveStatus(si->pUsers, pszUID, TM_StringToWord(si->pStatuses, pszStatus)); + USERINFO *ui = g_chatApi.UM_GiveStatus(si, pszUID, TM_StringToWord(si->pStatuses, pszStatus)); if (ui) { - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); + UM_SortUser(si, ui->pszUID); if (si->pDlg) si->pDlg->UpdateNickList(); } @@ -292,9 +294,9 @@ BOOL SM_SetContactStatus(const wchar_t *pszID, const char *pszModule, const wcha if (si == nullptr) return FALSE; - USERINFO *ui = g_chatApi.UM_SetContactStatus(si->pUsers, pszUID, wStatus); + USERINFO *ui = g_chatApi.UM_SetContactStatus(si, pszUID, wStatus); if (ui) { - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); + UM_SortUser(si, ui->pszUID); if (si->pDlg) si->pDlg->UpdateNickList(); } @@ -307,9 +309,9 @@ BOOL SM_TakeStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *p if (si == nullptr) return FALSE; - USERINFO *ui = g_chatApi.UM_TakeStatus(si->pUsers, pszUID, TM_StringToWord(si->pStatuses, pszStatus)); + USERINFO *ui = g_chatApi.UM_TakeStatus(si, pszUID, TM_StringToWord(si->pStatuses, pszStatus)); if (ui) { - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); + UM_SortUser(si, ui->pszUID); if (si->pDlg) si->pDlg->UpdateNickList(); } @@ -366,10 +368,10 @@ BOOL SM_ChangeNick(const wchar_t *pszID, const char *pszModule, GCEVENT *gce) for (auto &si : g_arSessions) { if ((!pszID || !mir_wstrcmpi(si->ptszID, pszID)) && !mir_strcmpi(si->pszModule, pszModule)) { - USERINFO *ui = g_chatApi.UM_FindUser(si->pUsers, gce->ptszUID); + USERINFO *ui = g_chatApi.UM_FindUser(si, gce->ptszUID); if (ui) { replaceStrW(ui->pszNick, gce->ptszText); - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); + UM_SortUser(si, ui->pszUID); if (si->pDlg) si->pDlg->UpdateNickList(); if (g_chatApi.OnChangeNick) @@ -485,7 +487,6 @@ SESSION_INFO* SM_FindSessionByIndex(const char *pszModule, int iItem) } } return nullptr; - } char* SM_GetUsers(SESSION_INFO *si) @@ -493,31 +494,12 @@ char* SM_GetUsers(SESSION_INFO *si) if (si == nullptr) return nullptr; - USERINFO *utemp = nullptr; - for (auto &p : g_arSessions) { - if (si == p) { - if ((utemp = p->pUsers) == nullptr) - return nullptr; - - break; - } - } - if (utemp == nullptr) - return nullptr; - - char *p = nullptr; - size_t alloced = 0; - do { - size_t pLen = mir_strlen(p), nameLen = mir_wstrlen(utemp->pszUID); - if (pLen + nameLen + 2 > alloced) - p = (char*)mir_realloc(p, alloced += 4096); + CMStringA res; + + for (auto &it : si->getUserList()) + res.AppendFormat("%S ", it->pszNick); - WideCharToMultiByte(CP_ACP, 0, utemp->pszUID, -1, p + pLen, (int)nameLen + 1, nullptr, nullptr); - mir_strcpy(p + pLen + nameLen, " "); - utemp = utemp->next; - } - while (utemp != nullptr); - return p; + return res.Detach(); } static void SM_InvalidateLogDirectories() @@ -530,7 +512,14 @@ static void SM_InvalidateLogDirectories() // Module Manager functions // Necessary to keep track of all modules that has registered with the plugin -static MODULEINFO* MM_AddModule(const char *pszModule) +GCModuleInfoBase::GCModuleInfoBase() : + arUsers(1, CompareUser) +{} + +GCModuleInfoBase::~GCModuleInfoBase() +{} + +MODULEINFO* MM_AddModule(const char *pszModule) { if (pszModule == nullptr) return nullptr; @@ -538,7 +527,7 @@ static MODULEINFO* MM_AddModule(const char *pszModule) if (g_chatApi.MM_FindModule(pszModule)) return nullptr; - MODULEINFO *node = (MODULEINFO*)mir_calloc(g_cbModuleInfo); + MODULEINFO *node = g_chatApi.MM_CreateModule(); replaceStr(node->pszModule, pszModule); if (g_chatApi.OnCreateModule) g_chatApi.OnCreateModule(node); @@ -547,6 +536,11 @@ static MODULEINFO* MM_AddModule(const char *pszModule) return node; } +static MODULEINFO* MM_CreateModule() +{ + return new MODULEINFO(); +} + static void MM_IconsChanged() { LoadChatIcons(); @@ -567,7 +561,9 @@ static MODULEINFO* MM_FindModule(const char *pszModule) if (!pszModule) return nullptr; - return g_arModules.find((MODULEINFO*)&pszModule); + MODULEINFO *tmp = (MODULEINFO*)_alloca(sizeof(MODULEINFO)); + tmp->pszModule = (char*)pszModule; + return g_arModules.find(tmp); } static BOOL MM_RemoveAll(void) @@ -579,7 +575,7 @@ static BOOL MM_RemoveAll(void) mir_free(mi->pszModule); mir_free(mi->ptszModDispName); mir_free(mi->pszHeader); - mir_free(mi); + delete mi; } return TRUE; } @@ -677,123 +673,70 @@ static BOOL TM_RemoveAll(STATUSINFO **ppStatusList) // User manager functions // Necessary to keep track of the users in a window nicklist -static int UM_CompareItem(USERINFO *u1, const wchar_t *pszNick, WORD wStatus) +static USERINFO* UM_FindUser(SESSION_INFO *si, const wchar_t *pszUID) { - WORD dw1 = u1->Status; - WORD dw2 = wStatus; + if (!si || !pszUID) + return nullptr; - for (int i = 0; i < 8; i++) { - if ((dw1 & 1) && !(dw2 & 1)) - return -1; - if ((dw2 & 1) && !(dw1 & 1)) - return 1; - if ((dw1 & 1) && (dw2 & 1)) - return mir_wstrcmpi(u1->pszNick, pszNick); + for (auto &ui : si->getUserList()) + if (!mir_wstrcmpi(ui->pszUID, pszUID)) + return ui; - dw1 = dw1 >> 1; - dw2 = dw2 >> 1; - } - return mir_wstrcmpi(u1->pszNick, pszNick); + return nullptr; } -static USERINFO* UM_SortUser(USERINFO **ppUserList, const wchar_t *pszUID) +static int compareStub(const void *p1, const void *p2) { - USERINFO *ui = *ppUserList, *pLast = nullptr; - if (!ui || !pszUID) - return nullptr; - - while (ui && mir_wstrcmpi(ui->pszUID, pszUID)) { - pLast = ui; - ui = ui->next; - } - - if (ui == nullptr) - return nullptr; - - USERINFO *node = ui; - if (pLast) - pLast->next = ui->next; - else - *ppUserList = ui->next; - ui = *ppUserList; - - pLast = nullptr; - - while (ui && g_chatApi.UM_CompareItem(ui, node->pszNick, node->Status) <= 0) { - pLast = ui; - ui = ui->next; - } + return CompareUser(*(USERINFO**)p1, *(USERINFO**)p2); +} - if (*ppUserList == nullptr) { // list is empty - *ppUserList = node; - node->next = nullptr; - } - else { - if (pLast) { - node->next = ui; - pLast->next = node; - } - else { - node->next = *ppUserList; - *ppUserList = node; - } - } +bool UM_SortUser(SESSION_INFO *si, const wchar_t *pszUID) +{ + if (!UM_FindUser(si, pszUID)) + return false; - return node; + qsort(si->arUsers.getArray(), si->arUsers.getCount(), sizeof(void*), compareStub); + return true; } -USERINFO* UM_AddUser(STATUSINFO *pStatusList, USERINFO **ppUserList, const wchar_t *pszUID, const wchar_t *pszNick, WORD wStatus) +USERINFO* UM_AddUser(STATUSINFO *pStatusList, SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszNick, WORD wStatus) { - if (pStatusList == nullptr || ppUserList == nullptr || pszNick == nullptr) + if (pStatusList == nullptr || si == nullptr || pszNick == nullptr) return nullptr; - USERINFO *ui = *ppUserList, *pLast = nullptr; - while (ui && g_chatApi.UM_CompareItem(ui, pszNick, wStatus) <= 0) { - pLast = ui; - ui = ui->next; - } - - // if (!UM_FindUser(*ppUserList, pszUI, wStatus) - USERINFO *node = (USERINFO*)mir_calloc(sizeof(USERINFO)); + USERINFO *node = new USERINFO(); replaceStrW(node->pszUID, pszUID); - - if (*ppUserList == nullptr) { // list is empty - *ppUserList = node; - node->next = nullptr; - } - else { - if (pLast) { - node->next = ui; - pLast->next = node; - } - else { - node->next = *ppUserList; - *ppUserList = node; - } - } - + node->Status = wStatus; + si->getUserList().insert(node); return node; } -static USERINFO* UM_FindUser(USERINFO *pUserList, const wchar_t *pszUID) +static int UM_CompareItem(const USERINFO *u1, const USERINFO *u2) { - if (!pUserList || !pszUID) - return nullptr; + WORD dw1 = u1->Status; + WORD dw2 = u2->Status; - for (USERINFO *ui = pUserList; ui != nullptr; ui = ui->next) - if (!mir_wstrcmpi(ui->pszUID, pszUID)) - return ui; + for (int i = 0; i < 8; i++) { + if ((dw1 & 1) && !(dw2 & 1)) + return -1; + if ((dw2 & 1) && !(dw1 & 1)) + return 1; + if ((dw1 & 1) && (dw2 & 1)) + break; - return nullptr; + dw1 = dw1 >> 1; + dw2 = dw2 >> 1; + } + return mir_wstrcmpi(u1->pszNick, u2->pszNick); } -static USERINFO* UM_FindUserFromIndex(USERINFO *pUserList, int index) +static USERINFO* UM_FindUserFromIndex(SESSION_INFO *si, int index) { - if (!pUserList) + if (!si) return nullptr; int i = 0; - for (USERINFO *ui = pUserList; ui != nullptr; ui = ui->next) { + for (auto &ui : si->getUserList()) { if (i == index) return ui; i++; @@ -801,9 +744,9 @@ static USERINFO* UM_FindUserFromIndex(USERINFO *pUserList, int index) return nullptr; } -static USERINFO* UM_GiveStatus(USERINFO *pUserList, const wchar_t *pszUID, WORD status) +static USERINFO* UM_GiveStatus(SESSION_INFO *si, const wchar_t *pszUID, WORD status) { - USERINFO *ui = UM_FindUser(pUserList, pszUID); + USERINFO *ui = UM_FindUser(si, pszUID); if (ui == nullptr) return nullptr; @@ -811,9 +754,9 @@ static USERINFO* UM_GiveStatus(USERINFO *pUserList, const wchar_t *pszUID, WORD return ui; } -static USERINFO* UM_SetContactStatus(USERINFO *pUserList, const wchar_t *pszUID, WORD status) +static USERINFO* UM_SetContactStatus(SESSION_INFO *si, const wchar_t *pszUID, WORD status) { - USERINFO *ui = UM_FindUser(pUserList, pszUID); + USERINFO *ui = UM_FindUser(si, pszUID); if (ui == nullptr) return nullptr; @@ -821,12 +764,21 @@ static USERINFO* UM_SetContactStatus(USERINFO *pUserList, const wchar_t *pszUID, return ui; } -static BOOL UM_SetStatusEx(USERINFO *pUserList, const wchar_t* pszText, int flags) +BOOL UM_SetStatusEx(SESSION_INFO *si, const wchar_t* pszText, int flags) { int bOnlyMe = (flags & GC_SSE_ONLYLISTED) != 0, bSetStatus = (flags & GC_SSE_ONLINE) != 0; char cDelimiter = (flags & GC_SSE_TABDELIMITED) ? '\t' : ' '; - for (USERINFO *ui = pUserList; ui != nullptr; ui = ui->next) { + if (bOnlyMe) { + USERINFO *ui = UM_FindUser(si, pszText); + if (ui == nullptr) + return FALSE; + + ui->iStatusEx = (bSetStatus) ? 1 : 0; + return TRUE; + } + + for (auto &ui : si->getUserList()) { if (!bOnlyMe) ui->iStatusEx = 0; @@ -845,9 +797,9 @@ static BOOL UM_SetStatusEx(USERINFO *pUserList, const wchar_t* pszText, int flag return TRUE; } -static USERINFO* UM_TakeStatus(USERINFO *pUserList, const wchar_t *pszUID, WORD status) +static USERINFO* UM_TakeStatus(SESSION_INFO *si, const wchar_t *pszUID, WORD status) { - USERINFO *ui = UM_FindUser(pUserList, pszUID); + USERINFO *ui = UM_FindUser(si, pszUID); if (ui == nullptr) return nullptr; @@ -855,13 +807,13 @@ static USERINFO* UM_TakeStatus(USERINFO *pUserList, const wchar_t *pszUID, WORD return ui; } -static wchar_t* UM_FindUserAutoComplete(USERINFO *pUserList, const wchar_t* pszOriginal, const wchar_t* pszCurrent) +static wchar_t* UM_FindUserAutoComplete(SESSION_INFO *si, const wchar_t* pszOriginal, const wchar_t* pszCurrent) { - if (!pUserList || !pszOriginal || !pszCurrent) + if (!si || !pszOriginal || !pszCurrent) return nullptr; wchar_t *pszName = nullptr; - for (USERINFO *ui = pUserList; ui != nullptr; ui = ui->next) + for (auto &ui : si->getUserList()) if (ui->pszNick && my_strstri(ui->pszNick, pszOriginal) == ui->pszNick) if (mir_wstrcmpi(ui->pszNick, pszCurrent) > 0 && (!pszName || mir_wstrcmpi(ui->pszNick, pszName) < 0)) pszName = ui->pszNick; @@ -869,42 +821,36 @@ static wchar_t* UM_FindUserAutoComplete(USERINFO *pUserList, const wchar_t* pszO return pszName; } -static BOOL UM_RemoveUser(USERINFO **ppUserList, const wchar_t *pszUID) +static BOOL UM_RemoveUser(SESSION_INFO *si, const wchar_t *pszUID) { - if (!ppUserList || !pszUID) + if (!si || !pszUID) return FALSE; - USERINFO *ui = *ppUserList, *pLast = nullptr; - while (ui != nullptr) { + auto &arUsers = si->getUserList(); + for (auto &ui : arUsers) { if (!mir_wstrcmpi(ui->pszUID, pszUID)) { - if (pLast == nullptr) - *ppUserList = ui->next; - else - pLast->next = ui->next; mir_free(ui->pszNick); mir_free(ui->pszUID); - mir_free(ui); + arUsers.remove(arUsers.indexOf(&ui)); return TRUE; } - pLast = ui; - ui = ui->next; } return FALSE; } -static BOOL UM_RemoveAll(USERINFO **ppUserList) +BOOL UM_RemoveAll(SESSION_INFO *si) { - if (!ppUserList) + if (!si) return FALSE; - while (*ppUserList != nullptr) { - USERINFO *pLast = ppUserList[0]->next; - mir_free(ppUserList[0]->pszUID); - mir_free(ppUserList[0]->pszNick); - mir_free(*ppUserList); - *ppUserList = pLast; + if (!si->pMI->bSharedUsers) { + auto &arUsers = si->getUserList(); + for (auto &ui : arUsers) { + mir_free(ui->pszUID); + mir_free(ui->pszNick); + } + arUsers.destroy(); } - *ppUserList = nullptr; return TRUE; } @@ -983,7 +929,7 @@ MIR_APP_DLL(CHAT_MANAGER*) Chat_CustomizeApi(const CHAT_MANAGER_INITDATA *pInit) mir_cslock lck(csChat); for (auto &p : g_arSessions) { - SESSION_INFO *p1 = (SESSION_INFO*)mir_realloc(p, pInit->cbSession); + SESSION_INFO *p1 = (SESSION_INFO*)realloc(p, pInit->cbSession); memset(PBYTE(p1) + sizeof(GCSessionInfoBase), 0, pInit->cbSession - sizeof(GCSessionInfoBase)); if (p1 != p) { // realloc could change a pointer, reinsert a structure g_arSessions.remove(p); @@ -995,7 +941,7 @@ MIR_APP_DLL(CHAT_MANAGER*) Chat_CustomizeApi(const CHAT_MANAGER_INITDATA *pInit) mir_cslock lck(csChat); for (auto &mi : g_arModules) { - MODULEINFO *p1 = (MODULEINFO*)mir_realloc(mi, pInit->cbModuleInfo); + MODULEINFO *p1 = (MODULEINFO*)realloc(mi, pInit->cbModuleInfo); memset(PBYTE(p1) + sizeof(GCModuleInfoBase), 0, pInit->cbModuleInfo - sizeof(GCModuleInfoBase)); if (p1 != mi) { // realloc could change a pointer, reinsert a structure g_arModules.remove(mi); @@ -1013,6 +959,7 @@ MIR_APP_DLL(CHAT_MANAGER*) Chat_CustomizeApi(const CHAT_MANAGER_INITDATA *pInit) g_chatApi.SetActiveSession = SetActiveSession; g_chatApi.GetActiveSession = GetActiveSession; + g_chatApi.SM_CreateSession = SM_CreateSession; g_chatApi.SM_FindSession = SM_FindSession; g_chatApi.SM_GetStatusIcon = SM_GetStatusIcon; g_chatApi.SM_BroadcastMessage = SM_BroadcastMessage; @@ -1024,7 +971,7 @@ MIR_APP_DLL(CHAT_MANAGER*) Chat_CustomizeApi(const CHAT_MANAGER_INITDATA *pInit) g_chatApi.SM_GetUserFromIndex = SM_GetUserFromIndex; g_chatApi.SM_InvalidateLogDirectories = SM_InvalidateLogDirectories; - g_chatApi.MM_AddModule = MM_AddModule; + g_chatApi.MM_CreateModule = MM_CreateModule; g_chatApi.MM_FindModule = MM_FindModule; g_chatApi.MM_FontsChanged = MM_FontsChanged; g_chatApi.MM_IconsChanged = MM_IconsChanged; @@ -1034,9 +981,8 @@ MIR_APP_DLL(CHAT_MANAGER*) Chat_CustomizeApi(const CHAT_MANAGER_INITDATA *pInit) g_chatApi.TM_WordToString = TM_WordToString; g_chatApi.TM_RemoveAll = TM_RemoveAll; - g_chatApi.UM_SetStatusEx = UM_SetStatusEx; g_chatApi.UM_AddUser = UM_AddUser; - g_chatApi.UM_SortUser = UM_SortUser; + g_chatApi.UM_CompareItem = UM_CompareItem; g_chatApi.UM_FindUser = UM_FindUser; g_chatApi.UM_FindUserFromIndex = UM_FindUserFromIndex; g_chatApi.UM_GiveStatus = UM_GiveStatus; @@ -1044,8 +990,6 @@ MIR_APP_DLL(CHAT_MANAGER*) Chat_CustomizeApi(const CHAT_MANAGER_INITDATA *pInit) g_chatApi.UM_TakeStatus = UM_TakeStatus; g_chatApi.UM_FindUserAutoComplete = UM_FindUserAutoComplete; g_chatApi.UM_RemoveUser = UM_RemoveUser; - g_chatApi.UM_RemoveAll = UM_RemoveAll; - g_chatApi.UM_CompareItem = UM_CompareItem; g_chatApi.LM_AddEvent = LM_AddEvent; g_chatApi.LM_TrimLog = LM_TrimLog; diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index db9a72be2d..c9e20939c5 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -142,7 +142,7 @@ EXTERN_C MIR_APP_DLL(int) Chat_GetInfo(GC_INFO *gci) if (gci->Flags & GCF_DATA) gci->pItemData = si->pItemData; if (gci->Flags & GCF_HCONTACT) gci->hContact = si->hContact; if (gci->Flags & GCF_TYPE) gci->iType = si->iType; - if (gci->Flags & GCF_COUNT) gci->iCount = si->nUsersInNicklist; + if (gci->Flags & GCF_COUNT) gci->iCount = si->getUserList().getCount(); if (gci->Flags & GCF_USERS) gci->pszUsers = SM_GetUsers(si); if (gci->Flags & GCF_ID) gci->pszID = si->ptszID; if (gci->Flags & GCF_NAME) gci->pszName = si->ptszName; @@ -158,7 +158,7 @@ MIR_APP_DLL(int) Chat_Register(const GCREGISTER *gcr) return GC_ERROR; mir_cslock lck(csChat); - MODULEINFO *mi = g_chatApi.MM_AddModule(gcr->pszModule); + MODULEINFO *mi = MM_AddModule(gcr->pszModule); if (mi == nullptr) return GC_ERROR; @@ -170,6 +170,7 @@ MIR_APP_DLL(int) Chat_Register(const GCREGISTER *gcr) mi->bBkgColor = (gcr->dwFlags & GC_BKGCOLOR) != 0; mi->bAckMsg = (gcr->dwFlags & GC_ACKMSG) != 0; mi->bChanMgr = (gcr->dwFlags & GC_CHANMGR) != 0; + mi->bSharedUsers = (gcr->dwFlags & GC_SHAREDUSERS) != 0; mi->iMaxText = gcr->iMaxText; mi->pszHeader = g_chatApi.Log_CreateRtfHeader(); @@ -195,12 +196,11 @@ EXTERN_C MIR_APP_DLL(GCSessionInfoBase*) Chat_NewSession( // try to restart a session first SESSION_INFO *si = SM_FindSession(ptszID, pszModule); if (si != nullptr) { - g_chatApi.UM_RemoveAll(&si->pUsers); + UM_RemoveAll(si); g_chatApi.TM_RemoveAll(&si->pStatuses); lck.unlock(); si->iStatusCount = 0; - si->nUsersInNicklist = 0; si->pMe = nullptr; if (g_chatApi.OnReplaceSession) @@ -209,9 +209,10 @@ EXTERN_C MIR_APP_DLL(GCSessionInfoBase*) Chat_NewSession( } // create a new session - si = (SESSION_INFO*)mir_calloc(g_cbSession); + si = g_chatApi.SM_CreateSession(); si->ptszID = mir_wstrdup(ptszID); si->pszModule = mir_strdup(pszModule); + si->pMI = mi; g_chatApi.arSessions.insert(si); lck.unlock(); @@ -369,11 +370,10 @@ static void AddUser(GCEVENT *gce) WORD status = TM_StringToWord(si->pStatuses, gce->ptszStatus); - USERINFO *ui = g_chatApi.UM_AddUser(si->pStatuses, &si->pUsers, gce->ptszUID, gce->ptszNick, status); + USERINFO *ui = g_chatApi.UM_AddUser(si->pStatuses, si, gce->ptszUID, gce->ptszNick, status); if (ui == nullptr) return; - si->nUsersInNicklist++; if (g_chatApi.OnAddUser) g_chatApi.OnAddUser(si, ui); @@ -398,7 +398,7 @@ static BOOL AddEventToAllMatchingUID(GCEVENT *gce) if (!si->bInitDone || mir_strcmpi(si->pszModule, gce->pszModule)) continue; - if (!g_chatApi.UM_FindUser(si->pUsers, gce->ptszUID)) + if (!g_chatApi.UM_FindUser(si, gce->ptszUID)) continue; if (g_chatApi.OnEventBroadcast) @@ -533,7 +533,7 @@ static INT_PTR CALLBACK sttEventStub(void *_param) if (si && (si->bInitDone || gce->iType == GC_EVENT_TOPIC || (gce->iType == GC_EVENT_JOIN && gce->bIsMe))) { if (gce->ptszNick == nullptr && gce->ptszUID != nullptr) { - USERINFO *ui = g_chatApi.UM_FindUser(si->pUsers, gce->ptszUID); + USERINFO *ui = g_chatApi.UM_FindUser(si, gce->ptszUID); if (ui != nullptr) gce->ptszNick = ui->pszNick; } @@ -625,7 +625,7 @@ MIR_APP_DLL(int) Chat_ChangeUserId(const char *szModule, const wchar_t *wszId, c if ((wszId && mir_wstrcmpi(si->ptszID, wszId)) || mir_strcmpi(si->pszModule, szModule)) continue; - USERINFO *ui = g_chatApi.UM_FindUser(si->pUsers, wszOldId); + USERINFO *ui = g_chatApi.UM_FindUser(si, wszOldId); if (ui) replaceStrW(ui->pszUID, wszNewId); if (wszId) @@ -691,7 +691,7 @@ MIR_APP_DLL(int) Chat_SetStatusEx(const char *szModule, const wchar_t *wszId, in if ((wszId && mir_wstrcmpi(si->ptszID, wszId)) || mir_strcmpi(si->pszModule, szModule)) continue; - g_chatApi.UM_SetStatusEx(si->pUsers, wszText, flags); + UM_SetStatusEx(si, wszText, flags); if (si->pDlg) RedrawWindow(GetDlgItem(si->pDlg->GetHwnd(), IDC_LIST), nullptr, nullptr, RDW_INVALIDATE); if (wszId) diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 1ebcb18629..25c27789a7 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -661,3 +661,8 @@ g_hevEventEdited @693 NONAME g_hevEventFiltered @694 NONAME g_hevMarkedRead @695 NONAME g_hevSettingChanged @696 NONAME +??0GCModuleInfoBase@@QAE@XZ @697 NONAME +??0GCSessionInfoBase@@QAE@XZ @698 NONAME +??1GCModuleInfoBase@@QAE@XZ @699 NONAME +??1GCSessionInfoBase@@QAE@XZ @700 NONAME +?getUserList@GCSessionInfoBase@@QAEAAU?$OBJLIST@UUSERINFO@@@@XZ @701 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 5b9ec3aaf3..3c09b922e7 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -661,3 +661,8 @@ g_hevEventEdited @693 NONAME g_hevEventFiltered @694 NONAME g_hevMarkedRead @695 NONAME g_hevSettingChanged @696 NONAME +??0GCModuleInfoBase@@QEAA@XZ @697 NONAME +??0GCSessionInfoBase@@QEAA@XZ @698 NONAME +??1GCModuleInfoBase@@QEAA@XZ @699 NONAME +??1GCSessionInfoBase@@QEAA@XZ @700 NONAME +?getUserList@GCSessionInfoBase@@QEAAAEAU?$OBJLIST@UUSERINFO@@@@XZ @701 NONAME diff --git a/src/mir_app/src/srmm_base.cpp b/src/mir_app/src/srmm_base.cpp index 923b34f58f..7c3a8ef9d4 100644 --- a/src/mir_app/src/srmm_base.cpp +++ b/src/mir_app/src/srmm_base.cpp @@ -66,16 +66,13 @@ CSrmmBaseDialog::CSrmmBaseDialog(CMPluginBase &pPlugin, int idDialog, SESSION_IN if (si) { m_hContact = si->hContact; - MODULEINFO *mi = g_chatApi.MM_FindModule(si->pszModule); - if (mi != nullptr) { - if (mi->bColor) { - m_iFG = 4; - m_bFGSet = true; - } - if (mi->bBkgColor) { - m_iBG = 2; - m_bBGSet = true; - } + if (si->pMI->bColor) { + m_iFG = 4; + m_bFGSet = true; + } + if (si->pMI->bBkgColor) { + m_iBG = 2; + m_bBGSet = true; } } } @@ -578,8 +575,10 @@ LRESULT CSrmmBaseDialog::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam if (dc == nullptr) break; + int nUsers = m_si->getUserList().getCount(); + int index = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); - if (index == LB_ERR || m_si->nUsersInNicklist <= 0) + if (index == LB_ERR || nUsers <= 0) break; int height = m_nickList.SendMsg(LB_GETITEMHEIGHT, 0, 0); @@ -588,7 +587,7 @@ LRESULT CSrmmBaseDialog::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam GetClientRect(m_nickList.GetHwnd(), &rc); - int items = m_si->nUsersInNicklist - index; + int items = nUsers - index; if (rc.bottom - rc.top > items * height) { rc.top = items * height; FillRect(dc, &rc, g_chatApi.hListBkgBrush); @@ -851,12 +850,10 @@ void CSrmmBaseDialog::onClick_History(CCtrlButton *pButton) if (!pButton->Enabled()) return; - if (m_si != nullptr) { - MODULEINFO *pInfo = g_chatApi.MM_FindModule(m_si->pszModule); - if (pInfo) - ShellExecute(m_hwnd, nullptr, g_chatApi.GetChatLogsFilename(m_si, 0), nullptr, nullptr, SW_SHOW); - } - else CallService(MS_HISTORY_SHOWCONTACTHISTORY, m_hContact, 0); + if (m_si != nullptr) + ShellExecute(m_hwnd, nullptr, g_chatApi.GetChatLogsFilename(m_si, 0), nullptr, nullptr, SW_SHOW); + else + CallService(MS_HISTORY_SHOWCONTACTHISTORY, m_hContact, 0); } void CSrmmBaseDialog::onClick_ChanMgr(CCtrlButton *pButton) @@ -873,7 +870,7 @@ void CSrmmBaseDialog::onDblClick_List(CCtrlListBox *pList) ScreenToClient(pList->GetHwnd(), &hti.pt); int item = LOWORD(pList->SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y))); - USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si->pUsers, item); + USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, item); if (ui == nullptr) return; @@ -975,11 +972,7 @@ void CSrmmBaseDialog::RefreshButtonStatus(void) cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_BACKCOLOR | CFM_COLOR; m_message.SendMsg(EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); - MODULEINFO *mi = g_chatApi.MM_FindModule(m_si->pszModule); - if (mi == nullptr) - return; - - if (mi->bColor) { + if (m_si->pMI->bColor) { bool bState = m_btnColor.IsPushed(); if (!bState && cf.crTextColor != m_clrInputFG) m_btnColor.Push(true); @@ -987,7 +980,7 @@ void CSrmmBaseDialog::RefreshButtonStatus(void) m_btnColor.Push(false); } - if (mi->bBkgColor) { + if (m_si->pMI->bBkgColor) { bool bState = m_btnBkColor.IsPushed(); if (!bState && cf.crBackColor != m_clrInputBG) m_btnBkColor.Push(true); @@ -995,7 +988,7 @@ void CSrmmBaseDialog::RefreshButtonStatus(void) m_btnBkColor.Push(false); } - if (mi->bBold) { + if (m_si->pMI->bBold) { bool bState = m_btnBold.IsPushed(); UINT u2 = cf.dwEffects & CFE_BOLD; if (!bState && u2 != 0) @@ -1004,7 +997,7 @@ void CSrmmBaseDialog::RefreshButtonStatus(void) m_btnBold.Push(false); } - if (mi->bItalics) { + if (m_si->pMI->bItalics) { bool bState = m_btnItalic.IsPushed(); UINT u2 = cf.dwEffects & CFE_ITALIC; if (!bState && u2 != 0) @@ -1013,7 +1006,7 @@ void CSrmmBaseDialog::RefreshButtonStatus(void) m_btnItalic.Push(false); } - if (mi->bUnderline) { + if (m_si->pMI->bUnderline) { bool bState = m_btnUnderline.IsPushed(); UINT u2 = cf.dwEffects & CFE_UNDERLINE; if (!bState && u2 != 0) -- cgit v1.2.3