From 52991c925d39c95e85a9049edf628a0c7a04cfbc Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 3 Jun 2011 13:17:10 +0200 Subject: [PATCH 1/5] send Connected packet from libircclient-qt backend --- backends/libircclient-qt/session.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backends/libircclient-qt/session.cpp b/backends/libircclient-qt/session.cpp index fd5328f5..64e87962 100644 --- a/backends/libircclient-qt/session.cpp +++ b/backends/libircclient-qt/session.cpp @@ -19,9 +19,8 @@ MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, QObject* this->user = user; } -void MyIrcSession::on_connected() -{ - std::cout << "connected:\n"; +void MyIrcSession::on_connected(){ + std::cout << "connected:\n"; } void MyIrcSession::on_disconnected() @@ -184,6 +183,9 @@ void MyIrcBuffer::on_ctcpActionReceived(const QString& origin, const QString& ac void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, const QStringList& params) { switch (code) { + case 251: + np->handleConnected(user); + break; case 332: m_topicData = params.value(2).toStdString(); break; From 877d783276c09f323ba31cae33da622d74927cbc Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 3 Jun 2011 19:40:30 +0200 Subject: [PATCH 2/5] Fixed compilation with latest Swiften. Using SafeByteArray for communication with backends --- backends/libpurple/main.cpp | 4 +-- examples/server_connect/main.cpp | 3 ++- include/transport/networkplugin.h | 4 +-- include/transport/networkpluginserver.h | 4 +-- include/transport/transport.h | 4 +-- src/networkplugin.cpp | 36 +++++++++++-------------- src/networkpluginserver.cpp | 36 +++++++++++-------------- src/rostermanager.cpp | 10 +++---- src/transport.cpp | 12 ++++----- 9 files changed, 52 insertions(+), 61 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 22f7e2ae..f90dc2d9 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -400,7 +400,7 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif // They weren't able to do anything with that and I don't know what to do too, // so it's better to hack through it by not trying to forward really broken things... if (len < 300000 && data) { - photo = Swift::ByteArray(data, len); + photo = Swift::createByteArray(data, len); // const gchar *ext = (gchar*)purple_buddy_icon_get_extension(icon); // if (ext) { // std::string extension(ext); @@ -416,7 +416,7 @@ static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotif } - np->handleVCard(np->m_accounts[account], np->m_vcards[np->m_accounts[account] + name], name, fullName, nickname, photo.toString()); + np->handleVCard(np->m_accounts[account], np->m_vcards[np->m_accounts[account] + name], name, fullName, nickname, Swift::byteArrayToString(photo)); np->m_vcards.erase(np->m_accounts[account] + name); return NULL; diff --git a/examples/server_connect/main.cpp b/examples/server_connect/main.cpp index 0a52bc29..0682e128 100644 --- a/examples/server_connect/main.cpp +++ b/examples/server_connect/main.cpp @@ -15,7 +15,8 @@ class DummyUserRegistry : public Swift::UserRegistry { public: DummyUserRegistry() {} - virtual bool isValidUserPassword(const Swift::JID&, const std::string&) const { + virtual bool isValidUserPassword(const Swift::JID&user, const Swift::SafeByteArray&) const { + onPasswordValid(user.toString()); return true; } }; diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index a1b64226..c6125be8 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -74,7 +74,7 @@ class NetworkPlugin { void handleJoinRoomPayload(const std::string &payload); void handleLeaveRoomPayload(const std::string &payload); void handleVCardPayload(const std::string &payload); - void handleDataRead(const Swift::ByteArray&); + void handleDataRead(const Swift::SafeByteArray&); void _handleConnected(bool error); void handleDisconnected(); @@ -82,7 +82,7 @@ class NetworkPlugin { void sendPong(); void pingTimeout(); - std::string m_data; + Swift::SafeByteArray m_data; std::string m_host; int m_port; Swift::BoostNetworkFactories *m_factories; diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 487c0b6b..83b35b99 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -44,7 +44,7 @@ class NetworkPluginServer { struct Client { bool pongReceived; std::list users; - std::string data; + Swift::SafeByteArray data; boost::shared_ptr connection; }; @@ -57,7 +57,7 @@ class NetworkPluginServer { private: void handleNewClientConnection(boost::shared_ptr c); void handleSessionFinished(Client *c); - void handleDataRead(Client *c, const Swift::ByteArray&); + void handleDataRead(Client *c, const Swift::SafeByteArray&); void handleConnectedPayload(const std::string &payload); void handleDisconnectedPayload(const std::string &payload); diff --git a/include/transport/transport.h b/include/transport/transport.h index 88b1b3b1..5c91442b 100644 --- a/include/transport/transport.h +++ b/include/transport/transport.h @@ -133,8 +133,8 @@ namespace Transport { void handleConnected(); void handleConnectionError(const Swift::ComponentError &error); void handlePresence(Swift::Presence::ref presence); - void handleDataRead(const std::string &data); - void handleDataWritten(const std::string &data); + void handleDataRead(const Swift::SafeByteArray &data); + void handleDataWritten(const Swift::SafeByteArray &data); // void handleDiscoInfoResponse(boost::shared_ptr info, Swift::ErrorPayload::ref error, const Swift::JID& jid); void handleCapsChanged(const Swift::JID& jid); diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index efd8bd9a..fa393588 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -124,6 +124,7 @@ void NetworkPlugin::handleBuddyChanged(const std::string &user, const std::strin } void NetworkPlugin::handleConnected(const std::string &user) { + std::cout << "LOGIN SENT\n"; pbnetwork::Connected d; d.set_user(user); @@ -264,14 +265,15 @@ void NetworkPlugin::handleVCardPayload(const std::string &data) { handleVCardRequest(payload.username(), payload.buddyname(), payload.id()); } -void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { - long expected_size = 0; - m_data += data.toString(); -// std::cout << "received data; size = " << m_data.size() << "\n"; +void NetworkPlugin::handleDataRead(const Swift::SafeByteArray &data) { + m_data.insert(m_data.begin(), data.begin(), data.end()); + while (m_data.size() != 0) { + unsigned int expected_size; + if (m_data.size() >= 4) { - expected_size = (((((m_data[0] << 8) | m_data[1]) << 8) | m_data[2]) << 8) | m_data[3]; -// std::cout << "expected_size=" << expected_size << "\n"; + expected_size = *((unsigned int*) &m_data[0]); + expected_size = ntohl(expected_size); if (m_data.size() - 4 < expected_size) return; } @@ -279,14 +281,12 @@ void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { return; } - std::string msg = m_data.substr(4, expected_size); - m_data.erase(0, 4 + expected_size); - pbnetwork::WrapperMessage wrapper; - if (wrapper.ParseFromString(msg) == false) { - // TODO: ERROR + if (wrapper.ParseFromArray(&m_data[4], expected_size) == false) { + m_data.erase(m_data.begin(), m_data.begin() + 4 + expected_size); return; } + m_data.erase(m_data.begin(), m_data.begin() + 4 + expected_size); switch(wrapper.type()) { case pbnetwork::WrapperMessage_Type_TYPE_LOGIN: @@ -317,15 +317,9 @@ void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { } void NetworkPlugin::send(const std::string &data) { - std::string header(" "); -// std::cout << data.size() << "\n"; - boost::int32_t size = data.size(); - for (int i = 0; i != 4; ++i) { - header.at(i) = static_cast(size >> (8 * (3 - i))); -// std::cout << std::hex << (int) header.at(i) << "\n"; - } - - m_conn->write(Swift::ByteArray(header + data)); + char header[4]; + *((int*)(header)) = htonl(data.size()); + m_conn->write(Swift::createSafeByteArray(std::string(header, 4) + data)); } void NetworkPlugin::sendPong() { @@ -336,7 +330,7 @@ void NetworkPlugin::sendPong() { wrap.SerializeToString(&message); send(message); -// std::cout << "SENDING PONG\n"; + std::cout << "SENDING PONG\n"; } void NetworkPlugin::pingTimeout() { diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 1a757e06..b27b817e 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -171,11 +171,12 @@ void NetworkPluginServer::handleSessionFinished(Client *c) { void NetworkPluginServer::handleConnectedPayload(const std::string &data) { pbnetwork::Connected payload; + std::cout << "CONNECTED LOGIN 2 " << payload.user() << "\n"; if (payload.ParseFromString(data) == false) { // TODO: ERROR return; } - std::cout << "CONNECTED LOGIN 2 " << payload.user() << "\n"; + std::cout << "CONNECTED LOGIN 3 " << payload.user() << "\n"; m_component->m_userRegistry->onPasswordValid(payload.user()); // std::cout << payload.name() << "\n"; } @@ -206,7 +207,7 @@ void NetworkPluginServer::handleVCardPayload(const std::string &data) { std::cout << "OMG?\n"; boost::shared_ptr vcard(new Swift::VCard()); vcard->setFullName(payload.fullname()); - vcard->setPhoto(Swift::ByteArray(payload.photo())); + vcard->setPhoto(Swift::createByteArray(payload.photo())); vcard->setNickname(payload.nickname()); m_vcardResponder->sendVCard(payload.id(), vcard); @@ -313,16 +314,15 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool conv->handleMessage(msg, payload.nickname()); } -void NetworkPluginServer::handleDataRead(Client *c, const Swift::ByteArray &data) { - long expected_size = 0; - c->data += data.toString(); -// std::cout << "received data; size = " << m_data.size() << "\n"; +void NetworkPluginServer::handleDataRead(Client *c, const Swift::SafeByteArray &data) { + c->data.insert(c->data.begin(), data.begin(), data.end()); + while (c->data.size() != 0) { + unsigned int expected_size; + if (c->data.size() >= 4) { - unsigned char * head = (unsigned char*) c->data.c_str(); - expected_size = (((((*head << 8) | *(head + 1)) << 8) | *(head + 2)) << 8) | *(head + 3); - //expected_size = m_data[0]; -// std::cout << "expected_size=" << expected_size << "\n"; + expected_size = *((unsigned int*) &c->data[0]); + expected_size = ntohl(expected_size); if (c->data.size() - 4 < expected_size) return; } @@ -330,14 +330,12 @@ void NetworkPluginServer::handleDataRead(Client *c, const Swift::ByteArray &data return; } - std::string msg = c->data.substr(4, expected_size); - c->data.erase(0, 4 + expected_size); - pbnetwork::WrapperMessage wrapper; - if (wrapper.ParseFromString(msg) == false) { - // TODO: ERROR + if (wrapper.ParseFromArray(&c->data[4], expected_size) == false) { + c->data.erase(c->data.begin(), c->data.begin() + 4 + expected_size); return; } + c->data.erase(c->data.begin(), c->data.begin() + 4 + expected_size); switch(wrapper.type()) { case pbnetwork::WrapperMessage_Type_TYPE_CONNECTED: @@ -374,11 +372,9 @@ void NetworkPluginServer::handleDataRead(Client *c, const Swift::ByteArray &data } void NetworkPluginServer::send(boost::shared_ptr &c, const std::string &data) { - std::string header(" "); - for (int i = 0; i != 4; ++i) - header.at(i) = static_cast(data.size() >> (8 * (3 - i))); - - c->write(Swift::ByteArray(header + data)); + char header[4]; + *((int*)(header)) = htonl(data.size()); + c->write(Swift::createSafeByteArray(std::string(header, 4) + data)); } void NetworkPluginServer::pingTimeout() { diff --git a/src/rostermanager.cpp b/src/rostermanager.cpp index ac212948..d9ac9191 100644 --- a/src/rostermanager.cpp +++ b/src/rostermanager.cpp @@ -70,7 +70,7 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) { payload->addItem(item); - Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, m_component->getIQRouter(), m_user->getJID().toBare()); + Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, m_user->getJID().toBare(), m_component->getIQRouter()); request->onResponse.connect(boost::bind(&RosterManager::handleBuddyRosterPushResponse, this, _1, buddy->getName())); request->send(); } @@ -124,10 +124,10 @@ void RosterManager::sendRIE() { for (std::map::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) { Buddy *buddy = (*it).second; Swift::RosterItemExchangePayload::Item item; - item.jid = buddy->getJID().toBare(); - item.name = buddy->getAlias(); - item.action = Swift::RosterItemExchangePayload::Add; - item.groups = buddy->getGroups(); + item.setJID(buddy->getJID().toBare()); + item.setName(buddy->getAlias()); + item.setAction(Swift::RosterItemExchangePayload::Item::Add); + item.setGroups(buddy->getGroups()); payload->addItem(item); } diff --git a/src/transport.cpp b/src/transport.cpp index d0eb9cdc..a9af9021 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -36,8 +36,8 @@ class MyUserRegistry : public Swift::UserRegistry { public: MyUserRegistry(Component *c) {component = c;} ~MyUserRegistry() {} - bool isValidUserPassword(const JID& user, const std::string& password) const { - users[user.toBare().toString()] = password; + bool isValidUserPassword(const JID& user, const Swift::SafeByteArray& password) const { + users[user.toBare().toString()] = Swift::safeByteArrayToString(password); Swift::Presence::ref response = Swift::Presence::create(); response->setTo(component->getJID()); response->setFrom(user); @@ -165,12 +165,12 @@ void Component::handleConnectionError(const ComponentError &error) { m_reconnectTimer->start(); } -void Component::handleDataRead(const std::string &data) { - onXMLIn(data); +void Component::handleDataRead(const Swift::SafeByteArray &data) { + onXMLIn(safeByteArrayToString(data)); } -void Component::handleDataWritten(const std::string &data) { - onXMLOut(data); +void Component::handleDataWritten(const Swift::SafeByteArray &data) { + onXMLOut(safeByteArrayToString(data)); } void Component::handlePresence(Swift::Presence::ref presence) { From 96fb9b61e85ab3a35d0779e557314dd24367961d Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 5 Jun 2011 11:35:37 +0200 Subject: [PATCH 3/5] Store icon_hask into databa => working avatars --- backends/libpurple/main.cpp | 64 ++++++++++++++++++------------ include/transport/sqlite3backend.h | 1 + src/buddy.cpp | 4 +- src/networkpluginserver.cpp | 2 + src/rostermanager.cpp | 8 ++++ src/rosterstorage.cpp | 2 + src/sqlite3backend.cpp | 32 ++++++++++++++- 7 files changed, 84 insertions(+), 29 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index f90dc2d9..a2f5fdfd 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -238,29 +238,41 @@ static void buddyListNewNode(PurpleBlistNode *node) { np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy)); } -static void buddyStatusChanged(PurpleBuddy *buddy, PurpleStatus *status_, PurpleStatus *old_status) { +// static void buddyStatusChanged(PurpleBuddy *buddy, PurpleStatus *status_, PurpleStatus *old_status) { +// PurpleAccount *account = purple_buddy_get_account(buddy); +// +// Swift::StatusShow status; +// std::string message; +// getStatus(buddy, status, message); +// +// np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy)); +// } +// +// static void buddySignedOn(PurpleBuddy *buddy) { +// PurpleAccount *account = purple_buddy_get_account(buddy); +// +// Swift::StatusShow status; +// std::string message; +// getStatus(buddy, status, message); +// +// np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy)); +// } +// +// static void buddySignedOff(PurpleBuddy *buddy) { +// PurpleAccount *account = purple_buddy_get_account(buddy); +// +// Swift::StatusShow status; +// std::string message; +// getStatus(buddy, status, message); +// +// np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy)); +// } + +void buddyListUpdate(PurpleBuddyList *list, PurpleBlistNode *node) { + if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) + return; + PurpleBuddy *buddy = (PurpleBuddy *) node; PurpleAccount *account = purple_buddy_get_account(buddy); - - Swift::StatusShow status; - std::string message; - getStatus(buddy, status, message); - - np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy)); -} - -static void buddySignedOn(PurpleBuddy *buddy) { - PurpleAccount *account = purple_buddy_get_account(buddy); - - Swift::StatusShow status; - std::string message; - getStatus(buddy, status, message); - - np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy)); -} - -static void buddySignedOff(PurpleBuddy *buddy) { - PurpleAccount *account = purple_buddy_get_account(buddy); - Swift::StatusShow status; std::string message; getStatus(buddy, status, message); @@ -279,7 +291,7 @@ static PurpleBlistUiOps blistUiOps = NULL, buddyListNewNode, NULL, - NULL, // buddyListUpdate, + buddyListUpdate, NULL, //NodeRemoved, NULL, NULL, @@ -543,9 +555,9 @@ static bool initPurple(Config &cfg) { // purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL); purple_signal_connect(purple_connections_get_handle(), "signed-on", &blist_handle,PURPLE_CALLBACK(signed_on), NULL); // purple_signal_connect(purple_blist_get_handle(), "buddy-removed", &blist_handle,PURPLE_CALLBACK(buddyRemoved), NULL); - purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL); - purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL); - purple_signal_connect(purple_blist_get_handle(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL); +// purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", &blist_handle,PURPLE_CALLBACK(buddySignedOn), NULL); +// purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", &blist_handle,PURPLE_CALLBACK(buddySignedOff), NULL); +// purple_signal_connect(purple_blist_get_handle(), "buddy-status-changed", &blist_handle,PURPLE_CALLBACK(buddyStatusChanged), NULL); purple_signal_connect(purple_blist_get_handle(), "blist-node-removed", &blist_handle,PURPLE_CALLBACK(NodeRemoved), NULL); // purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", &conversation_handle, PURPLE_CALLBACK(conv_chat_topic_changed), NULL); // diff --git a/include/transport/sqlite3backend.h b/include/transport/sqlite3backend.h index 3070c343..c34c78ce 100644 --- a/include/transport/sqlite3backend.h +++ b/include/transport/sqlite3backend.h @@ -109,6 +109,7 @@ class SQLite3Backend : public StorageBackend sqlite3_stmt *m_removeUserBuddiesSettings; sqlite3_stmt *m_addBuddy; sqlite3_stmt *m_updateBuddy; + sqlite3_stmt *m_updateBuddySetting; sqlite3_stmt *m_getBuddies; sqlite3_stmt *m_getBuddiesSettings; }; diff --git a/src/buddy.cpp b/src/buddy.cpp index 215a5001..36572514 100644 --- a/src/buddy.cpp +++ b/src/buddy.cpp @@ -109,9 +109,9 @@ Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new) // caps // presence->addPayload(boost::shared_ptr(new Swift::CapsInfo (CONFIG().caps))); - if (features & 0/*TRANSPORT_FEATURE_AVATARS*/) { +// if (features & 0/*TRANSPORT_FEATURE_AVATARS*/) { presence->addPayload(boost::shared_ptr(new Swift::VCardUpdate (getIconHash()))); - } +// } } if (only_new) { diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index b27b817e..8f06dc0d 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -69,6 +69,8 @@ class NetworkFactory : public Factory { buddy->setSubscription(buddyInfo.subscription); buddy->setGroups(buddyInfo.groups); buddy->setFlags((BuddyFlag) buddyInfo.flags); + if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end()) + buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s); return buddy; } private: diff --git a/src/rostermanager.cpp b/src/rostermanager.cpp index d9ac9191..fd3dd35a 100644 --- a/src/rostermanager.cpp +++ b/src/rostermanager.cpp @@ -47,6 +47,14 @@ RosterManager::RosterManager(User *user, Component *component){ RosterManager::~RosterManager() { m_setBuddyTimer->stop(); m_RIETimer->stop(); + if (m_rosterStorage) { + for (std::map::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) { + Buddy *buddy = (*it).second; + m_rosterStorage->storeBuddy(buddy); + } + m_rosterStorage->storeBuddies(); + } + for (std::map::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) { Buddy *buddy = (*it).second; delete buddy; diff --git a/src/rosterstorage.cpp b/src/rosterstorage.cpp index b76c369c..270e0257 100644 --- a/src/rosterstorage.cpp +++ b/src/rosterstorage.cpp @@ -106,6 +106,8 @@ bool RosterStorage::storeBuddies() { buddyInfo.subscription = buddy->getSubscription(); buddyInfo.id = buddy->getID(); buddyInfo.flags = buddy->getFlags(); + buddyInfo.settings["icon_hash"].s = buddy->getIconHash(); + buddyInfo.settings["icon_hash"].type = TYPE_STRING; // Buddy is in DB if (buddyInfo.id != -1) { diff --git a/src/sqlite3backend.cpp b/src/sqlite3backend.cpp index 398bec2f..128921a7 100644 --- a/src/sqlite3backend.cpp +++ b/src/sqlite3backend.cpp @@ -89,6 +89,7 @@ SQLite3Backend::~SQLite3Backend(){ FINALIZE_STMT(m_getUserSetting); FINALIZE_STMT(m_setUserSetting); FINALIZE_STMT(m_updateUserSetting); + FINALIZE_STMT(m_updateBuddySetting); sqlite3_close(m_db); } } @@ -114,6 +115,8 @@ bool SQLite3Backend::connect() { PREP_STMT(m_updateBuddy, "UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?"); PREP_STMT(m_getBuddies, "SELECT id, uin, subscription, nickname, groups, flags FROM " + m_prefix + "buddies WHERE user_id=? ORDER BY id ASC"); PREP_STMT(m_getBuddiesSettings, "SELECT buddy_id, type, var, value FROM " + m_prefix + "buddies_settings WHERE user_id=? ORDER BY buddy_id ASC"); + PREP_STMT(m_updateBuddySetting, "INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?)"); + PREP_STMT(m_getUserSetting, "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?"); PREP_STMT(m_setUserSetting, "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)"); PREP_STMT(m_updateUserSetting, "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?"); @@ -245,7 +248,19 @@ long SQLite3Backend::addBuddy(long userId, const BuddyInfo &buddyInfo) { onStorageError("addBuddy query", (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db))); return -1; } - return (long) sqlite3_last_insert_rowid(m_db); + + long id = (long) sqlite3_last_insert_rowid(m_db); + +// INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?) + BEGIN(m_updateBuddySetting); + BIND_INT(m_updateBuddySetting, userId); + BIND_INT(m_updateBuddySetting, id); + BIND_STR(m_updateBuddySetting, buddyInfo.settings.find("icon_hash")->first); + BIND_INT(m_updateBuddySetting, TYPE_STRING); + BIND_STR(m_updateBuddySetting, buddyInfo.settings.find("icon_hash")->second.s); + + EXECUTE_STATEMENT(m_updateBuddySetting, "updateBuddySetting query"); + return id; } void SQLite3Backend::updateBuddy(long userId, const BuddyInfo &buddyInfo) { @@ -259,6 +274,16 @@ void SQLite3Backend::updateBuddy(long userId, const BuddyInfo &buddyInfo) { BIND_STR(m_updateBuddy, buddyInfo.legacyName); EXECUTE_STATEMENT(m_updateBuddy, "updateBuddy query"); + +// INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?) + BEGIN(m_updateBuddySetting); + BIND_INT(m_updateBuddySetting, userId); + BIND_INT(m_updateBuddySetting, buddyInfo.id); + BIND_STR(m_updateBuddySetting, buddyInfo.settings.find("icon_hash")->first); + BIND_INT(m_updateBuddySetting, TYPE_STRING); + BIND_STR(m_updateBuddySetting, buddyInfo.settings.find("icon_hash")->second.s); + + EXECUTE_STATEMENT(m_updateBuddySetting, "updateBuddySetting query"); } bool SQLite3Backend::getBuddies(long id, std::list &roster) { @@ -292,6 +317,7 @@ bool SQLite3Backend::getBuddies(long id, std::list &roster) { } while(buddy_id == -1 && (ret = sqlite3_step(m_getBuddiesSettings)) == SQLITE_ROW) { + RESET_GET_COUNTER(m_getBuddiesSettings); buddy_id = GET_INT(m_getBuddiesSettings); var.type = GET_INT(m_getBuddiesSettings); @@ -306,6 +332,10 @@ bool SQLite3Backend::getBuddies(long id, std::list &roster) { var.s = val; break; default: + if (buddy_id == b.id) { + buddy_id = -1; + } + continue; break; } if (buddy_id == b.id) { From b63c1d0aaddae9775e0a60e7fe6233d139a4232e Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 5 Jun 2011 11:58:10 +0200 Subject: [PATCH 4/5] Store buddies if they change and don't store unchanged buddies on logout --- backends/libpurple/main.cpp | 2 +- include/transport/buddy.h | 2 ++ src/buddy.cpp | 1 + src/rostermanager.cpp | 16 ++++++++++------ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index a2f5fdfd..026d8844 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -268,7 +268,7 @@ static void buddyListNewNode(PurpleBlistNode *node) { // np->handleBuddyChanged(np->m_accounts[account], purple_buddy_get_name(buddy), getAlias(buddy), getGroups(buddy)[0], (int) status.getType(), message, getIconHash(buddy)); // } -void buddyListUpdate(PurpleBuddyList *list, PurpleBlistNode *node) { +static void buddyListUpdate(PurpleBuddyList *list, PurpleBlistNode *node) { if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) return; PurpleBuddy *buddy = (PurpleBuddy *) node; diff --git a/include/transport/buddy.h b/include/transport/buddy.h index 47a3baf7..2d4d4008 100644 --- a/include/transport/buddy.h +++ b/include/transport/buddy.h @@ -107,6 +107,8 @@ class Buddy { void handleVCardReceived(const std::string &id, const Swift::JID &to, Swift::VCard::ref vcard); + boost::signal onBuddyChanged; + virtual void getVCard(const std::string &id, const Swift::JID &to) = 0; /// Returns legacy network username of this buddy. (for example UIN for ICQ, diff --git a/src/buddy.cpp b/src/buddy.cpp index 36572514..2edda8eb 100644 --- a/src/buddy.cpp +++ b/src/buddy.cpp @@ -151,6 +151,7 @@ void Buddy::buddyChanged() { if (presence) { m_rosterManager->getUser()->getComponent()->getStanzaChannel()->sendPresence(presence); } + onBuddyChanged(); } void Buddy::handleVCardReceived(const std::string &id, const Swift::JID &to, Swift::VCard::ref vcard) { diff --git a/src/rostermanager.cpp b/src/rostermanager.cpp index fd3dd35a..261b7b0c 100644 --- a/src/rostermanager.cpp +++ b/src/rostermanager.cpp @@ -48,10 +48,10 @@ RosterManager::~RosterManager() { m_setBuddyTimer->stop(); m_RIETimer->stop(); if (m_rosterStorage) { - for (std::map::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) { - Buddy *buddy = (*it).second; - m_rosterStorage->storeBuddy(buddy); - } +// for (std::map::const_iterator it = m_buddies.begin(); it != m_buddies.end(); it++) { +// Buddy *buddy = (*it).second; +// m_rosterStorage->storeBuddy(buddy); +// } m_rosterStorage->storeBuddies(); } @@ -86,6 +86,10 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) { void RosterManager::setBuddyCallback(Buddy *buddy) { m_setBuddyTimer->onTick.disconnect(boost::bind(&RosterManager::setBuddyCallback, this, buddy)); + if (m_rosterStorage) { + buddy->onBuddyChanged.connect(boost::bind(&RosterStorage::storeBuddy, m_rosterStorage, buddy)); + } + std::cout << "ADDING " << buddy->getName() << "\n"; m_buddies[buddy->getName()] = buddy; onBuddySet(buddy); @@ -151,8 +155,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { void RosterManager::setStorageBackend(StorageBackend *storageBackend) { if (m_rosterStorage) { - m_rosterStorage->storeBuddies(); - delete m_rosterStorage; + return; } m_rosterStorage = new RosterStorage(m_user, storageBackend); @@ -163,6 +166,7 @@ void RosterManager::setStorageBackend(StorageBackend *storageBackend) { Buddy *buddy = m_component->getFactory()->createBuddy(this, *it); std::cout << "CREATING BUDDY FROM DATABASE CACHE " << buddy->getName() << "\n"; m_buddies[buddy->getName()] = buddy; + buddy->onBuddyChanged.connect(boost::bind(&RosterStorage::storeBuddy, m_rosterStorage, buddy)); onBuddySet(buddy); } } From 7a0e5e31e6e225c55704525c009c68cba30d0f53 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sun, 5 Jun 2011 14:01:26 +0200 Subject: [PATCH 5/5] Moved RosterResponder out of UserManager --- include/transport/networkpluginserver.h | 2 ++ {src => include/transport}/rosterresponder.h | 4 +--- include/transport/usermanager.h | 1 - src/networkpluginserver.cpp | 5 +++++ src/rosterresponder.cpp | 5 ++--- src/usermanager.cpp | 5 ----- 6 files changed, 10 insertions(+), 12 deletions(-) rename {src => include/transport}/rosterresponder.h (90%) diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 83b35b99..c1edda8f 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -38,6 +38,7 @@ class LocalBuddy; class Config; class NetworkConversation; class VCardResponder; +class RosterResponder; class NetworkPluginServer { public: @@ -83,6 +84,7 @@ class NetworkPluginServer { UserManager *m_userManager; VCardResponder *m_vcardResponder; + RosterResponder *m_rosterResponder; Config *m_config; boost::shared_ptr m_server; std::list m_clients; diff --git a/src/rosterresponder.h b/include/transport/rosterresponder.h similarity index 90% rename from src/rosterresponder.h rename to include/transport/rosterresponder.h index c4208fea..4fd3aebc 100644 --- a/src/rosterresponder.h +++ b/include/transport/rosterresponder.h @@ -27,18 +27,16 @@ namespace Transport { -class StorageBackend; class UserManager; class RosterResponder : public Swift::Responder { public: - RosterResponder(Swift::IQRouter *router, StorageBackend *storageBackend, UserManager *userManager); + RosterResponder(Swift::IQRouter *router, UserManager *userManager); ~RosterResponder(); private: virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr payload); virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr payload); - StorageBackend *m_storageBackend; UserManager *m_userManager; }; diff --git a/include/transport/usermanager.h b/include/transport/usermanager.h index cff90027..153be1bf 100644 --- a/include/transport/usermanager.h +++ b/include/transport/usermanager.h @@ -83,7 +83,6 @@ class UserManager { Component *m_component; StorageBackend *m_storageBackend; StorageResponder *m_storageResponder; - RosterResponder *m_rosterResponder; friend class RosterResponder; }; diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 8f06dc0d..2e635fcb 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -29,6 +29,7 @@ #include "transport/config.h" #include "transport/conversation.h" #include "transport/vcardresponder.h" +#include "transport/rosterresponder.h" #include "Swiften/Swiften.h" #include "Swiften/Server/ServerStanzaChannel.h" #include "Swiften/Elements/StreamError.h" @@ -126,6 +127,9 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U m_vcardResponder->onVCardRequired.connect(boost::bind(&NetworkPluginServer::handleVCardRequired, this, _1, _2, _3)); m_vcardResponder->start(); + m_rosterResponder = new RosterResponder(component->getIQRouter(), userManager); + m_rosterResponder->start(); + m_server = component->getFactories()->getConnectionFactory()->createConnectionServer(10000); m_server->onNewConnection.connect(boost::bind(&NetworkPluginServer::handleNewClientConnection, this, _1)); m_server->start(); @@ -138,6 +142,7 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U NetworkPluginServer::~NetworkPluginServer() { m_pingTimer->stop(); delete m_vcardResponder; + delete m_rosterResponder; } void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr c) { diff --git a/src/rosterresponder.cpp b/src/rosterresponder.cpp index 68f566a6..3c8554f3 100644 --- a/src/rosterresponder.cpp +++ b/src/rosterresponder.cpp @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include "rosterresponder.h" +#include "transport/rosterresponder.h" #include #include @@ -33,8 +33,7 @@ using namespace boost; namespace Transport { -RosterResponder::RosterResponder(Swift::IQRouter *router, StorageBackend *storageBackend, UserManager *userManager) : Swift::Responder(router) { - m_storageBackend = storageBackend; +RosterResponder::RosterResponder(Swift::IQRouter *router, UserManager *userManager) : Swift::Responder(router) { m_userManager = userManager; } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 23f72469..57463705 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -25,7 +25,6 @@ #include "transport/conversationmanager.h" #include "transport/rostermanager.h" #include "storageresponder.h" -#include "rosterresponder.h" namespace Transport { @@ -38,9 +37,6 @@ UserManager::UserManager(Component *component, StorageBackend *storageBackend) { m_storageResponder = new StorageResponder(component->getIQRouter(), m_storageBackend, this); m_storageResponder->start(); - m_rosterResponder = new RosterResponder(component->getIQRouter(), m_storageBackend, this); - m_rosterResponder->start(); - component->onUserPresenceReceived.connect(bind(&UserManager::handlePresence, this, _1)); m_component->getStanzaChannel()->onMessageReceived.connect(bind(&UserManager::handleMessageReceived, this, _1)); m_component->getStanzaChannel()->onPresenceReceived.connect(bind(&UserManager::handleGeneralPresenceReceived, this, _1)); @@ -50,7 +46,6 @@ UserManager::UserManager(Component *component, StorageBackend *storageBackend) { UserManager::~UserManager(){ m_storageResponder->stop(); delete m_storageResponder; - delete m_rosterResponder; } void UserManager::addUser(User *user) {