summaryrefslogtreecommitdiff
path: root/protocols/Facebook
diff options
context:
space:
mode:
authorikeblaster <ike@thez.info>2019-12-16 21:01:48 +0100
committerikeblaster <ike@thez.info>2019-12-16 21:03:46 +0100
commitc7d790f5266571eae33b779bd59550e24efe3cd8 (patch)
tree077426b598778fde3e999534f65a5f28636c0e60 /protocols/Facebook
parent762cd6b8b161223d01aee31c422ce507838d3df6 (diff)
FacebookMQTT - authentication, MQTT connection, ...
Temporary credentials dialog, loading GraphQL data, various constants (taken from Pidgin)
Diffstat (limited to 'protocols/Facebook')
-rw-r--r--protocols/Facebook/res/facebook.rc17
-rw-r--r--protocols/Facebook/src/dialogs.cpp80
-rw-r--r--protocols/Facebook/src/dialogs.h27
-rw-r--r--protocols/Facebook/src/http.cpp59
-rw-r--r--protocols/Facebook/src/mqtt.cpp37
-rw-r--r--protocols/Facebook/src/mqtt.h2
-rw-r--r--protocols/Facebook/src/proto.cpp10
-rw-r--r--protocols/Facebook/src/proto.h300
-rw-r--r--protocols/Facebook/src/resource.h3
-rw-r--r--protocols/Facebook/src/server.cpp53
-rw-r--r--protocols/Facebook/src/stdafx.h2
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;