diff --git a/application/ChatProtocolMessages.h b/application/ChatProtocolMessages.h index 4e2e2ac..ffa8689 100644 --- a/application/ChatProtocolMessages.h +++ b/application/ChatProtocolMessages.h @@ -402,14 +402,22 @@ enum im_what_code { * Special messages */ - //! Special message forwarded to protocol + //! Special message forwarded to protocol; Unused IM_SPECIAL_TO_PROTOCOL = 1000, - //! Special message forwarded from protocol + //! Special message forwarded from protocol; Unused IM_SPECIAL_FROM_PROTOCOL = 1001, - //! Protocol is ready to receive messages + /*! Protocol is ready →App + Should be sent after connection is established, initialization done */ IM_PROTOCOL_READY = 1002, + + /*! Account has just been disabled →App + Sent as the account disconnects, and will not be automatically + reconnected on the add-on's side. + Should be sent in two cases: When connection fails due to an error, + or when account has been closed by user (ChatProtocol::Shutdown()) */ + IM_PROTOCOL_DISABLED = 1003 }; #endif // _CHAT_PROTOCOL_MESSAGES_H diff --git a/protocols/purple/PurpleApp.cpp b/protocols/purple/PurpleApp.cpp index 5c6f1c1..396fb86 100644 --- a/protocols/purple/PurpleApp.cpp +++ b/protocols/purple/PurpleApp.cpp @@ -870,7 +870,6 @@ init_libpurple() BString cachePlugin = BString(purple_cache()).Append("/plugins/"); purple_plugins_add_search_path(cachePlugin.String()); purple_plugins_add_finddir(B_USER_LIB_DIRECTORY); - purple_plugins_add_finddir(B_SYSTEM_LIB_DIRECTORY); purple_plugins_add_finddir(B_USER_NONPACKAGED_LIB_DIRECTORY); purple_plugins_add_finddir(B_SYSTEM_NONPACKAGED_LIB_DIRECTORY); @@ -960,6 +959,12 @@ init_signals() purple_signal_connect(purple_accounts_get_handle(), "account-signed-on", &handle, PURPLE_CALLBACK(signal_account_signed_on), NULL); + purple_signal_connect(purple_accounts_get_handle(), "account-signed-off", + &handle, PURPLE_CALLBACK(signal_account_signed_off), NULL); + purple_signal_connect(purple_accounts_get_handle(), "account-disabled", + &handle, PURPLE_CALLBACK(signal_account_disabled), NULL); + purple_signal_connect(purple_accounts_get_handle(), "account-error-changed", + &handle, PURPLE_CALLBACK(signal_account_error_changed), NULL); purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", &handle, PURPLE_CALLBACK(signal_account_status_changed), NULL); @@ -1019,6 +1024,37 @@ signal_account_signed_on(PurpleAccount* account) } +static void +signal_account_signed_off(PurpleAccount* account) +{ + signal_account_disabled(account); +} + + +static void +signal_account_disabled(PurpleAccount* account) +{ + BMessage disabled(IM_MESSAGE); + disabled.AddInt32("im_what", IM_PROTOCOL_DISABLED); + ((PurpleApp*)be_app)->SendMessage(account, disabled); +} + + +static void +signal_account_error_changed(PurpleAccount* account, + const PurpleConnectionErrorInfo* old_error, + const PurpleConnectionErrorInfo* current_error) +{ + if (current_error == NULL) return; + + BMessage error(IM_ERROR); + error.AddString("error", purple_connection_error_name(current_error)); + error.AddString("detail", current_error->description); + ((PurpleApp*)be_app)->SendMessage(account, error); +} + + + static void signal_account_status_changed(PurpleAccount* account, PurpleStatus* old, PurpleStatus* cur) @@ -1473,6 +1509,48 @@ purple_status_to_cardie(PurpleStatus* status) } +const char* +purple_connection_error_name(const PurpleConnectionErrorInfo* error) +{ + switch (error->type) + { + case PURPLE_CONNECTION_ERROR_NETWORK_ERROR: + return "Connection error"; + case PURPLE_CONNECTION_ERROR_INVALID_USERNAME: + return "Invalid username"; + case PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED: + return "Authentication failed"; + case PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE: + return "Authentication impossible"; + case PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT: + return "SSL unsupported"; + case PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR: + return "Encryption error"; + case PURPLE_CONNECTION_ERROR_NAME_IN_USE: + return "Username in use"; + case PURPLE_CONNECTION_ERROR_INVALID_SETTINGS: + return "Settings invalid"; + case PURPLE_CONNECTION_ERROR_CERT_NOT_PROVIDED: + return "No SSL certificate provided"; + case PURPLE_CONNECTION_ERROR_CERT_UNTRUSTED: + return "Untrusted SSL certificate"; + case PURPLE_CONNECTION_ERROR_CERT_EXPIRED: + return "Expired SSL certificate"; + case PURPLE_CONNECTION_ERROR_CERT_NOT_ACTIVATED: + return "Unactivated SSL certificate"; + case PURPLE_CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH: + return "Certificate and hostname conflict"; + case PURPLE_CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH: + return "Certifcate and fingerprint conflict"; + case PURPLE_CONNECTION_ERROR_CERT_SELF_SIGNED: + return "Self-signed certificate"; + case PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR: + return "Certificate error"; + } + return "Misc. error"; +} + + const char* purple_cache() { diff --git a/protocols/purple/PurpleApp.h b/protocols/purple/PurpleApp.h index 68a06c6..5fd4698 100644 --- a/protocols/purple/PurpleApp.h +++ b/protocols/purple/PurpleApp.h @@ -121,6 +121,11 @@ private: // Account signals static void signal_account_signed_on(PurpleAccount* account); + static void signal_account_signed_off(PurpleAccount* account); + static void signal_account_disabled(PurpleAccount* account); + static void signal_account_error_changed(PurpleAccount* account, + const PurpleConnectionErrorInfo* old_error, + const PurpleConnectionErrorInfo* current_error); static void signal_account_status_changed(PurpleAccount* account, PurpleStatus* old, PurpleStatus* cur); @@ -219,6 +224,9 @@ private: PurpleStatusPrimitive cardie_status_to_purple(UserStatus status); UserStatus purple_status_to_cardie(PurpleStatus* status); + const char* purple_connection_error_name( + const PurpleConnectionErrorInfo* error); + const char* purple_cache(); void purple_plugins_add_finddir(directory_which finddir);