From b851fab1407c33074d6c753ec436a9ff9472d58d Mon Sep 17 00:00:00 2001 From: HanzZ Date: Thu, 20 Sep 2012 22:00:10 +0200 Subject: [PATCH 1/5] Use _WIN32 instead of _MSC_VER --- src/transport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport.cpp b/src/transport.cpp index 5c251509..99ef21d9 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -28,7 +28,7 @@ #include "transport/logging.h" #include "discoinforesponder.h" #include "storageparser.h" -#ifdef _MSC_VER +#ifdef _WIN32 #include #include "Swiften/TLS/Schannel/SchannelServerContext.h" #include "Swiften/TLS/Schannel/SchannelServerContextFactory.h" From 1c5504d7c60b07f394a3724dded0f6ac563fb6a1 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 21 Sep 2012 07:52:43 +0200 Subject: [PATCH 2/5] Autojoin rooms with password --- backends/libcommuni/ircnetworkplugin.cpp | 2 +- backends/libcommuni/session.cpp | 27 +++++++++---------- backends/libcommuni/session.h | 24 ++++++++++++++--- .../libcommuni/singleircnetworkplugin.cpp | 2 +- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/backends/libcommuni/ircnetworkplugin.cpp b/backends/libcommuni/ircnetworkplugin.cpp index 74bdec24..a925dc97 100644 --- a/backends/libcommuni/ircnetworkplugin.cpp +++ b/backends/libcommuni/ircnetworkplugin.cpp @@ -105,7 +105,7 @@ void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std: } } std::cout << "JOINING " << r << "\n"; - m_sessions[u]->addAutoJoinChannel(r); + m_sessions[u]->addAutoJoinChannel(r, password); m_sessions[u]->sendCommand(IrcCommand::createJoin(FROM_UTF8(r), FROM_UTF8(password))); m_sessions[u]->rooms += 1; // update nickname, because we have nickname per session, no nickname per room. diff --git a/backends/libcommuni/session.cpp b/backends/libcommuni/session.cpp index 43709a20..51505fb4 100644 --- a/backends/libcommuni/session.cpp +++ b/backends/libcommuni/session.cpp @@ -11,7 +11,6 @@ #include "session.h" #include #include -#include "Swiften/Elements/StatusShow.h" #include #include @@ -40,8 +39,8 @@ void MyIrcSession::on_connected() { np->handleConnected(user); } - for(std::list::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { - sendCommand(IrcCommand::createJoin(FROM_UTF8(*it))); + for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { + sendCommand(IrcCommand::createJoin(FROM_UTF8(it->second->getChannel()), FROM_UTF8(it->second->getPassword()))); } if (getIdentify().find(" ") != std::string::npos) { @@ -88,23 +87,23 @@ void MyIrcSession::on_parted(IrcMessage *message) { void MyIrcSession::on_quit(IrcMessage *message) { IrcQuitMessage *m = (IrcQuitMessage *) message; - for(std::list::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { + for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { bool flags = 0; std::string nickname = TO_UTF8(m->sender().name()); flags = correctNickname(nickname); - LOG4CXX_INFO(logger, user << ": " << nickname << " quit " << (*it) + suffix); - np->handleParticipantChanged(user, nickname, (*it) + suffix,(int) flags, pbnetwork::STATUS_NONE, TO_UTF8(m->reason())); + LOG4CXX_INFO(logger, user << ": " << nickname << " quit " << it->second->getChannel() + suffix); + np->handleParticipantChanged(user, nickname, it->second->getChannel() + suffix,(int) flags, pbnetwork::STATUS_NONE, TO_UTF8(m->reason())); } } void MyIrcSession::on_nickChanged(IrcMessage *message) { IrcNickMessage *m = (IrcNickMessage *) message; - for(std::list::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { + for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { std::string nickname = TO_UTF8(m->sender().name()); - bool flags = m_modes[(*it) + nickname]; + bool flags = m_modes[it->second->getChannel() + nickname]; LOG4CXX_INFO(logger, user << ": " << nickname << " changed nickname to " << TO_UTF8(m->nick())); - np->handleParticipantChanged(user, nickname, (*it) + suffix,(int) flags, pbnetwork::STATUS_ONLINE, "", TO_UTF8(m->nick())); + np->handleParticipantChanged(user, nickname, it->second->getChannel() + suffix,(int) flags, pbnetwork::STATUS_ONLINE, "", TO_UTF8(m->nick())); } } @@ -117,15 +116,15 @@ void MyIrcSession::on_modeChanged(IrcMessage *message) { if (nickname.empty()) return; LOG4CXX_INFO(logger, user << ": " << nickname << " changed mode to " << mode); - for(std::list::const_iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { + for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) { if (mode == "+o") { - m_modes[(*it) + nickname] = 1; + m_modes[it->second->getChannel() + nickname] = 1; } else { - m_modes[(*it) + nickname] = 0; + m_modes[it->second->getChannel() + nickname] = 0; } - bool flags = m_modes[(*it) + nickname]; - np->handleParticipantChanged(user, nickname, (*it) + suffix,(int) flags, pbnetwork::STATUS_ONLINE, ""); + bool flags = m_modes[it->second->getChannel() + nickname]; + np->handleParticipantChanged(user, nickname, it->second->getChannel() + suffix,(int) flags, pbnetwork::STATUS_ONLINE, ""); } } diff --git a/backends/libcommuni/session.h b/backends/libcommuni/session.h index 8b31da58..bff2aee4 100644 --- a/backends/libcommuni/session.h +++ b/backends/libcommuni/session.h @@ -13,6 +13,8 @@ #include #include +#include "Swiften/Swiften.h" +#include using namespace Transport; @@ -21,17 +23,31 @@ class MyIrcSession : public IrcSession Q_OBJECT public: + class AutoJoinChannel { + public: + AutoJoinChannel(const std::string &channel = "", const std::string &password = "") : m_channel(channel), m_password(password) {} + virtual ~AutoJoinChannel() {} + + const std::string &getChannel() { return m_channel; } + const std::string &getPassword() { return m_password; } + private: + std::string m_channel; + std::string m_password; + }; + + typedef std::map > AutoJoinMap; + MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0); std::map m_modes; std::string suffix; int rooms; - void addAutoJoinChannel(const std::string &channel) { - m_autoJoin.push_back(channel); + void addAutoJoinChannel(const std::string &channel, const std::string &password) { + m_autoJoin[channel] = boost::make_shared(channel, password); } void removeAutoJoinChannel(const std::string &channel) { - m_autoJoin.remove(channel); + m_autoJoin.erase(channel); } void setIdentify(const std::string &identify) { @@ -63,7 +79,7 @@ protected: NetworkPlugin *np; std::string user; std::string m_identify; - std::list m_autoJoin; + AutoJoinMap m_autoJoin; std::string m_topicData; bool m_connected; }; diff --git a/backends/libcommuni/singleircnetworkplugin.cpp b/backends/libcommuni/singleircnetworkplugin.cpp index 276ac5ec..439d765b 100644 --- a/backends/libcommuni/singleircnetworkplugin.cpp +++ b/backends/libcommuni/singleircnetworkplugin.cpp @@ -114,7 +114,7 @@ void SingleIRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, cons } LOG4CXX_INFO(logger, user << ": Joining " << room); - m_sessions[user]->addAutoJoinChannel(room); + m_sessions[user]->addAutoJoinChannel(room, password); m_sessions[user]->sendCommand(IrcCommand::createJoin(FROM_UTF8(room), FROM_UTF8(password))); m_sessions[user]->rooms += 1; From 4717bd00718542fabd57efd4774f86d9e2188287 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 21 Sep 2012 13:56:17 +0200 Subject: [PATCH 3/5] Send unavailable presence when server goes down. Use LOG4CXX macros in irc backend --- backends/libcommuni/ircnetworkplugin.cpp | 28 ++++++++++++++---------- include/transport/conversation.h | 2 ++ src/conversation.cpp | 22 +++++++++++++++++++ src/conversationmanager.cpp | 1 + src/tests/conversationmanager.cpp | 17 ++++++++++++++ 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/backends/libcommuni/ircnetworkplugin.cpp b/backends/libcommuni/ircnetworkplugin.cpp index a925dc97..85e55d25 100644 --- a/backends/libcommuni/ircnetworkplugin.cpp +++ b/backends/libcommuni/ircnetworkplugin.cpp @@ -1,6 +1,9 @@ #include "ircnetworkplugin.h" #include #include +#include "transport/logging.h" + +DEFINE_LOGGER(logger, "IRCNetworkPlugin"); #define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size()) #define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size()) @@ -17,7 +20,6 @@ void IRCNetworkPlugin::readData() { if (availableBytes == 0) return; - std::cout << "READ\n"; std::string d = std::string(m_socket->readAll().data(), availableBytes); handleDataRead(d); } @@ -27,7 +29,8 @@ void IRCNetworkPlugin::sendData(const std::string &string) { } void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { - // Server is in server-mode, so user is JID of server when we want to connect + // In server mode, hostname of the server we want to connect to is stored in "user" JID. + // In component mode we will connect user to the IRC network once he joins the room. if (CONFIG_BOOL(config, "service.server_mode")) { MyIrcSession *session = new MyIrcSession(user, this); std::string h = user.substr(0, user.find("@")); @@ -35,10 +38,11 @@ void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::st session->setHost(FROM_UTF8(h.substr(h.find("%") + 1))); session->setPort(6667); session->open(); - std::cout << "CONNECTING IRC NETWORK " << h.substr(h.find("%") + 1) << "\n"; + LOG4CXX_INFO(logger, user << ": Connecting IRC network " << h.substr(h.find("%") + 1)); m_sessions[user] = session; } else { + LOG4CXX_INFO(logger, user << ": Ready for connections"); handleConnected(user); } } @@ -53,7 +57,6 @@ void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::s void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) { std::string u = user; - std::cout << "AAAAA " << legacyName << "\n"; if (!CONFIG_BOOL(config, "service.server_mode")) { u = user + legacyName.substr(legacyName.find("@") + 1); if (u.find("/") != std::string::npos) { @@ -61,7 +64,7 @@ void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const s } } if (m_sessions[u] == NULL) { - std::cout << "No session for " << u << "\n"; + LOG4CXX_WARN(logger, user << ": Session name: " << u << ", No session for user"); return; } @@ -74,19 +77,19 @@ void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const s r = legacyName.substr(legacyName.find("/") + 1); } } - std::cout << "MESSAGE " << u << " " << r << "\n"; + LOG4CXX_INFO(logger, user << ": Session name: " << u << ", message to " << r); m_sessions[u]->sendCommand(IrcCommand::createMessage(FROM_UTF8(r), FROM_UTF8(message))); - std::cout << "SENT\n"; } void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { - std::cout << "JOIN\n"; std::string r = room; std::string u = user; if (!CONFIG_BOOL(config, "service.server_mode")) { u = user + room.substr(room.find("@") + 1); r = room.substr(0, room.find("@")); } + + LOG4CXX_INFO(logger, user << ": Session name: " << u << ", Joining room " << r); if (m_sessions[u] == NULL) { // in gateway mode we want to login this user to network according to legacyName if (room.find("@") != std::string::npos) { @@ -96,15 +99,15 @@ void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std: session->setHost(FROM_UTF8(room.substr(room.find("@") + 1))); session->setPort(6667); session->open(); - std::cout << "CONNECTING IRC NETWORK " << room.substr(room.find("@") + 1) << "\n"; - std::cout << "SUFFIX " << room.substr(room.find("@")) << "\n"; + LOG4CXX_INFO(logger, user << ": Connecting IRC network " << room.substr(room.find("@") + 1)); m_sessions[u] = session; } else { + LOG4CXX_WARN(logger, user << ": There's no proper server defined in room to which this user wants to join: " << room); return; } } - std::cout << "JOINING " << r << "\n"; + m_sessions[u]->addAutoJoinChannel(r, password); m_sessions[u]->sendCommand(IrcCommand::createJoin(FROM_UTF8(r), FROM_UTF8(password))); m_sessions[u]->rooms += 1; @@ -123,11 +126,14 @@ void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std if (m_sessions[u] == NULL) return; + LOG4CXX_INFO(logger, user << ": Session name: " << u << ", Leaving room " << r); + m_sessions[u]->sendCommand(IrcCommand::createPart(FROM_UTF8(r))); m_sessions[u]->removeAutoJoinChannel(r); m_sessions[u]->rooms -= 1; if (m_sessions[u]->rooms <= 0) { + LOG4CXX_INFO(logger, user << ": Session name: " << u << ", User is not in room, disconnecting from network"); m_sessions[u]->close(); m_sessions[u]->deleteLater(); m_sessions.erase(u); diff --git a/include/transport/conversation.h b/include/transport/conversation.h index d3999d28..d228099f 100644 --- a/include/transport/conversation.h +++ b/include/transport/conversation.h @@ -114,6 +114,8 @@ class Conversation { return m_room; } + void destroyRoom(); + private: ConversationManager *m_conversationManager; std::string m_legacyName; diff --git a/src/conversation.cpp b/src/conversation.cpp index 7aca1f4c..22799776 100644 --- a/src/conversation.cpp +++ b/src/conversation.cpp @@ -38,6 +38,28 @@ Conversation::Conversation(ConversationManager *conversationManager, const std:: Conversation::~Conversation() { } +void Conversation::destroyRoom() { + if (m_muc) { + Swift::Presence::ref presence = Swift::Presence::create(); + std::string legacyName = m_legacyName; + if (legacyName.find_last_of("@") != std::string::npos) { + legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK + } + presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), m_nickname)); + presence->setTo(m_jid); + presence->setType(Swift::Presence::Unavailable); + + Swift::MUCItem item; + item.affiliation = Swift::MUCOccupant::NoAffiliation; + item.role = Swift::MUCOccupant::NoRole; + Swift::MUCUserPayload *p = new Swift::MUCUserPayload (); + p->addItem(item); + + presence->addPayload(boost::shared_ptr(p)); + m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence); + } +} + void Conversation::setRoom(const std::string &room) { m_room = room; m_legacyName = m_room + "/" + m_legacyName; diff --git a/src/conversationmanager.cpp b/src/conversationmanager.cpp index 58d88c24..2089238e 100644 --- a/src/conversationmanager.cpp +++ b/src/conversationmanager.cpp @@ -41,6 +41,7 @@ ConversationManager::ConversationManager(User *user, Component *component){ ConversationManager::~ConversationManager() { while(!m_convs.empty()) { LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Removing conversation " << (*m_convs.begin()).first); + (*m_convs.begin()).second->destroyRoom(); delete (*m_convs.begin()).second; m_convs.erase(m_convs.begin()); } diff --git a/src/tests/conversationmanager.cpp b/src/tests/conversationmanager.cpp index 4319177b..5d517f7c 100644 --- a/src/tests/conversationmanager.cpp +++ b/src/tests/conversationmanager.cpp @@ -28,6 +28,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe CPPUNIT_TEST(handleChatstateMessages); CPPUNIT_TEST(handleParticipantChanged); CPPUNIT_TEST(handlePMFromXMPP); + CPPUNIT_TEST(handleGroupchatRemoved); CPPUNIT_TEST_SUITE_END(); public: @@ -278,6 +279,22 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe pmconv->handleMessage(msg2); } + void handleGroupchatRemoved() { + User *user = userManager->getUser("user@localhost"); + TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true); + conv->setNickname("nickname"); + conv->setJID("user@localhost/resource"); + received.clear(); + conv->destroyRoom(); + delete conv; + + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); + CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::None, dynamic_cast(getStanza(received[0]))->getShow()); + CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast(getStanza(received[0]))->getTo().toString()); + CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/nickname"), dynamic_cast(getStanza(received[0]))->getFrom().toString()); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION (ConversationManagerTest); From 40dbe667beea56d2ccc4250c6ff9c910ac91ec4c Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 21 Sep 2012 14:09:19 +0200 Subject: [PATCH 4/5] m_session should be private --- backends/libcommuni/ircnetworkplugin.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backends/libcommuni/ircnetworkplugin.h b/backends/libcommuni/ircnetworkplugin.h index c15dc9a1..ff77d2bc 100644 --- a/backends/libcommuni/ircnetworkplugin.h +++ b/backends/libcommuni/ircnetworkplugin.h @@ -26,8 +26,6 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin { void handleLeaveRoomRequest(const std::string &user, const std::string &room); - std::map m_sessions; - public slots: void readData(); void sendData(const std::string &string); @@ -35,4 +33,5 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin { private: Config *config; QTcpSocket *m_socket; + std::map m_sessions; }; \ No newline at end of file From bf1cad516b2a1d62484af67c45279b314debaf7d Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 21 Sep 2012 17:55:56 +0200 Subject: [PATCH 5/5] Handle 'unregister' field also when it has text-single type --- src/userregistration.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/userregistration.cpp b/src/userregistration.cpp index 1fbdd82d..a13006ca 100644 --- a/src/userregistration.cpp +++ b/src/userregistration.cpp @@ -316,6 +316,12 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID else if (textSingle->getName() == "local_password") { local_password = textSingle->getValue(); } + // Pidgin sends it as textSingle, not sure why... + else if (textSingle->getName() == "unregister") { + if (textSingle->getValue() == "1" || textSingle->getValue() == "true") { + payload->setRemove(true); + } + } continue; }