diff options
Diffstat (limited to 'protocols/Tox/src/tox_chatrooms.cpp')
| -rw-r--r-- | protocols/Tox/src/tox_chatrooms.cpp | 332 | 
1 files changed, 332 insertions, 0 deletions
diff --git a/protocols/Tox/src/tox_chatrooms.cpp b/protocols/Tox/src/tox_chatrooms.cpp new file mode 100644 index 0000000000..684cac1246 --- /dev/null +++ b/protocols/Tox/src/tox_chatrooms.cpp @@ -0,0 +1,332 @@ +#include "common.h"
 +
 +MCONTACT CToxProto::GetChatRoom(int groupNumber)
 +{
 +	MCONTACT hContact = NULL;
 +	for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
 +	{
 +		if (!isChatRoom(hContact))
 +		{
 +			continue;
 +		}
 +		int chatRoumNumber = getWord(hContact, TOX_SETTINGS_CHAT_ID, TOX_ERROR);
 +		if (groupNumber == chatRoumNumber)
 +		{
 +			break;
 +		}
 +	}
 +	return hContact;
 +}
 +
 +MCONTACT CToxProto::AddChatRoom(int groupNumber)
 +{
 +	MCONTACT hContact = GetChatRoom(groupNumber);
 +	if (!hContact)
 +	{
 +		hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
 +		CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName);
 +
 +		setWord(hContact, TOX_SETTINGS_CHAT_ID, groupNumber);
 +
 +		TCHAR title[MAX_PATH];
 +		mir_sntprintf(title, SIZEOF(title), _T("%s #%d"), TranslateT("Groupchat"), groupNumber);
 +		setTString(hContact, "Nick", title);
 +
 +		DBVARIANT dbv;
 +		if (!db_get_s(NULL, "Chat", "AddToGroup", &dbv, DBVT_TCHAR))
 +		{
 +			db_set_ts(hContact, "CList", "Group", dbv.ptszVal);
 +			db_free(&dbv);
 +		}
 +
 +		setByte(hContact, "ChatRoom", 1);
 +	}
 +	return hContact;
 +}
 +
 +void CToxProto::LoadChatRoomList(void*)
 +{
 +	uint32_t count = tox_count_chatlist(tox);
 +	if (count == 0)
 +	{
 +		debugLogA("CToxProto::LoadGroupChatList: your group chat list is empty");
 +		return;
 +	}
 +	int32_t *groupChats = (int32_t*)mir_alloc(count * sizeof(int32_t));
 +	tox_get_chatlist(tox, groupChats, count);
 +	for (uint32_t i = 0; i < count; i++)
 +	{
 +		int32_t groupNumber = groupChats[i];
 +		int type = tox_group_get_type(tox, groupNumber);
 +		if (type == TOX_GROUPCHAT_TYPE_AV)
 +		{
 +			continue;
 +		}
 +		MCONTACT hContact = AddChatRoom(groupNumber);
 +		if (hContact)
 +		{
 +			uint8_t title[TOX_MAX_NAME_LENGTH] = { 0 };
 +			tox_group_get_title(tox, groupNumber, title, TOX_MAX_NAME_LENGTH);
 +			setWString(hContact, "Nick", ptrT(mir_utf8decodeT((char*)title)));
 +		}
 +	}
 +	mir_free(groupChats);
 +}
 +
 +int CToxProto::OnGroupChatEventHook(WPARAM, LPARAM lParam)
 +{
 +	GCHOOK *gch = (GCHOOK*)lParam;
 +	if (!gch)
 +	{
 +		return 1;
 +	}
 +	else if (strcmp(gch->pDest->pszModule, this->m_szModuleName) != 0)
 +	{
 +		return 0;
 +	}
 +	return 0;
 +}
 +
 +int CToxProto::OnGroupChatMenuHook(WPARAM, LPARAM lParam)
 +{
 +	GCMENUITEMS *gcmi = (GCMENUITEMS*)lParam;
 +	if (stricmp(gcmi->pszModule, this->m_szModuleName) != 0)
 +	{
 +		return 0;
 +	}
 +	return 0;
 +}
 +
 +INT_PTR CToxProto::OnJoinChatRoom(WPARAM hContact, LPARAM)
 +{
 +	if (hContact)
 +	{
 +	}
 +	return 0;
 +}
 +
 +INT_PTR CToxProto::OnLeaveChatRoom(WPARAM hContact, LPARAM)
 +{
 +	if (hContact)
 +	{
 +	}
 +	return 0;
 +}
 +
 +INT_PTR CToxProto::OnCreateChatRoom(WPARAM, LPARAM)
 +{
 +	if (!IsToxCoreInited())
 +	{
 +		return 1;
 +	}
 +	int groupNumber = tox_add_groupchat(tox);
 +	if (groupNumber == TOX_ERROR)
 +	{
 +		return 1;
 +	}
 +	MCONTACT hContact = AddChatRoom(groupNumber);
 +	if (!hContact)
 +	{
 +		return 1;
 +	}
 +	return 0;
 +}
 +
 +void CToxProto::InitGroupChatModule()
 +{
 +	GCREGISTER gcr = { sizeof(gcr) };
 +	gcr.iMaxText = 0;
 +	gcr.ptszDispName = this->m_tszUserName;
 +	gcr.pszModule = this->m_szModuleName;
 +	CallServiceSync(MS_GC_REGISTER, 0, (LPARAM)&gcr);
 +
 +	HookProtoEvent(ME_GC_EVENT, &CToxProto::OnGroupChatEventHook);
 +	HookProtoEvent(ME_GC_BUILDMENU, &CToxProto::OnGroupChatMenuHook);
 +}
 +
 +void CToxProto::CloseAllChatChatSessions()
 +{
 +	GC_INFO gci = { 0 };
 +	gci.Flags = GCF_BYINDEX | GCF_ID | GCF_DATA;
 +	gci.pszModule = m_szModuleName;
 +
 +	int count = CallServiceSync(MS_GC_GETSESSIONCOUNT, 0, (LPARAM)m_szModuleName);
 +	for (int i = 0; i < count; i++)
 +	{
 +		gci.iItem = i;
 +		if (!CallServiceSync(MS_GC_GETINFO, 0, (LPARAM)&gci))
 +		{
 +			GCDEST gcd = { m_szModuleName, gci.pszID, GC_EVENT_CONTROL };
 +			GCEVENT gce = { sizeof(gce), &gcd };
 +			CallServiceSync(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce);
 +			CallServiceSync(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gce);
 +		}
 +	}
 +}
 +
 +void CToxProto::OnGroupChatInvite(Tox *tox, int32_t friendNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg)
 +{
 +	CToxProto *proto = (CToxProto*)arg;
 +
 +	if (type == TOX_GROUPCHAT_TYPE_AV)
 +	{
 +		proto->debugLogA("CToxProto::OnGroupChatInvite: audio chat is not supported yet");
 +		return;
 +	}
 +
 +	int groupNumber = tox_join_groupchat(tox, friendNumber, data, length);
 +	if (groupNumber == TOX_ERROR)
 +	{
 +		proto->debugLogA("CToxProto::OnFriendRequest: failed to join to group chat");
 +		return;
 +	}
 +
 +	MCONTACT hContact = proto->AddChatRoom(groupNumber);
 +	if (!hContact)
 +	{
 +		proto->debugLogA("CToxProto::OnFriendRequest: failed to create group chat");
 +	}
 +}
 +
 +void CToxProto::ChatValidateContact(HWND hwndList, const std::vector<MCONTACT> &contacts, MCONTACT hContact)
 +{
 +	//if (mir_strcmpi(GetContactProto(hContact), m_szModuleName) == 0 && !isChatRoom(hContact))
 +	{
 +		if (std::find(contacts.begin(), contacts.end(), hContact) != contacts.end())
 +		{
 +			SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hContact, 0);
 +		}
 +		return;
 +	}
 +	SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hContact, 0);
 +}
 +
 +void CToxProto::ChatPrepare(HWND hwndList, const std::vector<MCONTACT> &contacts, MCONTACT hContact)
 +{
 +	if (hContact == NULL)
 +	{
 +		hContact = (MCONTACT)::SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0);
 +	}
 +	while (hContact)
 +	{
 +		if (IsHContactGroup(hContact))
 +		{
 +			MCONTACT hSubContact = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hContact);
 +			if (hSubContact)
 +			{
 +				ChatPrepare(hwndList, contacts, hSubContact);
 +			}
 +		}
 +		else if (IsHContactContact(hContact))
 +		{
 +			ChatValidateContact(hwndList, contacts, hContact);
 +		}
 +		hContact = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXT, (LPARAM)hContact);
 +	}
 +}
 +
 +std::vector<MCONTACT> CToxProto::GetInvitedContacts(HWND hwndList, MCONTACT hContact)
 +{
 +	std::vector<MCONTACT> contacts;
 +	if (hContact == NULL)
 +	{
 +		hContact = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0);
 +	}
 +	while (hContact)
 +	{
 +		if (IsHContactGroup(hContact))
 +		{
 +			MCONTACT hSubContact = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hContact);
 +			if (hSubContact)
 +			{
 +				std::vector<MCONTACT> subContacts = GetInvitedContacts(hwndList, hSubContact);
 +				contacts.insert(contacts.end(), subContacts.begin(), subContacts.end());
 +			}
 +		}
 +		else
 +		{
 +			int cheked = SendMessage(hwndList, CLM_GETCHECKMARK, (WPARAM)hContact, 0);
 +			if (cheked)
 +			{
 +				contacts.push_back(hContact);
 +			}
 +		}
 +		hContact = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXT, (LPARAM)hContact);
 +	}
 +	return contacts;
 +}
 +
 +INT_PTR CALLBACK CToxProto::ChatRoomInviteProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	HWND hwndList = GetDlgItem(hwndDlg, IDC_CCLIST);
 +	CToxProto *proto = (CToxProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 +
 +	switch (msg) {
 +	case WM_INITDIALOG:
 +		TranslateDialogDefault(hwndDlg);
 +		{
 +			proto = (CToxProto*)lParam;
 +			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
 +			{
 +				HWND hwndClist = GetDlgItem(hwndDlg, IDC_CCLIST);
 +				SetWindowLongPtr(hwndClist, GWL_STYLE, GetWindowLongPtr(hwndClist, GWL_STYLE) & ~CLS_HIDEOFFLINE);
 +			}
 +		}
 +		break;
 +
 +	case WM_CLOSE:
 +		EndDialog(hwndDlg, 0);
 +		break;
 +
 +	case WM_NOTIFY:
 +	{
 +		NMCLISTCONTROL *nmc = (NMCLISTCONTROL*)lParam;
 +		if (nmc->hdr.idFrom == IDC_CCLIST)
 +		{
 +			switch (nmc->hdr.code)
 +			{
 +			case CLN_NEWCONTACT:
 +				if ((nmc->flags & (CLNF_ISGROUP | CLNF_ISINFO)) == 0)
 +				{
 +					std::vector<MCONTACT> invitedContacts;
 +					proto->ChatValidateContact(nmc->hdr.hwndFrom, invitedContacts, (MCONTACT)nmc->hItem);
 +				}
 +				break;
 +
 +			case CLN_LISTREBUILT:
 +			{
 +				std::vector<MCONTACT> invitedContacts;
 +				proto->ChatPrepare(nmc->hdr.hwndFrom, invitedContacts);
 +			}
 +				break;
 +			}
 +		}
 +	}
 +	break;
 +
 +	case WM_COMMAND:
 +		switch (LOWORD(wParam))
 +		{
 +		case IDOK:
 +		{
 +			std::vector<MCONTACT> invitedContacts = GetInvitedContacts(hwndList);
 +			if (invitedContacts.empty())
 +			{
 +				proto->ShowNotification(TranslateT("You did not select any contact"));
 +			}
 +			else
 +			{
 +				//SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
 +				EndDialog(hwndDlg, IDOK);
 +			}
 +		}
 +		break;
 +
 +		case IDCANCEL:
 +			EndDialog(hwndDlg, IDCANCEL);
 +			break;
 +		}
 +		break;
 +	}
 +	return FALSE;
 +}
  | 
