diff options
-rw-r--r-- | protocols/FacebookRM/src/client.h | 5 | ||||
-rw-r--r-- | protocols/FacebookRM/src/communication.cpp | 124 | ||||
-rw-r--r-- | protocols/FacebookRM/src/connection.cpp | 27 | ||||
-rw-r--r-- | protocols/FacebookRM/src/contacts.cpp | 55 | ||||
-rw-r--r-- | protocols/FacebookRM/src/process.cpp | 163 | ||||
-rw-r--r-- | protocols/FacebookRM/src/proto.cpp | 4 | ||||
-rw-r--r-- | protocols/FacebookRM/src/proto.h | 3 | ||||
-rw-r--r-- | protocols/FacebookRM/src/version.h | 4 |
8 files changed, 162 insertions, 223 deletions
diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h index 3e6993eb9a..b17cc8b202 100644 --- a/protocols/FacebookRM/src/client.h +++ b/protocols/FacebookRM/src/client.h @@ -148,11 +148,6 @@ public: HANDLE buddies_lock_;
HANDLE send_message_lock_;
- bool buddy_list();
- bool load_friends();
- bool load_pages();
- bool feeds();
-
////////////////////////////////////////////////////////////
// Messages handling
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp index 6eb267b1e0..4caf79d536 100644 --- a/protocols/FacebookRM/src/communication.cpp +++ b/protocols/FacebookRM/src/communication.cpp @@ -1009,130 +1009,6 @@ bool facebook_client::reconnect() } } -bool facebook_client::buddy_list() -{ - handle_entry("buddy_list"); - - // Prepare update data - std::string data = "user=" + this->self_.user_id + "&fetch_mobile=true&phstamp=0&fb_dtsg=" + this->dtsg_ + "&__user=" + this->self_.user_id; - - { - ScopedLock s(buddies_lock_); - - data += "&cached_user_info_ids="; - int counter = 0; - for (List::Item< facebook_user >* i = buddies.begin(); i != NULL; i = i->next, counter++) - { - data += i->data->user_id + "%2C"; - } - } - - // Get buddy list - http::response resp = flap(REQUEST_BUDDY_LIST, &data); - - switch (resp.code) { - case HTTP_CODE_OK: - parent->ForkThread(&FacebookProto::ProcessBuddyList, new std::string(resp.data)); - return handle_success("buddy_list"); - - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("buddy_list"); - } -} - -bool facebook_client::load_friends() -{ - handle_entry("load_friends"); - - // Get buddy list - http::response resp = flap(REQUEST_LOAD_FRIENDS); - - switch (resp.code) { - case HTTP_CODE_OK: - parent->ForkThread(&FacebookProto::ProcessFriendList, new std::string(resp.data)); - return handle_success("load_friends"); - - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("load_friends"); - } -} - -bool facebook_client::feeds() -{ - handle_entry("feeds"); - - // Get feeds - http::response resp = flap(REQUEST_FEEDS); - - switch (resp.code) { - case HTTP_CODE_OK: - if (resp.data.find("\"num_stories\":0") == std::string::npos) - parent->ForkThread(&FacebookProto::ProcessFeeds, new std::string(resp.data)); - - return handle_success("feeds"); - - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("feeds"); - } -} - -bool facebook_client::load_pages() -{ - if (!parent->getByte(FACEBOOK_KEY_LOAD_PAGES, DEFAULT_LOAD_PAGES)) - return true; - - handle_entry("load_pages"); - - // Get feeds - http::response resp = flap(REQUEST_PAGES); - - switch (resp.code) { - case HTTP_CODE_OK: - { - std::string content = utils::text::source_get_value(&resp.data, 2, "id=\"bookmarksSeeAllSection\"", "</code>"); - - std::string::size_type start, end; - start = content.find("<li", 0); - while (start != std::string::npos) { - end = content.find("<li", start+1); - if (end == std::string::npos) - end = content.length(); - - std::string item = content.substr(start, end - start); - //item = utils::text::source_get_value(&item, 2, "data-gt=", ">"); - - start = content.find("<li", start+1); - - std::string id = utils::text::source_get_value(&item, 3, "data-gt=", "bmid":"", """); - std::string title = utils::text::special_expressions_decode(utils::text::slashu_to_utf8(utils::text::source_get_value(&item, 3, "data-gt=", "title=\"", "\""))); - std::string href = utils::text::source_get_value(&item, 3, "data-gt=", "href=\"", "\""); - - // Ignore pages channel - if (href.find("/pages/feed") != std::string::npos) - continue; - - if (id.empty() || title.empty()) - continue; - - parent->debugLogA(" Got page: %s (%s)", title.c_str(), id.c_str()); - pages[id] = title; - } - - return handle_success("load_pages"); - } - case HTTP_CODE_FAKE_ERROR: - case HTTP_CODE_FAKE_DISCONNECTED: - default: - return handle_error("load_pages"); - } -} - bool facebook_client::channel() { handle_entry("channel"); diff --git a/protocols/FacebookRM/src/connection.cpp b/protocols/FacebookRM/src/connection.cpp index 4ff500a31b..48c290dfba 100644 --- a/protocols/FacebookRM/src/connection.cpp +++ b/protocols/FacebookRM/src/connection.cpp @@ -77,13 +77,12 @@ void FacebookProto::ChangeStatus(void*) ResetEvent(update_loop_lock_);
- if (NegotiateConnection() && facy.home())
+ if (NegotiateConnection() && facy.home() && facy.reconnect())
{
- facy.reconnect();
- facy.load_friends();
- facy.load_pages();
+ // Load all friends
+ ProcessFriendList(NULL);
- // Process Friends requests
+ // Process friendship requests
ForkThread(&FacebookProto::ProcessFriendRequests, NULL);
// Get unread messages
@@ -92,6 +91,9 @@ void FacebookProto::ChangeStatus(void*) // Get notifications
ForkThread(&FacebookProto::ProcessNotifications, NULL);
+ // Load pages for post status dialog
+ ForkThread(&FacebookProto::ProcessPages, NULL);
+
setDword("LogonTS", (DWORD)time(NULL));
ForkThread(&FacebookProto::UpdateLoop, NULL);
ForkThread(&FacebookProto::MessageLoop, NULL);
@@ -122,7 +124,8 @@ void FacebookProto::ChangeStatus(void*) }
facy.chat_state(m_iDesiredStatus != ID_STATUS_INVISIBLE);
- facy.buddy_list();
+
+ ForkThread(&FacebookProto::ProcessBuddyList, NULL);
m_iStatus = facy.self_.status_id = m_iDesiredStatus;
ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
@@ -175,16 +178,14 @@ void FacebookProto::UpdateLoop(void *) for (int i = -1; !isOffline(); i = ++i % 50)
{
- if (i != -1) {
- if (!facy.buddy_list())
- break;
- }
+ if (i != -1)
+ ProcessBuddyList(NULL);
+
if (i == 2 && getByte(FACEBOOK_KEY_EVENT_FEEDS_ENABLE, DEFAULT_EVENT_FEEDS_ENABLE))
- if (!facy.feeds())
- break;
+ ProcessFeeds(NULL);
if (i == 49)
- ForkThread(&FacebookProto::ProcessFriendRequests, NULL);
+ ProcessFriendRequests(NULL);
debugLogA("***** FacebookProto::UpdateLoop[%d] going to sleep...", tim);
if (WaitForSingleObjectEx(update_loop_lock_, GetPollRate() * 1000, true) != WAIT_TIMEOUT)
diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp index 5c82419ac1..2fb0d5fb70 100644 --- a/protocols/FacebookRM/src/contacts.cpp +++ b/protocols/FacebookRM/src/contacts.cpp @@ -171,50 +171,43 @@ void FacebookProto::LoadContactInfo(facebook_user* fbu) } } -MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_save) +MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_add) { - MCONTACT hContact; + // First, check if this contact exists (and if does, just return it) + if (!force_add) { + MCONTACT hContact = ContactIDToHContact(fbu->user_id); - // First, check if this contact exists - hContact = ContactIDToHContact(fbu->user_id); - - // If we have contact and don't need to force save data, just return it - if (hContact && !force_save) - return hContact; - - force_save = !hContact; + if (hContact) + return hContact; + } - // If not, try to make a new contact - if (!hContact) { - hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); + // Try to make a new contact + MCONTACT hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); - if (hContact && CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName) != 0) { - CallService(MS_DB_CONTACT_DELETE, hContact, 0); - hContact = NULL; - } + if (hContact && CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName) != 0) { + CallService(MS_DB_CONTACT_DELETE, hContact, 0); + hContact = NULL; } // If we have some contact, we'll save its data if (hContact) { - if (force_save) { - // Save these values only when adding new contact, not when updating existing - setString(hContact, FACEBOOK_KEY_ID, fbu->user_id.c_str()); + // Save these values only when adding new contact, not when updating existing + setString(hContact, FACEBOOK_KEY_ID, fbu->user_id.c_str()); - std::string homepage = FACEBOOK_URL_PROFILE + fbu->user_id; - setString(hContact, "Homepage", homepage.c_str()); - setTString(hContact, "MirVer", fbu->getMirVer()); + std::string homepage = FACEBOOK_URL_PROFILE + fbu->user_id; + setString(hContact, "Homepage", homepage.c_str()); + setTString(hContact, "MirVer", fbu->getMirVer()); - db_unset(hContact, "CList", "MyHandle"); + db_unset(hContact, "CList", "MyHandle"); - ptrT group(getTStringA(NULL, FACEBOOK_KEY_DEF_GROUP)); - if (group) - db_set_ts(hContact, "CList", "Group", group); + ptrT group(getTStringA(NULL, FACEBOOK_KEY_DEF_GROUP)); + if (group) + db_set_ts(hContact, "CList", "Group", group); - setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, type); + setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, type); - if (getByte(FACEBOOK_KEY_DISABLE_STATUS_NOTIFY, 0)) - CallService(MS_IGNORE_IGNORE, hContact, (LPARAM)IGNOREEVENT_USERONLINE); - } + if (getByte(FACEBOOK_KEY_DISABLE_STATUS_NOTIFY, 0)) + CallService(MS_IGNORE_IGNORE, hContact, (LPARAM)IGNOREEVENT_USERONLINE); if (!fbu->real_name.empty()) SaveName(hContact, fbu); diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp index 8b4778f8b2..639fdee23d 100644 --- a/protocols/FacebookRM/src/process.cpp +++ b/protocols/FacebookRM/src/process.cpp @@ -22,24 +22,38 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "common.h"
-void FacebookProto::ProcessBuddyList(void* data)
+void FacebookProto::ProcessBuddyList(void*)
{
- if (data == NULL)
+ ScopedLock s(facy.buddies_lock_);
+
+ if (isOffline())
return;
- ScopedLock s(facy.buddies_lock_);
+ facy.handle_entry("ProcessBuddyList");
- std::string* resp = (std::string*)data;
+ // Prepare update data
+ std::string post_data = "user=" + facy.self_.user_id + "&fetch_mobile=true&phstamp=0&fb_dtsg=" + facy.dtsg_ + "&__user=" + facy.self_.user_id + "&cached_user_info_ids=";
+
+ int counter = 0;
+ for (List::Item< facebook_user >* i = facy.buddies.begin(); i != NULL; i = i->next, counter++)
+ {
+ post_data += i->data->user_id + "%2C";
+ }
- if (isOffline())
- goto exit;
+ // Get buddy list
+ http::response resp = facy.flap(REQUEST_BUDDY_LIST, &post_data);
+
+ if (resp.code != HTTP_CODE_OK) {
+ facy.handle_error("buddy_list");
+ return;
+ }
debugLogA("***** Starting processing buddy list");
CODE_BLOCK_TRY
facebook_json_parser* p = new facebook_json_parser(this);
- p->parse_buddy_list(data, &facy.buddies);
+ p->parse_buddy_list(&resp.data, &facy.buddies);
delete p;
for (List::Item< facebook_user >* i = facy.buddies.begin(); i != NULL;)
@@ -130,17 +144,24 @@ void FacebookProto::ProcessBuddyList(void* data) debugLogA("***** Error processing buddy list: %s", e.what());
CODE_BLOCK_END
-
-exit:
- delete resp;
}
-void FacebookProto::ProcessFriendList(void* data)
+void FacebookProto::ProcessFriendList(void*)
{
- if (data == NULL)
+ ScopedLock s(facy.buddies_lock_);
+
+ if (isOffline())
return;
- std::string* resp = (std::string*)data;
+ facy.handle_entry("load_friends");
+
+ // Get buddy list
+ http::response resp = facy.flap(REQUEST_LOAD_FRIENDS);
+
+ if (resp.code != HTTP_CODE_OK) {
+ facy.handle_error("load_friends");
+ return;
+ }
debugLogA("***** Starting processing friend list");
@@ -149,7 +170,7 @@ void FacebookProto::ProcessFriendList(void* data) std::map<std::string, facebook_user*> friends;
facebook_json_parser* p = new facebook_json_parser(this);
- p->parse_friends(data, &friends);
+ p->parse_friends(&resp.data, &friends);
delete p;
@@ -234,7 +255,7 @@ void FacebookProto::ProcessFriendList(void* data) // Check remaining contacts in map and add them to contact list
for (std::map< std::string, facebook_user* >::iterator it = friends.begin(); it != friends.end(); ) {
if (!it->second->deleted)
- AddToContactList(it->second, CONTACT_FRIEND, true); // there could be race-condition between this thread and channel/buddy_list thread, so this contact might be created already
+ AddToContactList(it->second, CONTACT_FRIEND, true); // we know this contact doesn't exists, so we force add it
delete it->second;
it = friends.erase(it);
@@ -248,8 +269,6 @@ void FacebookProto::ProcessFriendList(void* data) debugLogA("***** Error processing friend list: %s", e.what());
CODE_BLOCK_END
-
- delete resp;
}
void FacebookProto::ProcessUnreadMessages(void*)
@@ -269,30 +288,30 @@ void FacebookProto::ProcessUnreadMessages(void*) http::response resp = facy.flap(REQUEST_UNREAD_THREADS, &data);
- if (resp.code == HTTP_CODE_OK) {
-
- CODE_BLOCK_TRY
+ if (resp.code != HTTP_CODE_OK) {
+ facy.handle_error("ProcessUnreadMessages");
+ return;
+ }
+
+ CODE_BLOCK_TRY
- std::vector<std::string> threads;
+ std::vector<std::string> threads;
- facebook_json_parser* p = new facebook_json_parser(this);
- p->parse_unread_threads(&resp.data, &threads, inboxOnly);
- delete p;
+ facebook_json_parser* p = new facebook_json_parser(this);
+ p->parse_unread_threads(&resp.data, &threads, inboxOnly);
+ delete p;
- ForkThread(&FacebookProto::ProcessUnreadMessage, new std::vector<std::string>(threads));
+ ForkThread(&FacebookProto::ProcessUnreadMessage, new std::vector<std::string>(threads));
- debugLogA("***** Unread threads list processed");
+ debugLogA("***** Unread threads list processed");
- CODE_BLOCK_CATCH
+ CODE_BLOCK_CATCH
- debugLogA("***** Error processing unread threads list: %s", e.what());
+ debugLogA("***** Error processing unread threads list: %s", e.what());
- CODE_BLOCK_END
+ CODE_BLOCK_END
- facy.handle_success("ProcessUnreadMessages");
- } else {
- facy.handle_error("ProcessUnreadMessages");
- }
+ facy.handle_success("ProcessUnreadMessages");
}
void FacebookProto::ProcessUnreadMessage(void *p)
@@ -717,13 +736,21 @@ void FacebookProto::ProcessFriendRequests(void*) void FacebookProto::ProcessFeeds(void* data)
{
- if (data == NULL)
+ if (!isOnline())
return;
- std::string* resp = (std::string*)data;
+ facy.handle_entry("feeds");
- if (!isOnline())
- goto exit;
+ // Get feeds
+ http::response resp = facy.flap(REQUEST_FEEDS);
+
+ if (resp.code != HTTP_CODE_OK) {
+ facy.handle_error("feeds");
+ return;
+ }
+
+ if (resp.data.empty() || resp.data.find("\"num_stories\":0") != std::string::npos)
+ return;
CODE_BLOCK_TRY
@@ -734,16 +761,16 @@ void FacebookProto::ProcessFeeds(void* data) std::string::size_type pos = 0;
UINT limit = 0;
- *resp = utils::text::slashu_to_utf8(*resp);
- *resp = utils::text::source_get_value(resp, 2, "\"html\":\"", ">\"");
+ resp.data = utils::text::slashu_to_utf8(resp.data);
+ resp.data = utils::text::source_get_value(&resp.data, 2, "\"html\":\"", ">\"");
- while ((pos = resp->find("<div class=\\\"mainWrapper\\\"", pos)) != std::string::npos && limit <= 25)
+ while ((pos = resp.data.find("<div class=\\\"mainWrapper\\\"", pos)) != std::string::npos && limit <= 25)
{
- std::string::size_type pos2 = resp->find("<div class=\\\"mainWrapper\\\"", pos+5);
+ std::string::size_type pos2 = resp.data.find("<div class=\\\"mainWrapper\\\"", pos+5);
if (pos2 == std::string::npos)
- pos2 = resp->length();
+ pos2 = resp.data.length();
- std::string post = resp->substr(pos, pos2 - pos);
+ std::string post = resp.data.substr(pos, pos2 - pos);
pos += 5;
std::string post_header = utils::text::source_get_value(&post, 4, "<h5 class=", "uiStreamHeadline", ">", "<\\/h5>");
@@ -817,8 +844,54 @@ void FacebookProto::ProcessFeeds(void* data) CODE_BLOCK_END
-exit:
- delete resp;
+ facy.handle_success("feeds");
+}
+
+void FacebookProto::ProcessPages(void *data)
+{
+ if (!getByte(FACEBOOK_KEY_LOAD_PAGES, DEFAULT_LOAD_PAGES))
+ return;
+
+ facy.handle_entry("load_pages");
+
+ // Get feeds
+ http::response resp = facy.flap(REQUEST_PAGES);
+
+ if (resp.code != HTTP_CODE_OK) {
+ facy.handle_error("load_pages");
+ return;
+ }
+
+ std::string content = utils::text::source_get_value(&resp.data, 2, "id=\"bookmarksSeeAllSection\"", "</code>");
+
+ std::string::size_type start, end;
+ start = content.find("<li", 0);
+ while (start != std::string::npos) {
+ end = content.find("<li", start + 1);
+ if (end == std::string::npos)
+ end = content.length();
+
+ std::string item = content.substr(start, end - start);
+ //item = utils::text::source_get_value(&item, 2, "data-gt=", ">");
+
+ start = content.find("<li", start + 1);
+
+ std::string id = utils::text::source_get_value(&item, 3, "data-gt=", "bmid":"", """);
+ std::string title = utils::text::special_expressions_decode(utils::text::slashu_to_utf8(utils::text::source_get_value(&item, 3, "data-gt=", "title=\"", "\"")));
+ std::string href = utils::text::source_get_value(&item, 3, "data-gt=", "href=\"", "\"");
+
+ // Ignore pages channel
+ if (href.find("/pages/feed") != std::string::npos)
+ continue;
+
+ if (id.empty() || title.empty())
+ continue;
+
+ debugLogA(" Got page: %s (%s)", title.c_str(), id.c_str());
+ facy.pages[id] = title;
+ }
+
+ facy.handle_success("load_pages");
}
void FacebookProto::SearchAckThread(void *targ)
diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp index abd24e7d7d..b94bd1d5db 100644 --- a/protocols/FacebookRM/src/proto.cpp +++ b/protocols/FacebookRM/src/proto.cpp @@ -523,7 +523,7 @@ INT_PTR FacebookProto::CheckNewsfeeds(WPARAM, LPARAM) {
if (!isOffline()) {
facy.client_notify(TranslateT("Loading newsfeeds..."));
- facy.feeds();
+ ForkThread(&FacebookProto::ProcessFeeds, NULL);
}
return 0;
}
@@ -541,7 +541,7 @@ INT_PTR FacebookProto::RefreshBuddyList(WPARAM, LPARAM) {
if (!isOffline()) {
facy.client_notify(TranslateT("Refreshing buddy list..."));
- facy.buddy_list();
+ ForkThread(&FacebookProto::ProcessBuddyList, NULL);
}
return 0;
}
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h index 1cc6cce4f9..716cdd3d62 100644 --- a/protocols/FacebookRM/src/proto.h +++ b/protocols/FacebookRM/src/proto.h @@ -168,6 +168,7 @@ public: void __cdecl ProcessFriendRequests(void*);
void __cdecl SearchAckThread(void*);
void __cdecl SearchIdAckThread(void*);
+ void __cdecl ProcessPages(void*);
// Worker threads
void __cdecl SignOn(void*);
@@ -192,7 +193,7 @@ public: MCONTACT ChatIDToHContact(std::tstring);
std::string ThreadIDToContactID(std::string thread_id);
void FacebookProto::LoadContactInfo(facebook_user* fbu);
- MCONTACT AddToContactList(facebook_user*, ContactType type, bool force_save = false);
+ MCONTACT AddToContactList(facebook_user*, ContactType type, bool force_add = false);
void SetAllContactStatuses(int status);
MCONTACT HContactFromAuthEvent(HANDLE hEvent);
diff --git a/protocols/FacebookRM/src/version.h b/protocols/FacebookRM/src/version.h index 12c19d23ed..33e28ff56f 100644 --- a/protocols/FacebookRM/src/version.h +++ b/protocols/FacebookRM/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0
#define __MINOR_VERSION 2
-#define __RELEASE_NUM 4
-#define __BUILD_NUM 1
+#define __RELEASE_NUM 5
+#define __BUILD_NUM 0
#include <stdver.h>
|