diff --git a/backends/libcommuni/ircnetworkplugin.cpp b/backends/libcommuni/ircnetworkplugin.cpp index f2fc457488cf0e9e8c3453c0fd3b37f59b656ffc..bda4cc4d94b54cf18fa798169061c50cd6948184 100644 --- a/backends/libcommuni/ircnetworkplugin.cpp +++ b/backends/libcommuni/ircnetworkplugin.cpp @@ -11,6 +11,7 @@ DEFINE_LOGGER(logger, "IRCNetworkPlugin"); IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) { this->config = config; m_currentServer = 0; + m_firstPing = true; m_socket = new QTcpSocket(); m_socket->connectToHost(FROM_UTF8(host), port); connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData())); @@ -48,6 +49,17 @@ void IRCNetworkPlugin::readData() { if (availableBytes == 0) return; + if (m_firstPing) { + m_firstPing = false; + // Users can join the network without registering if we allow + // one user to connect multiple IRC networks. + if (m_servers.empty()) { + NetworkPlugin::PluginConfig cfg; + cfg.setNeedRegistration(false); + sendConfig(cfg); + } + } + std::string d = std::string(m_socket->readAll().data(), availableBytes); handleDataRead(d); } diff --git a/backends/libcommuni/ircnetworkplugin.h b/backends/libcommuni/ircnetworkplugin.h index 043089cd807f494b451c35d78106f9e999343658..d4a84d730906c96b65d4da5b51d366fdd5e96ae3 100644 --- a/backends/libcommuni/ircnetworkplugin.h +++ b/backends/libcommuni/ircnetworkplugin.h @@ -46,4 +46,5 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin { std::vector m_servers; int m_currentServer; std::string m_identify; + bool m_firstPing; }; \ No newline at end of file diff --git a/backends/libcommuni/session.cpp b/backends/libcommuni/session.cpp index 91a7fee84137d4cb236636f98dde8c6c6d7bbf74..cb0b6c9273aaf68949c62763314a6184aad97c2c 100644 --- a/backends/libcommuni/session.cpp +++ b/backends/libcommuni/session.cpp @@ -189,6 +189,7 @@ void MyIrcSession::on_messageReceived(IrcMessage *message) { void MyIrcSession::on_numericMessageReceived(IrcMessage *message) { QString channel; QStringList members; + std::string nick; IrcNumericMessage *m = (IrcNumericMessage *) message; switch (m->code()) { @@ -196,7 +197,14 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) { m_topicData = TO_UTF8(m->parameters().value(2)); break; case 333: - np->handleSubject(user, TO_UTF8(m->parameters().value(1)) + suffix, m_topicData, TO_UTF8(m->parameters().value(2))); + nick = TO_UTF8(m->parameters().value(2)); + if (nick.find("!") != std::string::npos) { + nick = nick.substr(0, nick.find("!")); + } + if (nick.find("/") != std::string::npos) { + nick = nick.substr(0, nick.find("/")); + } + np->handleSubject(user, TO_UTF8(m->parameters().value(1)) + suffix, m_topicData, nick); break; case 353: channel = m->parameters().value(2); diff --git a/include/transport/conversation.h b/include/transport/conversation.h index e137b5666b721fed90c30fbe0ec35c0d4887bf3e..ff109aa24bf2c2877c725e15f95c011907fe2eaa 100644 --- a/include/transport/conversation.h +++ b/include/transport/conversation.h @@ -148,6 +148,8 @@ class Conversation { Swift::JID m_jid; std::list m_jids; std::map m_participants; + boost::shared_ptr m_subject; + bool m_sentInitialPresence; }; } diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index b562232630ffd57e6d9b724178d0cf02b0cb48d4..3dde9c53d4045e727e335c2e2ceb03d0ea7ae594 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -63,7 +63,7 @@ NetworkPlugin::~NetworkPlugin() { } void NetworkPlugin::sendConfig(const PluginConfig &cfg) { - std::string data = "[registration]"; + std::string data = "[registration]\n"; data += std::string("needPassword=") + (cfg.m_needPassword ? "1" : "0") + "\n"; data += std::string("needRegistration=") + (cfg.m_needRegistration ? "1" : "0") + "\n"; diff --git a/src/conversation.cpp b/src/conversation.cpp index 67a5c386faa5a90b7ae8a6751216c8dba34c20ea..9cd8f7391a936c1ef87e9fe3e8cb86464317e71e 100644 --- a/src/conversation.cpp +++ b/src/conversation.cpp @@ -33,6 +33,7 @@ Conversation::Conversation(ConversationManager *conversationManager, const std:: // m_conversationManager->addConversation(this); m_muc = isMUC; m_jid = m_conversationManager->getUser()->getJID().toBare(); + m_sentInitialPresence = false; } Conversation::~Conversation() { @@ -128,6 +129,11 @@ void Conversation::handleMessage(boost::shared_ptr &message, con 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; + } m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message); } } @@ -169,6 +175,7 @@ Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int Swift::MUCUserPayload::StatusCode c; c.code = 110; p->addStatusCode(c); + m_sentInitialPresence = true; } @@ -217,6 +224,11 @@ void Conversation::handleParticipantChanged(const std::string &nick, int flag, i if (!newname.empty()) { handleParticipantChanged(newname, flag, status, statusMessage); } + + if (m_sentInitialPresence && m_subject) { + m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(m_subject); + m_subject.reset(); + } } } diff --git a/src/tests/conversationmanager.cpp b/src/tests/conversationmanager.cpp index ef31975de6fd47865d193f086168b0a5eaf391f6..c182146cce55d33fe84f4a56d950554ac66ae71a 100644 --- a/src/tests/conversationmanager.cpp +++ b/src/tests/conversationmanager.cpp @@ -94,26 +94,35 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe void handleSubjectMessages() { User *user = userManager->getUser("user@localhost"); - - TestingConversation *conv = new TestingConversation(user->getConversationManager(), "buddy1"); - user->getConversationManager()->addConversation(conv); + TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true); + conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2)); + conv->setNickname("nickname"); + conv->addJID("user@localhost/resource"); boost::shared_ptr msg(new Swift::Message()); msg->setSubject("subject"); + msg->setType(Swift::Message::Groupchat); - // Forward it conv->handleMessage(msg); loop->processEvents(); + + // No response, because presence with code 110 has not been sent yet and we must not send + // subject before this one. + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); + + // this user presence - status code 110 + conv->handleParticipantChanged("nickname", 1, Swift::StatusShow::Away, "my status message"); + loop->processEvents(); - CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); - CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); - CPPUNIT_ASSERT_EQUAL(std::string("subject"), dynamic_cast(getStanza(received[0]))->getSubject()); + CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[1]))); + CPPUNIT_ASSERT_EQUAL(std::string("subject"), dynamic_cast(getStanza(received[1]))->getSubject()); received.clear(); // send response msg->setFrom("user@localhost/resource"); - msg->setTo("buddy1@localhost/bot"); + msg->setTo("#room@localhost"); injectMessage(msg); loop->processEvents(); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 4e6e4b01b9a96206c44b44e23e3ca03d1591ddf1..fd4305ce7eae16075ebd7030ef7a2052e9e18da3 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -247,7 +247,8 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { // We allow auto_register feature in gateway-mode. This allows IRC user to register // the transport just by joining the room. if (!m_component->inServerMode()) { - if (!registered && CONFIG_BOOL(m_component->getConfig(), "registration.auto_register")) { + if (!registered && (CONFIG_BOOL(m_component->getConfig(), "registration.auto_register") || + !CONFIG_BOOL_DEFAULTED(m_component->getConfig(), "registration.needRegistration", true))) { res.password = ""; res.jid = userkey;