From 4ffd0909f7990643a0253849d46a750bd9f3233b Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sun, 22 Feb 2015 21:14:05 +0000 Subject: Tox: some code for group chats git-svn-id: http://svn.miranda-ng.org/main/trunk@12241 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/Tox_12.vcxproj | 3 + protocols/Tox/Tox_12.vcxproj.filters | 9 + protocols/Tox/res/resource.rc | 21 +++ protocols/Tox/src/api_groupchats.cpp | 29 +-- protocols/Tox/src/common.h | 6 + protocols/Tox/src/resource.h | 3 + protocols/Tox/src/tox_accounts.cpp | 12 ++ protocols/Tox/src/tox_chatrooms.cpp | 332 +++++++++++++++++++++++++++++++++++ protocols/Tox/src/tox_contacts.cpp | 49 ++---- protocols/Tox/src/tox_core.cpp | 2 + protocols/Tox/src/tox_events.cpp | 55 +++--- protocols/Tox/src/tox_menus.cpp | 41 +++++ protocols/Tox/src/tox_network.cpp | 1 + protocols/Tox/src/tox_options.cpp | 37 +++- protocols/Tox/src/tox_options.h | 10 ++ protocols/Tox/src/tox_proto.cpp | 8 + protocols/Tox/src/tox_proto.h | 38 +++- protocols/Tox/src/version.h | 2 +- 18 files changed, 569 insertions(+), 89 deletions(-) create mode 100644 protocols/Tox/src/tox_chatrooms.cpp create mode 100644 protocols/Tox/src/tox_menus.cpp create mode 100644 protocols/Tox/src/tox_options.h (limited to 'protocols') diff --git a/protocols/Tox/Tox_12.vcxproj b/protocols/Tox/Tox_12.vcxproj index a0f0c23c04..6c1124e464 100644 --- a/protocols/Tox/Tox_12.vcxproj +++ b/protocols/Tox/Tox_12.vcxproj @@ -204,6 +204,7 @@ + @@ -224,6 +225,8 @@ + + diff --git a/protocols/Tox/Tox_12.vcxproj.filters b/protocols/Tox/Tox_12.vcxproj.filters index 71e635fa90..4361341f01 100644 --- a/protocols/Tox/Tox_12.vcxproj.filters +++ b/protocols/Tox/Tox_12.vcxproj.filters @@ -51,6 +51,9 @@ Header Files\api + + Header Files + @@ -125,6 +128,12 @@ Source Files + + Source Files + + + Source Files + diff --git a/protocols/Tox/res/resource.rc b/protocols/Tox/res/resource.rc index 71684ef390..5a10f365e0 100644 --- a/protocols/Tox/res/resource.rc +++ b/protocols/Tox/res/resource.rc @@ -192,6 +192,17 @@ BEGIN COMBOBOX IDC_COMBO_VIDEOINPUT,12,78,138,30,CBS_DROPDOWN | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP END +IDD_CHATROOM_INVITE DIALOGEX 0, 0, 190, 179 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOPMOST +CAPTION "Invite contacts to chat room" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "&Invite",IDOK,87,158,46,14 + PUSHBUTTON "&Cancel",IDCANCEL,138,158,45,14 + CONTROL "",IDC_CCLIST,"CListControl",WS_TABSTOP | 0x16f,7,7,176,145,WS_EX_CLIENTEDGE +END + ///////////////////////////////////////////////////////////////////////////// // @@ -277,6 +288,16 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 228 END + + IDD_CHATROOM_INVITE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 183 + TOPMARGIN, 7 + BOTTOMMARGIN, 172 + HORZGUIDE, 152 + HORZGUIDE, 158 + END END #endif // APSTUDIO_INVOKED diff --git a/protocols/Tox/src/api_groupchats.cpp b/protocols/Tox/src/api_groupchats.cpp index 8f49b8f421..a84c4eaab9 100644 --- a/protocols/Tox/src/api_groupchats.cpp +++ b/protocols/Tox/src/api_groupchats.cpp @@ -1,12 +1,13 @@ #include "common.h" /* GROUP CHAT FUNCTIONS: WARNING Group chats will be rewritten so this might change */ -/* + void tox_callback_group_invite(Tox *tox, void(*function)(Tox *tox, int32_t, uint8_t, const uint8_t *, uint16_t, void *), void *userdata) { + CreateFunction(__FUNCTION__)(tox, function, userdata); } -void tox_callback_group_message(Tox *tox, void(*function)(Tox *tox, int, int, const uint8_t *, uint16_t, void *), void *userdata) +/*void tox_callback_group_message(Tox *tox, void(*function)(Tox *tox, int, int, const uint8_t *, uint16_t, void *), void *userdata) { } @@ -20,17 +21,19 @@ void tox_callback_group_title(Tox *tox, void(*function)(Tox *tox, int, int, cons void tox_callback_group_namelist_change(Tox *tox, void(*function)(Tox *tox, int, int, uint8_t, void *), void *userdata) { -} +}*/ int tox_add_groupchat(Tox *tox) { + return CreateFunction(__FUNCTION__)(tox); } int tox_del_groupchat(Tox *tox, int groupnumber) { + return CreateFunction(__FUNCTION__)(tox, groupnumber); } -int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name) +/*int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name) { } @@ -40,13 +43,14 @@ int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8 int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber) { -} +}*/ int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length) { + return CreateFunction(__FUNCTION__)(tox, friendnumber, data, length); } -int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint16_t length) +/*int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint16_t length) { } @@ -56,13 +60,14 @@ int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint int tox_group_set_title(Tox *tox, int groupnumber, const uint8_t *title, uint8_t length) { -} +}*/ int tox_group_get_title(Tox *tox, int groupnumber, uint8_t *title, uint32_t max_length) { + return CreateFunction(__FUNCTION__)(tox, groupnumber, title, max_length); } -unsigned int tox_group_peernumber_is_ours(const Tox *tox, int groupnumber, int peernumber) +/*unsigned int tox_group_peernumber_is_ours(const Tox *tox, int groupnumber, int peernumber) { } @@ -72,17 +77,19 @@ int tox_group_number_peers(const Tox *tox, int groupnumber) int tox_group_get_names(const Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], uint16_t length) { -} +}*/ uint32_t tox_count_chatlist(const Tox *tox) { + return CreateFunction(__FUNCTION__)(tox); } uint32_t tox_get_chatlist(const Tox *tox, int32_t *out_list, uint32_t list_size) { + return CreateFunction(__FUNCTION__)(tox, out_list, list_size); } int tox_group_get_type(const Tox *tox, int groupnumber) { -} -*/ \ No newline at end of file + return CreateFunction(__FUNCTION__)(tox, groupnumber); +} \ No newline at end of file diff --git a/protocols/Tox/src/common.h b/protocols/Tox/src/common.h index 5e2953ca62..9d4b7dfedc 100644 --- a/protocols/Tox/src/common.h +++ b/protocols/Tox/src/common.h @@ -29,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -38,6 +42,7 @@ #include "version.h" #include "resource.h" #include "tox_address.h" +#include "tox_options.h" #include "tox_transfer.h" #include "tox_proto.h" @@ -54,6 +59,7 @@ extern HINSTANCE g_hInstance; #define TOX_SETTINGS_ID "ToxID" #define TOX_SETTINGS_DNS "DnsID" +#define TOX_SETTINGS_CHAT_ID "ChatID" #define TOX_SETTINGS_GROUP "DefaultGroup" #define TOX_SETTINGS_AVATAR_HASH "AvatarHash" diff --git a/protocols/Tox/src/resource.h b/protocols/Tox/src/resource.h index 0375fdef4b..e3b405e215 100644 --- a/protocols/Tox/src/resource.h +++ b/protocols/Tox/src/resource.h @@ -2,6 +2,7 @@ // Microsoft Visual C++ generated include file. // Used by e:\Projects\C++\MirandaNG\protocols\Tox\res\resource.rc // +#define IDD_CHATROOM_INVITE 16 #define IDD_USER_INFO 101 #define IDD_PASSWORD 102 #define IDD_ACCOUNT_MANAGER 104 @@ -13,6 +14,8 @@ #define IDD_OPTIONS_MAIN1 109 #define IDD_OPTIONS_AV 109 #define IDI_TOX 120 +#define IDC_CCLIST 173 +#define IDC_EDITSCR 174 #define IDC_TOXID 1001 #define IDC_CLIPBOARD 1002 #define IDC_SEARCH 1004 diff --git a/protocols/Tox/src/tox_accounts.cpp b/protocols/Tox/src/tox_accounts.cpp index 2e18334a4c..c2d84e9515 100644 --- a/protocols/Tox/src/tox_accounts.cpp +++ b/protocols/Tox/src/tox_accounts.cpp @@ -28,6 +28,8 @@ int CToxProto::OnAccountLoaded(WPARAM, LPARAM) HookProtoEvent(ME_USERINFO_INITIALISE, &CToxProto::OnUserInfoInit); HookProtoEvent(ME_MSG_PRECREATEEVENT, &CToxProto::OnPreCreateMessage); + InitGroupChatModule(); + return 0; } @@ -41,4 +43,14 @@ int CToxProto::OnAccountRenamed(WPARAM, LPARAM) accountName = mir_tstrdup(m_tszUserName); return 0; +} + +INT_PTR CToxProto::OnAccountManagerInit(WPARAM, LPARAM lParam) +{ + return (INT_PTR)CreateDialogParam( + g_hInstance, + MAKEINTRESOURCE(IDD_ACCOUNT_MANAGER), + (HWND)lParam, + CToxProto::MainOptionsProc, + (LPARAM)this); } \ No newline at end of file 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 &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 &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 CToxProto::GetInvitedContacts(HWND hwndList, MCONTACT hContact) +{ + std::vector 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 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 invitedContacts; + proto->ChatValidateContact(nmc->hdr.hwndFrom, invitedContacts, (MCONTACT)nmc->hItem); + } + break; + + case CLN_LISTREBUILT: + { + std::vector invitedContacts; + proto->ChatPrepare(nmc->hdr.hwndFrom, invitedContacts); + } + break; + } + } + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + { + std::vector 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; +} diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index 5b06d3f41e..729cb056f6 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -54,20 +54,11 @@ MCONTACT CToxProto::GetContact(const char *pubKey) MCONTACT hContact = NULL; for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { - DBVARIANT dbv; - if (!db_get(hContact, m_szModuleName, TOX_SETTINGS_ID, &dbv)) + ptrA contactPubKey(getStringA(hContact, TOX_SETTINGS_ID)); + // check only public key part of address + if (strnicmp(pubKey, contactPubKey, TOX_PUBLIC_KEY_SIZE) == 0) { - std::string contactPubKey; - if (dbv.type == DBVT_ASCIIZ) - { - contactPubKey = dbv.pszVal; - } - db_free(&dbv); - // check only public key part of address - if (strnicmp(pubKey, contactPubKey.c_str(), TOX_PUBLIC_KEY_SIZE) == 0) - { - break; - } + break; } } return hContact; @@ -115,9 +106,10 @@ void CToxProto::LoadFriendList(void*) tox_get_friendlist(tox, friends, count); uint8_t data[TOX_PUBLIC_KEY_SIZE]; - for (uint32_t i = 0; i < count; ++i) + for (uint32_t i = 0; i < count; i++) { - tox_get_client_id(tox, friends[i], data); + uint32_t friendNumber = friends[i]; + tox_get_client_id(tox, friendNumber, data); ToxHexAddress pubKey(data, TOX_PUBLIC_KEY_SIZE); MCONTACT hContact = AddContact(pubKey, _T("")); if (hContact) @@ -125,15 +117,15 @@ void CToxProto::LoadFriendList(void*) delSetting(hContact, "Auth"); delSetting(hContact, "Grant"); - int size = tox_get_name_size(tox, friends[i]); + int size = tox_get_name_size(tox, friendNumber); if (size != TOX_ERROR) { std::string nick(size, 0); - tox_get_name(tox, friends[i], (uint8_t*)nick.data()); - setWString(hContact, "Nick", ptrW(Utf8DecodeW(nick.c_str()))); + tox_get_name(tox, friendNumber, (uint8_t*)nick.data()); + setWString(hContact, "Nick", ptrT(Utf8DecodeT(nick.c_str()))); } - uint64_t timestamp = tox_get_last_online(tox, friends[i]); + uint64_t timestamp = tox_get_last_online(tox, friendNumber); if (timestamp) { setDword(hContact, "LastEventDateTS", timestamp); @@ -149,23 +141,6 @@ void CToxProto::LoadFriendList(void*) } } -int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM) -{ - if (!IsOnline()) - { - return 1; - } - - ToxBinAddress pubKey = ptrA(getStringA(hContact, TOX_SETTINGS_ID)); - int32_t number = tox_get_friend_number(tox, pubKey); - if (number == TOX_ERROR || tox_del_friend(tox, number) == TOX_ERROR) - { - return 1; - } - - return 0; -} - void CToxProto::OnFriendRequest(Tox *, const uint8_t *data, const uint8_t *message, const uint16_t messageSize, void *arg) { CToxProto *proto = (CToxProto*)arg; @@ -174,7 +149,7 @@ void CToxProto::OnFriendRequest(Tox *, const uint8_t *data, const uint8_t *messa MCONTACT hContact = proto->AddContact(address, _T("")); if (!hContact) { - return; + proto->debugLogA("CToxProto::OnFriendRequest: failed to create contact"); } proto->delSetting(hContact, "Auth"); diff --git a/protocols/Tox/src/tox_core.cpp b/protocols/Tox/src/tox_core.cpp index cff5d56c0d..ae1d8eec51 100644 --- a/protocols/Tox/src/tox_core.cpp +++ b/protocols/Tox/src/tox_core.cpp @@ -63,6 +63,8 @@ bool CToxProto::InitToxCore() // avatars tox_callback_avatar_info(tox, OnGotFriendAvatarInfo, this); tox_callback_avatar_data(tox, OnGotFriendAvatarData, this); + // group chats + tox_callback_group_invite(tox, OnGroupChatInvite, this); uint8_t data[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, data); diff --git a/protocols/Tox/src/tox_events.cpp b/protocols/Tox/src/tox_events.cpp index 3820c500dd..e372b9ee39 100644 --- a/protocols/Tox/src/tox_events.cpp +++ b/protocols/Tox/src/tox_events.cpp @@ -1,37 +1,30 @@ #include "common.h" -INT_PTR CToxProto::OnAccountManagerInit(WPARAM, LPARAM lParam) +int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM) { - return (INT_PTR)CreateDialogParam( - g_hInstance, - MAKEINTRESOURCE(IDD_ACCOUNT_MANAGER), - (HWND)lParam, - CToxProto::MainOptionsProc, - (LPARAM)this); -} + if (!IsOnline()) + { + return 1; + } -int CToxProto::OnOptionsInit(WPARAM wParam, LPARAM) -{ - char *title = mir_t2a(m_tszUserName); - - OPTIONSDIALOGPAGE odp = { sizeof(odp) }; - odp.hInstance = g_hInstance; - odp.pszTitle = title; - odp.dwInitParam = (LPARAM)this; - odp.flags = ODPF_BOLDGROUPS; - odp.pszGroup = LPGEN("Network"); - - odp.pszTab = LPGEN("Account"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_MAIN); - odp.pfnDlgProc = MainOptionsProc; - Options_AddPage(wParam, &odp); - - odp.pszTab = LPGEN("Nodes"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_NODES); - odp.pfnDlgProc = NodesOptionsProc; - Options_AddPage(wParam, &odp); - - mir_free(title); + ToxBinAddress pubKey = ptrA(getStringA(hContact, TOX_SETTINGS_ID)); + if (!isChatRoom(hContact)) + { + int32_t friendNumber = tox_get_friend_number(tox, pubKey); + if (friendNumber == TOX_ERROR || tox_del_friend(tox, friendNumber) == TOX_ERROR) + { + return 1; + } + } + else + { + OnLeaveChatRoom(hContact, 0); + int groupNumber = 0; // ??? + if (groupNumber == TOX_ERROR || tox_del_groupchat(tox, groupNumber) == TOX_ERROR) + { + return 1; + } + } return 0; -} +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_menus.cpp b/protocols/Tox/src/tox_menus.cpp new file mode 100644 index 0000000000..2afa6fd218 --- /dev/null +++ b/protocols/Tox/src/tox_menus.cpp @@ -0,0 +1,41 @@ +#include "common.h" + +int CToxProto::OnInitStatusMenu() +{ + char text[MAX_PATH]; + mir_strcpy(text, m_szModuleName); + char *tDest = text + strlen(text); + + CLISTMENUITEM mi = { sizeof(mi) }; + mi.pszService = text; + + HGENMENU hStatusMunuRoot = MO_GetProtoRootMenu(m_szModuleName); + if (!hStatusMunuRoot) + { + mi.ptszName = m_tszUserName; + mi.position = -1999901006; + mi.hParentMenu = HGENMENU_ROOT; + mi.flags = CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; + //mi.icolibItem = CToxProto::GetSkinIconHandle("main"); + hStatusMunuRoot = /*m_hMenuRoot = */Menu_AddProtoMenuItem(&mi); + } + else + { + //if (m_hMenuRoot) + // CallService(MO_REMOVEMENUITEM, (WPARAM)m_hMenuRoot, 0); + //m_hMenuRoot = NULL; + } + + mi.hParentMenu = hStatusMunuRoot; + mi.flags = CMIF_CHILDPOPUP | CMIF_TCHAR; + + // Create chat room command + mir_strcpy(tDest, "/CreateChatRoom"); + CreateProtoService(tDest, &CToxProto::OnCreateChatRoom); + mi.ptszName = LPGENT("Create group chat"); + mi.position = 200000;// +SMI_CHAT_CREATE; + //mi.icolibItem = CToxProto::GetSkinIconHandle("conference"); + Menu_AddProtoMenuItem(&mi); + + return 0; +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_network.cpp b/protocols/Tox/src/tox_network.cpp index 694d966753..ac39e053ff 100644 --- a/protocols/Tox/src/tox_network.cpp +++ b/protocols/Tox/src/tox_network.cpp @@ -97,6 +97,7 @@ void CToxProto::TryConnect() debugLogA("CToxProto::PollingThread: successfuly connected to DHT"); ForkThread(&CToxProto::LoadFriendList, NULL); + ForkThread(&CToxProto::LoadChatRoomList, NULL); m_iStatus = m_iDesiredStatus; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus); diff --git a/protocols/Tox/src/tox_options.cpp b/protocols/Tox/src/tox_options.cpp index 10662f0134..2deebd152c 100644 --- a/protocols/Tox/src/tox_options.cpp +++ b/protocols/Tox/src/tox_options.cpp @@ -196,12 +196,6 @@ INT_PTR CToxProto::MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l return FALSE; } -struct ItemInfo -{ - int iItem; - HWND hwndList; -}; - int AddItemToListView(HWND hwndList, UINT mask, int iGroupId, int iItem, int iSubItem, char *pszText, int iImage = -1) { LVITEMA lvi = { 0 }; @@ -662,3 +656,34 @@ INT_PTR CALLBACK CToxProto::NodesOptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wPa } return FALSE; } + +int CToxProto::OnOptionsInit(WPARAM wParam, LPARAM) +{ + char *title = mir_t2a(m_tszUserName); + + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = g_hInstance; + odp.pszTitle = title; + odp.dwInitParam = (LPARAM)this; + odp.flags = ODPF_BOLDGROUPS; + odp.pszGroup = LPGEN("Network"); + + odp.pszTab = LPGEN("Account"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_MAIN); + odp.pfnDlgProc = MainOptionsProc; + Options_AddPage(wParam, &odp); + + /*odp.pszTab = LPGEN("Audio/Video"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_AV); + odp.pfnDlgProc = AVOptionsProc; + Options_AddPage(wParam, &odp);*/ + + odp.pszTab = LPGEN("Nodes"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_NODES); + odp.pfnDlgProc = NodesOptionsProc; + Options_AddPage(wParam, &odp); + + mir_free(title); + + return 0; +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_options.h b/protocols/Tox/src/tox_options.h new file mode 100644 index 0000000000..19b61d6710 --- /dev/null +++ b/protocols/Tox/src/tox_options.h @@ -0,0 +1,10 @@ +#ifndef _TOX_OPTIONS_H_ +#define _TOX_OPTIONS_H_ + +struct ItemInfo +{ + int iItem; + HWND hwndList; +}; + +#endif //_TOX_OPTIONS_H_ \ No newline at end of file diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index 5da0686a7a..117c7f8ec9 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -48,6 +48,10 @@ CToxProto::CToxProto(const char* protoName, const TCHAR* userName) : CreateProtoService(PS_SETMYNICKNAME, &CToxProto::SetMyNickname); + // chat rooms + CreateProtoService(PS_JOINCHAT, &CToxProto::OnJoinChatRoom); + CreateProtoService(PS_LEAVECHAT, &CToxProto::OnLeaveChatRoom); + // transfers transfers = new CTransferList(); } @@ -221,6 +225,7 @@ int __cdecl CToxProto::SetStatus(int iNewStatus) if (!Miranda_Terminated()) { SetAllContactsStatus(ID_STATUS_OFFLINE); + CloseAllChatChatSessions(); } m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; @@ -284,6 +289,9 @@ int __cdecl CToxProto::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM case EV_PROTO_ONCONTACTDELETED: return OnContactDeleted(wParam, lParam); + + case EV_PROTO_ONMENU: + return OnInitStatusMenu(); } return 1; diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index 0b53d7ba86..0ff5060f14 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -107,17 +107,25 @@ private: int __cdecl OnAccountLoaded(WPARAM, LPARAM); int __cdecl OnAccountRenamed(WPARAM, LPARAM); + INT_PTR __cdecl OnAccountManagerInit(WPARAM, LPARAM); + // netlib void InitNetlib(); void UninitNetlib(); + // menus + int OnInitStatusMenu(); + static void InitMenus(); + static void UninitMenus(); + // options static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK NodesOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl OnAccountManagerInit(WPARAM, LPARAM); + // events + int __cdecl OnContactDeleted(MCONTACT, LPARAM); // userinfo static INT_PTR CALLBACK UserInfoProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -137,8 +145,6 @@ private: void __cdecl LoadFriendList(void*); - int __cdecl OnContactDeleted(MCONTACT, LPARAM); - static void OnFriendRequest(Tox *tox, const uint8_t *pubKey, const uint8_t *message, const uint16_t messageSize, void *arg); static void OnFriendNameChange(Tox *tox, const int friendNumber, const uint8_t *name, const uint16_t nameSize, void *arg); static void OnStatusMessageChanged(Tox *tox, const int friendNumber, const uint8_t* message, const uint16_t messageSize, void *arg); @@ -151,6 +157,32 @@ private: static INT_PTR CALLBACK SearchDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + // chat rooms + //MCONTACT GetChatRoom(const char *pubKey); + MCONTACT GetChatRoom(int groupNumber); + + //MCONTACT GetChatRoom(const char *pubKey); + MCONTACT AddChatRoom(int groupNumber); + + void __cdecl LoadChatRoomList(void*); + + int __cdecl OnGroupChatEventHook(WPARAM, LPARAM lParam); + int __cdecl OnGroupChatMenuHook(WPARAM, LPARAM lParam); + + INT_PTR __cdecl OnJoinChatRoom(WPARAM hContact, LPARAM); + INT_PTR __cdecl OnLeaveChatRoom(WPARAM hContact, LPARAM); + INT_PTR __cdecl OnCreateChatRoom(WPARAM, LPARAM); + + void InitGroupChatModule(); + void CloseAllChatChatSessions(); + + static void OnGroupChatInvite(Tox *tox, int32_t friendNumber, uint8_t type, const uint8_t *data, const uint16_t length, void *arg); + + static void ChatValidateContact(HWND hwndList, const std::vector &contacts, MCONTACT hContact = NULL); + static void ChatPrepare(HWND hwndList, const std::vector &contacts, MCONTACT hContact = NULL); + static std::vector GetInvitedContacts(HWND hwndList, MCONTACT hContact = NULL); + static INT_PTR CALLBACK ChatRoomInviteProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + // messages static void OnFriendMessage(Tox *tox, const int number, const uint8_t *message, const uint16_t messageSize, void *arg); static void OnFriendAction(Tox *tox, const int number, const uint8_t *action, const uint16_t actionSize, void *arg); diff --git a/protocols/Tox/src/version.h b/protocols/Tox/src/version.h index 77b75e31ee..e3ec1bf9d5 100644 --- a/protocols/Tox/src/version.h +++ b/protocols/Tox/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 11 #define __RELEASE_NUM 0 -#define __BUILD_NUM 7 +#define __BUILD_NUM 8 #include -- cgit v1.2.3