From 1aa7fb19562f9462311e55dc0b9a7fac18c31180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Fri, 25 May 2012 18:11:53 +0000 Subject: Updated Facebook RM git-svn-id: http://svn.miranda-ng.org/main/trunk@176 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/FacebookRM/communication.cpp | 82 ++++------- protocols/FacebookRM/connection.cpp | 5 +- protocols/FacebookRM/constants.h | 6 + protocols/FacebookRM/contacts.cpp | 120 ++++++--------- protocols/FacebookRM/db.h | 56 ++++--- protocols/FacebookRM/facebook.rc | 5 +- protocols/FacebookRM/facebook_10.vcxproj | 5 +- protocols/FacebookRM/facebook_10.vcxproj.filters | 7 +- protocols/FacebookRM/icons/addFriend.ico | Bin 2550 -> 0 bytes protocols/FacebookRM/icons/removeFriend.ico | Bin 2550 -> 0 bytes protocols/FacebookRM/json.cpp | 2 +- protocols/FacebookRM/messages.cpp | 5 +- protocols/FacebookRM/process.cpp | 104 +++++++------ protocols/FacebookRM/proto.cpp | 179 ++++++++--------------- protocols/FacebookRM/proto.h | 9 +- protocols/FacebookRM/resource.h | 7 +- protocols/FacebookRM/stubs.cpp | 10 -- protocols/FacebookRM/theme.cpp | 177 ++++++++++++++++------ protocols/FacebookRM/theme.h | 10 +- 19 files changed, 391 insertions(+), 398 deletions(-) delete mode 100644 protocols/FacebookRM/icons/addFriend.ico delete mode 100644 protocols/FacebookRM/icons/removeFriend.ico diff --git a/protocols/FacebookRM/communication.cpp b/protocols/FacebookRM/communication.cpp index 5b2cb60ace..2e4dfc81f0 100644 --- a/protocols/FacebookRM/communication.cpp +++ b/protocols/FacebookRM/communication.cpp @@ -653,11 +653,9 @@ bool facebook_client::login(const std::string &username,const std::string &passw flap( FACEBOOK_REQUEST_HOME, NULL ); // Prepare login data - std::string data = "charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&locale=en&email="; - data += utils::url::encode( username ); - data += "&pass="; - data += utils::url::encode( password ); - data += "&pass_placeHolder=Password&login=Login&persistent=1"; + std::string data = "charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&locale=en&pass_placeHolder=Password&login=Login&persistent=1"; + data += "&email=" + utils::url::encode( username ); + data += "&pass=" + utils::url::encode( password ); // Send validation http::response resp = flap( FACEBOOK_REQUEST_LOGIN, &data ); @@ -681,14 +679,9 @@ bool facebook_client::login(const std::string &username,const std::string &passw resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE ); std::string inner_data = "machine_name=MirandaIM&submit[Save%20Device]=Save%20Device"; - inner_data += "&post_form_id="; - inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" ); - - inner_data += "&lsd="; - inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"lsd\"", "value=\"", "\"" ); - - inner_data += "&nh="; - inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\"" ); + inner_data += "&post_form_id=" + utils::text::source_get_value(&resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" ); + inner_data += "&lsd=" + utils::text::source_get_value(&resp.data, 3, "name=\"lsd\"", "value=\"", "\"" ); + inner_data += "&nh=" + utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\"" ); resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE, &inner_data ); validate_response(&resp); @@ -778,12 +771,9 @@ bool facebook_client::logout( ) handle_entry( "logout" ); - std::string data = "post_form_id="; - data += ( this->post_form_id_.length( ) ) ? this->post_form_id_ : "0"; - data += "&fb_dtsg="; - data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0"; - data += "&ref=mb&h="; - data += this->logout_hash_; + std::string data = "post_form_id=" + (this->post_form_id_.length() ? this->post_form_id_ : "0"); + data += "&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0"); + data += "&ref=mb&h=" + this->logout_hash_; http::response resp = flap( FACEBOOK_REQUEST_LOGOUT, &data ); @@ -918,13 +908,9 @@ bool facebook_client::chat_state( bool online ) std::string data = "visibility="; data += ( online ) ? "1" : "0"; - data += "&window_id=0"; - data += "&post_form_id="; - data += ( post_form_id_.length( ) ) ? post_form_id_ : "0"; - data += "&post_form_id_source=AsyncRequest"; - data += "&fb_dtsg=" + this->dtsg_; - data += "&lsd=&phstamp=0&__user="; - data += self_.user_id; + data += "&window_id=0&post_form_id=" + (post_form_id_.length() ? post_form_id_ : "0"); + data += "&post_form_id_source=AsyncRequest&fb_dtsg=" + this->dtsg_; + data += "&lsd=&phstamp=0&__user=" + self_.user_id; http::response resp = flap( FACEBOOK_REQUEST_VISIBILITY, &data ); return handle_success( "chat_state" ); @@ -1262,16 +1248,10 @@ void facebook_client::close_chat( std::string message_recipient ) can't close it so soon. But maybe this didnt help also. */ Sleep(300); - std::string data = "close_chat="; - data += message_recipient; - data += "&window_id=0"; - data += "&post_form_id="; - data += ( post_form_id_.length( ) ) ? post_form_id_ : "0"; - data += "&post_form_id_source=AsyncRequest"; - data += "&fb_dtsg="; - data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0"; - data += "&__user="; - data += self_.user_id; + std::string data = "close_chat=" + message_recipient; + data += "&window_id=0&post_form_id=" + (post_form_id_.length() ? post_form_id_ : "0"); + data += "&post_form_id_source=AsyncRequest&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0"); + data += "&__user=" + self_.user_id; http::response resp = flap( FACEBOOK_REQUEST_TABS, &data ); } @@ -1280,14 +1260,11 @@ void facebook_client::chat_mark_read( std::string message_recipient ) { // TODO RM: optimalization? - std::string data = "action=chatMarkRead&other_user="; - data += message_recipient; - data += "&post_form_id="; - data += ( post_form_id_.length( ) ) ? post_form_id_ : "0"; - data += "&fb_dtsg="; - data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0"; - data += "&post_form_id_source=AsyncRequest&lsd=&__user="; - data += self_.user_id; + std::string data = "action=chatMarkRead"; + data += "&other_user=" + message_recipient; + data += "&post_form_id=" + (post_form_id_.length() ? post_form_id_ : "0"); + data += "&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0"); + data += "&post_form_id_source=AsyncRequest&lsd=&__user=" + self_.user_id; http::response resp = flap( FACEBOOK_REQUEST_ASYNC, &data ); } @@ -1296,19 +1273,16 @@ bool facebook_client::set_status(const std::string &status_text) { handle_entry( "set_status" ); - std::string data = "post_form_id_source=AsyncRequest&post_form_id="; - data += ( this->post_form_id_.length( ) ) ? this->post_form_id_ : "0"; - data += "&fb_dtsg="; - data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0"; - data += "&target_id="; - data += this->self_.user_id; + std::string data = "post_form_id_source=AsyncRequest"; + data += "&post_form_id=" + (this->post_form_id_.length() ? this->post_form_id_ : "0"); + data += "&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0"); + data += "&target_id=" + this->self_.user_id; if ( status_text.length( ) ) { - data += "&action=PROFILE_UPDATE&app_id=&hey_kid_im_a_composer=true&display_context=profile&_log_display_context=profile&ajax_log=1&status="; - data += utils::url::encode( status_text ); - data += "&profile_id="; - data += this->self_.user_id; + data += "&action=PROFILE_UPDATE&app_id=&hey_kid_im_a_composer=true&display_context=profile&_log_display_context=profile&ajax_log=1"; + data += "&status=" + utils::url::encode( status_text ); + data += "&profile_id=" + this->self_.user_id; } http::response resp = flap( FACEBOOK_REQUEST_STATUS_SET, &data ); diff --git a/protocols/FacebookRM/connection.cpp b/protocols/FacebookRM/connection.cpp index 14b5c181c1..5d955d917f 100644 --- a/protocols/FacebookRM/connection.cpp +++ b/protocols/FacebookRM/connection.cpp @@ -191,7 +191,7 @@ void FacebookProto::UpdateLoop(void *) time_t tim = ::time(NULL); LOG( ">>>>> Entering Facebook::UpdateLoop[%d]", tim ); - for ( int i = -1; !isOffline(); i = ++i % 100 ) + for ( int i = -1; !isOffline(); i = ++i % 50 ) { if ( i != -1 ) { if ( !facy.invisible_ ) @@ -202,7 +202,7 @@ void FacebookProto::UpdateLoop(void *) if ( !facy.feeds( ) ) break; - if ( i == 99 ) + if ( i == 49 ) ForkThread( &FacebookProto::ProcessFriendRequests, this, NULL ); LOG( "***** FacebookProto::UpdateLoop[%d] going to sleep...", tim ); @@ -217,7 +217,6 @@ void FacebookProto::UpdateLoop(void *) void FacebookProto::MessageLoop(void *) { - //ScopedLock s(message_loop_lock_); // TODO: Required? time_t tim = ::time(NULL); LOG( ">>>>> Entering Facebook::MessageLoop[%d]", tim ); diff --git a/protocols/FacebookRM/constants.h b/protocols/FacebookRM/constants.h index 93ae6022ee..e647cabf62 100644 --- a/protocols/FacebookRM/constants.h +++ b/protocols/FacebookRM/constants.h @@ -111,6 +111,12 @@ along with this program. If not, see . #define FACEBOOK_RECV_MESSAGE 1 #define FACEBOOK_SEND_MESSAGE 2 +// Contact types +#define FACEBOOK_CONTACT_FRIEND 1 // contact that IS on our server list +#define FACEBOOK_CONTACT_NONE 2 // contact that ISN'T on our server list +#define FACEBOOK_CONTACT_REQUEST 3 // contact that we asked for friendship +#define FACEBOOK_CONTACT_APPROVE 4 // contact that is asking us for approval of friendship + // News Feed types static const struct { diff --git a/protocols/FacebookRM/contacts.cpp b/protocols/FacebookRM/contacts.cpp index 0f1759e628..23a6ca4455 100644 --- a/protocols/FacebookRM/contacts.cpp +++ b/protocols/FacebookRM/contacts.cpp @@ -63,7 +63,7 @@ HANDLE FacebookProto::ContactIDToHContact(std::string user_id) return 0; } -HANDLE FacebookProto::AddToContactList(facebook_user* fbu, bool dont_check, const char *new_name) +HANDLE FacebookProto::AddToContactList(facebook_user* fbu, BYTE type, bool dont_check, const char *new_name) { HANDLE hContact; @@ -96,11 +96,13 @@ HANDLE FacebookProto::AddToContactList(facebook_user* fbu, bool dont_check, cons DBFreeVariant(&dbv); } - if (strlen(new_name) > 0) { + if (strlen(new_name) > 0) + { DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, new_name); DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NICK, new_name); - DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 1); // We suppose he is not on server list - } + } + + DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, type); if (getByte(FACEBOOK_KEY_DISABLE_STATUS_NOTIFY, 0)) CallService(MS_IGNORE_IGNORE, (WPARAM)hContact, (LPARAM)IGNOREEVENT_USERONLINE); @@ -155,20 +157,23 @@ void FacebookProto::DeleteContactFromServer(void *data) // Process result data facy.validate_response(&resp); - if (resp.data.find("\"success\":true", 0) != std::string::npos) { - - // TODO: do only when operation is successful + if (resp.data.find("\"payload\":null", 0) != std::string::npos) + { facebook_user* fbu = facy.buddies.find( id ); - if (fbu != NULL) { - fbu->deleted = true; - // TODO: change type of contact in database... - DBWriteContactSettingWord(fbu->handle, m_szModuleName, "Status", ID_STATUS_OFFLINE); // set offline status - - // TODO: if not in actual buddies list, search in database... - DBWriteContactSettingDword(fbu->handle, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL)); // set deleted time + if (fbu != NULL) + fbu->deleted = true; + + HANDLE hContact = ContactIDToHContact(id); + + // If contact wasn't deleted from database + if (hContact != NULL) + { + DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE); + DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_NONE); + DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL)); } - NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact was sucessfully removed from your server list."), NULL, FACEBOOK_EVENT_OTHER, NULL); + NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact was sucessfully removed from your server list."), NULL, FACEBOOK_EVENT_OTHER, NULL); } else { facy.client_notify( TranslateT("Error occured when removing contact from server.") ); } @@ -184,32 +189,34 @@ void FacebookProto::AddContactToServer(void *data) if ( data == NULL ) return; - std::string *id = (std::string*)data; + std::string id = (*(std::string*)data); + delete data; std::string query = "action=add_friend&how_found=profile_button&ref_param=ts&outgoing_id=&unwanted=&logging_location=&no_flyout_on_click=false&ego_log_data=&post_form_id_source=AsyncRequest&lsd=&fb_dtsg="; query += facy.dtsg_; query += "&post_form_id="; query += facy.post_form_id_; query += "&to_friend="; - query += *id; + query += id; query += "&__user="; query += facy.self_.user_id; - delete data; - // Get unread inbox threads http::response resp = facy.flap( FACEBOOK_REQUEST_REQUEST_FRIEND, &query ); // Process result data facy.validate_response(&resp); - if (resp.data.find("\"success\":true", 0) != std::string::npos) { - /*facebook_user* fbu = facy.buddies.find( id ); - if (fbu != NULL) { - // TODO: change type of contact in database... - // TODO: if not in actual buddies list, search in database... - }*/ + if (resp.data.find("\"success\":true", 0) != std::string::npos) + { + HANDLE hContact = ContactIDToHContact(id); + // If contact wasn't deleted from database + if (hContact != NULL) + { + DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_REQUEST); + } + NotifyEvent(TranslateT("Adding contact"), TranslateT("Request for friendship was sent successfully."), NULL, FACEBOOK_EVENT_OTHER, NULL); } else { facy.client_notify( TranslateT("Error occured when requesting friendship.") ); @@ -227,38 +234,27 @@ void FacebookProto::ApproveContactToServer(void *data) if ( data == NULL ) return; - std::string *id = (std::string*)data; - + HANDLE hContact = (*(HANDLE*)data); + delete data; + std::string post_data = "fb_dtsg=" + facy.dtsg_; post_data += "&charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&confirm_button="; - std::string get_data; - - HANDLE *hContact = (HANDLE*)data; + std::string get_data = "id="; DBVARIANT dbv; - if (!DBGetContactSettingString(*hContact, m_szModuleName, FACEBOOK_KEY_APPROVE, &dbv)) + if (!DBGetContactSettingString(hContact, m_szModuleName, FACEBOOK_KEY_ID, &dbv)) { - get_data = dbv.pszVal; + get_data += dbv.pszVal; DBFreeVariant(&dbv); - } - - // replace absolute link to params only - utils::text::replace_first(&get_data, "/a/notifications.php?", "&"); + } http::response resp = facy.flap( FACEBOOK_REQUEST_APPROVE_FRIEND, &post_data, &get_data ); // Process result data facy.validate_response(&resp); - if (resp.code != HTTP_CODE_OK) - facy.handle_error( "ApproveContactToServer" ); - else { - NotifyEvent(TranslateT("Adding contact"), TranslateT("Contact was added to your server list."), NULL, FACEBOOK_EVENT_OTHER, NULL); - DBDeleteContactSetting(*hContact, m_szModuleName, FACEBOOK_KEY_APPROVE); - } - - delete data; + DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_FRIEND); } HANDLE FacebookProto::GetAwayMsg(HANDLE hContact) @@ -266,41 +262,9 @@ HANDLE FacebookProto::GetAwayMsg(HANDLE hContact) return 0; // Status messages are disabled } -int FacebookProto::OnContactDeleted(WPARAM wparam,LPARAM) +int FacebookProto::OnContactDeleted(WPARAM wParam,LPARAM) { - HANDLE hContact = (HANDLE)wparam; - - DBVARIANT dbv; - char str[256]; - - if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) { - mir_snprintf(str,SIZEOF(str),Translate("Do you want to delete contact '%s' from server list?"), dbv.pszVal); - DBFreeVariant(&dbv); - } else if( !DBGetContactSettingUTF8String(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) { - mir_snprintf(str,SIZEOF(str),Translate("Do you want to delete contact '%s' from server list?"), dbv.pszVal); - DBFreeVariant(&dbv); - } - - TCHAR *text = mir_a2t_cp(str, CP_UTF8); - if (MessageBox( 0, text, m_tszUserName, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) == IDYES) { - - if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) - { - if (!isOffline()) { // TODO: is this needed? - std::string* id = new std::string(dbv.pszVal); - - facebook_user* fbu = facy.buddies.find( (*id) ); - if (fbu != NULL) { - fbu->handle = NULL; - } - - ForkThread( &FacebookProto::DeleteContactFromServer, this, ( void* )id ); - DBFreeVariant(&dbv); - } - } - - } - mir_free(text); + CancelFriendship(wParam, 1); return 0; } diff --git a/protocols/FacebookRM/db.h b/protocols/FacebookRM/db.h index cadddef8ca..c397522f3c 100644 --- a/protocols/FacebookRM/db.h +++ b/protocols/FacebookRM/db.h @@ -38,37 +38,35 @@ along with this program. If not, see . #define deleteSetting( setting ) DBDeleteContactSetting( NULL, m_szModuleName, setting ) // DB keys -#define FACEBOOK_KEY_LOGIN "Email" -#define FACEBOOK_KEY_ID "ID" -#define FACEBOOK_KEY_NAME "RealName" -#define FACEBOOK_KEY_NICK "Nick" -#define FACEBOOK_KEY_PASS "Password" -#define FACEBOOK_KEY_UPD_NAMES "UpdateNames" -#define FACEBOOK_KEY_DEVICE_ID "DeviceID" -#define FACEBOOK_KEY_AV_URL "AvatarURL" -#define FACEBOOK_KEY_DELETED "Deleted" -#define FACEBOOK_KEY_CONTACT_TYPE "ContactType" -#define FACEBOOK_KEY_APPROVE "ApproveAction" - -#define FACEBOOK_KEY_DEF_GROUP "DefaultGroup" -#define FACEBOOK_KEY_FORCE_HTTPS "ForceHTTPS" +#define FACEBOOK_KEY_LOGIN "Email" +#define FACEBOOK_KEY_ID "ID" +#define FACEBOOK_KEY_NAME "RealName" +#define FACEBOOK_KEY_NICK "Nick" +#define FACEBOOK_KEY_PASS "Password" +#define FACEBOOK_KEY_UPD_NAMES "UpdateNames" +#define FACEBOOK_KEY_DEVICE_ID "DeviceID" +#define FACEBOOK_KEY_AV_URL "AvatarURL" +#define FACEBOOK_KEY_DELETED "Deleted" +#define FACEBOOK_KEY_CONTACT_TYPE "ContactType" +#define FACEBOOK_KEY_DEF_GROUP "DefaultGroup" +#define FACEBOOK_KEY_FORCE_HTTPS "ForceHTTPS" #define FACEBOOK_KEY_FORCE_HTTPS_CHANNEL "ForceHTTPSChannel" #define FACEBOOK_KEY_CLOSE_WINDOWS_ENABLE "CloseChatEnable" -#define FACEBOOK_KEY_SET_MIRANDA_STATUS "SetMirandaStatus" -#define FACEBOOK_KEY_LOGGING_ENABLE "LoggingEnable" -#define FACEBOOK_KEY_SYSTRAY_NOTIFY "UseSystrayNotify" -#define FACEBOOK_KEY_DISABLE_STATUS_NOTIFY "DisableStatusNotify" -#define FACEBOOK_KEY_PARSE_MESSAGES "ParseUnreadMessages" -#define FACEBOOK_KEY_BIG_AVATARS "UseBigAvatars" -#define FACEBOOK_KEY_DISCONNECT_CHAT "DisconnectChatEnable" -#define FACEBOOK_KEY_MAP_STATUSES "MapStatuses" -#define FACEBOOK_KEY_LOAD_MOBILE "LoadMobile" -#define FACEBOOK_KEY_ENABLE_GROUPCHATS "GroupchatsEnable" - -#define FACEBOOK_KEY_POLL_RATE "PollRate" // [HIDDEN] -#define FACEBOOK_KEY_TIMEOUTS_LIMIT "TimeoutsLimit" // [HIDDEN] -#define FACEBOOK_KEY_DISABLE_LOGOUT "DisableLogout" // [HIDDEN] -#define FACEBOOK_KEY_VALIDATE_RESPONSE "ValidateResponse" // [HIDDEN] - 0 = standard, 1 = always, 2 = never +#define FACEBOOK_KEY_SET_MIRANDA_STATUS "SetMirandaStatus" +#define FACEBOOK_KEY_LOGGING_ENABLE "LoggingEnable" +#define FACEBOOK_KEY_SYSTRAY_NOTIFY "UseSystrayNotify" +#define FACEBOOK_KEY_DISABLE_STATUS_NOTIFY "DisableStatusNotify" +#define FACEBOOK_KEY_PARSE_MESSAGES "ParseUnreadMessages" +#define FACEBOOK_KEY_BIG_AVATARS "UseBigAvatars" +#define FACEBOOK_KEY_DISCONNECT_CHAT "DisconnectChatEnable" +#define FACEBOOK_KEY_MAP_STATUSES "MapStatuses" +#define FACEBOOK_KEY_LOAD_MOBILE "LoadMobile" +#define FACEBOOK_KEY_ENABLE_GROUPCHATS "GroupchatsEnable" + +#define FACEBOOK_KEY_POLL_RATE "PollRate" // [HIDDEN] +#define FACEBOOK_KEY_TIMEOUTS_LIMIT "TimeoutsLimit" // [HIDDEN] +#define FACEBOOK_KEY_DISABLE_LOGOUT "DisableLogout" // [HIDDEN] +#define FACEBOOK_KEY_VALIDATE_RESPONSE "ValidateResponse" // [HIDDEN] - 0 = standard, 1 = always, 2 = never #define FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE "EventNotificationsEnable" #define FACEBOOK_KEY_EVENT_FEEDS_ENABLE "EventFeedsEnable" diff --git a/protocols/FacebookRM/facebook.rc b/protocols/FacebookRM/facebook.rc index 7f66333cbc..ae7489daa4 100644 --- a/protocols/FacebookRM/facebook.rc +++ b/protocols/FacebookRM/facebook.rc @@ -53,8 +53,9 @@ END // remains consistent on all systems. IDI_FACEBOOK ICON "icons/facebook.ico" IDI_MIND ICON "icons/mind.ico" -IDI_ADDFRIEND ICON "icons/addFriend.ico" -IDI_REMOVEFRIEND ICON "icons/removeFriend.ico" +IDI_AUTH_GRANT ICON "icons/auth_grant.ico" +IDI_AUTH_ASK ICON "icons/auth_ask.ico" +IDI_AUTH_REVOKE ICON "icons/auth_revoke.ico" ///////////////////////////////////////////////////////////////////////////// // diff --git a/protocols/FacebookRM/facebook_10.vcxproj b/protocols/FacebookRM/facebook_10.vcxproj index 0fea434eeb..198c8e647b 100644 --- a/protocols/FacebookRM/facebook_10.vcxproj +++ b/protocols/FacebookRM/facebook_10.vcxproj @@ -310,8 +310,9 @@ - - + + + diff --git a/protocols/FacebookRM/facebook_10.vcxproj.filters b/protocols/FacebookRM/facebook_10.vcxproj.filters index fc92cf1075..5ddb449d60 100644 --- a/protocols/FacebookRM/facebook_10.vcxproj.filters +++ b/protocols/FacebookRM/facebook_10.vcxproj.filters @@ -142,10 +142,13 @@ Resource Files - + Resource Files - + + Resource Files + + Resource Files diff --git a/protocols/FacebookRM/icons/addFriend.ico b/protocols/FacebookRM/icons/addFriend.ico deleted file mode 100644 index d8879d15bb..0000000000 Binary files a/protocols/FacebookRM/icons/addFriend.ico and /dev/null differ diff --git a/protocols/FacebookRM/icons/removeFriend.ico b/protocols/FacebookRM/icons/removeFriend.ico deleted file mode 100644 index 9639a9c728..0000000000 Binary files a/protocols/FacebookRM/icons/removeFriend.ico and /dev/null differ diff --git a/protocols/FacebookRM/json.cpp b/protocols/FacebookRM/json.cpp index 2231596882..bb92cb4434 100644 --- a/protocols/FacebookRM/json.cpp +++ b/protocols/FacebookRM/json.cpp @@ -503,7 +503,7 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess facebook_user fbu; fbu.user_id = user_id; - HANDLE hContact = proto->AddToContactList(&fbu); + HANDLE hContact = proto->AddToContactList(&fbu, FACEBOOK_CONTACT_FRIEND); if ( DBGetContactSettingWord(hContact,proto->m_szModuleName,"Status", 0) == ID_STATUS_OFFLINE ) DBWriteContactSettingWord(hContact,proto->m_szModuleName,"Status",ID_STATUS_ONLINE); diff --git a/protocols/FacebookRM/messages.cpp b/protocols/FacebookRM/messages.cpp index d8fd7e6d58..072ae88b4f 100644 --- a/protocols/FacebookRM/messages.cpp +++ b/protocols/FacebookRM/messages.cpp @@ -114,8 +114,9 @@ void FacebookProto::SendTypingWorker(void *p) send_typing *typing = static_cast(p); - // Dont send typing notifications to contacts, that are offline - if ( DBGetContactSettingWord(typing->hContact,m_szModuleName,"Status", 0) == ID_STATUS_OFFLINE ) + // Dont send typing notifications to contacts, that are offline or not friends + if ( DBGetContactSettingWord(typing->hContact,m_szModuleName,"Status", 0) == ID_STATUS_OFFLINE + || DBGetContactSettingByte(typing->hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND) return; // TODO RM: maybe better send typing optimalization diff --git a/protocols/FacebookRM/process.cpp b/protocols/FacebookRM/process.cpp index 4dd98c5678..4c51141cb1 100644 --- a/protocols/FacebookRM/process.cpp +++ b/protocols/FacebookRM/process.cpp @@ -52,7 +52,7 @@ void FacebookProto::ProcessBuddyList( void* data ) { fbu = i->data; - if (fbu->handle && !fbu->deleted) + if (fbu->handle) DBWriteContactSettingWord(fbu->handle, m_szModuleName, "Status", ID_STATUS_OFFLINE); std::string to_delete( i->key ); @@ -63,7 +63,7 @@ void FacebookProto::ProcessBuddyList( void* data ) i = i->next; if (!fbu->handle) { // just been added - fbu->handle = AddToContactList(fbu); + fbu->handle = AddToContactList(fbu, FACEBOOK_CONTACT_FRIEND); if (!fbu->real_name.empty()) { DBWriteContactSettingUTF8String(fbu->handle,m_szModuleName,FACEBOOK_KEY_NAME,fbu->real_name.c_str()); @@ -75,8 +75,9 @@ void FacebookProto::ProcessBuddyList( void* data ) DBWriteContactSettingWord(fbu->handle,m_szModuleName,"Status", fbu->status_id ); } - if (DBGetContactSettingByte(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE, 0)) { - DBDeleteContactSetting(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE); // Set type "on server-list" contact + if (DBGetContactSettingByte(fbu->handle, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND) { + DBWriteContactSettingByte(fbu->handle, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_FRIEND); + // TODO: remove that popup and use "Contact added you" event? } // Wasn't contact removed from "server-list" someday? @@ -156,15 +157,6 @@ void FacebookProto::ProcessFriendList( void* data ) if ( DBGetContactSettingByte(hContact, m_szModuleName, "Gender", 0) != fbu->gender ) DBWriteContactSettingByte(hContact, m_szModuleName, "Gender", fbu->gender); - // TODO: Remove in next version - if( !DBGetContactSettingString(hContact, m_szModuleName, "MirVer", &dbv) ) { - update_required = strcmp( dbv.pszVal, FACEBOOK_NAME ) != 0; - DBFreeVariant(&dbv); - } - if (update_required) { - DBWriteContactSettingString(hContact, m_szModuleName, "MirVer", FACEBOOK_NAME); - } - // Update real name if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) { @@ -177,8 +169,9 @@ void FacebookProto::ProcessFriendList( void* data ) DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NICK, fbu->real_name.c_str()); } - if (DBGetContactSettingByte(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE, 0)) { - DBDeleteContactSetting(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE); // Has type "on server-list" contact + if (DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND) { + DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_FRIEND); + // TODO: remove that popup and use "Contact added you" event? } // Wasn't contact removed from "server-list" someday? @@ -202,11 +195,13 @@ void FacebookProto::ProcessFriendList( void* data ) } else { // Contact was removed from "server-list", notify it - // Wasnt we already been notified about this contact? - if ( !DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) - && !DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) ) { // And is this contact "on-server" contact? + // Wasnt we already been notified about this contact? And was this real friend? + if (!DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) + && DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) == FACEBOOK_CONTACT_FRIEND) + { DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL)); + DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_NONE); std::string contactname = id; if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) { @@ -231,7 +226,7 @@ void FacebookProto::ProcessFriendList( void* data ) { facebook_user *fbu = iter->second; - HANDLE hContact = AddToContactList(fbu, true); // This contact is surely new + HANDLE hContact = AddToContactList(fbu, FACEBOOK_CONTACT_FRIEND, true); // This contact is surely new DBWriteContactSettingByte(hContact, m_szModuleName, "Gender", fbu->gender ); DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, fbu->real_name.c_str()); @@ -313,7 +308,7 @@ void FacebookProto::ProcessUnreadMessages( void* ) facebook_user fbu; fbu.user_id = user_id; - HANDLE hContact = AddToContactList(&fbu); + HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE); // TODO: if contact is newly added, get his user info // TODO: maybe create new "receiveMsg" function and use it for offline and channel messages? @@ -431,7 +426,7 @@ void FacebookProto::ProcessMessages( void* data ) facebook_user fbu; fbu.user_id = messages[i]->user_id; - HANDLE hContact = AddToContactList(&fbu, false, messages[i]->sender_name.c_str()); + HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE, false, messages[i]->sender_name.c_str()); // TODO: if contact is newly added, get his user info // TODO: maybe create new "receiveMsg" function and use it for offline and channel messages? @@ -568,7 +563,8 @@ void FacebookProto::ProcessFriendRequests( void* ) last = true; } - std::string get = utils::text::source_get_value(&req, 3, ""); + std::string get = utils::text::source_get_value(&req, 3, ""); + std::string time = utils::text::source_get_value2(&get, "seenrequesttime=", "&\""); facebook_user *fbu = new facebook_user(); fbu->real_name = utils::text::source_get_value(&req, 2, "class=\"actor\">", "user_id.length() && fbu->real_name.length()) { - HANDLE hContact = AddToContactList(fbu, false, fbu->real_name.c_str()); - DBWriteContactSettingString(hContact, m_szModuleName, FACEBOOK_KEY_APPROVE, get.c_str()); + HANDLE hContact = AddToContactList(fbu, FACEBOOK_CONTACT_APPROVE, false, fbu->real_name.c_str()); + DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_APPROVE); - LOG(" Friendship request from: %s (%s)", fbu->real_name.c_str(), fbu->user_id.c_str()); + bool seen = false; - /* TODO: How to write event for auth requests etc.? */ -/* CCSDATA ccs; - PROTORECVEVENT pre; + DBVARIANT dbv; + if (!DBGetContactSettingString(hContact, m_szModuleName, "RequestTime", &dbv)) { + seen = !strcmp(dbv.pszVal, time.c_str()); + DBFreeVariant(&dbv); + } - ccs.szProtoService = PSR_AUTH; - ccs.hContact = hContact; - ccs.wParam = 0; - ccs.lParam = (LPARAM)⪯ - pre.flags |= PREF_UTF; - pre.timestamp = ::time(NULL); - pre.lParam = sizeof(DWORD) + sizeof(HANDLE) + fbu->real_name.length() + 5; - - char* pCurBlob = (char*)alloca(pre.lParam); - pre.szMessage = pCurBlob; - - *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID - *(PHANDLE)pCurBlob = hContact; pCurBlob += sizeof(HANDLE); // Contact Handle - strcpy(pCurBlob, fbu->real_name.c_str()); pCurBlob += fbu->real_name.length() + 1; // Nickname - *pCurBlob = '\0'; pCurBlob++; // First Name - *pCurBlob = '\0'; pCurBlob++; // Last Name - *pCurBlob = '\0'; pCurBlob++; // E-mail - *pCurBlob = '\0'; // Reason - - CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs); */ + if (!seen) { + // This is new request + DBWriteContactSettingString(hContact, m_szModuleName, "RequestTime", time.c_str()); + + //blob is: uin( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), first( ASCIIZ ), last( ASCIIZ ), email( ASCIIZ ), reason( ASCIIZ ) + //blob is: 0( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ) + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof( DBEVENTINFO ); + dbei.szModule = m_szModuleName; + dbei.timestamp = ::time( NULL ); + dbei.flags = 0; //DBEF_UTF; + dbei.eventType = EVENTTYPE_AUTHREQUEST; + dbei.cbBlob = (DWORD)(sizeof( DWORD )+ sizeof( HANDLE ) + fbu->real_name.length() + 5); + + PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob ); + *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID + *(PHANDLE)pCurBlob = hContact; pCurBlob += sizeof(HANDLE); // Contact Handle + strcpy((char*)pCurBlob, fbu->real_name.c_str()); pCurBlob += fbu->real_name.length()+1; // Nickname + *pCurBlob = '\0'; pCurBlob++; // First Name + *pCurBlob = '\0'; pCurBlob++; // Last Name + *pCurBlob = '\0'; pCurBlob++; // E-mail + *pCurBlob = '\0'; // Reason + + CallService(MS_DB_EVENT_ADD, (WPARAM)NULL, (LPARAM)&dbei); + + LOG(" (New) Friendship request from: %s (%s) [%s]", fbu->real_name.c_str(), fbu->user_id.c_str(), time.c_str()); + } else { + LOG(" (Old) Friendship request from: %s (%s) [%s]", fbu->real_name.c_str(), fbu->user_id.c_str(), time.c_str()); + } } else { LOG(" !!! Wrong friendship request"); + LOG(req.c_str()); } } diff --git a/protocols/FacebookRM/proto.cpp b/protocols/FacebookRM/proto.cpp index 14a9dcfedc..fd203dffb2 100644 --- a/protocols/FacebookRM/proto.cpp +++ b/protocols/FacebookRM/proto.cpp @@ -96,7 +96,6 @@ FacebookProto::~FacebookProto( ) CloseHandle( avatar_lock_ ); CloseHandle( log_lock_ ); CloseHandle( update_loop_lock_ ); - //CloseHandle( this->message_loop_lock_ ); CloseHandle( facy.buddies_lock_ ); CloseHandle( facy.send_message_lock_ ); CloseHandle( facy.fcb_conn_lock_ ); @@ -114,7 +113,7 @@ DWORD_PTR FacebookProto::GetCaps( int type, HANDLE hContact ) { case PFLAGNUM_1: // TODO: Other caps available: PF1_BASICSEARCH, PF1_SEARCHBYEMAIL { - 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_USERIDISEMAIL | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | PF1_ADDSEARCHRES; // | PF1_VISLIST | PF1_INVISLIST; if ( getByte( FACEBOOK_KEY_SET_MIRANDA_STATUS, 0 ) ) return flags |= PF1_MODEMSG; @@ -262,7 +261,7 @@ HANDLE FacebookProto::AddToList(int flags, PROTOSEARCHRESULT* psr) fbu.real_name += " "; fbu.real_name += surname; - HANDLE hContact = AddToContactList(&fbu, false, fbu.real_name.c_str()); + HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE, false, fbu.real_name.c_str()); if (hContact) { if (flags & PALF_TEMPORARY) { @@ -285,7 +284,18 @@ HANDLE FacebookProto::AddToList(int flags, PROTOSEARCHRESULT* psr) int FacebookProto::AuthRequest(HANDLE hContact,const PROTOCHAR *message) { - return AddFriend((WPARAM)hContact, NULL); + return RequestFriendship((WPARAM)hContact, NULL); +} + +int FacebookProto::Authorize(HANDLE hContact) +{ + return ApproveFriendship((WPARAM)hContact, NULL); +} + +int FacebookProto::AuthDeny(HANDLE hContact,const PROTOCHAR *reason) +{ + // TODO: hide from facebook requests list + return 0; } ////////////////////////////////////////////////////////////////////////////// @@ -378,18 +388,6 @@ int FacebookProto::OnPreShutdown(WPARAM wParam,LPARAM lParam) return 0; } -int FacebookProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam) -{ - HANDLE hContact = reinterpret_cast(wParam); - if(IsMyContact(hContact/*, true*/)) { - bool hide = (DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) - || DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) ); - ShowContactMenus(true, hide); - } - - return 0; -} - int FacebookProto::OnOptionsInit(WPARAM wParam,LPARAM lParam) { OPTIONSDIALOGPAGE odp = {sizeof(odp)}; @@ -422,55 +420,6 @@ int FacebookProto::OnOptionsInit(WPARAM wParam,LPARAM lParam) return 0; } -int FacebookProto::OnBuildStatusMenu(WPARAM wParam,LPARAM lParam) -{ - char text[200]; - strcpy(text,m_szModuleName); - char *tDest = text+strlen(text); - - HGENMENU hRoot; - CLISTMENUITEM mi = {sizeof(mi)}; - mi.pszService = text; - - hRoot = MO_GetProtoRootMenu(m_szModuleName); - if (hRoot == NULL) - { - mi.popupPosition = 500085000; - mi.hParentMenu = HGENMENU_ROOT; - mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED | ( this->isOnline() ? 0 : CMIF_GRAYED ); - mi.icolibItem = GetIconHandle( "facebook" ); - mi.ptszName = m_tszUserName; - hRoot = m_hMenuRoot = reinterpret_cast( CallService( - MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast(&mi)) ); - } else { - if ( m_hMenuRoot ) - CallService( MS_CLIST_REMOVEMAINMENUITEM, ( WPARAM )m_hMenuRoot, 0 ); - m_hMenuRoot = NULL; - } - - mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP | ( this->isOnline() ? 0 : CMIF_GRAYED ); - mi.position = 201001; - - CreateProtoService(m_szModuleName,"/Mind",&FacebookProto::OnMind,this); - strcpy(tDest,"/Mind"); - mi.hParentMenu = hRoot; - mi.pszName = LPGEN("Mind..."); - mi.icolibItem = GetIconHandle("mind"); - m_hStatusMind = reinterpret_cast( CallService( - MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast(&mi)) ); - - CreateProtoService(m_szModuleName,"/VisitProfile",&FacebookProto::VisitProfile,this); - strcpy(tDest,"/VisitProfile"); - mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP; - mi.pszName = LPGEN("Visit Profile"); - mi.icolibItem = GetIconHandle("homepage"); - // TODO RM: remember and properly free in destructor? - /*m_hStatusMind = */reinterpret_cast( CallService( - MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast(&mi)) ); - - return 0; -} - int FacebookProto::OnMind(WPARAM,LPARAM) { HWND hDlg = CreateDialogParam( g_hInstance, MAKEINTRESOURCE( IDD_MIND ), @@ -488,57 +437,75 @@ int FacebookProto::VisitProfile(WPARAM wParam,LPARAM lParam) { CallService(MS_UTILS_OPENURL,1,reinterpret_cast(dbv.pszVal)); DBFreeVariant(&dbv); + } + else if (DBGetContactSettingByte(hContact,m_szModuleName,"ChatRoom",0)) + { + std::string url = FACEBOOK_URL_GROUP; + if (!DBGetContactSettingString(hContact,m_szModuleName,"ChatRoomID",&dbv)) { + url += dbv.pszVal; + DBFreeVariant(&dbv); + } + CallService(MS_UTILS_OPENURL,1,reinterpret_cast(url.c_str())); } else { - // self contact, probably // TODO: why isn't wParam == 0 when is status menu moved to main menu? CallService(MS_UTILS_OPENURL,1,reinterpret_cast(FACEBOOK_URL_PROFILE)); - return 0; } return 0; } -int FacebookProto::RemoveFriend(WPARAM wParam,LPARAM lParam) +int FacebookProto::CancelFriendship(WPARAM wParam,LPARAM lParam) { - if (wParam == NULL) - { // self contact - // CallService(MS_UTILS_OPENURL,1,reinterpret_cast(FACEBOOK_URL_PROFILE)); - return 0; - } - - if (isOffline()) + if (wParam == NULL || isOffline()) return 0; - if (MessageBox( 0, TranslateT("Are you sure?"), TranslateT("Delete contact from server list"), MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) != IDYES) - return 0; + bool deleting = (lParam == 1); HANDLE hContact = reinterpret_cast(wParam); - DBVARIANT dbv; - if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) - { - if (!isOffline()) { + // Ignore groupchats and, if deleting, also not-friends + if (DBGetContactSettingByte(hContact, m_szModuleName, "ChatRoom", 0) + || (deleting && DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND)) + return 0; + + DBVARIANT dbv; + char str[256]; + + if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) { + mir_snprintf(str,SIZEOF(str),Translate("Do you want to cancel your friendship with '%s'?"), dbv.pszVal); + DBFreeVariant(&dbv); + } else if( !DBGetContactSettingUTF8String(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) { + mir_snprintf(str,SIZEOF(str),Translate("Do you want to cancel your friendship with '%s'?"), dbv.pszVal); + DBFreeVariant(&dbv); + } + + TCHAR *text = mir_a2t_cp(str, CP_UTF8); + if (MessageBox( 0, text, m_tszUserName, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) == IDYES) { + + if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) + { std::string* id = new std::string(dbv.pszVal); + + if (deleting) { + facebook_user* fbu = facy.buddies.find( (*id) ); + if (fbu != NULL) { + fbu->handle = NULL; + } + } + ForkThread( &FacebookProto::DeleteContactFromServer, this, ( void* )id ); DBFreeVariant(&dbv); - - if ( !DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) ) - DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL)); } + } + mir_free(text); return 0; } -int FacebookProto::AddFriend(WPARAM wParam,LPARAM lParam) +int FacebookProto::RequestFriendship(WPARAM wParam,LPARAM lParam) { - if (wParam == NULL) - { // self contact -// CallService(MS_UTILS_OPENURL,1,reinterpret_cast(FACEBOOK_URL_PROFILE)); - return 0; - } - - if (isOffline()) + if (wParam == NULL || isOffline()) return 0; HANDLE hContact = reinterpret_cast(wParam); @@ -546,25 +513,17 @@ int FacebookProto::AddFriend(WPARAM wParam,LPARAM lParam) DBVARIANT dbv; if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) { - if (!isOffline()) { - std::string* id = new std::string(dbv.pszVal); - ForkThread( &FacebookProto::AddContactToServer, this, ( void* )id ); - DBFreeVariant(&dbv); - } + std::string* id = new std::string(dbv.pszVal); + ForkThread( &FacebookProto::AddContactToServer, this, ( void* )id ); + DBFreeVariant(&dbv); } return 0; } -int FacebookProto::ApproveFriend(WPARAM wParam,LPARAM lParam) +int FacebookProto::ApproveFriendship(WPARAM wParam,LPARAM lParam) { - if (wParam == NULL) - { // self contact -// CallService(MS_UTILS_OPENURL,1,reinterpret_cast(FACEBOOK_URL_PROFILE)); - return 0; - } - - if (isOffline()) + if (wParam == NULL || isOffline()) return 0; HANDLE *hContact = new HANDLE(reinterpret_cast(wParam)); @@ -572,13 +531,3 @@ int FacebookProto::ApproveFriend(WPARAM wParam,LPARAM lParam) return 0; } - -void FacebookProto::ToggleStatusMenuItems( BOOL bEnable ) -{ - CLISTMENUITEM clmi = { 0 }; - clmi.cbSize = sizeof( CLISTMENUITEM ); - clmi.flags = CMIM_FLAGS | (( bEnable ) ? 0 : CMIF_GRAYED); - - CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hMenuRoot, ( LPARAM )&clmi ); - CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hStatusMind, ( LPARAM )&clmi ); -} diff --git a/protocols/FacebookRM/proto.h b/protocols/FacebookRM/proto.h index bacdc5c109..d4966874ce 100644 --- a/protocols/FacebookRM/proto.h +++ b/protocols/FacebookRM/proto.h @@ -116,9 +116,9 @@ public: int __cdecl GetAvatarInfo(WPARAM, LPARAM ); int __cdecl GetAvatarCaps(WPARAM, LPARAM ); int __cdecl VisitProfile(WPARAM, LPARAM ); - int __cdecl RemoveFriend(WPARAM, LPARAM ); - int __cdecl AddFriend(WPARAM, LPARAM ); - int __cdecl ApproveFriend(WPARAM, LPARAM ); + int __cdecl CancelFriendship(WPARAM, LPARAM ); + int __cdecl RequestFriendship(WPARAM, LPARAM ); + int __cdecl ApproveFriendship(WPARAM, LPARAM ); // Events int __cdecl OnModulesLoaded(WPARAM, LPARAM); @@ -166,7 +166,7 @@ public: // Contacts handling bool IsMyContact(HANDLE, bool include_chat = false); HANDLE ContactIDToHContact(std::string); - HANDLE AddToContactList(facebook_user*, bool dont_check = false, const char *new_name = ""); + HANDLE AddToContactList(facebook_user*, BYTE type, bool dont_check = false, const char *new_name = ""); void SetAllContactStatuses(int); // Chats handling @@ -195,7 +195,6 @@ public: HANDLE avatar_lock_; HANDLE log_lock_; HANDLE update_loop_lock_; - //HANDLE message_loop_lock_; HANDLE m_hNetlibUser; diff --git a/protocols/FacebookRM/resource.h b/protocols/FacebookRM/resource.h index 14ff2d1e6b..887119bd4b 100644 --- a/protocols/FacebookRM/resource.h +++ b/protocols/FacebookRM/resource.h @@ -4,8 +4,9 @@ // #define IDI_FACEBOOK 101 #define IDI_MIND 102 -#define IDI_ADDFRIEND 103 -#define IDI_REMOVEFRIEND 104 +#define IDI_AUTH_GRANT 103 +#define IDI_AUTH_ASK 104 +#define IDI_AUTH_REVOKE 105 #define IDD_FACEBOOKACCOUNT 111 #define IDD_MIND 112 #define IDD_OPTIONS 113 @@ -61,7 +62,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 121 +#define _APS_NEXT_RESOURCE_VALUE 126 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 131 diff --git a/protocols/FacebookRM/stubs.cpp b/protocols/FacebookRM/stubs.cpp index 2bbb2ffb3b..6237a39129 100644 --- a/protocols/FacebookRM/stubs.cpp +++ b/protocols/FacebookRM/stubs.cpp @@ -27,16 +27,6 @@ HANDLE FacebookProto::AddToListByEvent(int flags,int iContact,HANDLE hDbEvent) return 0; } -int FacebookProto::Authorize(HANDLE hContact) -{ - return 0; -} - -int FacebookProto::AuthDeny(HANDLE hContact,const PROTOCHAR *reason) -{ - return 0; -} - int FacebookProto::AuthRecv(HANDLE hContact,PROTORECVEVENT *) { return 0; diff --git a/protocols/FacebookRM/theme.cpp b/protocols/FacebookRM/theme.cpp index ddf612e4d6..fd8d0be032 100644 --- a/protocols/FacebookRM/theme.cpp +++ b/protocols/FacebookRM/theme.cpp @@ -33,13 +33,15 @@ struct } static const icons[] = { - { "facebook", LPGEN("Facebook Icon"), IDI_FACEBOOK }, - { "mind", LPGEN("Mind"), IDI_MIND }, - { "removeFriend", LPGEN("Remove from server"), IDI_REMOVEFRIEND }, - { "addFriend", LPGEN("Request friendship"), IDI_ADDFRIEND }, - { "approveFriend", LPGEN("Approve friendship"), 0, "core_main_8" }, // TODO: add better icon + { "facebook", LPGEN("Facebook Icon"), IDI_FACEBOOK }, + { "mind", LPGEN("Mind"), IDI_MIND }, - { "homepage", LPGEN("Visit Profile"), 0, "core_main_2" }, + { "authRevoke", LPGEN("Cancel friendship"), IDI_AUTH_REVOKE }, + //{ "authRevokeReq", LPGEN("Cancel friendship request"), IDI_AUTH_REVOKE }, + { "authAsk", LPGEN("Request friendship"), IDI_AUTH_ASK }, + { "authGrant", LPGEN("Approve friendship"), IDI_AUTH_GRANT }, + + { "homepage", LPGEN("Visit Profile"), 0, "core_main_2" }, }; static HANDLE hIconLibItem[SIZEOF(icons)]; @@ -107,7 +109,9 @@ char *GetIconDescription(const char* name) } // Contact List menu stuff -HANDLE g_hMenuItems[5]; +HANDLE hHookPreBuildMenu; +HANDLE g_hContactMenuItems[CMITEMS_COUNT]; +HANDLE g_hContactMenuSvc[CMITEMS_COUNT]; // Helper functions static FacebookProto * GetInstanceByHContact(HANDLE hContact) @@ -133,13 +137,15 @@ INT_PTR GlobalService(WPARAM wParam,LPARAM lParam) static int PrebuildContactMenu(WPARAM wParam,LPARAM lParam) { - ShowContactMenus(false); + for (size_t i=0; i(wParam)); return proto ? proto->OnPrebuildContactMenu(wParam,lParam) : 0; } -HANDLE hHookPreBuildMenu, sVisitProfile, sAddFriend, sRemoveFriend, sApproveFriend; void InitContactMenus() { hHookPreBuildMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU,PrebuildContactMenu); @@ -151,56 +157,141 @@ void InitContactMenus() mi.icolibItem = GetIconHandle("homepage"); mi.pszName = GetIconDescription("homepage"); mi.pszService = "FacebookProto/VisitProfile"; - sVisitProfile = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::VisitProfile>); - g_hMenuItems[1] = reinterpret_cast( + g_hContactMenuSvc[CMI_VISIT_PROFILE] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::VisitProfile>); + g_hContactMenuItems[CMI_VISIT_PROFILE] = reinterpret_cast( CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) ); - mi.position=-2000006000; - mi.icolibItem = GetIconHandle("removeFriend"); - mi.pszName = GetIconDescription("removeFriend"); - mi.pszService = "FacebookProto/RemoveFriend"; - sRemoveFriend = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::RemoveFriend>); - g_hMenuItems[2] = reinterpret_cast( + mi.position=-2000006001; + mi.icolibItem = GetIconHandle("authRevoke"); + mi.pszName = GetIconDescription("authRevoke"); + mi.pszService = "FacebookProto/CancelFriendship"; + g_hContactMenuSvc[CMI_AUTH_REVOKE] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::CancelFriendship>); + g_hContactMenuItems[CMI_AUTH_REVOKE] = reinterpret_cast( CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) ); - mi.position=-2000006000; - mi.icolibItem = GetIconHandle("addFriend"); - mi.pszName = GetIconDescription("addFriend"); - mi.pszService = "FacebookProto/AddFriend"; - sAddFriend = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::AddFriend>); - g_hMenuItems[3] = reinterpret_cast( + /* mi.position=-2000006001; + mi.icolibItem = GetIconHandle("authRevokeReq"); + mi.pszName = GetIconDescription("authRevokeReq"); + mi.pszService = "FacebookProto/CancelFriendshipRequest"; + g_hContactMenuSvc[CMI_AUTH_REVOKE_REQ] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::CancelFriendshipRequest>); + g_hContactMenuItems[CMI_AUTH_REVOKE_REQ] = reinterpret_cast( + CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) ); */ + + mi.position=-2000006002; + mi.icolibItem = GetIconHandle("authAsk"); + mi.pszName = GetIconDescription("authAsk"); + mi.pszService = "FacebookProto/RequestFriendship"; + g_hContactMenuSvc[CMI_AUTH_ASK] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::RequestFriendship>); + g_hContactMenuItems[CMI_AUTH_ASK] = reinterpret_cast( CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) ); - mi.position=-2000006000; - mi.icolibItem = GetIconHandle("approveFriend"); - mi.pszName = GetIconDescription("approveFriend"); - mi.pszService = "FacebookProto/ApproveFriend"; - sApproveFriend = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::ApproveFriend>); - g_hMenuItems[4] = reinterpret_cast( + mi.position=-2000006003; + mi.icolibItem = GetIconHandle("authGrant"); + mi.pszName = GetIconDescription("authGrant"); + mi.pszService = "FacebookProto/ApproveFriendship"; + g_hContactMenuSvc[CMI_AUTH_GRANT] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::ApproveFriendship>); + g_hContactMenuItems[CMI_AUTH_GRANT] = reinterpret_cast( CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) ); } void UninitContactMenus() { - for(size_t i=0; i(wParam); + + EnableMenuItem(g_hContactMenuItems[CMI_VISIT_PROFILE], true); + + if (!isOffline() && !DBGetContactSettingByte(hContact, m_szModuleName, "ChatRoom", 0)) { - CLISTMENUITEM item = { sizeof(item) }; - item.flags = CMIM_FLAGS; - if(!show || (i == 3 && !deleted) || (i == 2 && deleted) || (i == 4 && !deleted)) // 2 = REMOVE CONTACT; 3 = ADD CONTACT; 4 = APPROVE CONTACT - item.flags |= CMIF_HIDDEN; + bool ctrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0; + + BYTE type = DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0); + + EnableMenuItem(g_hContactMenuItems[CMI_AUTH_ASK], ctrlPressed || type == FACEBOOK_CONTACT_NONE || !type); + EnableMenuItem(g_hContactMenuItems[CMI_AUTH_GRANT], ctrlPressed || type == FACEBOOK_CONTACT_APPROVE); + EnableMenuItem(g_hContactMenuItems[CMI_AUTH_REVOKE], ctrlPressed || type == FACEBOOK_CONTACT_FRIEND); + //EnableMenuItem(g_hContactMenuItems[CMI_AUTH_CANCEL], ctrlPressed || type == FACEBOOK_CONTACT_REQUEST); + } - CallService(MS_CLIST_MODIFYMENUITEM,reinterpret_cast(g_hMenuItems[i]), - reinterpret_cast(&item)); + return 0; +} + +int FacebookProto::OnBuildStatusMenu(WPARAM wParam,LPARAM lParam) +{ + char text[200]; + strcpy(text,m_szModuleName); + char *tDest = text+strlen(text); + + HGENMENU hRoot; + CLISTMENUITEM mi = {sizeof(mi)}; + mi.pszService = text; + + hRoot = MO_GetProtoRootMenu(m_szModuleName); + if (hRoot == NULL) + { + mi.popupPosition = 500085000; + mi.hParentMenu = HGENMENU_ROOT; + mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED | ( this->isOnline() ? 0 : CMIF_GRAYED ); + mi.icolibItem = GetIconHandle( "facebook" ); + mi.ptszName = m_tszUserName; + hRoot = m_hMenuRoot = reinterpret_cast( CallService( + MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast(&mi)) ); + } else { + if ( m_hMenuRoot ) + CallService( MS_CLIST_REMOVEMAINMENUITEM, ( WPARAM )m_hMenuRoot, 0 ); + m_hMenuRoot = NULL; } + + mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP | ( this->isOnline() ? 0 : CMIF_GRAYED ); + mi.position = 201001; + + CreateProtoService(m_szModuleName,"/Mind",&FacebookProto::OnMind,this); + strcpy(tDest,"/Mind"); + mi.hParentMenu = hRoot; + mi.pszName = LPGEN("Mind..."); + mi.icolibItem = GetIconHandle("mind"); + m_hStatusMind = reinterpret_cast( CallService( + MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast(&mi)) ); + + CreateProtoService(m_szModuleName,"/VisitProfile",&FacebookProto::VisitProfile,this); + strcpy(tDest,"/VisitProfile"); + mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP; + mi.pszName = LPGEN("Visit Profile"); + mi.icolibItem = GetIconHandle("homepage"); + // TODO RM: remember and properly free in destructor? + /*m_hStatusMind = */reinterpret_cast( CallService( + MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast(&mi)) ); + + return 0; +} + +void FacebookProto::ToggleStatusMenuItems( BOOL bEnable ) +{ + CLISTMENUITEM clmi = { 0 }; + clmi.cbSize = sizeof( CLISTMENUITEM ); + clmi.flags = CMIM_FLAGS | (( bEnable ) ? 0 : CMIF_GRAYED); + + CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hMenuRoot, ( LPARAM )&clmi ); + CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hStatusMind, ( LPARAM )&clmi ); } diff --git a/protocols/FacebookRM/theme.h b/protocols/FacebookRM/theme.h index 4330c35dce..e6bf689676 100644 --- a/protocols/FacebookRM/theme.h +++ b/protocols/FacebookRM/theme.h @@ -27,4 +27,12 @@ HANDLE GetIconHandle(const char *name); void InitContactMenus(void); void UninitContactMenus(void); -void ShowContactMenus(bool show, bool deleted = false); +void EnableMenuItem(HANDLE hMenuItem, bool enable); + +/* Contact menu item indexes */ +#define CMI_VISIT_PROFILE 0 +#define CMI_AUTH_REVOKE 1 +#define CMI_AUTH_ASK 2 +#define CMI_AUTH_GRANT 3 + +#define CMITEMS_COUNT 4 \ No newline at end of file -- cgit v1.2.3