diff --git a/src/user.cpp b/src/user.cpp index c66da59591e93995411f4e4a5accc02fcdf819f7..9b1d7fd66f6aabfc77cd207a2880ba9de7046dd1 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -43,7 +43,7 @@ namespace Transport { static LoggerPtr logger = Logger::getLogger("User"); User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, UserManager *userManager) { - m_jid = jid; + m_jid = jid.toBare(); m_data = NULL; m_component = component; @@ -54,6 +54,7 @@ User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, User m_connected = false; m_readyForConnect = false; m_ignoreDisconnect = false; + m_resources = 0; m_reconnectTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(10000); m_reconnectTimer->onTick.connect(boost::bind(&User::onConnectingTimeout, this)); @@ -96,6 +97,10 @@ Swift::JID User::getJIDWithFeature(const std::string &feature) { else { continue; } + + if (!discoInfo) { + continue; + } #else continue; #endif @@ -129,30 +134,37 @@ void User::sendCurrentPresence() { return; } - if (m_connected) { - Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare()); - if (highest) { - Swift::Presence::ref response = Swift::Presence::create(highest); - response->setTo(m_jid); - response->setFrom(m_component->getJID()); - m_component->getStanzaChannel()->sendPresence(response); + std::vector presences = m_presenceOracle->getAllPresence(m_jid); + foreach(Swift::Presence::ref presence, presences) { + if (presence->getType() == Swift::Presence::Unavailable) { + continue; + } + + if (m_connected) { + Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare()); + if (highest) { + Swift::Presence::ref response = Swift::Presence::create(highest); + response->setTo(presence->getFrom()); + response->setFrom(m_component->getJID()); + m_component->getStanzaChannel()->sendPresence(response); + } + else { + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo(presence->getFrom()); + response->setFrom(m_component->getJID()); + response->setType(Swift::Presence::Unavailable); + m_component->getStanzaChannel()->sendPresence(response); + } } else { Swift::Presence::ref response = Swift::Presence::create(); - response->setTo(m_jid.toBare()); + response->setTo(presence->getFrom()); response->setFrom(m_component->getJID()); response->setType(Swift::Presence::Unavailable); + response->setStatus("Connecting"); m_component->getStanzaChannel()->sendPresence(response); } } - else { - Swift::Presence::ref response = Swift::Presence::create(); - response->setTo(m_jid.toBare()); - response->setFrom(m_component->getJID()); - response->setType(Swift::Presence::Unavailable); - response->setStatus("Connecting"); - m_component->getStanzaChannel()->sendPresence(response); - } } void User::setConnected(bool connected) { @@ -164,6 +176,10 @@ void User::setConnected(bool connected) { } void User::handlePresence(Swift::Presence::ref presence) { + int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size(); + + m_conversationManager->resetResources(); + if (!m_connected) { // we are not connected to legacy network, so we should do it when disco#info arrive :) if (m_readyForConnect == false) { @@ -210,12 +226,35 @@ void User::handlePresence(Swift::Presence::ref presence) { if (presence->getPayload() != NULL) { password = presence->getPayload()->getPassword() ? *presence->getPayload()->getPassword() : ""; } - onRoomJoined(room, presence->getTo().getResource(), password); + onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password); } return; } - sendCurrentPresence(); + + // User wants to disconnect this resource + if (!m_component->inServerMode()) { + if (presence->getType() == Swift::Presence::Unavailable) { + // Send unavailable presences for online contacts + m_rosterManager->sendUnavailablePresences(presence->getFrom()); + + // Send unavailable presence for transport contact itself + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo(presence->getFrom()); + response->setFrom(m_component->getJID()); + response->setType(Swift::Presence::Unavailable); + m_component->getStanzaChannel()->sendPresence(response); + } + else { + sendCurrentPresence(); + // This resource is new, so we have to send buddies presences + if (currentResourcesCount != m_resources) { + m_rosterManager->sendCurrentPresences(presence->getFrom()); + } + } + } + + m_resources = currentResourcesCount; // Change legacy network presence