summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/FacebookRM/src/communication.cpp14
-rw-r--r--protocols/FacebookRM/src/constants.h11
-rw-r--r--protocols/FacebookRM/src/process.cpp78
-rw-r--r--protocols/FacebookRM/src/proto.cpp36
-rw-r--r--protocols/FacebookRM/src/proto.h1
-rw-r--r--protocols/FacebookRM/src/utils.cpp4
-rw-r--r--protocols/FacebookRM/src/utils.h2
7 files changed, 110 insertions, 36 deletions
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp
index c1b012672f..5ef0009d30 100644
--- a/protocols/FacebookRM/src/communication.cpp
+++ b/protocols/FacebookRM/src/communication.cpp
@@ -225,6 +225,7 @@ DWORD facebook_client::choose_security_level(RequestType request_type)
// case REQUEST_DTSG:
// case REQUEST_BUDDY_LIST:
// case REQUEST_LOAD_FRIENDS:
+// case REQUEST_USER_INFO:
// case REQUEST_LOAD_REQUESTS:
// case REQUEST_SEARCH:
// case REQUEST_DELETE_FRIEND:
@@ -282,7 +283,8 @@ int facebook_client::choose_method(RequestType request_type)
// case REQUEST_FEEDS:
// case REQUEST_NOTIFICATIONS:
// case REQUEST_RECONNECT:
-// case REQUEST_LOAD_FRIENDS:
+// case REQUEST_LOAD_FRIENDS:
+// case REQUEST_USER_INFO:
// case REQUEST_LOAD_REQUESTS:
// case REQUEST_SEARCH:
// case REQUEST_UNREAD_THREADS:
@@ -322,6 +324,7 @@ std::string facebook_client::choose_server(RequestType request_type, std::string
case REQUEST_SEARCH:
case REQUEST_UNREAD_THREADS:
case REQUEST_UNREAD_MESSAGES:
+ case REQUEST_USER_INFO:
return FACEBOOK_SERVER_MOBILE;
// case REQUEST_LOGOUT:
@@ -378,6 +381,15 @@ std::string facebook_client::choose_action(RequestType request_type, std::string
return action;
}
+ case REQUEST_USER_INFO:
+ {
+ std::string action = "/%s?v=info";
+ if (get_data != NULL) {
+ utils::text::replace_all(&action, "%s", *get_data);
+ }
+ return action;
+ }
+
case REQUEST_LOAD_REQUESTS:
{
return "/friends/";
diff --git a/protocols/FacebookRM/src/constants.h b/protocols/FacebookRM/src/constants.h
index 764dadcda2..9fa288bb7b 100644
--- a/protocols/FacebookRM/src/constants.h
+++ b/protocols/FacebookRM/src/constants.h
@@ -94,16 +94,17 @@ enum RequestType {
REQUEST_LOAD_REQUESTS, // getting friend requests
REQUEST_STATUS_SET, // setting my "What's on my mind?"
- REQUEST_SEARCH, // searching
+ REQUEST_SEARCH, // searching
REQUEST_POKE, // sending pokes
REQUEST_NOTIFICATIONS_READ, // marking notifications read
REQUEST_BUDDY_LIST, // getting regular updates (friends online, ...)
REQUEST_LOAD_FRIENDS, // getting list of all friends
- REQUEST_REQUEST_FRIEND, // requesting friends
- REQUEST_APPROVE_FRIEND, // approving friends
- REQUEST_DELETE_FRIEND, // deleting friends
- REQUEST_CANCEL_REQUEST, // canceling friends request
+ REQUEST_USER_INFO, // getting info about particular user
+ REQUEST_REQUEST_FRIEND, // requesting friendships
+ REQUEST_APPROVE_FRIEND, // approving friendships
+ REQUEST_DELETE_FRIEND, // deleting friendships
+ REQUEST_CANCEL_REQUEST, // canceling friendship request
REQUEST_MESSAGE_SEND, // sending message
REQUEST_MESSAGE_SEND2, // sending message through inbox
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index 3338d5de34..3212fe1bc5 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -771,11 +771,11 @@ void FacebookProto::SearchAckThread(void *targ)
if (id.empty() || id == facy.self_.user_id)
continue;
- TCHAR* tid = mir_utf8decodeT(id.c_str());
- TCHAR* tname = mir_utf8decodeT(name.c_str());
- TCHAR* tsurname = mir_utf8decodeT(surname.c_str());
- TCHAR* tnick = mir_utf8decodeT(nick.c_str());
- TCHAR* tcommon = mir_utf8decodeT(common.c_str());
+ ptrT tid = mir_utf8decodeT(id.c_str());
+ ptrT tname = mir_utf8decodeT(utils::text::special_expressions_decode(name).c_str());
+ ptrT tsurname = mir_utf8decodeT(utils::text::special_expressions_decode(surname).c_str());
+ ptrT tnick = mir_utf8decodeT(utils::text::special_expressions_decode(nick).c_str());
+ ptrT tcommon = mir_utf8decodeT(utils::text::special_expressions_decode(common).c_str());
PROTOSEARCHRESULT isr = {0};
isr.cbSize = sizeof(isr);
@@ -787,15 +787,9 @@ void FacebookProto::SearchAckThread(void *targ)
isr.email = tcommon;
ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, targ, (LPARAM)&isr);
-
- mir_free(tid);
- mir_free(tnick);
- mir_free(tname);
- mir_free(tsurname);
- mir_free(tcommon);
}
- ssid = utils::text::source_get_value(&items, 3, "id=\"more_objects\"", "ssid=", "&");
+ ssid = utils::text::source_get_value(&items, 3, "id=\"more_objects\"", "ssid=", "&");
if (ssid.empty())
break; // No more results
}
@@ -808,3 +802,63 @@ void FacebookProto::SearchAckThread(void *targ)
mir_free(targ);
mir_free(arg);
}
+
+void FacebookProto::SearchIdAckThread(void *targ)
+{
+ facy.handle_entry("searchIdAckThread");
+
+ char *arg = mir_utf8encodeT((TCHAR*)targ);
+ std::string search = utils::url::encode(arg);
+
+ if (!isOffline())
+ {
+ http::response resp = facy.flap(REQUEST_USER_INFO, NULL, &search);
+
+ if (resp.code == HTTP_CODE_FOUND && resp.headers.find("Location") != resp.headers.end()) {
+ search = utils::text::source_get_value2(&resp.headers["Location"], FACEBOOK_SERVER_MOBILE"/", "?", true);
+ resp = facy.flap(REQUEST_USER_INFO, NULL, &search);
+ }
+
+ facy.validate_response(&resp);
+
+ if (resp.code == HTTP_CODE_OK)
+ {
+ std::string about = utils::text::source_get_value(&resp.data, 2, "<div class=\"timeline", "<div id=\"footer");
+
+ std::string id = utils::text::source_get_value2(&about, ";id=", "&\"");
+ if (id.empty())
+ id = utils::text::source_get_value2(&about, "?bid=", "&\"");
+ std::string name = utils::text::source_get_value(&about, 3, "class=\"profileName", ">", "</");
+ std::string surname;
+
+ std::string::size_type pos;
+ if ((pos = name.find(" ")) != std::string::npos) {
+ surname = name.substr(pos + 1, name.length() - pos - 1);
+ name = name.substr(0, pos);
+ }
+
+ // ignore self contact and empty ids
+ if (!id.empty() && id != facy.self_.user_id){
+ ptrT tid = mir_utf8decodeT(id.c_str());
+ ptrT tname = mir_utf8decodeT(name.c_str());
+ ptrT tsurname = mir_utf8decodeT(surname.c_str());
+
+ PROTOSEARCHRESULT isr = {0};
+ isr.cbSize = sizeof(isr);
+ isr.flags = PSR_TCHAR;
+ isr.id = tid;
+ isr.firstName = tname;
+ isr.lastName = tsurname;
+
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, targ, (LPARAM)&isr);
+ }
+ }
+ }
+
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, targ, 0);
+
+ facy.handle_success("searchIdAckThread");
+
+ mir_free(targ);
+ mir_free(arg);
+} \ No newline at end of file
diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp
index 5bc721b63a..224a9768f3 100644
--- a/protocols/FacebookRM/src/proto.cpp
+++ b/protocols/FacebookRM/src/proto.cpp
@@ -117,7 +117,7 @@ DWORD_PTR FacebookProto::GetCaps(int type, HANDLE hContact)
{
case PFLAGNUM_1:
{
- DWORD_PTR flags = PF1_IM | PF1_CHAT | PF1_SERVERCLIST | PF1_AUTHREQ | /*PF1_ADDED |*/ PF1_BASICSEARCH | PF1_USERIDISEMAIL | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | PF1_ADDSEARCHRES; // | PF1_VISLIST | PF1_INVISLIST;
+ DWORD_PTR flags = PF1_IM | PF1_CHAT | PF1_SERVERCLIST | PF1_AUTHREQ | /*PF1_ADDED |*/ PF1_BASICSEARCH | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | PF1_ADDSEARCHRES; // | PF1_VISLIST | PF1_INVISLIST;
if (getByte(FACEBOOK_KEY_SET_MIRANDA_STATUS, 0))
return flags |= PF1_MODEMSG;
@@ -214,34 +214,42 @@ HANDLE FacebookProto::SearchBasic(const PROTOCHAR* id)
if (isOffline())
return 0;
- TCHAR* email = mir_tstrdup(id);
- ForkThread(&FacebookProto::SearchAckThread, email);
- return email;
+ TCHAR *tid = mir_tstrdup(id);
+ ForkThread(&FacebookProto::SearchIdAckThread, tid);
+ return tid;
}
HANDLE FacebookProto::SearchByEmail(const PROTOCHAR* email)
{
- return SearchBasic(email);
+ if (isOffline())
+ return 0;
+
+ TCHAR *temail = mir_tstrdup(email);
+ ForkThread(&FacebookProto::SearchAckThread, temail);
+ return temail;
}
HANDLE FacebookProto::SearchByName(const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName)
{
TCHAR arg[200];
_sntprintf (arg, SIZEOF(arg), _T("%s %s %s"), nick, firstName, lastName);
- return SearchBasic(arg);
+ return SearchByEmail(arg); // Facebook is using one search method for everything (except IDs)
}
HANDLE FacebookProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
{
- char *id = mir_t2a_cp(psr->id, CP_UTF8);
- char *name = mir_t2a_cp(psr->firstName, CP_UTF8);
- char *surname = mir_t2a_cp(psr->lastName, CP_UTF8);
+ ptrA id = mir_t2a_cp(psr->id, CP_UTF8);
+ ptrA name = mir_t2a_cp(psr->firstName, CP_UTF8);
+ ptrA surname = mir_t2a_cp(psr->lastName, CP_UTF8);
facebook_user fbu;
fbu.user_id = id;
- fbu.real_name = name;
- fbu.real_name += " ";
- fbu.real_name += surname;
+ if (name != NULL)
+ fbu.real_name = name;
+ if (surname != NULL) {
+ fbu.real_name += " ";
+ fbu.real_name += surname;
+ }
HANDLE hContact = AddToContactList(&fbu, CONTACT_NONE);
if (hContact) {
@@ -255,10 +263,6 @@ HANDLE FacebookProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
}
}
- mir_free(id);
- mir_free(name);
- mir_free(surname);
-
return hContact;
}
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index e36af93199..0352945043 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -150,6 +150,7 @@ public:
void __cdecl ProcessNotifications(void*);
void __cdecl ProcessFriendRequests(void*);
void __cdecl SearchAckThread(void*);
+ void __cdecl SearchIdAckThread(void*);
// Worker threads
void __cdecl SignOn(void*);
diff --git a/protocols/FacebookRM/src/utils.cpp b/protocols/FacebookRM/src/utils.cpp
index 44de994a73..6851154a89 100644
--- a/protocols/FacebookRM/src/utils.cpp
+++ b/protocols/FacebookRM/src/utils.cpp
@@ -405,7 +405,7 @@ std::string utils::text::source_get_value(std::string* data, unsigned int argume
return ret;
}
-std::string utils::text::source_get_value2(std::string* data, const char *term, const char *endings)
+std::string utils::text::source_get_value2(std::string* data, const char *term, const char *endings, bool wholeString)
{
std::string::size_type start = 0, end = 0;
std::string ret;
@@ -417,6 +417,8 @@ std::string utils::text::source_get_value2(std::string* data, const char *term,
end = data->find_first_of(endings, start);
if (end != std::string::npos) {
ret = data->substr(start, end - start);
+ } else if (wholeString) {
+ ret = data->substr(start);
}
}
diff --git a/protocols/FacebookRM/src/utils.h b/protocols/FacebookRM/src/utils.h
index c0c8e680d3..b794290195 100644
--- a/protocols/FacebookRM/src/utils.h
+++ b/protocols/FacebookRM/src/utils.h
@@ -62,7 +62,7 @@ namespace utils
std::string slashu_to_utf8(std::string data);
std::string trim(std::string data, bool rtrim = false);
std::string source_get_value(std::string* data, unsigned int argument_count, ...);
- std::string source_get_value2(std::string* data, const char *term, const char *endings);
+ std::string source_get_value2(std::string* data, const char *term, const char *endings, bool wholeString = false);
void explode(std::string str, std::string separator, std::vector<std::string>* results);
void append_ordinal(unsigned long value, std::string* data);
};