diff options
author | ikeblaster <ike@thez.info> | 2019-12-16 21:01:48 +0100 |
---|---|---|
committer | ikeblaster <ike@thez.info> | 2019-12-16 21:03:46 +0100 |
commit | c7d790f5266571eae33b779bd59550e24efe3cd8 (patch) | |
tree | 077426b598778fde3e999534f65a5f28636c0e60 /protocols | |
parent | 762cd6b8b161223d01aee31c422ce507838d3df6 (diff) |
FacebookMQTT - authentication, MQTT connection, ...
Temporary credentials dialog, loading GraphQL data, various constants (taken from Pidgin)
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/Facebook/res/facebook.rc | 17 | ||||
-rw-r--r-- | protocols/Facebook/src/dialogs.cpp | 80 | ||||
-rw-r--r-- | protocols/Facebook/src/dialogs.h | 27 | ||||
-rw-r--r-- | protocols/Facebook/src/http.cpp | 59 | ||||
-rw-r--r-- | protocols/Facebook/src/mqtt.cpp | 37 | ||||
-rw-r--r-- | protocols/Facebook/src/mqtt.h | 2 | ||||
-rw-r--r-- | protocols/Facebook/src/proto.cpp | 10 | ||||
-rw-r--r-- | protocols/Facebook/src/proto.h | 300 | ||||
-rw-r--r-- | protocols/Facebook/src/resource.h | 3 | ||||
-rw-r--r-- | protocols/Facebook/src/server.cpp | 53 | ||||
-rw-r--r-- | protocols/Facebook/src/stdafx.h | 2 |
11 files changed, 557 insertions, 33 deletions
diff --git a/protocols/Facebook/res/facebook.rc b/protocols/Facebook/res/facebook.rc index d5669c116a..38a251d644 100644 --- a/protocols/Facebook/res/facebook.rc +++ b/protocols/Facebook/res/facebook.rc @@ -48,5 +48,22 @@ END IDI_FACEBOOK ICON "facebook.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_FACEBOOKACCOUNT DIALOGEX 0, 0, 186, 134 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "E-mail:",IDC_STATIC,6,0,46,12,0,WS_EX_RIGHT + EDITTEXT IDC_UN,56,0,122,12,ES_AUTOHSCROLL + LTEXT "Password:",IDC_STATIC,6,16,46,12,0,WS_EX_RIGHT + EDITTEXT IDC_PW,56,16,122,12,ES_PASSWORD | ES_AUTOHSCROLL +END + #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/protocols/Facebook/src/dialogs.cpp b/protocols/Facebook/src/dialogs.cpp new file mode 100644 index 0000000000..4e544e729b --- /dev/null +++ b/protocols/Facebook/src/dialogs.cpp @@ -0,0 +1,80 @@ +/* + +Facebook plugin for Miranda Instant Messenger +_____________________________________________ + +Copyright © 2009-11 Michal Zelinka, 2011-17 Robert Pösel, 2017-19 Miranda NG team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "stdafx.h" + + + +INT_PTR CALLBACK FBAccountProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) +{ + FacebookProto *proto = reinterpret_cast<FacebookProto*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); + + switch (message) { + + case WM_INITDIALOG: + { + TranslateDialogDefault(hwnd); + + proto = reinterpret_cast<FacebookProto*>(lparam); + SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam); + + ptrA login(db_get_sa(0, proto->ModuleName(), DBKEY_USERNAME)); + if (login != nullptr) + SetDlgItemTextA(hwnd, IDC_UN, login); + + ptrA password(db_get_sa(0, proto->ModuleName(), DBKEY_PASS)); + if (password != nullptr) + SetDlgItemTextA(hwnd, IDC_PW, password); + + //if (!proto->isOffline()) { + // SendDlgItemMessage(hwnd, IDC_UN, EM_SETREADONLY, 1, 0); + // SendDlgItemMessage(hwnd, IDC_PW, EM_SETREADONLY, 1, 0); + //} + return TRUE; + } + case WM_COMMAND: + if (HIWORD(wparam) == EN_CHANGE && reinterpret_cast<HWND>(lparam) == GetFocus()) { + switch (LOWORD(wparam)) { + case IDC_UN: + case IDC_PW: + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } + } + break; + + case WM_NOTIFY: + if (reinterpret_cast<NMHDR*>(lparam)->code == PSN_APPLY) { + char str[128]; + + GetDlgItemTextA(hwnd, IDC_UN, str, _countof(str)); + db_set_s(0, proto->ModuleName(), DBKEY_USERNAME, str); + + GetDlgItemTextA(hwnd, IDC_PW, str, _countof(str)); + db_set_s(0, proto->ModuleName(), DBKEY_PASS, str); + return TRUE; + } + break; + + } + + return FALSE; +} diff --git a/protocols/Facebook/src/dialogs.h b/protocols/Facebook/src/dialogs.h new file mode 100644 index 0000000000..6a8e7d2509 --- /dev/null +++ b/protocols/Facebook/src/dialogs.h @@ -0,0 +1,27 @@ +/*
+
+Facebook plugin for Miranda Instant Messenger
+_____________________________________________
+
+Copyright © 2009-11 Michal Zelinka, 2011-17 Robert Pösel, 2017-19 Miranda NG team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#pragma once
+
+INT_PTR CALLBACK FBAccountProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
+
+/////////////////////////////////////////////////////////////////////////////////
diff --git a/protocols/Facebook/src/http.cpp b/protocols/Facebook/src/http.cpp index 88a73c4006..537dc8b3d8 100644 --- a/protocols/Facebook/src/http.cpp +++ b/protocols/Facebook/src/http.cpp @@ -37,7 +37,8 @@ void AsyncHttpRequest::CalcSig() CMStringA buf; for (auto &it : params) buf.AppendFormat("%s=%s", it->key.c_str(), it->val.c_str()); - buf.Append(FB_APP_SECRET); + + buf.Append(FB_API_SECRET); char szHash[33]; BYTE digest[16]; @@ -99,8 +100,11 @@ AsyncHttpRequest* FacebookProto::CreateRequest(const char *szName, const char *s { AsyncHttpRequest *pReq = new AsyncHttpRequest(); pReq->requestType = REQUEST_POST; - pReq << CHAR_PARAM("api_key", FB_APP_KEY) << CHAR_PARAM("device_id", m_szDeviceID) << CHAR_PARAM("fb_api_req_friendly_name", szName) - << CHAR_PARAM("format", "json") << CHAR_PARAM("method", szMethod); + pReq << CHAR_PARAM("api_key", FB_API_KEY) + << CHAR_PARAM("device_id", m_szDeviceID) + << CHAR_PARAM("fb_api_req_friendly_name", szName) + << CHAR_PARAM("format", "json") + << CHAR_PARAM("method", szMethod); CMStringA szLocale = getMStringA(DBKEY_LOCALE); if (szLocale.IsEmpty()) @@ -112,10 +116,51 @@ AsyncHttpRequest* FacebookProto::CreateRequest(const char *szName, const char *s pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); - unsigned int id; - Utils_GetRandom(&id, sizeof(id)); - id &= ~0x80000000; - pReq << INT_PARAM("queryid", id); + //unsigned int id; + //Utils_GetRandom(&id, sizeof(id)); + //id &= ~0x80000000; + //pReq << INT_PARAM("queryid", id); + + return pReq; +} + +AsyncHttpRequest* FacebookProto::CreateRequestGQL(int64_t query_id) { + const char* szName; + + switch (query_id) { + case FB_API_QUERY_CONTACT: + szName = "UsersQuery"; + break; + case FB_API_QUERY_CONTACTS: + szName = "FetchContactsFullQuery"; + break; + case FB_API_QUERY_CONTACTS_AFTER: + szName = "FetchContactsFullWithAfterQuery"; + break; + case FB_API_QUERY_CONTACTS_DELTA: + szName = "FetchContactsDeltaQuery"; + break; + case FB_API_QUERY_STICKER: + szName = "FetchStickersWithPreviewsQuery"; + break; + case FB_API_QUERY_THREAD: + szName = "ThreadQuery"; + break; + case FB_API_QUERY_SEQ_ID: + case FB_API_QUERY_THREADS: + szName = "ThreadListQuery"; + break; + case FB_API_QUERY_XMA: + szName = "XMAQuery"; + break; + default: + return nullptr; + } + + AsyncHttpRequest* pReq = CreateRequest(szName, "get"); + + pReq->m_szUrl = FB_API_URL_GQL; + pReq << INT64_PARAM("query_id", query_id); return pReq; } diff --git a/protocols/Facebook/src/mqtt.cpp b/protocols/Facebook/src/mqtt.cpp index 2b9449a744..1ffe35a4ac 100644 --- a/protocols/Facebook/src/mqtt.cpp +++ b/protocols/Facebook/src/mqtt.cpp @@ -158,6 +158,7 @@ bool FacebookProto::MqttConnect() NETLIBOPENCONNECTION nloc = {}; nloc.szHost = "mqtt.facebook.com"; nloc.wPort = 443; + nloc.flags = NLOCF_SSL | NLOCF_V2; m_mqttConn = Netlib_OpenConnection(m_hNetlibUser, &nloc); if (m_mqttConn == nullptr) { debugLogA("connection failed, exiting"); @@ -169,7 +170,7 @@ bool FacebookProto::MqttConnect() void FacebookProto::MqttOpen() { - Utils_GetRandom(&m_iMqttId, sizeof(m_iMqttId)); + Utils_GetRandom(&m_iMqttId, sizeof(m_iMqttId) / 2); FbThrift thrift; thrift.writeField(FB_THRIFT_TYPE_STRING); // Client identifier @@ -181,7 +182,7 @@ void FacebookProto::MqttOpen() thrift.writeInt64(m_uid); thrift.writeField(FB_THRIFT_TYPE_STRING); // User agent - thrift << FACEBOOK_ORCA_AGENT; + thrift << FB_API_MQTT_AGENT; thrift.writeField(FB_THRIFT_TYPE_I64); thrift.writeInt64(23); @@ -211,9 +212,13 @@ void FacebookProto::MqttOpen() thrift.writeField(FB_THRIFT_TYPE_STRING); thrift << m_szAuthToken << (BYTE)0; - FILE *out = fopen("C:\\qq.out", "wb"); - fwrite(thrift.data(), 1, thrift.size(), out); - fclose(out); + //FILE *out = fopen("C:\\qq.out", "wb"); + //fwrite(thrift.data(), 1, thrift.size(), out); + //fclose(out); + // + //out = fopen("C:\\qq.size", "w"); + //fprintf(out, "%d", thrift.size()); + //fclose(out); size_t dataSize = thrift.size() + 100; BYTE *pData = (BYTE *)mir_alloc(dataSize); @@ -225,7 +230,8 @@ void FacebookProto::MqttOpen() zStreamOut.avail_out = (unsigned)dataSize; zStreamOut.next_out = (BYTE *)pData; - switch (deflate(&zStreamOut, Z_SYNC_FLUSH)) { + switch (deflate(&zStreamOut, Z_FINISH)) { + case Z_STREAM_END: debugLogA("Deflate: Z_STREAM_END"); break; case Z_OK: debugLogA("Deflate: Z_OK"); break; case Z_BUF_ERROR: debugLogA("Deflate: Z_BUF_ERROR"); break; case Z_DATA_ERROR: debugLogA("Deflate: Z_DATA_ERROR"); break; @@ -235,9 +241,26 @@ void FacebookProto::MqttOpen() deflateEnd(&zStreamOut); dataSize = dataSize - zStreamOut.avail_out; + //pData[2]++; + + //dataSize -= 4; + + //out = fopen("C:\\qq_deflated.out", "wb"); + //fwrite(pData, 1, dataSize, out); + //fclose(out); + // + //out = fopen("C:\\qq_deflated.size", "w"); + //fprintf(out, "%d", dataSize); + //fclose(out); + + //dataSize = 369; + //out = fopen("c:\\Users\\Uzivatel\\Desktop\\deflated_purple", "rb"); + //fread(pData, 1, dataSize, out); + //fclose(out); + uint8_t protocolVersion = 3; uint8_t flags = FB_MQTT_CONNECT_FLAG_USER | FB_MQTT_CONNECT_FLAG_PASS | FB_MQTT_CONNECT_FLAG_CLR | FB_MQTT_CONNECT_FLAG_QOS1; - MqttMessage payload(FB_MQTT_MESSAGE_TYPE_CONNECT, 0, dataSize - 3); + MqttMessage payload(FB_MQTT_MESSAGE_TYPE_CONNECT, 0, dataSize + 12); // size of things between size and payload (header, ...) payload.writeStr("MQTToT"); payload << protocolVersion << flags; payload.writeInt16(60); // timeout diff --git a/protocols/Facebook/src/mqtt.h b/protocols/Facebook/src/mqtt.h index e1652230ca..8b9597f304 100644 --- a/protocols/Facebook/src/mqtt.h +++ b/protocols/Facebook/src/mqtt.h @@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #pragma once -#define FACEBOOK_ORCA_AGENT "[FBAN/Orca-Android;FBAV/192.0.0.31.101;FBPN/com.facebook.orca;FBLC/en_US;FBBV/52182662]" +#define FACEBOOK_ORCA_AGENT FB_API_MQTT_AGENT #define FB_THRIFT_TYPE_STOP 0 #define FB_THRIFT_TYPE_VOID 1 diff --git a/protocols/Facebook/src/proto.cpp b/protocols/Facebook/src/proto.cpp index a30b7c1ac1..101d641910 100644 --- a/protocols/Facebook/src/proto.cpp +++ b/protocols/Facebook/src/proto.cpp @@ -66,6 +66,8 @@ FacebookProto::FacebookProto(const char *proto_name, const wchar_t *username) : nlu.szSettingsModule = m_szModuleName; nlu.szDescriptiveName.w = descr; m_hNetlibUser = Netlib_RegisterUser(&nlu); + + CreateProtoService(PS_CREATEACCMGRUI, &FacebookProto::SvcCreateAccMgrUI); } FacebookProto::~FacebookProto() @@ -169,3 +171,11 @@ int FacebookProto::SetStatus(int iNewStatus) ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus); return 0; } + +////////////////////////////////////////////////////////////////////////////// +// EVENTS + +INT_PTR FacebookProto::SvcCreateAccMgrUI(WPARAM, LPARAM lParam) { + return (INT_PTR) CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_FACEBOOKACCOUNT), + (HWND) lParam, FBAccountProc, (LPARAM) this); +}
\ No newline at end of file diff --git a/protocols/Facebook/src/proto.h b/protocols/Facebook/src/proto.h index 6f8c4fd110..29c55a197e 100644 --- a/protocols/Facebook/src/proto.h +++ b/protocols/Facebook/src/proto.h @@ -20,11 +20,292 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #pragma once -#define FB_HOST_BAPI "https://b-api.facebook.com" + +/** + * FB_API_AHOST: + * + * The HTTP host for the Facebook API. + */ +#define FB_API_AHOST "https://api.facebook.com" + +/** + * FB_API_BHOST: + * + * The HTTP host for the Facebook BAPI. + */ +#define FB_API_BHOST "https://b-api.facebook.com" + +/** + * FB_API_GHOST: + * + * The HTTP host for the Facebook Graph API. + */ +#define FB_API_GHOST "https://graph.facebook.com" + +/** + * FB_API_WHOST: + * + * The HTTP host for the Facebook website. + */ +#define FB_API_WHOST "https://www.facebook.com" + +/** + * FB_API_FBRPC_PREFIX + * + * The fbrpc URL prefix used in links shared from the mobile app. + */ +#define FB_API_FBRPC_PREFIX "fbrpc://facebook/nativethirdparty" + +/** + * FB_API_KEY: + * + * The Facebook API key. + */ +#define FB_API_KEY "256002347743983" + +/** + * FB_API_SECRET: + * + * The Facebook API secret. + */ +#define FB_API_SECRET "374e60f8b9bb6b8cbb30f78030438895" + +/** + * FB_ORCA_AGENT + * + * The part of the user agent that looks like the official client, since the + * server started checking this. + */ + +#define FB_ORCA_AGENT "[FBAN/Orca-Android;FBAV/192.0.0.31.101;FBPN/com.facebook.orca;FBLC/en_US;FBBV/52182662]" + +/** + * FB_API_AGENT: + * + * The HTTP User-Agent header. + */ +#define FB_API_AGENT "Facebook plugin / Purple / 0.9.6 " FB_ORCA_AGENT + +/** + * FB_API_MQTT_AGENT + * + * The client information string sent in the MQTT CONNECT message + */ + +#define FB_API_MQTT_AGENT FB_API_AGENT + +/** + * FB_API_URL_ATTACH: + * + * The URL for attachment URL requests. + */ +#define FB_API_URL_ATTACH FB_API_AHOST "/method/messaging.getAttachment" +//#define FB_API_URL_ATTACH FB_API_AHOST "/method/messaging.attachmentRedirect" + +/** + * FB_API_URL_AUTH: + * + * The URL for authentication requests. + */ +#define FB_API_URL_AUTH FB_API_BHOST "/method/auth.login" + +/** + * FB_API_URL_GQL: + * + * The URL for GraphQL requests. + */ +#define FB_API_URL_GQL FB_API_GHOST "/graphql" + +/** + * FB_API_URL_MESSAGES: + * + * The URL for linking message threads. + */ +#define FB_API_URL_MESSAGES FB_API_WHOST "/messages" + +/** + * FB_API_URL_PARTS: + * + * The URL for participant management requests. + */ +#define FB_API_URL_PARTS FB_API_GHOST "/participants" + +/** + * FB_API_URL_THREADS: + * + * The URL for thread management requests. + */ +#define FB_API_URL_THREADS FB_API_GHOST "/me/group_threads" + +/** + * FB_API_URL_TOPIC: + * + * The URL for thread topic requests. + */ +#define FB_API_URL_TOPIC FB_API_AHOST "/method/messaging.setthreadname" + +/** + * FB_API_QUERY_CONTACT: + * + * The query hash for the `UsersQuery`. + * + * Key mapping: + * 0: user_fbids + * 1: include_full_user_info + * 2: profile_pic_large_size + * 3: profile_pic_medium_size + * 4: profile_pic_small_size + */ +#define FB_API_QUERY_CONTACT 10153915107411729 + +/** + * FB_API_QUERY_CONTACTS: + * + * The query hash for the `FetchContactsFullQuery`. + * + * Key mapping: + * 0: profile_types + * 1: limit + * 2: big_img_size + * 3: huge_img_size + * 4: small_img_size + */ +#define FB_API_QUERY_CONTACTS 10154444360806729 + +/** + * FB_API_QUERY_CONTACTS_AFTER: + * + * The query hash for the `FetchContactsFullWithAfterQuery`. + * + * Key mapping: + * 0: profile_types + * 1: after + * 2: limit + * 3: big_img_size + * 4: huge_img_size + * 5: small_img_size + */ +#define FB_API_QUERY_CONTACTS_AFTER 10154444360816729 + + +/** + * FB_API_QUERY_CONTACTS_DELTA: + * + * The query hash for the `FetchContactsDeltaQuery`. + * + * Key mapping: + * 0: after + * 1: profile_types + * 2: limit + * 3: big_img_size + * 4: huge_img_size + * 5: small_img_size + */ +#define FB_API_QUERY_CONTACTS_DELTA 10154444360801729 + +/** + * FB_API_QUERY_STICKER: + * + * The query hash for the `FetchStickersWithPreviewsQuery`. + * + * Key mapping: + * 0: sticker_ids + * 1: media_type + * 2: preview_size + * 3: scaling_factor + * 4: animated_media_type + */ +#define FB_API_QUERY_STICKER 10152877994321729 + +/** + * FB_API_QUERY_THREAD: + * + * The query hash for the `ThreadQuery`. + * + * Key mapping: + * 0: thread_ids + * 1: verification_type + * 2: hash_key + * 3: small_preview_size + * 4: large_preview_size + * 5: item_count + * 6: event_count + * 7: full_screen_height + * 8: full_screen_width + * 9: medium_preview_size + * 10: fetch_users_separately + * 11: include_message_info + * 12: msg_count + * 13: include_full_user_info + * 14: profile_pic_large_size + * 15: profile_pic_medium_size + * 16: profile_pic_small_size + */ +#define FB_API_QUERY_THREAD 10153919752036729 + +/** + * FB_API_QUERY_THREADS: + * + * The query hash for the `ThreadListQuery`. + * + * Key mapping: + * 0: folder_tag + * 1: thread_count + * 2: include_thread_info + * 3: verification_type + * 4: hash_key + * 5: small_preview_size + * 6: large_preview_size + * 7: item_count + * 8: event_count + * 9: full_screen_height + * 10: full_screen_width + * 11: medium_preview_size + * 12: fetch_users_separately + * 13: include_message_info + * 14: msg_count + * 15: UNKNOWN + * 16: profile_pic_large_size + * 17: profile_pic_medium_size + * 18: profile_pic_small_size + */ +#define FB_API_QUERY_THREADS 10153919752026729 + +/** + * FB_API_QUERY_SEQ_ID: + * + * A variant of ThreadListQuery with sequence ID + * + * TODO: parameters. + */ + +#define FB_API_QUERY_SEQ_ID 10155268192741729 + +/** + * FB_API_QUERY_XMA: + * + * The query hash for the `XMAQuery`. + * + * Key mapping: + * 0: xma_id + */ +#define FB_API_QUERY_XMA 10153919431161729 + +/** + * FB_API_CONTACTS_COUNT: + * + * The maximum amount of contacts to fetch in a single request. If this + * value is set too high, HTTP request will fail. This is due to the + * request data being too large. + */ +#define FB_API_CONTACTS_COUNT "500" + #define FACEBOOK_MESSAGE_LIMIT 100000 -#include "../../../miranda-private-keys/Facebook/app_secret.h" + + + class FacebookProto; @@ -52,19 +333,19 @@ class JsonReply { JSONNode *m_root = nullptr; int m_errorCode = 0; - JSONNode *m_data = nullptr; public: JsonReply(NETLIBHTTPREQUEST *); ~JsonReply(); - __forceinline JSONNode &data() const { return *m_data; } + __forceinline JSONNode &data() const { return *m_root; } __forceinline int error() const { return m_errorCode; } }; class FacebookProto : public PROTO<FacebookProto> { - AsyncHttpRequest* CreateRequest(const char *szName, const char *szMethod); + AsyncHttpRequest* CreateRequest(const char* szName, const char* szMethod); + AsyncHttpRequest* CreateRequestGQL(int64_t id); NETLIBHTTPREQUEST* ExecuteRequest(AsyncHttpRequest *pReq); // MQTT functions @@ -92,6 +373,10 @@ public: FacebookProto(const char *proto_name, const wchar_t *username); ~FacebookProto(); + inline const char* ModuleName() const { + return m_szModuleName; + } + //////////////////////////////////////////////////////////////////////////////////////// // PROTO_INTERFACE @@ -100,6 +385,11 @@ public: INT_PTR GetCaps(int type, MCONTACT hContact) override; int SetStatus(int iNewStatus) override; + + //////////////////////// + + // Services + INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM); }; struct CMPlugin : public ACCPROTOPLUGIN<FacebookProto> diff --git a/protocols/Facebook/src/resource.h b/protocols/Facebook/src/resource.h index 558effecf5..a4091c5c95 100644 --- a/protocols/Facebook/src/resource.h +++ b/protocols/Facebook/src/resource.h @@ -3,3 +3,6 @@ // Used by D:\Development\Miranda NG\Miranda NG\protocols\FacebookRM\res\facebook.rc // #define IDI_FACEBOOK 101 +#define IDD_FACEBOOKACCOUNT 111 +#define IDC_UN 1001 +#define IDC_PW 1002 diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp index 162c6f9fa6..4b0251fd2a 100644 --- a/protocols/Facebook/src/server.cpp +++ b/protocols/Facebook/src/server.cpp @@ -27,40 +27,57 @@ void FacebookProto::OnLoggedOut() ///////////////////////////////////////////////////////////////////////////////////////// -void FacebookProto::ServerThread(void *) +void FacebookProto::ServerThread(void *) { + m_szAuthToken = getMStringA(DBKEY_TOKEN); + if (m_szAuthToken.IsEmpty()) { - auto *pReq = new AsyncHttpRequest(); - pReq->requestType = REQUEST_GET; - pReq->flags = NLHRF_HTTP11 | NLHRF_REDIRECT; - pReq->m_szUrl = "https://www.facebook.com/v3.3/dialog/oauth?client_id=478386432928815&redirect_uri=https://oauth.miranda-ng.org/facebook.php&state=qq"; + auto* pReq = CreateRequest("authenticate", "auth.login"); + pReq->m_szUrl = FB_API_URL_AUTH; + + pReq << CHAR_PARAM("email", getMStringA(DBKEY_USERNAME)); + pReq << CHAR_PARAM("password", getMStringA(DBKEY_PASS)); - if (JsonReply(ExecuteRequest(pReq)).error()) { -FAIL: - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE)m_iStatus, m_iDesiredStatus); + pReq->CalcSig(); + + JsonReply reply(ExecuteRequest(pReq)); + + if (reply.error()) { + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE) m_iStatus, m_iDesiredStatus); m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, m_iDesiredStatus); + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, m_iDesiredStatus); + return; } + + m_szAuthToken = reply.data()["access_token"].as_mstring(); + setString(DBKEY_TOKEN, m_szAuthToken); + + m_uid = reply.data()["uid"].as_int(); + CMStringA m_szUid = reply.data()["uid"].as_mstring(); + setString(DBKEY_ID, m_szUid); } - auto *pReq = CreateRequest("FetchContactsFullQuery", "get"); - pReq->m_szUrl = "https://graph.facebook.com/me/friends"; + auto* pReq = CreateRequestGQL(FB_API_QUERY_CONTACTS); + pReq << CHAR_PARAM("query_params", "{\"0\":[\"user\"],\"1\":\"" FB_API_CONTACTS_COUNT "\"}"); pReq->CalcSig(); JsonReply reply(ExecuteRequest(pReq)); if (reply.error()) goto FAIL; + // TODO: process contacts + + if (!MqttConnect()) goto FAIL; MqttOpen(); int bufSize = 2048; - char *buf = (char*)mir_alloc(bufSize); + char* buf = (char*) mir_alloc(bufSize); while (!Miranda_IsTerminated()) { int ret = Netlib_Recv(m_mqttConn, buf, bufSize); @@ -72,10 +89,20 @@ FAIL: debugLogA("Connection closed gracefully"); break; } + + // TODO: process MQTT responses } debugLogA("exiting ServerThread"); int oldStatus = m_iStatus; m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, m_iStatus); + + return; + +FAIL: + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE) m_iStatus, m_iDesiredStatus); + + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, m_iDesiredStatus); } diff --git a/protocols/Facebook/src/stdafx.h b/protocols/Facebook/src/stdafx.h index 36af3e8128..871f268be3 100644 --- a/protocols/Facebook/src/stdafx.h +++ b/protocols/Facebook/src/stdafx.h @@ -53,7 +53,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../../libs/zlib/src/zlib.h" #include "db.h" +#include "dialogs.h" #include "mqtt.h" #include "proto.h" +#include "resource.h" extern bool g_bMessageState; |