diff options
Diffstat (limited to 'protocols/FacebookRM/src/messages.cpp')
-rw-r--r-- | protocols/FacebookRM/src/messages.cpp | 395 |
1 files changed, 0 insertions, 395 deletions
diff --git a/protocols/FacebookRM/src/messages.cpp b/protocols/FacebookRM/src/messages.cpp deleted file mode 100644 index dc103b739d..0000000000 --- a/protocols/FacebookRM/src/messages.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* - -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" - -MEVENT FacebookProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) -{ - StopTyping(hContact); - - return CSuper::RecvMsg(hContact, pre); -} - -void FacebookProto::SendMsgWorker(void *p) -{ - if (p == nullptr) - return; - - send_direct *data = static_cast<send_direct*>(p); - - ptrA id(getStringA(data->hContact, FACEBOOK_KEY_ID)); - - if (!isOnline()) - ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)data->msgid, (LPARAM)TranslateT("You cannot send messages when you are offline.")); - else if (id == nullptr) - ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)data->msgid); - else { - int tries = getByte(FACEBOOK_KEY_SEND_MESSAGE_TRIES, 1); - tries = min(max(tries, 1), 5); - - std::string error_text; - int result = SEND_MESSAGE_ERROR; - while (result == SEND_MESSAGE_ERROR && tries-- > 0) - result = facy.send_message(data->msgid, data->hContact, data->msg, &error_text); - - if (result == SEND_MESSAGE_OK) { - ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)data->msgid); - - // Remove from "readers" list and clear statusbar - facy.erase_reader(data->hContact); - } - else ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)data->msgid, (LPARAM)_A2T(error_text.c_str())); - } - - delete data; -} - -void FacebookProto::SendChatMsgWorker(void *p) -{ - if (p == nullptr) - return; - - send_chat *data = static_cast<send_chat*>(p); - std::string err_message; - - // replace %% back to %, because chat automatically does this to sent messages - utils::text::replace_all(&data->msg, "%%", "%"); - - MCONTACT hContact = ChatIDToHContact(data->chat_id); - if (hContact) { - ptrA tid_(getStringA(hContact, FACEBOOK_KEY_TID)); - std::string tid; - if (tid_ != nullptr && mir_strcmp(tid_, "null")) - tid = tid_; - else { - // request info about chat thread - http::response resp = facy.sendRequest(facy.threadInfoRequest(true, data->chat_id.c_str())); - - tid = utils::text::source_get_value(&resp.data, 2, "\"thread_id\":\"", "\""); - if (!tid.empty() && tid.compare("null")) - setString(hContact, FACEBOOK_KEY_TID, tid.c_str()); - debugLogA(" Got thread info: %s = %s", data->chat_id.c_str(), tid.c_str()); - } - - if (!tid.empty()) { - if (facy.send_message(0, hContact, data->msg, &err_message) == SEND_MESSAGE_OK) - UpdateChat(data->chat_id.c_str(), facy.self_.user_id.c_str(), facy.self_.real_name.c_str(), data->msg.c_str()); - else { - ptrA text(mir_utf8encode(err_message.c_str())); - UpdateChat(data->chat_id.c_str(), nullptr, nullptr, text); - } - } - } - - delete data; -} - -int FacebookProto::SendMsg(MCONTACT hContact, int, const char *msg) -{ - std::string message = msg; - unsigned int msgId = InterlockedIncrement(&facy.msgid_); - - ForkThread(&FacebookProto::SendMsgWorker, new send_direct(hContact, message, msgId)); - return msgId; -} - -int FacebookProto::UserIsTyping(MCONTACT hContact, int type) -{ - if (hContact && isOnline()) - ForkThread(&FacebookProto::SendTypingWorker, new send_typing(hContact, type)); - - return 0; -} - -void FacebookProto::SendTypingWorker(void *p) -{ - if (p == nullptr) - return; - - send_typing *typing = static_cast<send_typing*>(p); - - // Don't send typing notifications when we are invisible and user don't want that - bool typingWhenInvisible = getBool(FACEBOOK_KEY_TYPING_WHEN_INVISIBLE, DEFAULT_TYPING_WHEN_INVISIBLE); - if (isInvisible() && !typingWhenInvisible) { - delete typing; - return; - } - - // Dont send typing notifications to not friends - Facebook won't give them that info anyway - if (!isChatRoom(typing->hContact) && getWord(typing->hContact, FACEBOOK_KEY_CONTACT_TYPE, 0) != CONTACT_FRIEND) { - delete typing; - return; - } - - const char *value = (isChatRoom(typing->hContact) ? FACEBOOK_KEY_TID : FACEBOOK_KEY_ID); - ptrA id(getStringA(typing->hContact, value)); - if (id != nullptr) - http::response resp = facy.sendRequest(facy.sendTypingRequest(id, isChatRoom(typing->hContact), typing->status == PROTOTYPE_SELFTYPING_ON)); - - delete typing; -} - -void FacebookProto::ReadMessageWorker(void *p) -{ - if (p == nullptr) - return; - - if (getBool(FACEBOOK_KEY_KEEP_UNREAD, 0)) - return; - - std::set<MCONTACT> *hContacts = (std::set<MCONTACT>*)p; - - if (hContacts->empty()) { - delete hContacts; - return; - } - - LIST<char> ids(1); - for (auto &hContact : *hContacts) { - if (getBool(hContact, FACEBOOK_KEY_KEEP_UNREAD, 0)) - continue; - - // mark message read (also send seen info) - const char *value = (isChatRoom(hContact) ? FACEBOOK_KEY_TID : FACEBOOK_KEY_ID); - ptrA id(getStringA(hContact, value)); - if (id == nullptr) - continue; - - ids.insert(mir_strdup(id)); - } - - hContacts->clear(); - delete hContacts; - - facy.sendRequest(facy.markMessageReadRequest(ids)); - - FreeList(ids); - ids.destroy(); -} - -void FacebookProto::StickerAsSmiley(std::string sticker, const std::string &url, MCONTACT hContact) -{ - // Don't load stickers as smileys when we're loading history - if (facy.loading_history) - return; - - std::string b64 = ptrA(mir_base64_encode(sticker.c_str(), sticker.length())); - b64 = utils::url::encode(b64); - - std::wstring filename = GetAvatarFolder() + L"\\stickers\\"; - ptrW dir(mir_wstrdup(filename.c_str())); - - filename += (wchar_t*)_A2T(b64.c_str()); - filename += L".png"; - - // Check if we have this sticker already and download it if not - if (GetFileAttributes(filename.c_str()) == INVALID_FILE_ATTRIBUTES) { - HNETLIBCONN nlc = nullptr; - facy.save_url(url, filename, nlc); - Netlib_CloseHandle(nlc); - } - - SMADD_CONT cont; - cont.cbSize = sizeof(SMADD_CONT); - cont.hContact = hContact; - cont.type = 0; - cont.path = dir; - CallService(MS_SMILEYADD_LOADCONTACTSMILEYS, 0, (LPARAM)&cont); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -HttpRequest* facebook_client::sendMessageRequest( - const char *userId, - const char *threadId, - const char *messageId, - const char *messageText, - bool isChat, - const char *captcha, - const char *captchaPersistData) -{ - HttpRequest *p = new HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/messaging/send/"); - - // Don't notify errors for this request, because we're getting them inline in messaging window - p->NotifyErrors = false; - - // Use own persistent connection for sending messages - p->Persistent = p->MESSAGES; - - p << INT_PARAM("dpr", 1); - - if (mir_strlen(captcha) > 0) - p->Body << CHAR_PARAM("captcha_persist_data", captchaPersistData) << CHAR_PARAM("captcha_response", captcha); - - p->Body << CHAR_PARAM("client", "mercury") << CHAR_PARAM("action_type", "ma-type:user-generated-message"); - - // Experimental sticker sending support - std::string message_text = messageText; // FIXME: Rewrite this without std::string... - if (message_text.substr(0, 10) == "[[sticker:" && message_text.substr(message_text.length() - 2) == "]]") - // TODO: For sending GIF images instead of "sticker_id=" there is "image_ids[0]=", otherwise it's same - p->Body - << CHAR_PARAM("body", "") - << CHAR_PARAM("sticker_id", message_text.substr(10, message_text.length() - 10 - 2).c_str()) - << BOOL_PARAM("has_attachment", true); - else - p->Body << CHAR_PARAM("body", messageText) << BOOL_PARAM("has_attachment", false); - - p->Body - << INT_PARAM("ephemeral_ttl_mode", 0) - << CHAR_PARAM("message_id", messageId) - << CHAR_PARAM("offline_threading_id", messageId); // Same as message ID - - if (isChat) { - // NOTE: Remove "id." prefix as here we need to give threadFbId and not threadId - std::string threadFbid = threadId; // FIXME: Rewrite this without std::string... - if (threadFbid.substr(0, 3) == "id.") - threadFbid = threadFbid.substr(3); - - p->Body << CHAR_PARAM("thread_fbid", threadFbid.c_str()); - } - else - p->Body - << CHAR_PARAM("other_user_fbid", userId) - << CHAR_PARAM("specific_to_list[0]", CMStringA(::FORMAT, "fbid:%s", userId)) - << CHAR_PARAM("specific_to_list[1]", CMStringA(::FORMAT, "fbid:%s", self_.user_id.c_str())); - - p->Body - // << "signature_id=" // TODO: How to generate signature ID? It is present only when sending via "mercury" - << CHAR_PARAM("source", "source:chat:web") // or "source:titan:web" for web_messenger - << CHAR_PARAM("timestamp", utils::time::mili_timestamp().c_str()) - << CHAR_PARAM("ui_push_phase", "V3") - << CHAR_PARAM("__user", self_.user_id.c_str()) - << CHAR_PARAM("__dyn", __dyn()) - << CHAR_PARAM("__req", __req()) - << CHAR_PARAM("__rev", __rev()) - << CHAR_PARAM("fb_dtsg", dtsg_.c_str()) - << CHAR_PARAM("ttstamp", ttstamp_.c_str()) - << INT_PARAM("__a", 1) - << CHAR_PARAM("__pc", "PHASED:DEFAULT") - << INT_PARAM("__be", -1); - - return p; -} - -HttpRequest* facebook_client::sendTypingRequest(const char *userId, bool isChat, bool isTyping) -{ - HttpRequest *p = new HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/ajax/messaging/typ.php"); - - p << INT_PARAM("dpr", 1); - - p->Body - << INT_PARAM("typ", isTyping ? 1 : 0) - << CHAR_PARAM("to", isChat ? "" : userId) - << CHAR_PARAM("thread", userId) - << CHAR_PARAM("source", "mercury-chat") - << CHAR_PARAM("__user", self_.user_id.c_str()) - << CHAR_PARAM("__dyn", __dyn()) - << CHAR_PARAM("__req", __req()) - << CHAR_PARAM("__rev", __rev()) - << CHAR_PARAM("fb_dtsg", dtsg_.c_str()) - << CHAR_PARAM("ttstamp", ttstamp_.c_str()) - << CHAR_PARAM("__pc", "PHASED:DEFAULT") - << INT_PARAM("__a", 1) - << INT_PARAM("__be", -1); - - return p; -} - -HttpRequest* facebook_client::markMessageReadRequest(const LIST<char> &ids) -{ - HttpRequest *p = new HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/ajax/mercury/change_read_status.php"); - - p << INT_PARAM("__a", 1); - - for (auto &it : ids) { - std::string id_ = it; - // NOTE: Remove "id." prefix as here we need to give threadFbId and not threadId - if (id_.substr(0, 3) == "id.") - id_ = id_.substr(3); - - CMStringA id(::FORMAT, "ids[%s]", mir_urlEncode(id_.c_str()).c_str()); - p->Body << BOOL_PARAM(id, true); - } - - p->Body - << CHAR_PARAM("fb_dtsg", dtsg_.c_str()) - << CHAR_PARAM("ttstamp", ttstamp_.c_str()) - << CHAR_PARAM("__user", self_.user_id.c_str()) - << CHAR_PARAM("__dyn", __dyn()) - << CHAR_PARAM("__req", __req()) - << CHAR_PARAM("__rev", __rev()) - << INT_PARAM("__a", 1); - - return p; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -HttpRequest* facebook_client::destroyThreadRequest(facebook_chatroom *fbc) -{ - HttpRequest *p = new HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/ajax/mercury/delete_thread.php"); - - p << INT_PARAM("dpr", 1); - - p->Body - << CHAR_PARAM("ids[0]", fbc->thread_id.substr(3).c_str()) - << CHAR_PARAM("__user", self_.user_id.c_str()) - << CHAR_PARAM("fb_dtsg", dtsg_.c_str()) - << CHAR_PARAM("__dyn", __dyn()) - << CHAR_PARAM("__req", __req()) - << CHAR_PARAM("__rev", __rev()) - << CHAR_PARAM("__pc", "PHASED:DEFAULT") - << INT_PARAM("__a", 1) - << INT_PARAM("__be", 1); - - return p; -} - -HttpRequest* facebook_client::exitThreadRequest(facebook_chatroom *fbc) -{ - HttpRequest *p = new HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/messaging/send/"); - - p << INT_PARAM("dpr", 1); - - std::string msgid = utils::text::rand_string(15); - - p->Body - << CHAR_PARAM("client", "mercury") - << CHAR_PARAM("action_type", "ma-type:log-message") - << CHAR_PARAM("log_message_data[removed_participants][0]", ("fbid:" + self_.user_id).c_str()) - << CHAR_PARAM("log_message_type", "log:unsubscribe") - << CHAR_PARAM("message_id", msgid.c_str()) - << CHAR_PARAM("offline_threading_id", msgid.c_str()) - << CHAR_PARAM("source", "source:chat:web") - << CHAR_PARAM("thread_fbid", fbc->thread_id.substr(3).c_str()) - << CHAR_PARAM("fb_dtsg", dtsg_.c_str()) - << INT64_PARAM("timestamp", ::time(0) * 1000) - << CHAR_PARAM("__user", self_.user_id.c_str()) - << CHAR_PARAM("__dyn", __dyn()) - << CHAR_PARAM("__req", __req()) - << CHAR_PARAM("__rev", __rev()) - << CHAR_PARAM("__pc", "PHASED:DEFAULT") - << INT_PARAM("__a", 1) - << INT_PARAM("__be", 1); - - return p; -} |