From de0c391964f20214bedcffa954c162360675d3b1 Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 15 Mar 2012 16:43:42 +0000 Subject: FacebookRM: version bump # For running plugin is required Miranda 0.9.43 or newer # Plugin is compiled with VS2005 (Fb x86) and a VS2010 (Fb x64) + Added 2 types of newsfeeds: Photos and Links * Reworked options ! Fixed setting to notify different type of newsfeeds ! Fixed and improved parsing newsfeeds ! Fixed getting groupchat messages which contains % ! Fixed not working login ! Improved deleting of contacts + Support for Miranda's EV_PROTO_ONCONTACTDELETED events + Added missing GUID for x64 version and updated user-agent ! Some other minor fixes or improvements ! Fixed item 'Visit Profile' when protocol menus are moved to Main menu * Updated language pack file (for translators) - Disabled option for closing message windows on website (temporary doesnt work) git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@279 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- FacebookRM/_changelog.txt | 232 --------------------------------- FacebookRM/build.h | 2 +- FacebookRM/chat.cpp | 4 +- FacebookRM/client.h | 3 +- FacebookRM/communication.cpp | 12 +- FacebookRM/constants.h | 4 +- FacebookRM/contacts.cpp | 71 +++++----- FacebookRM/facebook.rc | 22 ++-- FacebookRM/facebook_10.vcxproj | 16 ++- FacebookRM/facebook_10.vcxproj.filters | 6 + FacebookRM/main.cpp | 29 ++--- FacebookRM/process.cpp | 52 ++++---- FacebookRM/proto.cpp | 78 ++++++----- FacebookRM/proto.h | 4 +- FacebookRM/utils.cpp | 51 ++++---- 15 files changed, 191 insertions(+), 395 deletions(-) diff --git a/FacebookRM/_changelog.txt b/FacebookRM/_changelog.txt index 250632f..556d59a 100644 --- a/FacebookRM/_changelog.txt +++ b/FacebookRM/_changelog.txt @@ -1,235 +1,3 @@ -0.0.7.0 -------- - -+ Support for group chats (EXPERIMENTAL!) - enable it in options -! Fixed loading contact list -! Fixed potential freeze. - -0.0.6.1a -------- - -Reuploaded. - -0.0.6.1 -------- - -+ Returned option to close chat windows (on website) -+ New option to map non-standard statuses to Invisible (insetad of Online) -+ New option to load contacts, which have "On the Phone" status -! Fixed changing chat visibility -! Very long messages are no longer received duplicitely -! Changes and fixes related to multiuser messages and messages from people, which are not in server-list - -0.0.6.0 -------- - -* Reworked Facebook options -+ Option for use https connection also for "channel" requests -+ Option for use bigger avatars -+ Option for getting unread messages after login (EXPERIMENTAL!) -+ Option fot disconnect chat when going offline in Miranda -- Removed option for setting User-Agent -- Removed option for show Cookies -* When contact is deleted, in database you can found datetime of this discovery (value "Deleted" of type DWORD) -+ Option in contact menu for delete from server -+ Option in contact menu for request friendship -+ When deleting contact is showed dialog with option to delete contact also from server -! Fixed not working login - -0.0.5.5 -------- - -! Fixed contacts not going to offline. - -0.0.5.4 -------- - -! Fixed few problems with connecting -! Fixes for some crashes, memory leaks and communication (thanks borkra) -@ If is your Facebook disconnecting and you have enabled HTTPS connection, disable option "Validate SSL certificates" for Facebook in Options/Networks. - -0.0.5.3 -------- - -! Fixed issue with login for some people -! Fixed not receiving some messages -! Fixed broken getting own name -* Faster sending messages - -0.0.5.2 -------- - -! Fix for connecting and crashing problem. - -0.0.5.1 -------- - -! Work-around for sending messages with url links. - -0.0.5.0 -------- - -+ Notification about friends, which are back on serverlist. -* Completely reworked avatar support. -* Using small square avatars by default (can be changed by hidden setting "UseBigAvatars") -! Fixed use of hidden setting "UseBigAvatars" -! Fixed setting status message. -! Fixed crash with MetaContacts. -! Fixed login for some people. -! Fixes related to popups on login. -! Fixed memory leak related to popups. -! Fixed getting unread messages on login (if used hidden setting "ParseUnreadMessages") -! Fixed login with setting Device name. -! Various fixes, improvements and code cleanup. -- Removed hidden key "OldFeedsTimestamp" -@ Thanks borkra for helping me with many things. - -0.0.4.3 -------- - -! Fix for new facebook layout. -! Fix for getting contact name for new contacts. - -0.0.4.2 -------- - -! Fixed not enabling items in status menu. -! Don't automatically set contact's status to Online when we got message from him. -! Fixed message's sending error codepage. -+ Added support for sending messages in invisible status. -+ Protocol status respects changes of chat status on website. -+ Notify concrete unread notifications after login -+ Added hidden key (ParseUnreadMessages) for getting unread messages after login << WARNING: not fully working!!! - -0.0.4.1 -------- - -! Reverted change that made contacts not going offline. - -0.0.4.0 -------- - -* Internal changes about changing status -- Removed support for "Away" status -! Fixed parsing newsfeeds -- Removed notification about unread messages in "Invisible" status -+ In "Invisible" status are inbox messages parsed directly to messages -+ Getting gender of contacts -+ Getting all contacts from server at once (not only these, which are online right now) -+ Notification when somebody cancel our friendship (= or when disables his facebook account) - -0.0.3.3 -------- - -! Fix for communication (getting seq number) -! Fixed notification with unread events after login - -0.0.3.2 -------- - -! Mark chat messages on facebook read. -* Disabled channel refresh notification - -0.0.3.1 -------- - -! Fixed notify about timeout when sending message. - -0.0.3.0 -------- - -! Fixed downloading avatars -! Fixed loading avatars in SRMM -! (Maybe) Fixed not loading for some people with miranda 0.9.17 -! Fixed crashes and freezes when deleting account -! Few fixes and improvements related to login procedure -! Fixed parsing some newsfeeds -! (Hopefully) Fixed some other crashes -! Fix for logon crash when notify unread events. -* Improvement in getting contact avatars (2x faster) -* Optimized compiler settings -> 2x smaller file (thanks borkra) -+ Used persistent http connection (thanks borkra) -+ Destroy service and hook on exit (thanks FREAK_THEMIGHTY) -+ Support for per-plugin-translation (for MIM 0.10#2) (thanks FREAK_THEMIGHTY) -+ Support for EV_PROTO_ONCONTACTDELETED (for MIM 0.10#2) (thanks FREAK_THEMIGHTY) -- Do not translate options page title, since it is the account name -- Disabled close chat "optimalization" -! Fixed sending typing notifications -! Fixed parsing links from newsfeeds -* Enabled sending offline messages -! Fixed getting errors from sending messages (+ show concrete error) -+ 5 attempts to send message before showing error message - -0.0.2.4 -------- - -! Fixed duplicit messages and notifications -* Limit for popup messages from group chats - max. one per 15 seconds -* Optimalization for sending typing notify -* Optimalization for closing chat windows on website -+ Notify when is possible that we didnt received some chat message(s) -+ Show popup when try to send offline message and open website for send private message when onclick - -0.0.2.3 -------- - -! Fixed loading contact names -! Fixed updater support for x64 versions -+ Added 32px status icons -+ Added option for chose type of newsfeeds to notify -* Changed user-agent names to user-friendlier -* Enhanced parsing newsfeeds - -0.0.2.3 -------- - -! Fixed loading contact names -! Fixed updater support for x64 versions -+ Added 32px status icons -+ Added option for chose type of newsfeeds to notify -* Changed user-agent names to user-friendlier -* Enhanced parsing newsfeeds - -0.0.2.2 -------- - -+ Updater support -+ Added item in contact and status menu for open contact profile on website (+ saving in db as Homepage key) -+ Notify about new private (not chat) messages in invisible -+ Automatically set https when connecting if required -* Optimalization for downloading avatars of contacts -! Fix for -in newsfeeds popups -! Fix for html tags in connecting error message -! Fix for broken sending messages - -0.0.2.1 -------- - -! Fixes for statuses (cannot switch to Away, work in threads) -! Fix for loading own avatar when changed -* Sounds are using account name (thanks FREAK_THEMIGHTY) -! Fixes for x64 version (thanks FREAK_THEMIGHTY) -! Fix for thread synchronization -! Fixed order of outgoing messages and notify about delivery errors -! Fix few things which was causing not delivering all incoming messages -! Fixes for internal list implementation -* Refactoring and simplify few things -+ Added x64 version of plugin -+ Notify about new notifications after login -! Fixed parsing few types of newsfeeds -+ 1. stage of groupchats - notifying incomming messages - -0.0.2.0 -------- - -* Guided as new plugin Facebook RM + new readme and folder structure -x Temporarily disabled updater support (and notification about jarvis's new "fb api") -! Fix for load own avatar -! Fix for loading newsfeeds and their better parsing -+ Added Away and Invisible statuses -* Using away status as idle flag -! Fixed idle control - facebook falls into idle only when Away status 0.1.3.2 ------- diff --git a/FacebookRM/build.h b/FacebookRM/build.h index a5ae562..bcbabbb 100644 --- a/FacebookRM/build.h +++ b/FacebookRM/build.h @@ -1 +1 @@ -#define __BUILD 2063 +#define __BUILD 2119 diff --git a/FacebookRM/chat.cpp b/FacebookRM/chat.cpp index a7c2ca5..7326254 100644 --- a/FacebookRM/chat.cpp +++ b/FacebookRM/chat.cpp @@ -105,9 +105,9 @@ void FacebookProto::AddChatContact(const char *chat_id, const char *id, const ch gce.time = ::time(NULL); gce.bIsMe = !strcmp(id, facy.self_.user_id.c_str()); -/* if (gce.bIsMe) + if (gce.bIsMe) gce.ptszStatus = _T("Admin"); - else*/ + else gce.ptszStatus = _T("Normal"); CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); diff --git a/FacebookRM/client.h b/FacebookRM/client.h index 0ae6dc0..45f4bb3 100644 --- a/FacebookRM/client.h +++ b/FacebookRM/client.h @@ -41,7 +41,7 @@ public: msgid_ = error_count_ = last_feeds_update_ = last_notification_time_ = 0; - invisible_ = is_typing_ = false; + is_idle_ = invisible_ = is_typing_ = false; buddies_lock_ = send_message_lock_ = NULL; hMsgCon = NULL; @@ -74,6 +74,7 @@ public: std::string chat_reconnect_reason_; bool invisible_; bool is_typing_; + bool is_idle_; time_t last_feeds_update_; unsigned __int64 last_notification_time_; int msgid_; diff --git a/FacebookRM/communication.cpp b/FacebookRM/communication.cpp index e819f82..a7230fc 100644 --- a/FacebookRM/communication.cpp +++ b/FacebookRM/communication.cpp @@ -406,13 +406,15 @@ std::string facebook_client::choose_action( int request_type, std::string* data case FACEBOOK_REQUEST_RECONNECT: { - std::string action = "/ajax/presence/reconnect.php?__a=1&reason=%s&iframe_loaded=false&post_form_id=%s"; + std::string action = "/ajax/presence/reconnect.php?__a=1&reason=%s&fb_dtsg=%s&post_form_id=%s&__user=%s"; if (this->chat_reconnect_reason_.empty()) - this->chat_reconnect_reason_ = "0"; + this->chat_reconnect_reason_ = "0"; // 6? utils::text::replace_first( &action, "%s", this->chat_reconnect_reason_ ); + utils::text::replace_first( &action, "%s", this->dtsg_ ); utils::text::replace_first( &action, "%s", this->post_form_id_ ); + utils::text::replace_first( &action, "%s", this->self_.user_id ); return action; } @@ -851,9 +853,6 @@ bool facebook_client::home( ) ForkThread( &FacebookProto::ProcessNotifications, this->parent, NULL ); } - // TODO RM: if enabled groupchats support - - if (DBGetContactSettingByte(NULL, parent->m_szModuleName, FACEBOOK_KEY_ENABLE_GROUPCHATS, DEFAULT_ENABLE_GROUPCHATS)) { // Get group chats std::string favorites = utils::text::source_get_value( &resp.data, 2, "
chat_reconnect_reason_ = utils::text::source_get_value2( &resp.data, "\"reason\":", ",}" ); parent->Log(" Reconnect reason: %s", this->chat_reconnect_reason_.c_str()); + this->chat_sequence_num_ = utils::text::source_get_value2( &resp.data, "\"seq\":", ",}" ); + parent->Log(" Got self sequence number: %s", this->chat_sequence_num_.c_str()); + return this->reconnect( ); } else { // Something has been received, throw to new thread to process diff --git a/FacebookRM/constants.h b/FacebookRM/constants.h index b53a696..f02283b 100644 --- a/FacebookRM/constants.h +++ b/FacebookRM/constants.h @@ -24,8 +24,8 @@ along with this program. If not, see . // Version management #include "build.h" -#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0, 0, 7, 1) -#define __VERSION_STRING "0.0.7.1" +#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0, 0, 8, 0) +#define __VERSION_STRING "0.0.8.0" // Product management #define FACEBOOK_NAME "Facebook" diff --git a/FacebookRM/contacts.cpp b/FacebookRM/contacts.cpp index 20853c2..0b50411 100644 --- a/FacebookRM/contacts.cpp +++ b/FacebookRM/contacts.cpp @@ -146,6 +146,8 @@ void FacebookProto::DeleteContactFromServer(void *data) query += "&__user="; query += facy.self_.user_id; + delete data; + // Get unread inbox threads http::response resp = facy.flap( FACEBOOK_REQUEST_DELETE_FRIEND, &query ); @@ -156,9 +158,8 @@ void FacebookProto::DeleteContactFromServer(void *data) facy.handle_error( "DeleteContactFromServer" ); } - NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact was sucessfully removed from server."), NULL, FACEBOOK_EVENT_OTHER, NULL); - - delete data; + // TODO: better notify - check result code + NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact was sucessfully removed from server."), NULL, FACEBOOK_EVENT_OTHER, NULL); } void FacebookProto::AddContactToServer(void *data) @@ -179,6 +180,8 @@ void FacebookProto::AddContactToServer(void *data) query += "&__user="; query += facy.self_.user_id; + delete data; + // Get unread inbox threads http::response resp = facy.flap( FACEBOOK_REQUEST_ADD_FRIEND, &query ); @@ -188,10 +191,8 @@ void FacebookProto::AddContactToServer(void *data) if (resp.code != HTTP_CODE_OK || resp.data.find("\"success\":true") == std::string::npos) { facy.handle_error( "AddContactToServer" ); } -// RM TODO: better notify... +// RM TODO: better notify... - check result code NotifyEvent(TranslateT("Adding contact"), TranslateT("Request for friendship was sent successfully."), NULL, FACEBOOK_EVENT_OTHER, NULL); - - delete data; } @@ -204,41 +205,37 @@ int FacebookProto::OnContactDeleted(WPARAM wparam,LPARAM) { HANDLE hContact = (HANDLE)wparam; - if (IsMyContact(hContact)) - { -// if (!DBGetContactSettingByte(hContact,m_szModuleName,FACEBOOK_KEY_DELETE_NEXT,0)) { - if (MessageBox( 0, TranslateT("Do you want to delete this contact also from server list?"), m_tszUserName, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) == IDYES) { - DBVARIANT dbv; - if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) - { - if (!isOffline()) { - std::string* id = new std::string(dbv.pszVal); - ForkThread( &FacebookProto::DeleteContactFromServer, this, ( void* )id ); - DBFreeVariant(&dbv); - } else { -/* facebook_user fbu; - fbu.user_id = dbv.pszVal; - hContact = AddToContactList(&fbu); - - DBWriteContactSettingByte(hContact,m_szModuleName,FACEBOOK_KEY_DELETE_NEXT,1); - facy.client_notify(TranslateT("Contact will be deleted at next login."));*/ - NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact wasn't deleted, because you are not connected."), NULL, FACEBOOK_EVENT_OTHER, NULL); - } - } - } -// } - - ScopedLock s(facy.buddies_lock_); - - for (List::Item< facebook_user >* i = facy.buddies.begin( ); i != NULL; i = i->next ) + DBVARIANT dbv; + TCHAR text[512]; + if ( !DBGetContactSettingTString(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) { + mir_sntprintf(text,SIZEOF(text),TranslateT("Do you want to delete contact '%s' from server list?"),dbv.ptszVal); + DBFreeVariant(&dbv); + } else if( !DBGetContactSettingTString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) { + mir_sntprintf(text,SIZEOF(text),TranslateT("Do you want to delete contact '%s' from server list?"),dbv.ptszVal); + DBFreeVariant(&dbv); + } + + if (MessageBox( 0, text, m_tszUserName, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) == IDYES) { + + if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) { - if (hContact == i->data->handle) - { - facy.buddies.erase(i->key); - break; + if (!isOffline()) { // TODO: is this needed? + std::string* id = new std::string(dbv.pszVal); + ForkThread( &FacebookProto::DeleteContactFromServer, this, ( void* )id ); + DBFreeVariant(&dbv); } } } + //ScopedLock s(facy.buddies_lock_); + for (List::Item< facebook_user >* i = facy.buddies.begin( ); i != NULL; i = i->next ) + { + if (hContact == i->data->handle) + { + facy.buddies.erase(i->key); + break; + } + } + return 0; } diff --git a/FacebookRM/facebook.rc b/FacebookRM/facebook.rc index a329a8e..4004191 100644 --- a/FacebookRM/facebook.rc +++ b/FacebookRM/facebook.rc @@ -13,13 +13,11 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources +// English (United States) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) -#endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -168,8 +166,8 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,68,267,10 CONTROL "Get unread messages on login (EXPERIMENTAL)",IDC_PARSE_UNREAD, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,104,267,10 - CONTROL "Automatically close chat windows (on website)",IDC_CLOSE_WINDOWS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,80,267,10 + CONTROL "Automatically close chat windows (on website) (NOT WORKING)",IDC_CLOSE_WINDOWS, + "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,17,80,267,10 CONTROL "Map non-standard statuses to Invisible (instead of Online)",IDC_MAP_STATUSES, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,92,267,10 CONTROL "Enable groupchats support (EXPERIMENTAL)",IDC_GROUPCHATS, @@ -183,7 +181,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO +GUIDELINES DESIGNINFO BEGIN IDD_MIND, DIALOG BEGIN @@ -242,7 +240,7 @@ BEGIN VERTGUIDE, 17 VERTGUIDE, 32 VERTGUIDE, 119 - VERTGUIDE, 123 + VERTGUIDE, 122 VERTGUIDE, 284 TOPMARGIN, 7 BOTTOMMARGIN, 231 @@ -257,8 +255,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,7,1 - PRODUCTVERSION 0,9,14,0 + FILEVERSION 0,0,8,0 + PRODUCTVERSION 0,9,43,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -274,12 +272,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "Facebook protocol plugin for Miranda IM" - VALUE "FileVersion", "0, 0, 7, 1" + VALUE "FileVersion", "0.0.8.0" VALUE "InternalName", "Facebook RM" VALUE "LegalCopyright", "Copyright © 2009-2011 Michal Zelinka, 2011-2012 Robert Pösel" VALUE "OriginalFilename", "facebook.dll" VALUE "ProductName", "Facebook Protocol RM" - VALUE "ProductVersion", "0, 0, 7, 1" + VALUE "ProductVersion", "0.9.43.0" END END BLOCK "VarFileInfo" @@ -288,7 +286,7 @@ BEGIN END END -#endif // English (U.S.) resources +#endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/FacebookRM/facebook_10.vcxproj b/FacebookRM/facebook_10.vcxproj index 5dcb34b..6f5f68a 100644 --- a/FacebookRM/facebook_10.vcxproj +++ b/FacebookRM/facebook_10.vcxproj @@ -186,10 +186,10 @@ _UNICODE;UNICODE;%(PreprocessorDefinitions) - ../../include/msapi/ + + - $(OutDir)$(TargetName)$(TargetExt) true false $(TargetDir)$(TargetName).map @@ -201,6 +201,12 @@ uuid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) $(IntDir)$(TargetName).lib + + true + + + $(IntDir)$(TargetName)$(TargetExt).embed.manifest + @@ -229,10 +235,10 @@ _UNICODE;UNICODE;%(PreprocessorDefinitions) - ../../include/msapi/ + + - $(OutDir)$(TargetName)$(TargetExt) true $(TargetDir)$(TargetName).map Windows @@ -290,6 +296,8 @@ + + diff --git a/FacebookRM/facebook_10.vcxproj.filters b/FacebookRM/facebook_10.vcxproj.filters index b3b2a03..5239871 100644 --- a/FacebookRM/facebook_10.vcxproj.filters +++ b/FacebookRM/facebook_10.vcxproj.filters @@ -145,6 +145,12 @@ Resource Files + + Resource Files + + + Resource Files + diff --git a/FacebookRM/main.cpp b/FacebookRM/main.cpp index ec72a6b..f7995fc 100644 --- a/FacebookRM/main.cpp +++ b/FacebookRM/main.cpp @@ -41,18 +41,22 @@ PLUGININFOEX pluginInfo = { "Facebook Protocol RM x64", #else "Facebook Protocol RM", - #endif + #endif __VERSION_DWORD, "Provides basic support for Facebook Chat protocol. [Built: "__DATE__" "__TIME__"]", "Michal Zelinka, Robert Posel", "robyer@seznam.cz", - "(c) 2009-11 Michal Zelinka, 2011 Robert Posel", + "(c) 2009-11 Michal Zelinka, 2011-12 Robert Posel", "http://code.google.com/p/robyer/", UNICODE_AWARE, //not transient 0, //doesn't replace anything built-in + #ifdef _WIN64 + // {8808C20C-5404-48A6-8390-232AAE5E793A} + { 0x8808c20c, 0x5404, 0x48a6, { 0x83, 0x90, 0x23, 0x2a, 0xae, 0x5e, 0x79, 0x3a } } + #else // {8432B009-FF32-4727-AAE6-A9035038FD58} { 0x8432b009, 0xff32, 0x4727, { 0xaa, 0xe6, 0xa9, 0x3, 0x50, 0x38, 0xfd, 0x58 } } - + #endif }; ///////////////////////////////////////////////////////////////////////////// @@ -80,10 +84,10 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST); return NULL; } - else if(mirandaVersion < PLUGIN_MAKE_VERSION(0,9,14,0)) + else if(mirandaVersion < PLUGIN_MAKE_VERSION(0,9,43,0)) { MessageBox(0,_T("The Facebook protocol plugin cannot be loaded. ") - _T("It requires Miranda IM 0.9.14 or later."),_T("Miranda"), + _T("It requires Miranda IM 0.9.43 or later."),_T("Miranda"), MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST); return NULL; } @@ -92,15 +96,6 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda return &pluginInfo; } -/*extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) -{ - // TODO: Make product version controlled via definitions - MessageBox(0,_T("The Facebook protocol plugin cannot be loaded. ") - _T("It requires Miranda IM 0.9.14 or later."),_T("Miranda"), - MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST); - return NULL; -}*/ - ///////////////////////////////////////////////////////////////////////////////////////// // Interface information @@ -191,7 +186,11 @@ extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) agent << (( g_mirandaVersion >> 8) & 0xFF); agent << "."; agent << (( g_mirandaVersion ) & 0xFF); - agent << " FacebookProtocolRM/"; + #ifdef _WIN64 + agent << " Facebook Protocol RM x64/"; + #else + agent << " Facebook Protocol RM/"; + #endif agent << __VERSION_STRING; g_strUserAgent = agent.str( ); } diff --git a/FacebookRM/process.cpp b/FacebookRM/process.cpp index e3d0192..6f1ea0d 100644 --- a/FacebookRM/process.cpp +++ b/FacebookRM/process.cpp @@ -211,6 +211,7 @@ void FacebookProto::ProcessFriendList( void* data ) bool update_required = true; // TODO RM: remove, because contacts cant change it, so its only for "first run" + // - but what with contacts, that was added after logon? // Update gender if ( DBGetContactSettingByte(hContact, m_szModuleName, "Gender", 0) != fbu->gender ) DBWriteContactSettingByte(hContact, m_szModuleName, "Gender", fbu->gender ); @@ -537,43 +538,46 @@ void FacebookProto::ProcessFeeds( void* data ) std::string::size_type pos = 0; UINT limit = 0; - *resp = utils::text::slashu_to_utf8(*resp); + *resp = utils::text::slashu_to_utf8(*resp); + *resp = utils::text::source_get_value(resp, 2, "\"html\":\"", ">\""); - // TODO RM: first parse against
  • ...
  • ? - while ( ( pos = resp->find( "find( "find( "
    find( "
    find( "<\\/h6", pos ); + pos2 = resp->length(); + + std::string post = resp->substr( pos, pos2 - pos ); + pos += 5; - std::string post_content = resp->substr( pos, pos2 - pos ); - std::string rest_content; + std::string post_header = utils::text::source_get_value(&post, 4, "
    ", "<\\/h6>"); + std::string post_message = utils::text::source_get_value(&post, 3, "
    ", "<\\/h6>"); + std::string post_link = utils::text::source_get_value(&post, 3, "", "<\\/span>"); + std::string post_attach = utils::text::source_get_value(&post, 4, "
    ", "") + 5; + post_message = post_header.substr(pos2, post_header.length() - pos2) + post_message; + post_header = post_header.substr(0, pos2); - pos += 4; - facebook_newsfeed* nf = new facebook_newsfeed; - - nf->title = utils::text::source_get_value( &post_content, 3, "", "<\\/a" ); - nf->user_id = utils::text::source_get_value( &post_content, 2, "user.php?id=", "\\\"" ); - - if ( (pos2 = post_content.find( "<\\/a>" )) != std::string::npos ) - nf->text = post_content.substr( pos2, post_content.length() - pos2 ); - nf->text = nf->text.substr(0, nf->text.find("link = utils::text::source_get_value( &rest_content, 2, "href=\\\"", "\\\">" ); + facebook_newsfeed* nf = new facebook_newsfeed; nf->title = utils::text::trim( utils::text::special_expressions_decode( - utils::text::remove_html( nf->title ) ) ); + utils::text::remove_html( post_header ) ) ); + + nf->user_id = utils::text::source_get_value( &post_header, 2, "user.php?id=", "\\\"" ); + nf->link = utils::text::special_expressions_decode( + utils::text::source_get_value( &post_link, 2, "href=\\\"", "\\\">" ) ); + nf->text = utils::text::trim( utils::text::special_expressions_decode( utils::text::remove_html( - utils::text::edit_html( nf->text ) ) ) ); - - nf->link = utils::text::special_expressions_decode( nf->link ); + utils::text::edit_html( post_message ) ) ) ); if ( !nf->title.length() || !nf->text.length() ) { diff --git a/FacebookRM/proto.cpp b/FacebookRM/proto.cpp index 5ecd067..12dfd27 100644 --- a/FacebookRM/proto.cpp +++ b/FacebookRM/proto.cpp @@ -48,13 +48,10 @@ FacebookProto::FacebookProto(const char* proto_name,const TCHAR* username) CreateProtoService(m_szModuleName, PS_JOINCHAT, &FacebookProto::OnJoinChat, this); CreateProtoService(m_szModuleName, PS_LEAVECHAT, &FacebookProto::OnLeaveChat, this); - if(g_mirandaVersion < PLUGIN_MAKE_VERSION(0, 10, 0, 2)) - { - HookProtoEvent(ME_DB_CONTACT_DELETED, &FacebookProto::OnContactDeleted, this); - } HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &FacebookProto::OnBuildStatusMenu, this); HookProtoEvent(ME_OPT_INITIALISE, &FacebookProto::OnOptionsInit, this); HookProtoEvent(ME_GC_EVENT, &FacebookProto::OnChatOutgoing, this); + HookProtoEvent(ME_IDLE_CHANGED, &FacebookProto::OnIdleChanged, this); // Create standard network connection TCHAR descr[512]; @@ -117,18 +114,18 @@ DWORD_PTR FacebookProto::GetCaps( int type, HANDLE hContact ) { case PFLAGNUM_1: // TODO: Other caps available: PF1_BASICSEARCH, PF1_SEARCHBYEMAIL if ( getByte( FACEBOOK_KEY_SET_MIRANDA_STATUS, 0 ) ) - return PF1_IM | PF1_MODEMSG; + return PF1_IM | PF1_CHAT | PF1_SERVERCLIST | PF1_MODEMSG; else - return PF1_IM | PF1_MODEMSGRECV; + return PF1_IM | PF1_CHAT | PF1_SERVERCLIST | PF1_MODEMSGRECV; case PFLAGNUM_2: - return PF2_ONLINE | PF2_INVISIBLE | PF2_ONTHEPHONE; // | PF2_IDLE | PF2_SHORTAWAY; + return PF2_ONLINE | PF2_INVISIBLE | PF2_ONTHEPHONE | PF2_IDLE; // | PF2_SHORTAWAY; case PFLAGNUM_3: if ( getByte( FACEBOOK_KEY_SET_MIRANDA_STATUS, 0 ) ) return PF2_ONLINE; // | PF2_SHORTAWAY; else return 0; case PFLAGNUM_4: - return PF4_FORCEAUTH | PF4_NOCUSTOMAUTH /*| PF4_SUPPORTIDLE*/ | PF4_IMSENDUTF | PF4_AVATARS | PF4_SUPPORTTYPING | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE; + return PF4_FORCEAUTH | PF4_NOCUSTOMAUTH | PF4_SUPPORTIDLE | PF4_IMSENDUTF | PF4_AVATARS | PF4_SUPPORTTYPING | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE; case PFLAGNUM_5: return PF2_ONTHEPHONE; case PFLAG_MAXLENOFMESSAGE: @@ -170,7 +167,8 @@ int FacebookProto::SetStatus( int new_status ) case ID_STATUS_CONNECTING: m_iDesiredStatus = ID_STATUS_OFFLINE; break; - + + case ID_STATUS_IDLE: default: m_iDesiredStatus = ID_STATUS_INVISIBLE; if (DBGetContactSettingByte(NULL,m_szModuleName,FACEBOOK_KEY_MAP_STATUSES, DEFAULT_MAP_STATUSES)) @@ -251,6 +249,28 @@ int FacebookProto::GetMyAwayMsg( WPARAM wParam, LPARAM lParam ) } } +int FacebookProto::OnIdleChanged( WPARAM wParam, LPARAM lParam ) +{ + if (m_iStatus == ID_STATUS_INVISIBLE || m_iStatus <= ID_STATUS_OFFLINE) + return 0; + + bool bIdle = (lParam & IDF_ISIDLE) != 0; + bool bPrivacy = (lParam & IDF_PRIVACY) != 0; + + if (facy.is_idle_ && !bIdle) + { + facy.is_idle_ = false; + SetStatus(m_iDesiredStatus); + } + else if (!facy.is_idle_ && bIdle && !bPrivacy && m_iDesiredStatus != ID_STATUS_INVISIBLE) + { + facy.is_idle_ = true; + SetStatus(ID_STATUS_IDLE); + } + + return 0; +} + ////////////////////////////////////////////////////////////////////////////// int FacebookProto::OnEvent(PROTOEVENTTYPE event,WPARAM wParam,LPARAM lParam) @@ -261,10 +281,10 @@ int FacebookProto::OnEvent(PROTOEVENTTYPE event,WPARAM wParam,LPARAM lParam) return OnModulesLoaded(wParam,lParam); case EV_PROTO_ONEXIT: - return OnPreShutdown (wParam,lParam); + return OnPreShutdown(wParam,lParam); case EV_PROTO_ONOPTIONS: - return OnOptionsInit (wParam,lParam); + return OnOptionsInit(wParam,lParam); case EV_PROTO_ONCONTACTDELETED: return OnContactDeleted(wParam,lParam); @@ -292,10 +312,12 @@ int FacebookProto::OnModulesLoaded(WPARAM wParam,LPARAM lParam) { // Register group chat GCREGISTER gcr = {sizeof(gcr)}; - //gcr.dwFlags = GC_ACKMSG; + gcr.dwFlags = 0; //GC_ACKMSG; gcr.pszModule = m_szModuleName; gcr.pszModuleDispName = m_szModuleName; gcr.iMaxText = FACEBOOK_MESSAGE_LIMIT; + gcr.nColors = 0; + gcr.pColors = NULL; CallService(MS_GC_REGISTER,0,reinterpret_cast(&gcr)); return 0; @@ -410,19 +432,18 @@ int FacebookProto::OnMind(WPARAM,LPARAM) int FacebookProto::VisitProfile(WPARAM wParam,LPARAM lParam) { - if (wParam == NULL) - { // self contact - CallService(MS_UTILS_OPENURL,1,reinterpret_cast(FACEBOOK_URL_PROFILE)); - return 0; - } - HANDLE hContact = reinterpret_cast(wParam); DBVARIANT dbv; - if( !DBGetContactSettingString(hContact,m_szModuleName,"Homepage",&dbv) ) + if( wParam != 0 && !DBGetContactSettingString(hContact,m_szModuleName,"Homepage",&dbv) ) { CallService(MS_UTILS_OPENURL,1,reinterpret_cast(dbv.pszVal)); DBFreeVariant(&dbv); + } 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; @@ -454,14 +475,6 @@ int FacebookProto::RemoveFriend(WPARAM wParam,LPARAM lParam) if ( !DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) ) DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL)); - } else { -/* facebook_user fbu; - fbu.user_id = dbv.pszVal; - hContact = AddToContactList(&fbu); - - DBWriteContactSettingByte(hContact,m_szModuleName,FACEBOOK_KEY_DELETE_NEXT,1); - facy.client_notify(TranslateT("Contact will be deleted at next login."));*/ - NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact wasn't deleted, because you are not connected."), NULL, FACEBOOK_EVENT_OTHER, NULL); } } @@ -476,6 +489,9 @@ int FacebookProto::AddFriend(WPARAM wParam,LPARAM lParam) return 0; } + if (isOffline()) + return 0; + HANDLE hContact = reinterpret_cast(wParam); DBVARIANT dbv; @@ -485,14 +501,6 @@ int FacebookProto::AddFriend(WPARAM wParam,LPARAM lParam) std::string* id = new std::string(dbv.pszVal); ForkThread( &FacebookProto::AddContactToServer, this, ( void* )id ); DBFreeVariant(&dbv); - } else { -/* facebook_user fbu; - fbu.user_id = dbv.pszVal; - hContact = AddToContactList(&fbu); - - DBWriteContactSettingByte(hContact,m_szModuleName,FACEBOOK_KEY_DELETE_NEXT,1); - facy.client_notify(TranslateT("Contact will be deleted at next login."));*/ - NotifyEvent(TranslateT("Adding contact"), TranslateT("Contact wasn't added, because you are not connected."), NULL, FACEBOOK_EVENT_OTHER, NULL); } } diff --git a/FacebookRM/proto.h b/FacebookRM/proto.h index e792b09..037643a 100644 --- a/FacebookRM/proto.h +++ b/FacebookRM/proto.h @@ -130,7 +130,7 @@ public: int __cdecl OnMind(WPARAM,LPARAM); int __cdecl OnPreShutdown(WPARAM,LPARAM); int __cdecl OnPrebuildContactMenu(WPARAM,LPARAM); - // TODO RM: Chat handling + int __cdecl OnIdleChanged(WPARAM,LPARAM); int __cdecl OnChatOutgoing(WPARAM,LPARAM); int __cdecl OnJoinChat(WPARAM,LPARAM); int __cdecl OnLeaveChat(WPARAM,LPARAM); @@ -169,7 +169,7 @@ public: HANDLE AddToContactList(facebook_user*, bool dont_check = false, const char *new_name = ""); void SetAllContactStatuses(int); - // TODO RM: Chats handling + // Chats handling void AddChat(const char *id, const char *name); void UpdateChat(const char *chat_id, const char *id, const char *name, const char *message); bool IsChatContact(const char *chat_id, const char *id); diff --git a/FacebookRM/utils.cpp b/FacebookRM/utils.cpp index 71062c3..02a7662 100644 --- a/FacebookRM/utils.cpp +++ b/FacebookRM/utils.cpp @@ -151,8 +151,7 @@ std::string utils::text::edit_html( std::string data ) } } - start = 0; - end = 0; + start = end = 0; data = new_string; new_string = ""; @@ -168,6 +167,23 @@ std::string utils::text::edit_html( std::string data ) } } + // Remove "Translate" link + start = end = 0; + data = new_string; + new_string = ""; + while ( end != std::string::npos ) + { + end = data.find( "translate_story_link\\\">", start ); + if ( end != std::string::npos ) + { + new_string += data.substr( start, end - start ); + start = data.find( "<\\/div", end ); + } else { + new_string += data.substr( start, data.length() - start ); + } + } + + // Append newline after attachement title start = new_string.find( "class=\\\"uiAttachmentTitle", 0 ); if ( start != std::string::npos ) { @@ -183,7 +199,8 @@ std::string utils::text::edit_html( std::string data ) new_string.insert(start, "\n"); } - start = new_string.find( "uiAttachmentDesc\\\"", 0 ); + // Append newline between attachement link and description + start = new_string.find( "uiAttachmentDesc", 0 ); if ( start != std::string::npos ) { start = new_string.find( ">", start ); @@ -197,6 +214,8 @@ std::string utils::text::edit_html( std::string data ) utils::text::replace_all( &new_string, "
    ", "\n" ); utils::text::replace_all( &new_string, "\n\n\n", "\n\n" ); + //utils::text::replace_all( &new_string, "\\t", "" ); + //utils::text::replace_all( &new_string, "\\n", "" ); return new_string; } @@ -260,24 +279,25 @@ std::string utils::text::slashu_to_utf8( std::string data ) std::string utils::text::trim( std::string data ) { - std::string spaces = " \t\r\n"; // TODO: include "nbsp" + std::string spaces = " \t\r\n"; // TODO: include "nbsp"? std::string::size_type begin = data.find_first_not_of( spaces ); std::string::size_type end = data.find_last_not_of( spaces ) + 1; return (begin != std::string::npos) ? data.substr( begin, end - begin ) : ""; } -void utils::text::explode(std::string str, std::string separator, std::vector* results){ +void utils::text::explode(std::string str, std::string separator, std::vector* results) +{ std::string::size_type pos; pos = str.find_first_of(separator); - while(pos != std::string::npos){ - if(pos > 0){ + while (pos != std::string::npos) { + if (pos > 0) { results->push_back(str.substr(0,pos)); } str = str.substr(pos+1); pos = str.find_first_of(separator); } - if(str.length() > 0){ + if (str.length() > 0) { results->push_back(str); } } @@ -384,18 +404,3 @@ int ext_to_format(const std::string &ext) return PA_FORMAT_UNKNOWN; } - - -// OBSOLETE - -void MB( const char* m ) -{ - MessageBoxA( NULL, m, NULL, MB_OK ); -} - -void MBI( int a ) -{ - char b[32]; - itoa( a, b, 10 ); - MB( b ); -} -- cgit v1.2.3