Merge remote branch 'upstream/master'
This commit is contained in:
commit
3b0f45a49e
11 changed files with 102 additions and 34 deletions
|
@ -1,6 +1,9 @@
|
|||
#include "ircnetworkplugin.h"
|
||||
#include <IrcCommand>
|
||||
#include <IrcMessage>
|
||||
#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,16 +99,16 @@ 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);
|
||||
|
||||
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.
|
||||
|
@ -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);
|
||||
|
|
|
@ -26,8 +26,6 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin {
|
|||
|
||||
void handleLeaveRoomRequest(const std::string &user, const std::string &room);
|
||||
|
||||
std::map<std::string, MyIrcSession *> 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<std::string, MyIrcSession *> m_sessions;
|
||||
};
|
|
@ -11,7 +11,6 @@
|
|||
#include "session.h"
|
||||
#include <QtCore>
|
||||
#include <iostream>
|
||||
#include "Swiften/Elements/StatusShow.h"
|
||||
#include <IrcCommand>
|
||||
#include <IrcMessage>
|
||||
|
||||
|
@ -40,8 +39,8 @@ void MyIrcSession::on_connected() {
|
|||
np->handleConnected(user);
|
||||
}
|
||||
|
||||
for(std::list<std::string>::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<std::string>::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<std::string>::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<std::string>::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, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <IrcSession>
|
||||
#include <transport/networkplugin.h>
|
||||
#include "Swiften/Swiften.h"
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
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<std::string, boost::shared_ptr<AutoJoinChannel> > AutoJoinMap;
|
||||
|
||||
MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
|
||||
std::map<std::string, bool> 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<AutoJoinChannel>(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<std::string> m_autoJoin;
|
||||
AutoJoinMap m_autoJoin;
|
||||
std::string m_topicData;
|
||||
bool m_connected;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -114,6 +114,8 @@ class Conversation {
|
|||
return m_room;
|
||||
}
|
||||
|
||||
void destroyRoom();
|
||||
|
||||
private:
|
||||
ConversationManager *m_conversationManager;
|
||||
std::string m_legacyName;
|
||||
|
|
|
@ -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<Swift::Payload>(p));
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
|
||||
}
|
||||
}
|
||||
|
||||
void Conversation::setRoom(const std::string &room) {
|
||||
m_room = room;
|
||||
m_legacyName = m_room + "/" + m_legacyName;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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<Swift::Presence *>(getStanza(received[0])));
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::None, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/nickname"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION (ConversationManagerTest);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "transport/logging.h"
|
||||
#include "discoinforesponder.h"
|
||||
#include "storageparser.h"
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN32
|
||||
#include <Swiften/TLS/CAPICertificate.h>
|
||||
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
|
||||
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue