From 1b49b0cf36af265af36cfb28f00d1088fb5dc52a Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 25 Jan 2013 08:05:46 +0100 Subject: [PATCH] Fixed leaving the room even when its name doesn't start with '#' --- include/transport/usermanager.h | 1 + src/presenceoracle.cpp | 45 ++++++++++---------- src/tests/conversationmanager.cpp | 28 ++++++------- src/tests/user.cpp | 69 ++++++++++++++----------------- src/transport.cpp | 3 +- src/user.cpp | 19 +++++---- src/usermanager.cpp | 19 +++++++++ 7 files changed, 97 insertions(+), 87 deletions(-) diff --git a/include/transport/usermanager.h b/include/transport/usermanager.h index 4ccefb53..b0fd7605 100644 --- a/include/transport/usermanager.h +++ b/include/transport/usermanager.h @@ -137,6 +137,7 @@ class UserManager : public Swift::EntityCapsProvider { void handleProbePresence(Swift::Presence::ref presence); void handleErrorPresence(Swift::Presence::ref presence); void handleSubscription(Swift::Presence::ref presence); + void handleMUCPresence(Swift::Presence::ref presence); void handleRemoveTimeout(const std::string jid, User *user, bool reconnect); void handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr info); void addUser(User *user); diff --git a/src/presenceoracle.cpp b/src/presenceoracle.cpp index 49284321..f84b0a55 100644 --- a/src/presenceoracle.cpp +++ b/src/presenceoracle.cpp @@ -52,9 +52,8 @@ void PresenceOracle::clearPresences(const Swift::JID& bareJID) { void PresenceOracle::handleIncomingPresence(Presence::ref presence) { // ignore presences for some contact, we're checking only presences for the transport itself here. - bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; // filter out login/logout presence spam - if (!presence->getTo().getNode().empty() && isMUC == false) + if (!presence->getTo().getNode().empty()) return; JID bareJID(presence->getFrom().toBare()); @@ -62,29 +61,27 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) { } else { Presence::ref passedPresence = presence; - if (!isMUC) { - if (presence->getType() == Presence::Unsubscribe || presence->getType() == Presence::Unsubscribed) { - /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */ - passedPresence = Presence::ref(new Presence()); - passedPresence->setType(Presence::Unavailable); - passedPresence->setFrom(bareJID); - passedPresence->setStatus(presence->getStatus()); - } - std::map > jidMap = entries_[bareJID]; - if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) { - /* Have a bare-JID only presence of offline */ - jidMap.clear(); - } else if (passedPresence->getType() == Presence::Available) { - /* Don't have a bare-JID only offline presence once there are available presences */ - jidMap.erase(bareJID); - } - if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) { - jidMap.erase(passedPresence->getFrom()); - } else { - jidMap[passedPresence->getFrom()] = passedPresence; - } - entries_[bareJID] = jidMap; + if (presence->getType() == Presence::Unsubscribe || presence->getType() == Presence::Unsubscribed) { + /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */ + passedPresence = Presence::ref(new Presence()); + passedPresence->setType(Presence::Unavailable); + passedPresence->setFrom(bareJID); + passedPresence->setStatus(presence->getStatus()); } + std::map > jidMap = entries_[bareJID]; + if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) { + /* Have a bare-JID only presence of offline */ + jidMap.clear(); + } else if (passedPresence->getType() == Presence::Available) { + /* Don't have a bare-JID only offline presence once there are available presences */ + jidMap.erase(bareJID); + } + if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) { + jidMap.erase(passedPresence->getFrom()); + } else { + jidMap[passedPresence->getFrom()] = passedPresence; + } + entries_[bareJID] = jidMap; onPresenceChange(passedPresence); } } diff --git a/src/tests/conversationmanager.cpp b/src/tests/conversationmanager.cpp index cf3caf3d..b8f2eb4e 100644 --- a/src/tests/conversationmanager.cpp +++ b/src/tests/conversationmanager.cpp @@ -345,17 +345,17 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe injectPresence(response); loop->processEvents(); - CPPUNIT_ASSERT_EQUAL(4, (int) received.size()); + CPPUNIT_ASSERT_EQUAL(3, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[1]))); + CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast(getStanza(received[1]))->getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast(getStanza(received[1]))->getTo().toString()); + CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast(getStanza(received[1]))->getFrom().toString()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[2]))); - CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast(getStanza(received[2]))->getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast(getStanza(received[2]))->getBody()); CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast(getStanza(received[2]))->getTo().toString()); CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast(getStanza(received[2]))->getFrom().toString()); - CPPUNIT_ASSERT(dynamic_cast(getStanza(received[3]))); - CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast(getStanza(received[3]))->getBody()); - CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast(getStanza(received[3]))->getTo().toString()); - CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast(getStanza(received[3]))->getFrom().toString()); - } void handleGroupchatMessagesBouncerLeave() { @@ -410,17 +410,17 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe injectPresence(response); loop->processEvents(); - CPPUNIT_ASSERT_EQUAL(4, (int) received.size()); + CPPUNIT_ASSERT_EQUAL(3, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[1]))); + CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast(getStanza(received[1]))->getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast(getStanza(received[1]))->getTo().toString()); + CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast(getStanza(received[1]))->getFrom().toString()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[2]))); - CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast(getStanza(received[2]))->getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast(getStanza(received[2]))->getBody()); CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast(getStanza(received[2]))->getTo().toString()); CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast(getStanza(received[2]))->getFrom().toString()); - CPPUNIT_ASSERT(dynamic_cast(getStanza(received[3]))); - CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast(getStanza(received[3]))->getBody()); - CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast(getStanza(received[3]))->getTo().toString()); - CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast(getStanza(received[3]))->getFrom().toString()); - } void handleGroupchatMessagesTwoResources() { diff --git a/src/tests/user.cpp b/src/tests/user.cpp index d3e58e3b..8c58c468 100644 --- a/src/tests/user.cpp +++ b/src/tests/user.cpp @@ -125,7 +125,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { User *user = userManager->getUser("user@localhost"); Swift::Presence::ref response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource"); Swift::MUCPayload *payload = new Swift::MUCPayload(); @@ -134,11 +134,8 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { injectPresence(response); loop->processEvents(); - // no presence received in server mode, just disco#info - CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); - CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); - - CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); + CPPUNIT_ASSERT_EQUAL(std::string("room"), room); CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); @@ -147,7 +144,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { roomPassword = ""; // simulate that backend joined the room - TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true); + TestingConversation *conv = new TestingConversation(user->getConversationManager(), "room", true); conv->addJID("user@localhost/resource"); user->getConversationManager()->addConversation(conv); @@ -156,8 +153,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { loop->processEvents(); // no presence received in server mode, just disco#info - CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); - CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); CPPUNIT_ASSERT_EQUAL(std::string(""), room); CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); @@ -169,14 +165,14 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { User *user = userManager->getUser("user@localhost"); // Add 1 participant - Conversation *conv = user->getConversationManager()->getConversation("#room"); + Conversation *conv = user->getConversationManager()->getConversation("room"); conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message"); // Connect 2nd resource connectSecondResource(); received2.clear(); Swift::Presence::ref response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource2"); Swift::MUCPayload *payload = new Swift::MUCPayload(); @@ -189,19 +185,19 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); - CPPUNIT_ASSERT_EQUAL(2, (int) received2.size()); - CPPUNIT_ASSERT(dynamic_cast(getStanza(received2[1]))); - CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast(getStanza(received2[1]))->getShow()); - CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast(getStanza(received2[1]))->getTo().toString()); - CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast(getStanza(received2[1]))->getFrom().toString()); - CPPUNIT_ASSERT(getStanza(received2[1])->getPayload()); - CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[1])->getPayload()->getItems()[0].affiliation); - CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[1])->getPayload()->getItems()[0].role); + CPPUNIT_ASSERT_EQUAL(1, (int) received2.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received2[0]))); + CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast(getStanza(received2[0]))->getShow()); + CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast(getStanza(received2[0]))->getTo().toString()); + CPPUNIT_ASSERT_EQUAL(std::string("room@localhost/anotheruser"), dynamic_cast(getStanza(received2[0]))->getFrom().toString()); + CPPUNIT_ASSERT(getStanza(received2[0])->getPayload()); + CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[0])->getPayload()->getItems()[0].affiliation); + CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[0])->getPayload()->getItems()[0].role); } void handlePresenceLeaveRoom() { Swift::Presence::ref response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource"); response->setType(Swift::Presence::Unavailable); @@ -213,7 +209,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); - CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string("room"), room); CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); } @@ -224,7 +220,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { // User is still connected from resource2, so he should not leave the room Swift::Presence::ref response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource"); response->setType(Swift::Presence::Unavailable); @@ -243,7 +239,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { // disconnect also from resource // User is still connected from resource2, so he should not leave the room response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource2"); response->setType(Swift::Presence::Unavailable); @@ -255,7 +251,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); - CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string("room"), room); CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); } @@ -278,7 +274,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); - Conversation *conv = user->getConversationManager()->getConversation("#room"); + Conversation *conv = user->getConversationManager()->getConversation("room"); CPPUNIT_ASSERT_EQUAL(1, (int) conv->getJIDs().size()); CPPUNIT_ASSERT_EQUAL(Swift::JID("user@localhost/resource2"), conv->getJIDs().front()); } @@ -287,7 +283,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { User *user = userManager->getUser("user@localhost"); user->addUserSetting("stay_connected", "1"); Swift::Presence::ref response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource"); response->setType(Swift::Presence::Unavailable); @@ -312,7 +308,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { // User is still connected from resource2, so he should not leave the room Swift::Presence::ref response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource"); response->setType(Swift::Presence::Unavailable); @@ -332,7 +328,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { // disconnect also from resource // User is still connected from resource2, so he should not leave the room response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource2"); response->setType(Swift::Presence::Unavailable); @@ -368,7 +364,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); - Conversation *conv = user->getConversationManager()->getConversation("#room"); + Conversation *conv = user->getConversationManager()->getConversation("room"); CPPUNIT_ASSERT_EQUAL(1, (int) conv->getJIDs().size()); CPPUNIT_ASSERT_EQUAL(Swift::JID("user@localhost/resource2"), conv->getJIDs().front()); } @@ -377,12 +373,12 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { User *user = userManager->getUser("user@localhost"); handlePresenceJoinRoom(); - CPPUNIT_ASSERT(user->getConversationManager()->getConversation("#room")); + CPPUNIT_ASSERT(user->getConversationManager()->getConversation("room")); received.clear(); handlePresenceLeaveRoom(); - CPPUNIT_ASSERT(!user->getConversationManager()->getConversation("#room")); + CPPUNIT_ASSERT(!user->getConversationManager()->getConversation("room")); } void handleDisconnected() { @@ -427,7 +423,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { user->setConnected(false); Swift::Presence::ref response = Swift::Presence::create(); - response->setTo("#room@localhost/hanzz"); + response->setTo("room@localhost/hanzz"); response->setFrom("user@localhost/resource"); Swift::MUCPayload *payload = new Swift::MUCPayload(); @@ -436,16 +432,13 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { injectPresence(response); loop->processEvents(); - // no presence received in server mode, just disco#info - CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); - CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); - + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); CPPUNIT_ASSERT_EQUAL(std::string(""), room); CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); user->setConnected(true); - CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string("room"), room); CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); } @@ -460,7 +453,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { received.clear(); user->setConnected(true); - CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string("room"), room); CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); diff --git a/src/transport.cpp b/src/transport.cpp index 16e2de68..9c7172be 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -275,9 +275,8 @@ void Component::handleDataWritten(const Swift::SafeByteArray &data) { } void Component::handlePresence(Swift::Presence::ref presence) { - bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; // filter out login/logout presence spam - if (!presence->getTo().getNode().empty() && isMUC == false) + if (!presence->getTo().getNode().empty()) return; // filter out bad presences diff --git a/src/user.cpp b/src/user.cpp index 0046ae30..eb79cbb1 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -194,11 +194,6 @@ void User::setCacheMessages(bool cacheMessages) { } void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) { - - int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size(); - - m_conversationManager->resetResources(); - LOG4CXX_INFO(logger, "PRESENCE " << presence->getFrom().toString() << " " << presence->getTo().toString()); if (!m_connected) { // we are not connected to legacy network, so we should do it when disco#info arrive :) @@ -230,8 +225,9 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) { } } - bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; - if (isMUC) { + + if (!presence->getTo().getNode().empty()) { + bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; if (presence->getType() == Swift::Presence::Unavailable) { std::string room = Buddy::JIDToLegacyName(presence->getTo()); Conversation *conv = m_conversationManager->getConversation(room); @@ -259,7 +255,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) { } } } - else { + else if (isMUC) { // force connection to legacy network to let backend to handle auto-join on connect. if (!m_readyForConnect) { LOG4CXX_INFO(logger, m_jid.toString() << ": Ready to be connected to legacy network"); @@ -316,7 +312,12 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) { } return; } - + + int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size(); + + m_conversationManager->resetResources(); + + if (presence->getType() == Swift::Presence::Unavailable) { m_conversationManager->removeJID(presence->getFrom()); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index eb091156..b40c5695 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -400,6 +400,7 @@ void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) { break; case Swift::Presence::Available: case Swift::Presence::Unavailable: + handleMUCPresence(presence); break; case Swift::Presence::Probe: handleProbePresence(presence); @@ -412,6 +413,24 @@ void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) { }; } +void UserManager::handleMUCPresence(Swift::Presence::ref presence) { + // Don't let RosterManager to handle presences for us + if (presence->getTo().getNode().empty()) { + return; + } + + if (presence->getType() == Swift::Presence::Available) { + handlePresence(presence); + } + else if (presence->getType() == Swift::Presence::Unavailable) { + std::string userkey = presence->getFrom().toBare().toString(); + User *user = getUser(userkey); + if (user) { + user->handlePresence(presence); + } + } +} + void UserManager::handleProbePresence(Swift::Presence::ref presence) { // Don't let RosterManager to handle presences for us if (presence->getTo().getNode().empty()) {