From 899221e2d058f5afe30bb2ecdbf168c8ad3c15a6 Mon Sep 17 00:00:00 2001
From: George Hazan <ghazan@miranda.im>
Date: Fri, 27 Jan 2023 19:48:42 +0300
Subject: Group chats: all old APIs with lookup by module+session removed

---
 src/mir_app/src/chat.h           |  16 +--
 src/mir_app/src/chat_clist.cpp   |   2 +-
 src/mir_app/src/chat_manager.cpp |  80 ++++++--------
 src/mir_app/src/chat_svc.cpp     | 228 +++++++++++++++++++--------------------
 src/mir_app/src/mir_app.def      |  33 +++---
 src/mir_app/src/mir_app64.def    |  33 +++---
 src/mir_app/src/proto_utils.cpp  |   2 +-
 7 files changed, 194 insertions(+), 200 deletions(-)

(limited to 'src')

diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h
index 9e7a7f731f..b8580e1b51 100644
--- a/src/mir_app/src/chat.h
+++ b/src/mir_app/src/chat.h
@@ -66,20 +66,20 @@ char*         Log_SetStyle(int style);
 MODULEINFO*   MM_AddModule(const char *pszModule);
 MODULEINFO*   MM_FindModule(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);
+BOOL          SM_AddEvent(SESSION_INFO *si, GCEVENT *gce, bool bIsHighlighted);
+BOOL          SM_ChangeNick(SESSION_INFO *si, 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_GiveStatus(SESSION_INFO *si, 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, uint16_t wStatus);
+int           SM_RemoveModule(const char *pszModule, bool removeContact);
+int           SM_RemoveSession(SESSION_INFO *si, bool removeContact);
+BOOL          SM_RemoveUser(SESSION_INFO *si, const wchar_t *pszUID);
+BOOL          SM_SetContactStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t 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);
+BOOL          SM_TakeStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszStatus);
 BOOL          SM_UserTyping(GCEVENT* gce);
 
-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);
diff --git a/src/mir_app/src/chat_clist.cpp b/src/mir_app/src/chat_clist.cpp
index 85b56632c7..3981986acd 100644
--- a/src/mir_app/src/chat_clist.cpp
+++ b/src/mir_app/src/chat_clist.cpp
@@ -127,7 +127,7 @@ int RoomDoubleclicked(WPARAM hContact, LPARAM)
 	if (roomid == nullptr)
 		return 0;
 
