Spectrum can now works as IRC/whatever bouncer. Configurable using adhoc commands.
This commit is contained in:
parent
7e9dfbdead
commit
7e9ea5150d
14 changed files with 269 additions and 21 deletions
|
@ -92,6 +92,10 @@ class Conversation {
|
|||
m_jids.push_back(jid);
|
||||
}
|
||||
|
||||
void clearJIDs() {
|
||||
m_jids.clear();
|
||||
}
|
||||
|
||||
void removeJID(const Swift::JID &jid) {
|
||||
m_jids.remove(jid);
|
||||
}
|
||||
|
@ -136,6 +140,8 @@ class Conversation {
|
|||
|
||||
void sendParticipants(const Swift::JID &to);
|
||||
|
||||
void sendCachedMessages(const Swift::JID &to);
|
||||
|
||||
private:
|
||||
Swift::Presence::ref generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname = "");
|
||||
|
||||
|
@ -150,6 +156,7 @@ class Conversation {
|
|||
std::map<std::string, Participant> m_participants;
|
||||
boost::shared_ptr<Swift::Message> m_subject;
|
||||
bool m_sentInitialPresence;
|
||||
std::list<boost::shared_ptr<Swift::Message> > m_cachedMessages;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ class ConversationManager {
|
|||
|
||||
void resetResources();
|
||||
void removeJID(const Swift::JID &jid);
|
||||
void clearJIDs();
|
||||
|
||||
private:
|
||||
void handleMessageReceived(Swift::Message::ref message);
|
||||
|
|
|
@ -55,6 +55,7 @@ class SettingsAdHocCommandFactory : public AdHocCommandFactory {
|
|||
public:
|
||||
SettingsAdHocCommandFactory() {
|
||||
m_userSettings["send_headlines"] = "0";
|
||||
m_userSettings["stay_connected"] = "0";
|
||||
}
|
||||
|
||||
virtual ~SettingsAdHocCommandFactory() {}
|
||||
|
|
|
@ -124,6 +124,12 @@ class User : public Swift::EntityCapsProvider {
|
|||
return m_settings[key];
|
||||
}
|
||||
|
||||
void setCacheMessages(bool cacheMessages);
|
||||
|
||||
bool shouldCacheMessages() {
|
||||
return m_cacheMessages;
|
||||
}
|
||||
|
||||
boost::signal<void ()> onReadyToConnect;
|
||||
boost::signal<void (Swift::Presence::ref presence)> onPresenceChanged;
|
||||
boost::signal<void (const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password)> onRoomJoined;
|
||||
|
@ -154,6 +160,7 @@ class User : public Swift::EntityCapsProvider {
|
|||
int m_reconnectCounter;
|
||||
std::list<Swift::Presence::ref> m_joinedRooms;
|
||||
std::map<std::string, std::string> m_settings;
|
||||
bool m_cacheMessages;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ namespace Transport {
|
|||
|
||||
Conversation::Conversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMUC) : m_conversationManager(conversationManager) {
|
||||
m_legacyName = legacyName;
|
||||
// m_conversationManager->addConversation(this);
|
||||
m_muc = isMUC;
|
||||
m_jid = m_conversationManager->getUser()->getJID().toBare();
|
||||
m_sentInitialPresence = false;
|
||||
|
@ -140,15 +139,26 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
|
|||
if (n.empty()) {
|
||||
n = " ";
|
||||
}
|
||||
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
|
||||
message->setTo(jid);
|
||||
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
|
||||
// Subject has to be sent after our own presence (the one with code 110)
|
||||
if (!message->getSubject().empty() && m_sentInitialPresence == false) {
|
||||
m_subject = message;
|
||||
return;
|
||||
|
||||
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
|
||||
|
||||
if (m_conversationManager->getUser()->shouldCacheMessages()) {
|
||||
boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
|
||||
boost::shared_ptr<Swift::Delay> delay(boost::make_shared<Swift::Delay>());
|
||||
delay->setStamp(timestamp);
|
||||
message->addPayload(delay);
|
||||
m_cachedMessages.push_back(message);
|
||||
}
|
||||
else {
|
||||
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
|
||||
message->setTo(jid);
|
||||
// Subject has to be sent after our own presence (the one with code 110)
|
||||
if (!message->getSubject().empty() && m_sentInitialPresence == false) {
|
||||
m_subject = message;
|
||||
return;
|
||||
}
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
|
||||
}
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +171,14 @@ void Conversation::sendParticipants(const Swift::JID &to) {
|
|||
}
|
||||
}
|
||||
|
||||
void Conversation::sendCachedMessages(const Swift::JID &to) {
|
||||
for (std::list<boost::shared_ptr<Swift::Message> >::const_iterator it = m_cachedMessages.begin(); it != m_cachedMessages.end(); it++) {
|
||||
(*it)->setTo(to);
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(*it);
|
||||
}
|
||||
m_cachedMessages.clear();
|
||||
}
|
||||
|
||||
Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
|
||||
std::string nickname = nick;
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
|
|
|
@ -99,6 +99,12 @@ void ConversationManager::removeJID(const Swift::JID &jid) {
|
|||
}
|
||||
}
|
||||
|
||||
void ConversationManager::clearJIDs() {
|
||||
for (std::map<std::string, Conversation *>::const_iterator it = m_convs.begin(); it != m_convs.end(); it++) {
|
||||
(*it).second->clearJIDs();
|
||||
}
|
||||
}
|
||||
|
||||
void ConversationManager::handleMessageReceived(Swift::Message::ref message) {
|
||||
// std::string name = message->getTo().getUnescapedNode();
|
||||
// if (name.find_last_of("%") != std::string::npos) { // OK when commented
|
||||
|
|
|
@ -145,7 +145,7 @@ void RosterManager::sendBuddyRosterRemove(Buddy *buddy) {
|
|||
void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
|
||||
// user can't receive anything in server mode if he's not logged in.
|
||||
// He will ask for roster later (handled in rosterreponsder.cpp)
|
||||
if (m_component->inServerMode() && !m_user->isConnected())
|
||||
if (m_component->inServerMode() && (!m_user->isConnected() || m_user->shouldCacheMessages()))
|
||||
return;
|
||||
|
||||
Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
|
||||
|
|
|
@ -45,6 +45,11 @@ SettingsAdHocCommand::SettingsAdHocCommand(Component *component, UserManager *us
|
|||
field->setName("send_headlines");
|
||||
field->setLabel("Allow sending messages as headlines");
|
||||
addFormField(field);
|
||||
|
||||
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0") == "1");
|
||||
field->setName("stay_connected");
|
||||
field->setLabel("Stay connected to legacy network when offline on XMPP");
|
||||
addFormField(field);
|
||||
}
|
||||
|
||||
SettingsAdHocCommand::~SettingsAdHocCommand() {
|
||||
|
|
|
@ -237,9 +237,13 @@ void BasicTest::connectSecondResource() {
|
|||
}
|
||||
|
||||
void BasicTest::disconnectUser() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
if (user) {
|
||||
user->addUserSetting("stay_connected", "0");
|
||||
}
|
||||
received.clear();
|
||||
userManager->disconnectUser("user@localhost");
|
||||
dynamic_cast<Swift::DummyTimerFactory *>(factories->getTimerFactory())->setTime(10);
|
||||
dynamic_cast<Swift::DummyTimerFactory *>(factories->getTimerFactory())->setTime(100);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
|
||||
|
|
|
@ -26,6 +26,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
|
|||
CPPUNIT_TEST(handleNormalMessages);
|
||||
CPPUNIT_TEST(handleNormalMessagesHeadline);
|
||||
CPPUNIT_TEST(handleGroupchatMessages);
|
||||
CPPUNIT_TEST(handleGroupchatMessagesBouncer);
|
||||
CPPUNIT_TEST(handleGroupchatMessagesTwoResources);
|
||||
CPPUNIT_TEST(handleChatstateMessages);
|
||||
CPPUNIT_TEST(handleSubjectMessages);
|
||||
|
@ -295,6 +296,65 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
|
|||
CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody());
|
||||
}
|
||||
|
||||
void handleGroupchatMessagesBouncer() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
user->addUserSetting("stay_connected", "1");
|
||||
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
|
||||
user->getConversationManager()->addConversation(conv);
|
||||
conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
|
||||
conv->setNickname("nickname");
|
||||
conv->addJID("user@localhost/resource");
|
||||
|
||||
CPPUNIT_ASSERT(!user->shouldCacheMessages());
|
||||
|
||||
// disconnectUser
|
||||
userManager->disconnectUser("user@localhost");
|
||||
dynamic_cast<Swift::DummyTimerFactory *>(factories->getTimerFactory())->setTime(10);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT(user->shouldCacheMessages());
|
||||
|
||||
// reset resources should not touch this resource
|
||||
user->getConversationManager()->resetResources();
|
||||
|
||||
boost::shared_ptr<Swift::Message> msg(new Swift::Message());
|
||||
msg->setBody("hi there!");
|
||||
conv->handleMessage(msg, "anotheruser");
|
||||
|
||||
boost::shared_ptr<Swift::Message> msg2(new Swift::Message());
|
||||
msg2->setBody("hi there2!");
|
||||
conv->handleMessage(msg2, "anotheruser");
|
||||
|
||||
loop->processEvents();
|
||||
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
|
||||
|
||||
userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
|
||||
userRegistry->onPasswordValid(Swift::JID("user@localhost/resource"));
|
||||
loop->processEvents();
|
||||
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo("#room@localhost/hanzz");
|
||||
response->setFrom("user@localhost/resource");
|
||||
|
||||
Swift::MUCPayload *payload = new Swift::MUCPayload();
|
||||
payload->setPassword("password");
|
||||
response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(4, (int) received.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[2])));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getBody());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getTo().toString());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getFrom().toString());
|
||||
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[3])));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getBody());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getTo().toString());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getFrom().toString());
|
||||
|
||||
}
|
||||
|
||||
void handleGroupchatMessagesTwoResources() {
|
||||
connectSecondResource();
|
||||
received2.clear();
|
||||
|
|
|
@ -29,6 +29,9 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_TEST(handlePresenceLeaveRoom);
|
||||
CPPUNIT_TEST(handlePresenceLeaveRoomTwoResources);
|
||||
CPPUNIT_TEST(handlePresenceLeaveRoomTwoResourcesOneDisconnects);
|
||||
CPPUNIT_TEST(handlePresenceLeaveRoomBouncer);
|
||||
CPPUNIT_TEST(handlePresenceLeaveRoomTwoResourcesBouncer);
|
||||
CPPUNIT_TEST(handlePresenceLeaveRoomTwoResourcesOneDisconnectsBouncer);
|
||||
CPPUNIT_TEST(leaveJoinedRoom);
|
||||
CPPUNIT_TEST(joinRoomBeforeConnected);
|
||||
CPPUNIT_TEST(handleDisconnected);
|
||||
|
@ -63,6 +66,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
if (!disconnected) {
|
||||
disconnectUser();
|
||||
}
|
||||
userManager->removeAllUsers();
|
||||
tearMeDown();
|
||||
}
|
||||
|
||||
|
@ -279,6 +283,96 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_ASSERT_EQUAL(Swift::JID("user@localhost/resource2"), conv->getJIDs().front());
|
||||
}
|
||||
|
||||
void handlePresenceLeaveRoomBouncer() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
user->addUserSetting("stay_connected", "1");
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo("#room@localhost/hanzz");
|
||||
response->setFrom("user@localhost/resource");
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
|
||||
Swift::MUCPayload *payload = new Swift::MUCPayload();
|
||||
payload->setPassword("password");
|
||||
response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void handlePresenceLeaveRoomTwoResourcesBouncer() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
user->addUserSetting("stay_connected", "1");
|
||||
handlePresenceJoinRoomTwoResources();
|
||||
received.clear();
|
||||
|
||||
// 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->setFrom("user@localhost/resource");
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
|
||||
Swift::MUCPayload *payload = new Swift::MUCPayload();
|
||||
payload->setPassword("password");
|
||||
response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
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);
|
||||
|
||||
room = "something";
|
||||
// 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->setFrom("user@localhost/resource2");
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
|
||||
payload = new Swift::MUCPayload();
|
||||
payload->setPassword("password");
|
||||
response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("something"), room);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
}
|
||||
|
||||
void handlePresenceLeaveRoomTwoResourcesOneDisconnectsBouncer() {
|
||||
room = "something";
|
||||
handlePresenceJoinRoomTwoResources();
|
||||
received.clear();
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
|
||||
// User is still connected from resource2, so he should not leave the room
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo("localhost/hanzz");
|
||||
response->setFrom("user@localhost/resource");
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), room);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void leaveJoinedRoom() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
handlePresenceJoinRoom();
|
||||
|
|
|
@ -30,6 +30,7 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_TEST(connectUserVipOnlyNonVip);
|
||||
CPPUNIT_TEST(handleProbePresence);
|
||||
CPPUNIT_TEST(disconnectUser);
|
||||
CPPUNIT_TEST(disconnectUserBouncer);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
|
@ -180,6 +181,25 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_ASSERT_EQUAL(std::string("status2"), dynamic_cast<Swift::Presence *>(getStanza(received2[3]))->getStatus());
|
||||
}
|
||||
|
||||
void disconnectUserBouncer() {
|
||||
connectUser();
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
user->addUserSetting("stay_connected", "1");
|
||||
received.clear();
|
||||
userManager->disconnectUser("user@localhost");
|
||||
dynamic_cast<Swift::DummyTimerFactory *>(factories->getTimerFactory())->setTime(10);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount());
|
||||
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
|
||||
CPPUNIT_ASSERT(userManager->getUser("user@localhost"));
|
||||
|
||||
userManager->removeAllUsers();
|
||||
loop->processEvents();
|
||||
CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION (UserManagerTest);
|
||||
|
|
41
src/user.cpp
41
src/user.cpp
|
@ -47,6 +47,7 @@ User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, User
|
|||
m_jid = jid.toBare();
|
||||
m_data = NULL;
|
||||
|
||||
m_cacheMessages = false;
|
||||
m_component = component;
|
||||
m_presenceOracle = component->m_presenceOracle;
|
||||
m_entityCapsManager = component->m_entityCapsManager;
|
||||
|
@ -184,6 +185,10 @@ void User::setConnected(bool connected) {
|
|||
}
|
||||
}
|
||||
|
||||
void User::setCacheMessages(bool cacheMessages) {
|
||||
m_cacheMessages = cacheMessages;
|
||||
}
|
||||
|
||||
void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
|
||||
|
||||
int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size();
|
||||
|
@ -233,19 +238,21 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
|
|||
}
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
|
||||
onRoomLeft(room);
|
||||
if (getUserSetting("stay_connected") != "1") {
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
|
||||
onRoomLeft(room);
|
||||
|
||||
BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) {
|
||||
if (p->getTo() == presence->getTo()) {
|
||||
m_joinedRooms.remove(p);
|
||||
break;
|
||||
BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) {
|
||||
if (p->getTo() == presence->getTo()) {
|
||||
m_joinedRooms.remove(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conv) {
|
||||
m_conversationManager->removeConversation(conv);
|
||||
delete conv;
|
||||
if (conv) {
|
||||
m_conversationManager->removeConversation(conv);
|
||||
delete conv;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -270,6 +277,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
|
|||
else {
|
||||
conv->addJID(presence->getFrom());
|
||||
conv->sendParticipants(presence->getFrom());
|
||||
conv->sendCachedMessages(presence->getFrom());
|
||||
}
|
||||
|
||||
if (forceJoin) {
|
||||
|
@ -340,13 +348,26 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
|
|||
if (m_readyForConnect) {
|
||||
Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare());
|
||||
if (highest) {
|
||||
if (highest->getType() == Swift::Presence::Unavailable && getUserSetting("stay_connected") == "1") {
|
||||
m_resources = 0;
|
||||
m_conversationManager->clearJIDs();
|
||||
setCacheMessages(true);
|
||||
return;
|
||||
}
|
||||
Swift::Presence::ref response = Swift::Presence::create(highest);
|
||||
response->setTo(m_jid);
|
||||
response->setFrom(m_component->getJID());
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": Changing legacy network presence to " << response->getType());
|
||||
onPresenceChanged(highest);
|
||||
setCacheMessages(false);
|
||||
}
|
||||
else {
|
||||
if (getUserSetting("stay_connected") == "1") {
|
||||
m_resources = 0;
|
||||
m_conversationManager->clearJIDs();
|
||||
setCacheMessages(true);
|
||||
return;
|
||||
}
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo(m_jid.toBare());
|
||||
response->setFrom(m_component->getJID());
|
||||
|
|
|
@ -331,6 +331,10 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
|
|||
// Unavailable presence could remove this user, because he could be unavailable
|
||||
if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
if (user) {
|
||||
if (user->getUserSetting("stay_connected") == "1") {
|
||||
return;
|
||||
}
|
||||
|
||||
Swift::Presence::ref highest = m_component->getPresenceOracle()->getHighestPriorityPresence(presence->getFrom().toBare());
|
||||
// There's no presence for this user, so disconnect
|
||||
if (!highest || (highest && highest->getType() == Swift::Presence::Unavailable)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue