summaryrefslogtreecommitdiff
path: root/protocols/Facebook/src/proto.h
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2023-01-02 21:10:29 +0300
committerdartraiden <wowemuh@gmail.com>2023-01-02 21:10:29 +0300
commit1979fd80424d16b2e489f9b57d01d9c7811d25a2 (patch)
tree960d42c5fe4a51f0fe2850bea91256e226bce221 /protocols/Facebook/src/proto.h
parentadfbbb217d4f4a05acf198755f219a5223d31c27 (diff)
Update copyrights
Diffstat (limited to 'protocols/Facebook/src/proto.h')
-rw-r--r--protocols/Facebook/src/proto.h1114
1 files changed, 557 insertions, 557 deletions
diff --git a/protocols/Facebook/src/proto.h b/protocols/Facebook/src/proto.h
index 14dc343d18..7fbeebd2cb 100644
--- a/protocols/Facebook/src/proto.h
+++ b/protocols/Facebook/src/proto.h
@@ -1,557 +1,557 @@
-/*
-
-Facebook plugin for Miranda NG
-Copyright © 2019-22 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
-
-
-/**
- * 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/537.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 (INBOX, PENDING, ARCHIVED, OTHER, UNREAD)
- * 1: thread_count (result is sorted from newest to oldest when parameter is sent)
- * 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
-
-class FacebookProto;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-struct AsyncHttpRequest : public MTHttpRequest<FacebookProto>
-{
- struct Param
- {
- Param(const char *p1, const char *p2) :
- key(p1), val(p2)
- {}
-
- CMStringA key, val;
- };
- OBJLIST<Param> params;
-
- AsyncHttpRequest();
-
- void CalcSig();
-};
-
-AsyncHttpRequest *operator<<(AsyncHttpRequest *, const CHAR_PARAM &);
-AsyncHttpRequest *operator<<(AsyncHttpRequest *, const INT_PARAM &);
-
-class JsonReply
-{
- JSONNode *m_root = nullptr;
- int m_errorCode = 0;
-
-public:
- JsonReply(NETLIBHTTPREQUEST *);
- ~JsonReply();
-
- __forceinline JSONNode &data() const { return *m_root; }
- __forceinline int error() const { return m_errorCode; }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-struct FacebookUser
-{
- FacebookUser(__int64 _p1, MCONTACT _p2, bool _p3 = false, bool _p4 = false) :
- id(_p1),
- hContact(_p2),
- bIsChat(_p3),
- bIsChatInitialized(_p4)
- {}
-
- __int64 id;
- MCONTACT hContact;
- bool bIsChat;
- bool bIsChatInitialized;
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-struct COwnMessage
-{
- __int64 msgId;
- int reqId;
- MCONTACT hContact;
- CMStringW wszText;
-
- COwnMessage() :
- msgId(0),
- reqId(0),
- hContact(0)
- {
- }
-
- COwnMessage(__int64 _id, int _reqId, MCONTACT _hContact) :
- msgId(_id),
- reqId(_reqId),
- hContact(_hContact)
- {
- }
-};
-
-class FacebookProto : public PROTO<FacebookProto>
-{
- friend class CGroupchatInviteDlg;
-
- class FacebookImpl
- {
- friend class FacebookProto;
-
- FacebookProto &m_proto;
- CTimer m_heartBeat;
-
- void OnHeartBeat(CTimer *)
- {
- m_proto.MqttPing();
- }
-
- FacebookImpl(FacebookProto &pro) :
- m_proto(pro),
- m_heartBeat(Miranda_GetSystemWindow(), (UINT_PTR)this)
- {
- m_heartBeat.OnEvent = Callback(this, &FacebookImpl::OnHeartBeat);
- }
- } m_impl;
-
- uint8_t *doZip(size_t cbData, const void *pData, size_t &cbRes);
- uint8_t *doUnzip(size_t cbData, const void *pData, size_t &cbRes);
-
- void ConnectionFailed(int iErrorCode = 0);
-
- AsyncHttpRequest *CreateRequest(const char *szUrl, const char *szName, const char *szMethod);
- AsyncHttpRequest *CreateRequestGQL(int64_t id);
- NETLIBHTTPREQUEST *ExecuteRequest(AsyncHttpRequest *pReq);
-
- // Avatars
- void __cdecl AvatarsUpdate(void *);
- void GetAvatarFilename(MCONTACT hContact, wchar_t *pwszFileName);
-
- // Group chats
- void Chat_InviteUser(SESSION_INFO *si);
- int Chat_KickUser(SESSION_INFO *si, const wchar_t *pwszUid);
- void Chat_Leave(SESSION_INFO *si);
- void Chat_SendPrivateMessage(GCHOOK *gch);
- void Chat_ProcessLogMenu(SESSION_INFO *si, GCHOOK *gch);
- void Chat_ProcessNickMenu(SESSION_INFO *si, GCHOOK *gch);
-
- // MQTT
- void MqttLogin();
-
- void MqttPing();
- void MqttPublish(const char *topic, const JSONNode &value);
- void MqttSubscribe(const char *topic, ...);
- void MqttUnsubscribe(const char *topic, ...);
-
- bool MqttRead(MqttMessage &payload);
- bool MqttParse(const MqttMessage &payload);
- void MqttSend(const MqttMessage &payload);
-
- void MqttQueueConnect();
-
- void OnPublish(const char *str, const uint8_t *payLoad, size_t cbLen);
- void OnPublishMessage(FbThriftReader &rdr);
- void OnPublishPresence(FbThriftReader &rdr);
- void OnPublishUtn(FbThriftReader &rdr);
-
- HNETLIBCONN m_mqttConn;
- __int64 m_iMqttId;
- int16_t m_mid; // MQTT message id
-
- // internal data
- CMStringA m_szDeviceID; // stored, GUID that identifies this miranda's account
- CMStringA m_szClientID; // stored, random alphanumeric string of 20 chars
- __int64 m_uid; // stored, Facebook user id
-
- CMStringA m_szSyncToken; // stored, sequence query token
- __int64 m_sid; // stored, Facebook sequence id
-
- int m_iUnread;
- bool m_bOnline;
- bool m_QueueCreated;
-
- CMStringA m_szAuthToken; // calculated
-
- mir_cs m_csOwnMessages;
- OBJLIST<COwnMessage> arOwnMessages;
- bool ExtractOwnMessage(__int64 msgId, COwnMessage &res);
-
- mir_cs m_csUsers;
- OBJLIST<FacebookUser> m_users;
-
- FacebookUser* FindUser(__int64 id);
-
- FacebookUser *UserFromJson(const JSONNode &root, CMStringW &wszId, bool &bIsChat);
-
- bool CheckOwnMessage(FacebookUser *pUser, __int64 offlineId, const char *pszMsgId);
- void FetchAttach(const CMStringA &mid, __int64 fbid, CMStringA &szBody);
-
- void OnLoggedIn();
- void OnLoggedOut();
-
- FacebookUser* RefreshThread(JSONNode &n);
- FacebookUser* RefreshThread(CMStringW &wszId);
- bool RefreshSid();
- int RefreshToken();
- void RefreshThreads();
- int RefreshContacts();
-
- FacebookUser *AddContact(const CMStringW &wszId, bool bTemp = true);
-
- void __cdecl ServerThread(void *);
-
-public:
- FacebookProto(const char *proto_name, const wchar_t *username);
- ~FacebookProto();
-
- inline const char *ModuleName() const
- {
- return m_szModuleName;
- }
-
- void OnPublishPrivateMessage(const JSONNode &json);
- void OnPublishReadReceipt(const JSONNode &json);
- void OnPublishSentMessage(const JSONNode &json);
- void OnPublishThreadName(const JSONNode &json);
- void OnPublishChatJoin(const JSONNode &json);
- void OnPublishChatLeave(const JSONNode &json);
-
- //////////////////////////////////////////////////////////////////////////////////////
- // options
-
- CMOption<wchar_t *> m_wszDefaultGroup; // clist group to store contacts
- CMOption<bool> m_bUseBigAvatars; // use big or small avatars by default
- CMOption<bool> m_bUseGroupchats; // do we need group chats at all?
- CMOption<bool> m_bHideGroupchats; // do not open chat windows on creation
- CMOption<bool> m_bLoginInvisible; // login in the invisible mode
- CMOption<bool> m_bKeepUnread; // do not mark incoming messages as read
- CMOption<bool> m_bLoadAll; // load all contacts, not only those who have ARE_FRIENDS status
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // PROTO_INTERFACE
-
- void OnContactAdded(MCONTACT) override;
- void OnModulesLoaded() override;
- void OnShutdown() override;
-
- MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr) override;
- INT_PTR GetCaps(int type, MCONTACT hContact) override;
- int SendMsg(MCONTACT hContact, int flags, const char *pszSrc) override;
- int SetStatus(int iNewStatus) override;
- int UserIsTyping(MCONTACT hContact, int type) override;
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // Events
-
- int __cdecl OnMarkedRead(WPARAM, LPARAM);
- int __cdecl OnOptionsInit(WPARAM, LPARAM);
-
- int __cdecl GroupchatMenuHook(WPARAM, LPARAM);
- int __cdecl GroupchatEventHook(WPARAM, LPARAM);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // Services
-
- INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
- INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
- INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM);
-};
-
-typedef CProtoDlgBase<FacebookProto> CFBDlgBase;
-
-struct CMPlugin : public ACCPROTOPLUGIN<FacebookProto>
-{
- CMPlugin();
-
- int Load() override;
-};
+/*
+
+Facebook plugin for Miranda NG
+Copyright © 2019-23 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
+
+
+/**
+ * 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/537.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 (INBOX, PENDING, ARCHIVED, OTHER, UNREAD)
+ * 1: thread_count (result is sorted from newest to oldest when parameter is sent)
+ * 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
+
+class FacebookProto;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+struct AsyncHttpRequest : public MTHttpRequest<FacebookProto>
+{
+ struct Param
+ {
+ Param(const char *p1, const char *p2) :
+ key(p1), val(p2)
+ {}
+
+ CMStringA key, val;
+ };
+ OBJLIST<Param> params;
+
+ AsyncHttpRequest();
+
+ void CalcSig();
+};
+
+AsyncHttpRequest *operator<<(AsyncHttpRequest *, const CHAR_PARAM &);
+AsyncHttpRequest *operator<<(AsyncHttpRequest *, const INT_PARAM &);
+
+class JsonReply
+{
+ JSONNode *m_root = nullptr;
+ int m_errorCode = 0;
+
+public:
+ JsonReply(NETLIBHTTPREQUEST *);
+ ~JsonReply();
+
+ __forceinline JSONNode &data() const { return *m_root; }
+ __forceinline int error() const { return m_errorCode; }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+struct FacebookUser
+{
+ FacebookUser(__int64 _p1, MCONTACT _p2, bool _p3 = false, bool _p4 = false) :
+ id(_p1),
+ hContact(_p2),
+ bIsChat(_p3),
+ bIsChatInitialized(_p4)
+ {}
+
+ __int64 id;
+ MCONTACT hContact;
+ bool bIsChat;
+ bool bIsChatInitialized;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+struct COwnMessage
+{
+ __int64 msgId;
+ int reqId;
+ MCONTACT hContact;
+ CMStringW wszText;
+
+ COwnMessage() :
+ msgId(0),
+ reqId(0),
+ hContact(0)
+ {
+ }
+
+ COwnMessage(__int64 _id, int _reqId, MCONTACT _hContact) :
+ msgId(_id),
+ reqId(_reqId),
+ hContact(_hContact)
+ {
+ }
+};
+
+class FacebookProto : public PROTO<FacebookProto>
+{
+ friend class CGroupchatInviteDlg;
+
+ class FacebookImpl
+ {
+ friend class FacebookProto;
+
+ FacebookProto &m_proto;
+ CTimer m_heartBeat;
+
+ void OnHeartBeat(CTimer *)
+ {
+ m_proto.MqttPing();
+ }
+
+ FacebookImpl(FacebookProto &pro) :
+ m_proto(pro),
+ m_heartBeat(Miranda_GetSystemWindow(), (UINT_PTR)this)
+ {
+ m_heartBeat.OnEvent = Callback(this, &FacebookImpl::OnHeartBeat);
+ }
+ } m_impl;
+
+ uint8_t *doZip(size_t cbData, const void *pData, size_t &cbRes);
+ uint8_t *doUnzip(size_t cbData, const void *pData, size_t &cbRes);
+
+ void ConnectionFailed(int iErrorCode = 0);
+
+ AsyncHttpRequest *CreateRequest(const char *szUrl, const char *szName, const char *szMethod);
+ AsyncHttpRequest *CreateRequestGQL(int64_t id);
+ NETLIBHTTPREQUEST *ExecuteRequest(AsyncHttpRequest *pReq);
+
+ // Avatars
+ void __cdecl AvatarsUpdate(void *);
+ void GetAvatarFilename(MCONTACT hContact, wchar_t *pwszFileName);
+
+ // Group chats
+ void Chat_InviteUser(SESSION_INFO *si);
+ int Chat_KickUser(SESSION_INFO *si, const wchar_t *pwszUid);
+ void Chat_Leave(SESSION_INFO *si);
+ void Chat_SendPrivateMessage(GCHOOK *gch);
+ void Chat_ProcessLogMenu(SESSION_INFO *si, GCHOOK *gch);
+ void Chat_ProcessNickMenu(SESSION_INFO *si, GCHOOK *gch);
+
+ // MQTT
+ void MqttLogin();
+
+ void MqttPing();
+ void MqttPublish(const char *topic, const JSONNode &value);
+ void MqttSubscribe(const char *topic, ...);
+ void MqttUnsubscribe(const char *topic, ...);
+
+ bool MqttRead(MqttMessage &payload);
+ bool MqttParse(const MqttMessage &payload);
+ void MqttSend(const MqttMessage &payload);
+
+ void MqttQueueConnect();
+
+ void OnPublish(const char *str, const uint8_t *payLoad, size_t cbLen);
+ void OnPublishMessage(FbThriftReader &rdr);
+ void OnPublishPresence(FbThriftReader &rdr);
+ void OnPublishUtn(FbThriftReader &rdr);
+
+ HNETLIBCONN m_mqttConn;
+ __int64 m_iMqttId;
+ int16_t m_mid; // MQTT message id
+
+ // internal data
+ CMStringA m_szDeviceID; // stored, GUID that identifies this miranda's account
+ CMStringA m_szClientID; // stored, random alphanumeric string of 20 chars
+ __int64 m_uid; // stored, Facebook user id
+
+ CMStringA m_szSyncToken; // stored, sequence query token
+ __int64 m_sid; // stored, Facebook sequence id
+
+ int m_iUnread;
+ bool m_bOnline;
+ bool m_QueueCreated;
+
+ CMStringA m_szAuthToken; // calculated
+
+ mir_cs m_csOwnMessages;
+ OBJLIST<COwnMessage> arOwnMessages;
+ bool ExtractOwnMessage(__int64 msgId, COwnMessage &res);
+
+ mir_cs m_csUsers;
+ OBJLIST<FacebookUser> m_users;
+
+ FacebookUser* FindUser(__int64 id);
+
+ FacebookUser *UserFromJson(const JSONNode &root, CMStringW &wszId, bool &bIsChat);
+
+ bool CheckOwnMessage(FacebookUser *pUser, __int64 offlineId, const char *pszMsgId);
+ void FetchAttach(const CMStringA &mid, __int64 fbid, CMStringA &szBody);
+
+ void OnLoggedIn();
+ void OnLoggedOut();
+
+ FacebookUser* RefreshThread(JSONNode &n);
+ FacebookUser* RefreshThread(CMStringW &wszId);
+ bool RefreshSid();
+ int RefreshToken();
+ void RefreshThreads();
+ int RefreshContacts();
+
+ FacebookUser *AddContact(const CMStringW &wszId, bool bTemp = true);
+
+ void __cdecl ServerThread(void *);
+
+public:
+ FacebookProto(const char *proto_name, const wchar_t *username);
+ ~FacebookProto();
+
+ inline const char *ModuleName() const
+ {
+ return m_szModuleName;
+ }
+
+ void OnPublishPrivateMessage(const JSONNode &json);
+ void OnPublishReadReceipt(const JSONNode &json);
+ void OnPublishSentMessage(const JSONNode &json);
+ void OnPublishThreadName(const JSONNode &json);
+ void OnPublishChatJoin(const JSONNode &json);
+ void OnPublishChatLeave(const JSONNode &json);
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // options
+
+ CMOption<wchar_t *> m_wszDefaultGroup; // clist group to store contacts
+ CMOption<bool> m_bUseBigAvatars; // use big or small avatars by default
+ CMOption<bool> m_bUseGroupchats; // do we need group chats at all?
+ CMOption<bool> m_bHideGroupchats; // do not open chat windows on creation
+ CMOption<bool> m_bLoginInvisible; // login in the invisible mode
+ CMOption<bool> m_bKeepUnread; // do not mark incoming messages as read
+ CMOption<bool> m_bLoadAll; // load all contacts, not only those who have ARE_FRIENDS status
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // PROTO_INTERFACE
+
+ void OnContactAdded(MCONTACT) override;
+ void OnModulesLoaded() override;
+ void OnShutdown() override;
+
+ MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr) override;
+ INT_PTR GetCaps(int type, MCONTACT hContact) override;
+ int SendMsg(MCONTACT hContact, int flags, const char *pszSrc) override;
+ int SetStatus(int iNewStatus) override;
+ int UserIsTyping(MCONTACT hContact, int type) override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // Events
+
+ int __cdecl OnMarkedRead(WPARAM, LPARAM);
+ int __cdecl OnOptionsInit(WPARAM, LPARAM);
+
+ int __cdecl GroupchatMenuHook(WPARAM, LPARAM);
+ int __cdecl GroupchatEventHook(WPARAM, LPARAM);
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // Services
+
+ INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
+ INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
+ INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM);
+};
+
+typedef CProtoDlgBase<FacebookProto> CFBDlgBase;
+
+struct CMPlugin : public ACCPROTOPLUGIN<FacebookProto>
+{
+ CMPlugin();
+
+ int Load() override;
+};