-	SESSION_INFO *si = SM_FindSession(roomid, szProto);
+	SESSION_INFO *si = Chat_Find(roomid, szProto);
 	if (si) {
 		if (si->pDlg != nullptr && !g_clistApi.pfnGetEvent(hContact, 0) && IsWindowVisible(si->pDlg->GetHwnd()) && !IsIconic(si->pDlg->GetHwnd())) {
 			si->pDlg->CloseTab();
diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp
index 39d2ea158c..608e1bedac 100644
--- a/src/mir_app/src/chat_manager.cpp
+++ b/src/mir_app/src/chat_manager.cpp
@@ -67,7 +67,7 @@ static void SetActiveSession(SESSION_INFO *si)
 
 static SESSION_INFO* GetActiveSession(void)
 {
-	SESSION_INFO *si = SM_FindSession(g_chatApi.szActiveWndID, g_chatApi.szActiveWndModule);
+	SESSION_INFO *si = Chat_Find(g_chatApi.szActiveWndID, g_chatApi.szActiveWndModule);
 	if (si)
 		return si;
 
@@ -220,21 +220,11 @@ static void SM_FreeSession(SESSION_INFO *si, bool bRemoveContact = false)
 	delete si;
 }
 
-int SM_RemoveSession(const wchar_t *pszID, const char *pszModule, bool removeContact)
+int SM_RemoveModule(const char *pszModule, bool removeContact)
 {
 	if (pszModule == nullptr)
 		return FALSE;
 
-	if (pszID != nullptr) {
-		SESSION_INFO *si = SM_FindSession(pszID, pszModule);
-		if (si == nullptr)
-			return FALSE;
-
-		g_arSessions.remove(si);
-		SM_FreeSession(si, removeContact);
-		return TRUE;
-	}
-
 	auto T = g_arSessions.rev_iter();
 	for (auto &si : T) {
 		if (si->iType != GCW_SERVER && !mir_strcmpi(si->pszModule, pszModule)) {
@@ -242,10 +232,21 @@ int SM_RemoveSession(const wchar_t *pszID, const char *pszModule, bool removeCon
 			g_arSessions.removeItem(&si);
 		}
 	}
+
+	return TRUE;
+}
+
+int SM_RemoveSession(SESSION_INFO *si, bool removeContact)
+{
+	if (si == nullptr)
+		return FALSE;
+
+	g_arSessions.remove(si);
+	SM_FreeSession(si, removeContact);
 	return TRUE;
 }
 
-SESSION_INFO* SM_FindSession(const wchar_t *pszID, const char *pszModule)
+MIR_APP_DLL(SESSION_INFO*) Chat_Find(const wchar_t *pszID, const char *pszModule)
 {
 	if (!pszID || !pszModule)
 		return nullptr;
@@ -293,9 +294,8 @@ static HICON SM_GetStatusIcon(SESSION_INFO *si, USERINFO *ui)
 	return g_chatApi.hStatusIcons[0];
 }
 
-BOOL SM_AddEvent(const wchar_t *pszID, const char *pszModule, GCEVENT *gce, bool bIsHighlighted)
+BOOL SM_AddEvent(SESSION_INFO *si, GCEVENT *gce, bool bIsHighlighted)
 {
-	SESSION_INFO *si = SM_FindSession(pszID, pszModule);
 	if (si == nullptr)
 		return TRUE;
 
@@ -321,13 +321,13 @@ BOOL SM_AddEvent(const wchar_t *pszID, const char *pszModule, GCEVENT *gce, bool
 	return TRUE;
 }
 
-BOOL SM_RemoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID)
+BOOL SM_RemoveUser(SESSION_INFO *pSI, const wchar_t *pszUID)
 {
-	if (!pszModule || !pszUID)
+	if (!pSI || !pszUID)
 		return FALSE;
 
 	for (auto &si : g_arSessions) {
-		if ((pszID && mir_wstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule))
+		if (si != pSI || mir_strcmpi(si->pszModule, pSI->pszModule))
 			continue;
 
 		USERINFO *ui = UM_FindUser(si, pszUID);
@@ -342,7 +342,7 @@ BOOL SM_RemoveUser(const wchar_t *pszID, const char *pszModule, const wchar_t *p
 			if (si->pDlg)
 				si->pDlg->UpdateNickList();
 
-			if (pszID)
+			// !!!!!!!!!! if (pszID)
 				return TRUE;
 		}
 	}
@@ -352,13 +352,12 @@ 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);
+	SESSION_INFO *si = Chat_Find(pszID, pszModule);
 	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)
+BOOL SM_GiveStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszStatus)
 {
-	SESSION_INFO *si = SM_FindSession(pszID, pszModule);
 	if (si == nullptr)
 		return FALSE;
 	
@@ -371,9 +370,8 @@ BOOL SM_GiveStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *p
 	return TRUE;
 }
 
-BOOL SM_SetContactStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, uint16_t wStatus)
+BOOL SM_SetContactStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t wStatus)
 {
-	SESSION_INFO *si = SM_FindSession(pszID, pszModule);
 	if (si == nullptr)
 		return FALSE;
 
@@ -386,9 +384,8 @@ BOOL SM_SetContactStatus(const wchar_t *pszID, const char *pszModule, const wcha
 	return TRUE;
 }
 
-BOOL SM_TakeStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, const wchar_t *pszStatus)
+BOOL SM_TakeStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszStatus)
 {
-	SESSION_INFO *si = SM_FindSession(pszID, pszModule);
 	if (si == nullptr)
 		return FALSE;
 
@@ -426,7 +423,7 @@ BOOL SM_SetStatus(const char *pszModule, SESSION_INFO *si, int wStatus)
 
 BOOL SM_UserTyping(GCEVENT *gce)
 {
-	SESSION_INFO *si = SM_FindSession(gce->pszID.w, gce->pszModule);
+	SESSION_INFO *si = gce->si;
 	if (si == nullptr || si->pDlg == nullptr)
 		return FALSE;
 
@@ -438,27 +435,21 @@ BOOL SM_UserTyping(GCEVENT *gce)
 	return TRUE;
 }
 
-BOOL SM_ChangeNick(const wchar_t *pszID, const char *pszModule, GCEVENT *gce)
+BOOL SM_ChangeNick(SESSION_INFO *si, GCEVENT *gce)
 {
-	if (!pszModule)
+	if (!si)
 		return FALSE;
 
-	for (auto &si : g_arSessions) {
-		if ((!pszID || !mir_wstrcmpi(si->ptszID, pszID)) && !mir_strcmpi(si->pszModule, pszModule)) {
-			USERINFO *ui = UM_FindUser(si, gce->pszUID.w);
-			if (ui) {
-				replaceStrW(ui->pszNick, gce->pszText.w);
-				UM_SortUser(si);
-				if (si->pDlg)
-					si->pDlg->UpdateNickList();
-				if (g_chatApi.OnChangeNick)
-					g_chatApi.OnChangeNick(si);
-			}
-
-			if (pszID)
-				return TRUE;
-		}
+	USERINFO *ui = UM_FindUser(si, gce->pszUID.w);
+	if (ui) {
+		replaceStrW(ui->pszNick, gce->pszText.w);
+		UM_SortUser(si);
+		if (si->pDlg)
+			si->pDlg->UpdateNickList();
+		if (g_chatApi.OnChangeNick)
+			g_chatApi.OnChangeNick(si);
 	}
+
 	return TRUE;
 }
 
@@ -905,7 +896,6 @@ static void ResetApi()
 	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_GetCount = ::SM_GetCount;
 	g_chatApi.SM_FindSessionByIndex = ::SM_FindSessionByIndex;
diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp
index 4544f8f550..d4462ec3d2 100644
--- a/src/mir_app/src/chat_svc.cpp
+++ b/src/mir_app/src/chat_svc.cpp
@@ -146,7 +146,7 @@ static int SmileyOptionsChanged(WPARAM, LPARAM)
 /////////////////////////////////////////////////////////////////////////////////////////
 // retrieveing chat info
 
-EXTERN_C MIR_APP_DLL(int) Chat_GetInfo(GC_INFO *gci)
+MIR_APP_DLL(int) Chat_GetInfo(GC_INFO *gci)
 {
 	if (!gci || !gci->pszModule)
 		return 1;
@@ -155,7 +155,7 @@ EXTERN_C MIR_APP_DLL(int) Chat_GetInfo(GC_INFO *gci)
 	if (gci->Flags & GCF_BYINDEX)
 		si = SM_FindSessionByIndex(gci->pszModule, gci->iItem);
 	else
-		si = SM_FindSession(gci->pszID, gci->pszModule);
+		si = Chat_Find(gci->pszID, gci->pszModule);
 	if (si == nullptr)
 		return 1;
 
@@ -201,7 +201,7 @@ MIR_APP_DLL(int) Chat_Register(const GCREGISTER *gcr)
 /////////////////////////////////////////////////////////////////////////////////////////
 // starts new chat session
 
-EXTERN_C MIR_APP_DLL(SESSION_INFO*) Chat_NewSession(
+MIR_APP_DLL(SESSION_INFO*) Chat_NewSession(
 	int            iType,      // Use one of the GCW_* flags above to set the type of session
 	const char    *pszModule,  // The name of the protocol owning the session (the same as pszModule when you register)
 	const wchar_t *ptszID,     // The unique identifier for the session.
@@ -214,7 +214,7 @@ EXTERN_C MIR_APP_DLL(SESSION_INFO*) Chat_NewSession(
 		return nullptr;
 
 	// try to restart a session first
-	SESSION_INFO *si = SM_FindSession(ptszID, pszModule);
+	SESSION_INFO *si = Chat_Find(ptszID, pszModule);
 	if (si != nullptr) {
 		UM_RemoveAll(si);
 		g_chatApi.TM_RemoveAll(&si->pStatuses);
@@ -268,8 +268,7 @@ EXTERN_C MIR_APP_DLL(SESSION_INFO*) Chat_NewSession(
 
 struct ChatConrolParam
 {
-	const char *szModule;
-	const wchar_t *wszId;
+	SESSION_INFO *si;
 	int command;
 };
 
@@ -289,35 +288,26 @@ static INT_PTR __stdcall stubRoomControl(void *param)
 	ChatConrolParam *p = (ChatConrolParam*)param;
 
 	mir_cslock lck(csChat);
-	SESSION_INFO *si = nullptr;
-	if (p->szModule)
-		si = SM_FindSession(p->wszId, p->szModule);
+	SESSION_INFO *si = g_arSessions.find(p->si);
+	if (si == nullptr)
+		return GC_EVENT_ERROR;
 
 	switch (p->command) {
 	case WINDOW_HIDDEN:
-		if (si == nullptr)
-			return GC_EVENT_ERROR;
-
 		SetInitDone(si);
 		g_chatApi.SetActiveSession(si);
 		break;
 
 	case WINDOW_VISIBLE:
 	case SESSION_INITDONE:
-		if (si == nullptr)
-			return GC_EVENT_ERROR;
-
 		SetInitDone(si);
 		if (p->command != SESSION_INITDONE || !Chat::bPopupOnJoin)
 			g_chatApi.ShowRoom(si);
 		break;
 
 	case SESSION_OFFLINE:
-		if (si == nullptr && p->wszId != nullptr)
-			return GC_EVENT_ERROR;
-
-		SM_SetOffline(p->szModule, si);
-		SM_SetStatus(p->szModule, si, ID_STATUS_OFFLINE);
+		SM_SetOffline(si->pszModule, si);
+		SM_SetStatus(si->pszModule, si, ID_STATUS_OFFLINE);
 		if (si && si->pDlg) {
 			si->pDlg->UpdateStatusBar();
 			si->pDlg->UpdateNickList();
@@ -325,18 +315,12 @@ static INT_PTR __stdcall stubRoomControl(void *param)
 		break;
 
 	case SESSION_ONLINE:
-		if (si == nullptr && p->wszId != nullptr)
-			return GC_EVENT_ERROR;
-
-		SM_SetStatus(p->szModule, si, ID_STATUS_ONLINE);
+		SM_SetStatus(si->pszModule, si, ID_STATUS_ONLINE);
 		if (si && si->pDlg)
 			si->pDlg->UpdateStatusBar();
 		break;
 
 	case WINDOW_CLEARLOG:
-		if (si == nullptr)
-			return GC_EVENT_ERROR;
-
 		g_chatApi.LM_RemoveAll(&si->pLog, &si->pLogEnd);
 		si->iEventCount = 0;
 		si->LastTime = 0;
@@ -351,9 +335,9 @@ static INT_PTR __stdcall stubRoomControl(void *param)
 	return 0;
 }
 
-MIR_APP_DLL(int) Chat_Control(const char *szModule, const wchar_t *wszId, int iCommand)
+MIR_APP_DLL(int) Chat_Control(SESSION_INFO *si, int iCommand)
 {
-	ChatConrolParam param = { szModule, wszId, iCommand };
+	ChatConrolParam param = { si, iCommand };
 	return CallFunctionSync(stubRoomControl, &param);
 }
 
@@ -362,20 +346,31 @@ MIR_APP_DLL(int) Chat_Control(const char *szModule, const wchar_t *wszId, int iC
 
 struct ChatTerminateParam
 {
-	const char *szModule;
-	const wchar_t *wszId;
+	const char *pszModule;
+	SESSION_INFO *si;
 	bool bRemoveContact;
 };
 
 static INT_PTR __stdcall stubRoomTerminate(void *param)
 {
 	ChatTerminateParam *p = (ChatTerminateParam*)param;
-	return SM_RemoveSession(p->wszId, p->szModule, p->bRemoveContact);
+	if (p->si)
+		return SM_RemoveSession(p->si, p->bRemoveContact);
+	return SM_RemoveModule(p->pszModule, p->bRemoveContact);
+}
+
+MIR_APP_DLL(int) Chat_Terminate(const char *szModule, bool bRemoveContact)
+{
+	ChatTerminateParam param = { szModule, 0, bRemoveContact };
+	return CallFunctionSync(stubRoomTerminate, &param);
 }
 
-MIR_APP_DLL(int) Chat_Terminate(const char *szModule, const wchar_t *wszId, bool bRemoveContact)
+MIR_APP_DLL(int) Chat_Terminate(SESSION_INFO *si, bool bRemoveContact)
 {
-	ChatTerminateParam param = { szModule, wszId, bRemoveContact };
+	if (!g_arSessions.find(si))
+		return GC_EVENT_ERROR;
+
+	ChatTerminateParam param = { 0, si, bRemoveContact };
 	return CallFunctionSync(stubRoomTerminate, &param);
 }
 
@@ -384,7 +379,7 @@ MIR_APP_DLL(int) Chat_Terminate(const char *szModule, const wchar_t *wszId, bool
 
 static void AddUser(GCEVENT *gce)
 {
-	SESSION_INFO *si = SM_FindSession(gce->pszID.w, gce->pszModule);
+	SESSION_INFO *si = gce->si;
 	if (si == nullptr)
 		return;
 
@@ -414,7 +409,7 @@ static BOOL AddEventToAllMatchingUID(GCEVENT *gce)
 	int bManyFix = 0;
 
 	for (auto &si : g_arSessions) {
-		if (!si->bInitDone || mir_strcmpi(si->pszModule, gce->pszModule))
+		if (!si->bInitDone || mir_strcmpi(si->pszModule, gce->si->pszModule))
 			continue;
 
 		if (!g_chatApi.UM_FindUser(si, gce->pszUID.w))
@@ -424,7 +419,7 @@ static BOOL AddEventToAllMatchingUID(GCEVENT *gce)
 			g_chatApi.OnEventBroadcast(si, gce);
 
 		if (si->pDlg && si->bInitDone) {
-			if (SM_AddEvent(si->ptszID, si->pszModule, gce, FALSE))
+			if (SM_AddEvent(si, gce, FALSE))
 				si->pDlg->AddLog();
 			else
 				RedrawLog2(si);
@@ -447,7 +442,6 @@ static INT_PTR CALLBACK sttEventStub(void *_param)
 
 	GCEVENT gce = *(GCEVENT*)_param;
 	if (gce.dwFlags & GCEF_UTF8) {
-		gce.pszID.w = (wszId = mir_utf8decodeW(gce.pszID.a));
 		gce.pszUID.w = (wszUid = mir_utf8decodeW(gce.pszUID.a));
 		gce.pszNick.w = (wszNick = mir_utf8decodeW(gce.pszNick.a));
 		gce.pszText.w = (wszText = mir_utf8decodeW(gce.pszText.a));
@@ -464,10 +458,10 @@ static INT_PTR CALLBACK sttEventStub(void *_param)
 	// Do different things according to type of event
 	switch (gce.iType) {
 	case GC_EVENT_SETCONTACTSTATUS:
-		return SM_SetContactStatus(gce.pszID.w, gce.pszModule, gce.pszUID.w, (uint16_t)gce.dwItemData);
+		return SM_SetContactStatus(gce.si, gce.pszUID.w, (uint16_t)gce.dwItemData);
 
 	case GC_EVENT_TOPIC:
-		if (SESSION_INFO *si = SM_FindSession(gce.pszID.w, gce.pszModule)) {
+		if (SESSION_INFO *si = gce.si) {
 			wchar_t *pwszNew = RemoveFormatting(gce.pszText.w);
 			if (!mir_wstrcmp(si->ptszTopic, pwszNew)) // nothing changed? exiting
 				return 0;
@@ -491,25 +485,24 @@ static INT_PTR CALLBACK sttEventStub(void *_param)
 		break;
 
 	case GC_EVENT_ADDSTATUS:
-		SM_GiveStatus(gce.pszID.w, gce.pszModule, gce.pszUID.w, gce.pszStatus.w);
+		SM_GiveStatus(gce.si, gce.pszUID.w, gce.pszStatus.w);
 		bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce);
 		break;
 
 	case GC_EVENT_REMOVESTATUS:
-		SM_TakeStatus(gce.pszID.w, gce.pszModule, gce.pszUID.w, gce.pszStatus.w);
+		SM_TakeStatus(gce.si, gce.pszUID.w, gce.pszStatus.w);
 		bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce);
 		break;
 
 	case GC_EVENT_MESSAGE:
 	case GC_EVENT_ACTION:
-		if (!gce.bIsMe && gce.pszID.w && gce.pszText.w) {
-			SESSION_INFO *si = SM_FindSession(gce.pszID.w, gce.pszModule);
-			bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
+		if (!gce.bIsMe && gce.si && gce.pszText.w) {
+			bIsHighlighted = g_chatApi.IsHighlighted(gce.si, &gce);
 		}
 		break;
 
 	case GC_EVENT_NICK:
-		SM_ChangeNick(gce.pszID.w, gce.pszModule, &gce);
+		SM_ChangeNick(gce.si, &gce);
 		bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce);
 		break;
 
@@ -530,19 +523,14 @@ static INT_PTR CALLBACK sttEventStub(void *_param)
 	}
 
 	// Decide which window (log) should have the event
-	LPCTSTR pWnd = nullptr;
-	LPCSTR pMod = nullptr;
-	if (gce.pszID.w) {
-		pWnd = gce.pszID.w;
-		pMod = gce.pszModule;
+	SESSION_INFO *si = nullptr;
+	if (gce.si) {
+		si = gce.si;
 	}
 	else if (gce.iType == GC_EVENT_NOTICE || gce.iType == GC_EVENT_INFORMATION) {
-		SESSION_INFO *si = g_chatApi.GetActiveSession();
-		if (si && !mir_strcmp(si->pszModule, gce.pszModule)) {
-			pWnd = si->ptszID;
-			pMod = si->pszModule;
-		}
-		else return 0;
+		si = g_chatApi.GetActiveSession();
+		if (!si)
+			return 0;
 	}
 	else {
 		// Send the event to all windows with a user pszUID. Used for broadcasting QUIT etc
@@ -552,12 +540,10 @@ static INT_PTR CALLBACK sttEventStub(void *_param)
 	}
 
 	// add to log
-	if (pWnd) {
+	if (si) {
 		if (gce.dwFlags & GCEF_SILENT)
 			return 0;
 
-		SESSION_INFO *si = SM_FindSession(pWnd, pMod);
-
 		// fix for IRC's old style mode notifications. Should not affect any other protocol
 		if ((gce.iType == GC_EVENT_ADDSTATUS || gce.iType == GC_EVENT_REMOVESTATUS) && !(gce.dwFlags & GCEF_ADDTOLOG))
 			return 0;
@@ -572,7 +558,7 @@ static INT_PTR CALLBACK sttEventStub(void *_param)
 					gce.pszNick.w = ui->pszNick;
 			}
 
-			int isOk = SM_AddEvent(pWnd, pMod, &gce, bIsHighlighted);
+			int isOk = SM_AddEvent(si, &gce, bIsHighlighted);
 			if (si->pDlg) {
 				if (isOk)
 					si->pDlg->AddLog();
@@ -592,12 +578,12 @@ static INT_PTR CALLBACK sttEventStub(void *_param)
 	}
 
 	if (bRemoveFlag)
-		return SM_RemoveUser(gce.pszID.w, gce.pszModule, gce.pszUID.w) == 0;
+		return SM_RemoveUser(gce.si, gce.pszUID.w) == 0;
 
 	return GC_EVENT_ERROR;
 }
 
-EXTERN_C MIR_APP_DLL(int) Chat_Event(GCEVENT *gce)
+MIR_APP_DLL(int) Chat_Event(GCEVENT *gce)
 {
 	if (gce == nullptr)
 		return GC_EVENT_ERROR;
@@ -628,65 +614,59 @@ MIR_APP_DLL(int) Chat_AddGroup(SESSION_INFO *si, const wchar_t *wszText)
 	return 0;
 }
 
-MIR_APP_DLL(int) Chat_ChangeSessionName(const char *szModule, const wchar_t *wszId, const wchar_t *wszNewName)
+MIR_APP_DLL(int) Chat_ChangeSessionName(SESSION_INFO *si, const wchar_t *wszNewName)
 {
-	if (wszNewName == nullptr)
+	if (wszNewName == nullptr || si == nullptr)
 		return GC_EVENT_ERROR;
 
-	SESSION_INFO *si = SM_FindSession(wszId, szModule);
-	if (si != nullptr) {
-		// nothing really changed? exiting
-		if (!mir_wstrcmp(si->ptszName, wszNewName))
-			return 0;
+	// nothing really changed? exiting
+	if (!mir_wstrcmp(si->ptszName, wszNewName))
+		return 0;
 
-		replaceStrW(si->ptszName, wszNewName);
-		db_set_ws(si->hContact, szModule, "Nick", wszNewName);
-		if (si->pDlg)
-			si->pDlg->UpdateTitle();
-	}
+	replaceStrW(si->ptszName, wszNewName);
+	db_set_ws(si->hContact, si->pszModule, "Nick", wszNewName);
+	if (si->pDlg)
+		si->pDlg->UpdateTitle();
 	return 0;
 }
 
-MIR_APP_DLL(int) Chat_ChangeUserId(const char *szModule, const wchar_t *wszId, const wchar_t *wszOldId, const wchar_t *wszNewId)
+/////////////////////////////////////////////////////////////////////////////////////////
+
+MIR_APP_DLL(int) Chat_ChangeUserId(const char *szModule, const wchar_t *wszOldId, const wchar_t *wszNewId)
 {
 	if (szModule == nullptr || wszNewId == nullptr)
 		return GC_EVENT_ERROR;
-	
+
 	mir_cslock lck(csChat);
-	for (auto &si : g_arSessions) {
-		if ((wszId && mir_wstrcmpi(si->ptszID, wszId)) || mir_strcmpi(si->pszModule, szModule))
-			continue;
+	for (auto &si : g_arSessions)
+		if (!mir_strcmpi(si->pszModule, szModule))
+			Chat_ChangeUserId(si, wszOldId, wszNewId);
 
-		USERINFO *ui = g_chatApi.UM_FindUser(si, wszOldId);
-		if (ui) {
-			replaceStrW(ui->pszUID, wszNewId);
-			UM_SortKeys(si);
-		}
-		if (wszId)
-			break;
-	}
 	return 0;
 }
 
-MIR_APP_DLL(void*) Chat_GetUserInfo(const char *szModule, const wchar_t *wszId)
+MIR_APP_DLL(int) Chat_ChangeUserId(SESSION_INFO *si, const wchar_t *wszOldId, const wchar_t *wszNewId)
 {
-	if (SESSION_INFO *si = SM_FindSession(wszId, szModule))
-		return si->pItemData;
-	return nullptr;
+	if (wszNewId == nullptr)
+		return GC_EVENT_ERROR;
+
+	USERINFO *ui = g_chatApi.UM_FindUser(si, wszOldId);
+	if (ui) {
+		replaceStrW(ui->pszUID, wszNewId);
+		UM_SortKeys(si);
+	}
+	return 0;
 }
 
-MIR_APP_DLL(int) Chat_SendUserMessage(const char *szModule, const wchar_t *wszId, const wchar_t *wszText)
+MIR_APP_DLL(void*) Chat_GetUserInfo(SESSION_INFO *si)
 {
-	if (wszText == nullptr || szModule == nullptr)
-		return GC_EVENT_ERROR;
+	return (si) ? si->pItemData : nullptr;
+}
 
-	if (wszId != nullptr) {
-		SESSION_INFO *si = SM_FindSession(wszId, szModule);
-		if (si)
-			if (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS)
-				Chat_DoEventHook(si, GC_USER_MESSAGE, nullptr, wszText, 0);
-		return 0;
-	}
+MIR_APP_DLL(int) Chat_SendUserMessage(const char *szModule, const wchar_t *wszText)
+{
+	if (!szModule)
+		return 1;
 
 	mir_cslock lck(csChat);
 	for (auto &si : g_arSessions) {
@@ -699,9 +679,18 @@ MIR_APP_DLL(int) Chat_SendUserMessage(const char *szModule, const wchar_t *wszId
 	return 0;
 }
 
-MIR_APP_DLL(int) Chat_SetStatusbarText(const char *szModule, const wchar_t *wszId, const wchar_t *wszText)
+MIR_APP_DLL(int) Chat_SendUserMessage(SESSION_INFO *si, const wchar_t *wszText)
+{
+	if (wszText == nullptr || si == nullptr)
+		return GC_EVENT_ERROR;
+
+	if (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS)
+		Chat_DoEventHook(si, GC_USER_MESSAGE, nullptr, wszText, 0);
+	return 0;
+}
+
+MIR_APP_DLL(int) Chat_SetStatusbarText(SESSION_INFO *si, const wchar_t *wszText)
 {
-	SESSION_INFO *si = SM_FindSession(wszId, szModule);
 	if (si != nullptr) {
 		replaceStrW(si->ptszStatusbarText, wszText);
 		if (si->ptszStatusbarText)
@@ -715,28 +704,33 @@ MIR_APP_DLL(int) Chat_SetStatusbarText(const char *szModule, const wchar_t *wszI
 	return 0;
 }
 
-MIR_APP_DLL(int) Chat_SetStatusEx(const char *szModule, const wchar_t *wszId, int flags, const wchar_t *wszText)
+MIR_APP_DLL(int) Chat_SetStatusEx(SESSION_INFO *si, int flags, const wchar_t *wszText)
 {
-	if (!szModule)
+	if (!si)
 		return GC_EVENT_ERROR;
 
+	UM_SetStatusEx(si, wszText, flags);
+	if (si->pDlg)
+		RedrawWindow(GetDlgItem(si->pDlg->GetHwnd(), IDC_LIST), nullptr, nullptr, RDW_INVALIDATE);
+	return 0;
+}
+
+MIR_APP_DLL(int) Chat_SetStatusEx(const char *szModule, int flags, const wchar_t *wszText)
+{
+	if (!szModule)
+		return 1;
+
 	mir_cslock lck(csChat);
-	for (auto &si : g_arSessions) {
-		if ((wszId && mir_wstrcmpi(si->ptszID, wszId)) || mir_strcmpi(si->pszModule, szModule))
-			continue;
+	for (auto &si : g_arSessions)
+		if (!mir_strcmpi(si->pszModule, szModule))
+			Chat_SetStatusEx(si, flags, wszText);
 
-		UM_SetStatusEx(si, wszText, flags);
-		if (si->pDlg)
-			RedrawWindow(GetDlgItem(si->pDlg->GetHwnd(), IDC_LIST), nullptr, nullptr, RDW_INVALIDATE);
-		if (wszId)
-			break;
-	}
 	return 0;
 }
 
-MIR_APP_DLL(int) Chat_SetUserInfo(const char *szModule, const wchar_t *wszId, void *pItemData)
+MIR_APP_DLL(int) Chat_SetUserInfo(SESSION_INFO *si, void *pItemData)
 {
-	if (SESSION_INFO *si = g_chatApi.SM_FindSession(wszId, szModule)) {
+	if (si) {
 		si->pItemData = pItemData;
 		return 0;
 	}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index cc94a44a7c..bae7600aec 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -219,20 +219,6 @@ Chat_GetDefaultEventDescr @295
 FindDatabasePlugin @296
 RegisterDatabasePlugin @298
 Chat_CustomizeApi @299
-Chat_Event @300 
-Chat_GetInfo @301 
-Chat_NewSession @302 
-Chat_Register @303 
-Chat_GetUserInfo @304
-Chat_SetUserInfo @305
-Chat_ChangeUserId @306
-Chat_ChangeSessionName @307
-Chat_SetStatusbarText @308
-Chat_SendUserMessage @309
-Chat_SetStatusEx @310
-Chat_Terminate @311
-Chat_AddGroup @312
-Chat_Control @313
 Clist_FindItem @314
 Colour_Get @315
 Colour_GetW @316
@@ -811,3 +797,22 @@ Srmm_CreateHotkey @886 NONAME
 ?getBlob@PROTO_INTERFACE@@QAE?AVMBinBuffer@@PBD@Z @912 NONAME
 ?UpdateEventId@MDatabaseReadonly@@UAGHIPBD@Z @913 NONAME
 ?GetAvatarPath@PROTO_INTERFACE@@QBE?AV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@XZ @914 NONAME
+?Chat_AddGroup@@YGHPAUSESSION_INFO@@PB_W@Z @915 NONAME
+?Chat_ChangeSessionName@@YGHPAUSESSION_INFO@@PB_W@Z @916 NONAME
+?Chat_ChangeUserId@@YGHPAUSESSION_INFO@@PB_W1@Z @917 NONAME
+?Chat_ChangeUserId@@YGHPBDPB_W1@Z @918 NONAME
+?Chat_Control@@YGHPAUSESSION_INFO@@H@Z @919 NONAME
+?Chat_Event@@YGHPAUGCEVENT@@@Z @920 NONAME
+?Chat_Find@@YGPAUSESSION_INFO@@PB_WPBD@Z @921 NONAME
+?Chat_GetInfo@@YGHPAUGC_INFO@@@Z @922 NONAME
+?Chat_GetUserInfo@@YGPAXPAUSESSION_INFO@@@Z @923 NONAME
+?Chat_NewSession@@YGPAUSESSION_INFO@@HPBDPB_W1PAX@Z @924 NONAME
+?Chat_Register@@YGHPBUGCREGISTER@@@Z @925 NONAME
+?Chat_SendUserMessage@@YGHPAUSESSION_INFO@@PB_W@Z @926 NONAME
+?Chat_SendUserMessage@@YGHPBDPB_W@Z @927 NONAME
+?Chat_SetStatusEx@@YGHPAUSESSION_INFO@@HPB_W@Z @928 NONAME
+?Chat_SetStatusEx@@YGHPBDHPB_W@Z @929 NONAME
+?Chat_SetStatusbarText@@YGHPAUSESSION_INFO@@PB_W@Z @930 NONAME
+?Chat_SetUserInfo@@YGHPAUSESSION_INFO@@PAX@Z @931 NONAME
+?Chat_Terminate@@YGHPAUSESSION_INFO@@_N@Z @932 NONAME
+?Chat_Terminate@@YGHPBD_N@Z @933 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index 23413c088a..20cdf0907d 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -219,20 +219,6 @@ Chat_GetDefaultEventDescr @295
 FindDatabasePlugin @296
 RegisterDatabasePlugin @298
 Chat_CustomizeApi @299
-Chat_Event @300 
-Chat_GetInfo @301 
-Chat_NewSession @302 
-Chat_Register @303 
-Chat_GetUserInfo @304
-Chat_SetUserInfo @305
-Chat_ChangeUserId @306
-Chat_ChangeSessionName @307
-Chat_SetStatusbarText @308
-Chat_SendUserMessage @309
-Chat_SetStatusEx @310
-Chat_Terminate @311
-Chat_AddGroup @312
-Chat_Control @313
 Clist_FindItem @314
 Colour_Get @315
 Colour_GetW @316
@@ -811,3 +797,22 @@ Srmm_CreateHotkey @886 NONAME
 ?getBlob@PROTO_INTERFACE@@QEAA?AVMBinBuffer@@PEBD@Z @912 NONAME
 ?UpdateEventId@MDatabaseReadonly@@UEAAHIPEBD@Z @913 NONAME
 ?GetAvatarPath@PROTO_INTERFACE@@QEBA?AV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@XZ @914 NONAME
+?Chat_AddGroup@@YAHPEAUSESSION_INFO@@PEB_W@Z @915 NONAME
+?Chat_ChangeSessionName@@YAHPEAUSESSION_INFO@@PEB_W@Z @916 NONAME
+?Chat_ChangeUserId@@YAHPEAUSESSION_INFO@@PEB_W1@Z @917 NONAME
+?Chat_ChangeUserId@@YAHPEBDPEB_W1@Z @918 NONAME
+?Chat_Control@@YAHPEAUSESSION_INFO@@H@Z @919 NONAME
+?Chat_Event@@YAHPEAUGCEVENT@@@Z @920 NONAME
+?Chat_Find@@YAPEAUSESSION_INFO@@PEB_WPEBD@Z @921 NONAME
+?Chat_GetInfo@@YAHPEAUGC_INFO@@@Z @922 NONAME
+?Chat_GetUserInfo@@YAPEAXPEAUSESSION_INFO@@@Z @923 NONAME
+?Chat_NewSession@@YAPEAUSESSION_INFO@@HPEBDPEB_W1PEAX@Z @924 NONAME
+?Chat_Register@@YAHPEBUGCREGISTER@@@Z @925 NONAME
+?Chat_SendUserMessage@@YAHPEAUSESSION_INFO@@PEB_W@Z @926 NONAME
+?Chat_SendUserMessage@@YAHPEBDPEB_W@Z @927 NONAME
+?Chat_SetStatusEx@@YAHPEAUSESSION_INFO@@HPEB_W@Z @928 NONAME
+?Chat_SetStatusEx@@YAHPEBDHPEB_W@Z @929 NONAME
+?Chat_SetStatusbarText@@YAHPEAUSESSION_INFO@@PEB_W@Z @930 NONAME
+?Chat_SetUserInfo@@YAHPEAUSESSION_INFO@@PEAX@Z @931 NONAME
+?Chat_Terminate@@YAHPEAUSESSION_INFO@@_N@Z @932 NONAME
+?Chat_Terminate@@YAHPEBD_N@Z @933 NONAME
diff --git a/src/mir_app/src/proto_utils.cpp b/src/mir_app/src/proto_utils.cpp
index 85ef574e3c..dcb3d051fa 100644
--- a/src/mir_app/src/proto_utils.cpp
+++ b/src/mir_app/src/proto_utils.cpp
@@ -112,7 +112,7 @@ void PROTO_INTERFACE::setAllContactStatuses(int iStatus, bool bSkipChats)
 			if (!bSkipChats && iStatus == ID_STATUS_OFFLINE) {
 				ptrW wszRoom(Contact::GetInfo(CNF_UNIQUEID, hContact));
 				if (wszRoom != nullptr)
-					Chat_Control(m_szModuleName, wszRoom, SESSION_OFFLINE);
+					Chat_Control(Chat_Find(wszRoom, m_szModuleName), SESSION_OFFLINE);
 			}
 		}
 		else setWord(hContact, "Status", iStatus);
-- 
cgit v1.2.3