diff --git a/protocols/purple/PurpleApp.cpp b/protocols/purple/PurpleApp.cpp index 2deeb4c..2d44c34 100644 --- a/protocols/purple/PurpleApp.cpp +++ b/protocols/purple/PurpleApp.cpp @@ -50,18 +50,18 @@ void PurpleApp::MessageReceived(BMessage* msg) { int64 thread_id; - if (msg->FindInt64("thread_id", &thread_id) != B_OK) - return; switch (msg->what) { case PURPLE_REQUEST_PROTOCOL_COUNT: { + if (msg->FindInt64("thread_id", &thread_id) != B_OK) return; send_data(thread_id, fProtocols.CountItems(), NULL, 0); break; } case PURPLE_REQUEST_PROTOCOL_INFO: { + if (msg->FindInt64("thread_id", &thread_id) != B_OK) return; int32 index = msg->FindInt32("index", 0); ProtocolInfo* info = fProtocols.ItemAt(index); @@ -78,6 +78,11 @@ PurpleApp::MessageReceived(BMessage* msg) send_data(thread_id, 0, buffer, size); break; } + case PURPLE_LOAD_ACCOUNT: + { + _ParseCardieSettings(msg); + break; + } default: BApplication::MessageReceived(msg); } @@ -115,7 +120,45 @@ PurpleApp::_ParseProtoOptions(PurplePluginProtocolInfo* info) { BMessage temp; + // Add a "username" setting, if not explicitly specified GList* prefIter = info->protocol_options; + for (int i = 0; prefIter != NULL; prefIter = prefIter->next) { + PurpleAccountOption* pref = (PurpleAccountOption*)prefIter->data; + + if (pref->pref_name == BString("username")) + break; + else if (prefIter->next == NULL) { + BMessage setting; + setting.AddString("name", "username"); + setting.AddString("description", "Username"); + setting.AddString("error", "A username needs to be specified!"); + setting.AddInt32("type", B_STRING_TYPE); + temp.AddMessage("setting", &setting); + } + } + + // Add any UserSplits (that is, parts of the protocols 'username' format) + GList* splitIter = info->user_splits; + for (int i = 0; splitIter != NULL; splitIter = splitIter->next) + { + PurpleAccountUserSplit* split = (PurpleAccountUserSplit*)splitIter->data; + BMessage setting; + setting.AddString("name", "username_split"); + setting.AddString("description", split->text); + setting.AddString("default", split->default_value); + setting.AddInt32("type", B_STRING_TYPE); + temp.AddMessage("setting", &setting); + } + + // Password setting + BMessage passwd; + passwd.AddString("name", "password"); + passwd.AddString("description", "Password"); + passwd.AddInt32("type", B_STRING_TYPE); + temp.AddMessage("setting", &passwd); + + // Whatever custom settings the protocol might like! + prefIter = info->protocol_options; for (int i = 0; prefIter != NULL; prefIter = prefIter->next) { PurpleAccountOption* pref = (PurpleAccountOption*)prefIter->data; @@ -140,15 +183,6 @@ PurpleApp::_ParseProtoOptions(PurplePluginProtocolInfo* info) setting.AddInt32("default", pref->default_value.integer); break; } - case PURPLE_PREF_STRING_LIST: { - bType = B_STRING_TYPE; - BString implicit; - GList* lists; - for (int j = 0; lists != NULL; lists = lists->next) - implicit << " " << lists->data; - setting.AddString("default", implicit); - break; - } default: bType = B_STRING_TYPE; setting.AddString("default", pref->default_value.string); @@ -160,11 +194,92 @@ PurpleApp::_ParseProtoOptions(PurplePluginProtocolInfo* info) setting.AddInt32("type", bType); temp.AddMessage("setting", &setting); } - return temp; } +void +PurpleApp::_ParseCardieSettings(BMessage* settings) +{ + PurplePlugin* plugin = _PluginFromMessage(settings); + PurplePluginProtocolInfo* info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); + const char* protoId = settings->FindString("signature"); + + if (plugin == NULL || info == NULL) + return; + + // Fetch and cobble together the username & password + BString username, password; + settings->FindString("username", &username); + settings->FindString("password", &password); + + GList* splitIter = info->user_splits; + for (int i = 0; splitIter != NULL; splitIter = splitIter->next) + { + PurpleAccountUserSplit* split = (PurpleAccountUserSplit*)splitIter->data; + username << split->field_sep; + + BString opt; + if (settings->FindString("username_split", i, &opt) == B_OK) + username << opt; + else + username << split->default_value; + i++; + } + std::cout << username << " of \n"; + + // Create/fetch the account itself + PurpleAccount* account = purple_accounts_find(username.String(), protoId); + if (account == NULL) { + account = purple_account_new(username.String(), protoId); + purple_account_set_password(account, password.String()); + purple_accounts_add(account); + } + + // Set all protocol settings + GList* prefIter = info->protocol_options; + for (int i = 0; prefIter != NULL; prefIter = prefIter->next) + { + PurpleAccountOption* pref = (PurpleAccountOption*)prefIter->data; + PurplePrefType type = pref->type; + + switch (type) + { + case PURPLE_PREF_BOOLEAN: + { + bool value; + if (settings->FindBool(pref->pref_name, &value) == B_OK) + purple_account_set_bool(account, pref->pref_name, value); + break; + } + case PURPLE_PREF_INT: + { + int32 value; + if (settings->FindInt32(pref->pref_name, &value) == B_OK) + purple_account_set_int(account, pref->pref_name, value); + break; + } + default: + { + BString value; + if (settings->FindString(pref->pref_name, &value) == B_OK) + purple_account_set_string(account, pref->pref_name, + value.String()); + } + } + } + + fAccounts.AddItem(settings->FindString("account_name"), username); +} + + +PurplePlugin* +PurpleApp::_PluginFromMessage(BMessage* msg) +{ + return purple_plugins_find_with_id(msg->FindString("signature")); +} + + static PurpleEventLoopUiOps _glib_eventloops = { g_timeout_add, diff --git a/protocols/purple/PurpleApp.h b/protocols/purple/PurpleApp.h index dc81447..f46c833 100644 --- a/protocols/purple/PurpleApp.h +++ b/protocols/purple/PurpleApp.h @@ -27,9 +27,14 @@ #include #include +#include + #include "PurpleMessages.h" +typedef KeyMap Accounts; + + #define PURPLE_GLIB_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) #define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) @@ -58,8 +63,13 @@ public: private: void _GetProtocolsInfo(); void _SaveProtocolInfo(PurplePlugin* plugin); - BMessage _ParseProtoOptions(PurplePluginProtocolInfo* info); + BMessage _ParseProtoOptions(PurplePluginProtocolInfo* info); + void _ParseCardieSettings(BMessage* settings); + + PurplePlugin* _PluginFromMessage(BMessage* msg); + + Accounts fAccounts; BObjectList fProtocols; }; diff --git a/protocols/purple/PurpleMessages.h b/protocols/purple/PurpleMessages.h index e51108e..65cdb61 100644 --- a/protocols/purple/PurpleMessages.h +++ b/protocols/purple/PurpleMessages.h @@ -30,7 +30,7 @@ enum purple_message { * Response is sent directly to the requesting thread * as a message's code, use receive_data() to catch it. * Requires: int64 thread_id */ - PURPLE_REQUEST_PROTOCOL_COUNT = 1, + PURPLE_REQUEST_PROTOCOL_COUNT = 'PApc', /*! Request protocol metadata. →Server * Response is sent directly to the requesting thread @@ -38,8 +38,14 @@ enum purple_message { * the first sending the size of the subsequently sent * flattened BMessage. * Requires: int32 protocol_index, int64 thread_id */ - PURPLE_REQUEST_PROTOCOL_INFO = 2 + PURPLE_REQUEST_PROTOCOL_INFO = 'PApi', + + /*! Load/start connecting the account →Server + * Just the account's settings message from Cardie's end. + * It's the server's job to tie the Cardie account name + * to the PurpleAccount. */ + PURPLE_LOAD_ACCOUNT = 'PAla' }; -#endif // _PURPLE_MESSAGESH +#endif // _PURPLE_MESSAGES_H diff --git a/protocols/purple/PurpleProtocol.cpp b/protocols/purple/PurpleProtocol.cpp index 2736196..50f54b1 100644 --- a/protocols/purple/PurpleProtocol.cpp +++ b/protocols/purple/PurpleProtocol.cpp @@ -63,8 +63,7 @@ protocol_count() ensure_app_messenger()->SendMessage(msg); thread_id sender; - int32 count = receive_data(&sender, NULL, 0); - return count; + return receive_data(&sender, NULL, 0); } @@ -159,13 +158,17 @@ PurpleProtocol::Process(BMessage* msg) status_t PurpleProtocol::UpdateSettings(BMessage* msg) { - thread_id thread = spawn_thread(connect_thread, "connect_thread", - B_NORMAL_PRIORITY, (void*)this); + ensure_app(); + fPrplMessenger = new BMessenger("application/x-vnd.cardie.purple"); + msg->what = PURPLE_LOAD_ACCOUNT; + _SendPrplMessage(msg); +// thread_id thread = spawn_thread(connect_thread, "connect_thread", +// B_NORMAL_PRIORITY, (void*)this); - if (thread < B_OK) - return B_ERROR; +// if (thread < B_OK) +// return B_ERROR; - resume_thread(thread); +// resume_thread(thread); return B_OK; } @@ -265,3 +268,13 @@ PurpleProtocol::MessengerInterface() const { return fMessenger; } + + +void +PurpleProtocol::_SendPrplMessage(BMessage* msg) +{ + msg->AddString("account_name", fName); + msg->AddString("signature", fSignature); + if (fPrplMessenger->IsValid()) + fPrplMessenger->SendMessage(msg); +} diff --git a/protocols/purple/PurpleProtocol.h b/protocols/purple/PurpleProtocol.h index da41a55..28074f9 100644 --- a/protocols/purple/PurpleProtocol.h +++ b/protocols/purple/PurpleProtocol.h @@ -75,7 +75,9 @@ public: MessengerInterface() const; private: + void _SendPrplMessage(BMessage* msg); ChatProtocolMessengerInterface* fMessenger; + BMessenger* fPrplMessenger; thread_id fServerThread; BString fName;