/* Facebook plugin for Miranda Instant Messenger _____________________________________________ Copyright © 2009-11 Michal Zelinka, 2011-17 Robert Pösel, 2017-18 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 . */ #include "constants.h" #pragma once #define FORCE_DISCONNECT 1 #define FORCE_QUIT 2 class facebook_client { public: //////////////////////////////////////////////////////////// // Client definition facebook_client() { } // Random generator value for this client unsigned int random_ = 0; // Parent handle FacebookProto *parent = nullptr; // User data facebook_user self_; std::string username_; std::string password_; std::string dtsg_; std::string ttstamp_; std::string logout_hash_; std::string chat_channel_; std::string chat_channel_host_; std::string chat_channel_partition_; std::string chat_sequence_num_; std::string chat_reconnect_reason_; std::string chat_sticky_num_; std::string chat_sticky_pool_; std::string chat_conn_num_; std::string chat_clientid_; std::string chat_traceid_; time_t last_feeds_update_ = 0; time_t last_notification_time_ = 0; volatile unsigned int msgid_ = 0; int chat_msgs_recv_ = 0; volatile unsigned int chat_req_ = 0; bool mbasicWorks = true; //////////////////////////////////////////////////////////// // Client vs protocol communication void client_notify(wchar_t* message); void info_notify(wchar_t* message); //////////////////////////////////////////////////////////// // Cookies, Data storage mir_cs cookies_lock_; std::map cookies; std::map pages; std::map chat_rooms; std::map notifications; // Contact/thread id caches std::map thread_id_to_user_id; std::map chat_id_to_hcontact; std::map user_id_to_hcontact; std::string get_server_type(); std::string get_privacy_type(); std::set ignore_read; std::set typers; // store info about typing contacts, because Facebook doesn't send "stopped typing" event when there is actual message being sent std::map readers; char* load_cookies(); void store_headers(http::response* resp, NETLIBHTTPHEADER* headers, int headers_count); void clear_cookies(); void clear_notifications(); void clear_chatrooms(); void clear_readers(); void insert_reader(MCONTACT, time_t, const std::string &readerId = ""); void erase_reader(MCONTACT); //////////////////////////////////////////////////////////// // Connection handling unsigned int error_count_ = 0; bool handle_entry(const std::string &method); bool handle_success(const std::string &method); bool handle_error(const std::string &method, int force_disconnect = 0); void __inline increment_error() { this->error_count_++; } void __inline decrement_error() { if (error_count_ > 0) error_count_--; } void __inline reset_error() { error_count_ = 0; } //////////////////////////////////////////////////////////// // Helpers for data __inline const char *__dyn() const { return "7AzkXxaA4ojgDxyLqzGomzEbHGbGey8WhLFwgoqwWhE98nwgUaoepovHyodEbbxW4E4u3ucDBwJx62i2PxOcG4K1Zxa2m4oqyUf8oCK251G6XDwnU567oeo5m4pHxC326U6OfBwHx"; // FIXME: What's this value and where it come from? Looks like it is the same through all requests. } __inline CMStringA __req() { // Increment request number and convert it to string with radix 36 (whole numbers + whole alphabet) char buffer[10]; itoa(InterlockedIncrement(&this->chat_req_), buffer, 36); return CMStringA(buffer); } __inline const char *__rev() const { return "3553943"; } //////////////////////////////////////////////////////////// // Login handling bool login(const char *username, const char *password); bool logout(); bool sms_code(const char *fb_dtsg); //////////////////////////////////////////////////////////// // Session handling bool home(); bool reconnect(); bool chat_state(bool online = true); //////////////////////////////////////////////////////////// // Updates handling mir_cs send_message_lock_; mir_cs notifications_lock_; //////////////////////////////////////////////////////////// // Messages handling std::map messages_ignore; std::map messages_timestamp; bool loading_history = false; mir_cs loading_history_lock_; bool channel(); bool activity_ping(); int send_message(int seqid, MCONTACT, const std::string &message_text, std::string *error_text, const std::string &captchaPersistData = "", const std::string &captcha = ""); //////////////////////////////////////////////////////////// // Status handling bool post_status(status_data *data); //////////////////////////////////////////////////////////// // HTTP communication http::response sendRequest(class HttpRequest *request); bool save_url(const std::string &url, const std::wstring &filename, HNETLIBCONN &nlc); // channel.cpp enum Type { PULL, PING }; HttpRequest* channelRequest(Type type); // contacts.cpp HttpRequest* addFriendRequest(const char *userId); HttpRequest* deleteFriendRequest(const char *userId); HttpRequest* getFriendshipsRequest(); HttpRequest* answerFriendshipRequest(const char *userId, bool bConfirm); HttpRequest* cancelFriendshipRequest(const char *userId); HttpRequest* userInfoRequest(const LIST &userIds); HttpRequest* userInfoAllRequest(); // feeds.cpp HttpRequest* newsfeedRequest(); HttpRequest* memoriesRequest(); // history.cpp HttpRequest* threadInfoRequest(bool isChat, const char *id, const char* timestamp = nullptr, int limit = -1, bool loadMessages = false); HttpRequest* threadInfoRequest(const LIST &ids, int limit); HttpRequest* unreadThreadsRequest(); // login.cpp HttpRequest* loginRequest(); HttpRequest* loginRequest(const char *username, const char *password, const char *urlData, const char *bodyData); HttpRequest* logoutRequest(); HttpRequest* loginSmsRequest(const char *dtsg); HttpRequest* setupMachineRequest(); HttpRequest* setupMachineRequest(const char *dtsg, const char *nh, const char *submit); // messages.cpp HttpRequest* sendMessageRequest(const char *userId, const char *threadId, const char *messageId, const char *messageText, bool isChat, const char *captcha, const char *captchaPersistData); HttpRequest* sendTypingRequest(const char *userId, bool isChat, bool isTyping); HttpRequest* markMessageReadRequest(const LIST &ids); HttpRequest* destroyThreadRequest(facebook_chatroom *fbc); HttpRequest* exitThreadRequest(facebook_chatroom *fbc); // notifications.cpp HttpRequest* getNotificationsRequest(int count); HttpRequest* markNotificationReadRequest(const char *id); // profile.cpp HttpRequest* homeRequest(); HttpRequest* dtsgRequest(); HttpRequest* profileRequest(const char *data); HttpRequest* profileInfoRequest(const char *userId); HttpRequest* profilePictureRequest(const char *userId); // search.cpp HttpRequest* searchRequest(const char *query, int s, int pn, const char *ssid); // status.cpp HttpRequest* reconnectRequest(); HttpRequest* setVisibilityRequest(bool online); // utils.cpp HttpRequest* linkScraperRequest(status_data *status); HttpRequest* refreshCaptchaRequest(const char *captchaPersistData); HttpRequest* getPagesRequest(); HttpRequest* switchIdentityRequest(const char *userId); HttpRequest* sharePostRequest(status_data *status, const char *linkData); HttpRequest* sendPokeRequest(const char *userId); //////////////////////////////////////////////////////////// // Netlib handle HNETLIBUSER handle_ = nullptr; void set_handle(HNETLIBUSER h) { handle_ = h; } };