summaryrefslogtreecommitdiff
path: root/protocols/Tox/src
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2015-02-22 21:14:05 +0000
committerAlexander Lantsev <aunsane@gmail.com>2015-02-22 21:14:05 +0000
commit4ffd0909f7990643a0253849d46a750bd9f3233b (patch)
treea0a004674fcd9ad0600f7c1ae5728bea499f9db0 /protocols/Tox/src
parent0e8ffa6f388f28411decbcc6fe6c834029830714 (diff)
Tox: some code for group chats
git-svn-id: http://svn.miranda-ng.org/main/trunk@12241 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Tox/src')
-rw-r--r--protocols/Tox/src/api_groupchats.cpp29
-rw-r--r--protocols/Tox/src/common.h6
-rw-r--r--protocols/Tox/src/resource.h3
-rw-r--r--protocols/Tox/src/tox_accounts.cpp12
-rw-r--r--protocols/Tox/src/tox_chatrooms.cpp332
-rw-r--r--protocols/Tox/src/tox_contacts.cpp49
-rw-r--r--protocols/Tox/src/tox_core.cpp2
-rw-r--r--protocols/Tox/src/tox_events.cpp55
-rw-r--r--protocols/Tox/src/tox_menus.cpp41
-rw-r--r--protocols/Tox/src/tox_network.cpp1
-rw-r--r--protocols/Tox/src/tox_options.cpp37
-rw-r--r--protocols/Tox/src/tox_options.h10
-rw-r--r--protocols/Tox/src/tox_proto.cpp8
-rw-r--r--protocols/Tox/src/tox_proto.h38
-rw-r--r--protocols/Tox/src/version.h2
15 files changed, 536 insertions, 89 deletions
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<int(*)(Tox*, void(*)(Tox*, int32_t, uint8_t, const uint8_t*, uint16_t, void*), void*)>(__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<int(*)(const Tox*)>(__FUNCTION__)(tox);
}
int tox_del_groupchat(Tox *tox, int groupnumber)
{
+ return CreateFunction<int(*)(Tox*, int)>(__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<int(*)(Tox*, int32_t, const uint8_t*, uint32_t)>(__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<int(*)(Tox*, int, uint8_t*, uint32_t)>(__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<int(*)(const Tox*)>(__FUNCTION__)(tox);
}
uint32_t tox_get_chatlist(const Tox *tox, int32_t *out_list, uint32_t list_size)
{
+ return CreateFunction<int(*)(const Tox*, int32_t*, uint32_t)>(__FUNCTION__)(tox, out_list, list_size);
}
int tox_group_get_type(const Tox *tox, int groupnumber)
{
-}
-*/ \ No newline at end of file
+ return CreateFunction<int(*)(const Tox*, int)>(__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 <m_message.h>
#include <m_avatars.h>
#include <m_skin.h>
+#include <m_chat.h>
+#include <m_genmenu.h>
+#include <m_clc.h>
+#include <m_clistint.h>
#include <tox.h>
#include <toxdns.h>
@@ -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<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;
+}
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<MCONTACT> &contacts, MCONTACT hContact = NULL);
+ static void ChatPrepare(HWND hwndList, const std::vector<MCONTACT> &contacts, MCONTACT hContact = NULL);
+ static std::vector<MCONTACT> 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 <stdver.h>