Merged SingleIrcNetworkPlugin with IrcNetworkPlugin to not duplicate code. Removed old SingleIrcNetworkPlugin.

This commit is contained in:
HanzZ 2012-09-22 10:38:42 +02:00
parent 74cd11e265
commit 05e06dd845
6 changed files with 108 additions and 253 deletions

View file

@ -13,6 +13,14 @@ IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, con
m_socket = new QTcpSocket();
m_socket->connectToHost(FROM_UTF8(host), port);
connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
m_server = CONFIG_STRING_DEFAULTED(config, "service.irc_server", "");
if (CONFIG_HAS_KEY(config, "service.irc_identify")) {
m_identify = CONFIG_STRING(config, "service.irc_identify");
}
else {
m_identify = "NickServ identify $name $password";
}
}
void IRCNetworkPlugin::readData() {
@ -28,122 +36,145 @@ void IRCNetworkPlugin::sendData(const std::string &string) {
m_socket->write(string.c_str(), string.size());
}
MyIrcSession *IRCNetworkPlugin::createSession(const std::string &user, const std::string &hostname, const std::string &nickname, const std::string &password, const std::string &suffix) {
MyIrcSession *session = new MyIrcSession(user, this, suffix);
session->setUserName(FROM_UTF8(nickname));
session->setNickName(FROM_UTF8(nickname));
session->setRealName(FROM_UTF8(nickname));
session->setHost(FROM_UTF8(hostname));
session->setPort(6667);
session->setEncoding( "utf-8" );
if (!password.empty()) {
std::string identify = m_identify;
boost::replace_all(identify, "$password", password);
boost::replace_all(identify, "$name", nickname);
session->setIdentify(identify);
}
LOG4CXX_INFO(logger, user << ": Connecting " << hostname << " as " << nickname << ", suffix=" << suffix);
session->open();
return session;
}
void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
// 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("@"));
session->setNickName(FROM_UTF8(h.substr(0, h.find("%"))));
session->setUserName(FROM_UTF8(h.substr(0, h.find("%"))));
session->setRealName(FROM_UTF8(h.substr(0, h.find("%"))));
session->setHost(FROM_UTF8(h.substr(h.find("%") + 1)));
session->setPort(6667);
session->open();
LOG4CXX_INFO(logger, user << ": Connecting IRC network " << h.substr(h.find("%") + 1));
m_sessions[user] = session;
if (!m_server.empty()) {
// legacy name is users nickname
if (m_sessions[user] != NULL) {
LOG4CXX_WARN(logger, user << ": Already logged in.");
return;
}
m_sessions[user] = createSession(user, m_server, legacyName, password, "");
}
else {
// We are waiting for first room join to connect user to IRC network, because we don't know which
// network he choose...
LOG4CXX_INFO(logger, user << ": Ready for connections");
handleConnected(user);
}
}
void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) {
if (m_sessions[user] == NULL)
if (m_sessions[user] == NULL) {
LOG4CXX_WARN(logger, user << ": Already disconnected.");
return;
}
LOG4CXX_INFO(logger, user << ": Disconnecting.");
m_sessions[user]->close();
m_sessions[user]->deleteLater();
m_sessions.erase(user);
}
void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
std::string IRCNetworkPlugin::getSessionName(const std::string &user, const std::string &legacyName) {
std::string u = user;
if (!CONFIG_BOOL(config, "service.server_mode")) {
if (!CONFIG_BOOL(config, "service.server_mode") && m_server.empty()) {
u = user + legacyName.substr(legacyName.find("@") + 1);
if (u.find("/") != std::string::npos) {
u = u.substr(0, u.find("/"));
}
}
if (m_sessions[u] == NULL) {
LOG4CXX_WARN(logger, user << ": Session name: " << u << ", No session for user");
return;
}
return u;
}
std::string IRCNetworkPlugin::getTargetName(const std::string &legacyName) {
std::string r = legacyName;
if (!CONFIG_BOOL(config, "service.server_mode")) {
// if (!CONFIG_BOOL(config, "service.server_mode")) {
if (legacyName.find("/") == std::string::npos) {
r = legacyName.substr(0, r.find("@"));
}
else {
r = legacyName.substr(legacyName.find("/") + 1);
}
}
LOG4CXX_INFO(logger, user << ": Session name: " << u << ", message to " << r);
m_sessions[u]->sendCommand(IrcCommand::createMessage(FROM_UTF8(r), FROM_UTF8(message)));
// }
return r;
}
if (r.find("#") == 0) {
handleMessage(user, legacyName, message, TO_UTF8(m_sessions[u]->nickName()));
void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
std::string session = getSessionName(user, legacyName);
if (m_sessions[session] == NULL) {
LOG4CXX_WARN(logger, user << ": Session name: " << session << ", No session for user");
return;
}
std::string target = getTargetName(legacyName);
LOG4CXX_INFO(logger, user << ": Session name: " << session << ", message to " << target);
m_sessions[session]->sendCommand(IrcCommand::createMessage(FROM_UTF8(target), FROM_UTF8(message)));
if (target.find("#") == 0) {
handleMessage(user, legacyName, message, TO_UTF8(m_sessions[session]->nickName()));
}
}
void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
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("@"));
}
std::string session = getSessionName(user, room);
std::string target = getTargetName(room);
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) {
// suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net
MyIrcSession *session = new MyIrcSession(user, this, room.substr(room.find("@")));
session->setNickName(FROM_UTF8(nickname));
session->setUserName(FROM_UTF8(nickname));
session->setRealName(FROM_UTF8(nickname));
session->setHost(FROM_UTF8(room.substr(room.find("@") + 1)));
session->setPort(6667);
session->open();
LOG4CXX_INFO(logger, user << ": Connecting IRC network " << room.substr(room.find("@") + 1));
m_sessions[u] = session;
LOG4CXX_INFO(logger, user << ": Session name: " << session << ", Joining room " << target);
if (m_sessions[session] == NULL) {
if (m_server.empty()) {
// in gateway mode we want to login this user to network according to legacyName
if (room.find("@") != std::string::npos) {
// suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net
m_sessions[session] = createSession(user, room.substr(room.find("@") + 1), nickname, "", room.substr(room.find("@")));
}
else {
LOG4CXX_WARN(logger, user << ": There's no proper server defined in room to which this user wants to join: " << room);
return;
}
}
else {
LOG4CXX_WARN(logger, user << ": There's no proper server defined in room to which this user wants to join: " << room);
LOG4CXX_WARN(logger, user << ": Join room requested for unconnected user");
return;
}
}
m_sessions[u]->addAutoJoinChannel(r, password);
m_sessions[u]->sendCommand(IrcCommand::createJoin(FROM_UTF8(r), FROM_UTF8(password)));
m_sessions[u]->rooms += 1;
m_sessions[session]->addAutoJoinChannel(target, password);
m_sessions[session]->sendCommand(IrcCommand::createJoin(FROM_UTF8(target), FROM_UTF8(password)));
m_sessions[session]->rooms += 1;
// update nickname, because we have nickname per session, no nickname per room.
handleRoomNicknameChanged(user, r, TO_UTF8(m_sessions[u]->nickName()));
handleRoomNicknameChanged(user, target, TO_UTF8(m_sessions[session]->nickName()));
}
void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) {
std::string r = room;
std::string u = user;
if (!CONFIG_BOOL(config, "service.server_mode")) {
r = room.substr(0, room.find("@"));
u = user + room.substr(room.find("@") + 1);
}
std::string session = getSessionName(user, room);
std::string target = getTargetName(room);
if (m_sessions[u] == NULL)
LOG4CXX_INFO(logger, user << ": Session name: " << session << ", Leaving room " << target);
if (m_sessions[session] == NULL)
return;
LOG4CXX_INFO(logger, user << ": Session name: " << u << ", Leaving room " << r);
m_sessions[session]->sendCommand(IrcCommand::createPart(FROM_UTF8(target)));
m_sessions[session]->removeAutoJoinChannel(target);
m_sessions[session]->rooms -= 1;
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);
if (m_sessions[session]->rooms <= 0 && m_server.empty()) {
LOG4CXX_INFO(logger, user << ": Session name: " << session << ", User is not in any room, disconnecting from network");
m_sessions[session]->close();
m_sessions[session]->deleteLater();
m_sessions.erase(session);
}
}

View file

@ -30,8 +30,15 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin {
void readData();
void sendData(const std::string &string);
private:
MyIrcSession *createSession(const std::string &user, const std::string &hostname, const std::string &nickname, const std::string &password, const std::string &suffix = "");
std::string getSessionName(const std::string &user, const std::string &legacyName);
std::string getTargetName(const std::string &legacyName);
private:
Config *config;
QTcpSocket *m_socket;
std::map<std::string, MyIrcSession *> m_sessions;
std::string m_server;
std::string m_identify;
};

View file

@ -16,7 +16,6 @@
#include <QtNetwork>
#include "Swiften/EventLoop/Qt/QtEventLoop.h"
#include "ircnetworkplugin.h"
#include "singleircnetworkplugin.h"
using namespace boost::program_options;
using namespace Transport;
@ -40,12 +39,7 @@ int main (int argc, char* argv[]) {
Swift::QtEventLoop eventLoop;
if (!CONFIG_HAS_KEY(cfg, "service.irc_server")) {
np = new IRCNetworkPlugin(cfg, &eventLoop, host, port);
}
else {
np = new SingleIRCNetworkPlugin(cfg, &eventLoop, host, port);
}
np = new IRCNetworkPlugin(cfg, &eventLoop, host, port);
return app.exec();
}

View file

@ -182,6 +182,7 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
channel = m->parameters().value(2);
members = m->parameters().value(3).split(" ");
LOG4CXX_INFO(logger, user << ": Received members for " << TO_UTF8(channel) << suffix);
for (int i = 0; i < members.size(); i++) {
bool flags = 0;
std::string nickname = TO_UTF8(members.at(i));

View file

@ -1,138 +0,0 @@
#include "singleircnetworkplugin.h"
#include "transport/logging.h"
#include <IrcCommand>
#include <IrcMessage>
#define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size())
#define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size())
DEFINE_LOGGER(logger, "SingleIRCNetworkPlugin");
SingleIRCNetworkPlugin::SingleIRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
this->config = config;
if (CONFIG_HAS_KEY(config, "service.irc_server")) {
m_server = CONFIG_STRING(config, "service.irc_server");
}
else {
LOG4CXX_ERROR(logger, "No [service] irc_server defined, exiting...");
exit(-1);
}
m_socket = new QTcpSocket();
m_socket->connectToHost(FROM_UTF8(host), port);
connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
if (CONFIG_HAS_KEY(config, "service.irc_identify")) {
m_identify = CONFIG_STRING(config, "service.irc_identify");
}
else {
m_identify = "NickServ identify $name $password";
}
LOG4CXX_INFO(logger, "SingleIRCNetworkPlugin for server " << m_server << " initialized.");
}
void SingleIRCNetworkPlugin::readData() {
size_t availableBytes = m_socket->bytesAvailable();
if (availableBytes == 0)
return;
std::string d = std::string(m_socket->readAll().data(), availableBytes);
handleDataRead(d);
}
void SingleIRCNetworkPlugin::sendData(const std::string &string) {
m_socket->write(string.c_str(), string.size());
}
void SingleIRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
// legacy name is users nickname
if (m_sessions[user] != NULL) {
LOG4CXX_WARN(logger, user << ": Already logged in.");
return;
}
LOG4CXX_INFO(logger, user << ": Connecting " << m_server << " as " << legacyName);
MyIrcSession *session = new MyIrcSession(user, this);
session->setUserName(FROM_UTF8(legacyName));
session->setNickName(FROM_UTF8(legacyName));
session->setRealName(FROM_UTF8(legacyName));
session->setHost(FROM_UTF8(m_server));
session->setPort(6667);
session->setEncoding( "utf-8" );
if (!password.empty()) {
std::string identify = m_identify;
boost::replace_all(identify, "$password", password);
boost::replace_all(identify, "$name", legacyName);
session->setIdentify(identify);
}
session->open();
m_sessions[user] = session;
}
void SingleIRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) {
if (m_sessions[user] == NULL) {
LOG4CXX_WARN(logger, user << ": Already disconnected.");
return;
}
LOG4CXX_INFO(logger, user << ": Disconnecting.");
m_sessions[user]->close();
m_sessions[user]->deleteLater();
m_sessions.erase(user);
}
void SingleIRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
if (m_sessions[user] == NULL) {
LOG4CXX_WARN(logger, user << ": Message received for unconnected user");
return;
}
// handle PMs
std::string r = legacyName;
if (legacyName.find("/") == std::string::npos) {
r = legacyName.substr(0, r.find("@"));
}
else {
r = legacyName.substr(legacyName.find("/") + 1);
}
LOG4CXX_INFO(logger, user << ": Forwarding message to " << r);
m_sessions[user]->sendCommand(IrcCommand::createMessage(FROM_UTF8(r), FROM_UTF8(message)));
if (r.find("#") == 0) {
handleMessage(user, legacyName, message, TO_UTF8(m_sessions[user]->nickName()));
}
}
void SingleIRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
if (m_sessions[user] == NULL) {
LOG4CXX_WARN(logger, user << ": Join room requested for unconnected user");
return;
}
LOG4CXX_INFO(logger, user << ": Joining " << room);
m_sessions[user]->addAutoJoinChannel(room, password);
m_sessions[user]->sendCommand(IrcCommand::createJoin(FROM_UTF8(room), FROM_UTF8(password)));
m_sessions[user]->rooms += 1;
// update nickname, because we have nickname per session, no nickname per room.
handleRoomNicknameChanged(user, room, TO_UTF8(m_sessions[user]->userName()));
}
void SingleIRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) {
std::string r = room;
std::string u = user;
if (m_sessions[u] == NULL) {
LOG4CXX_WARN(logger, user << ": Leave room requested for unconnected user");
return;
}
LOG4CXX_INFO(logger, user << ": Leaving " << room);
m_sessions[u]->sendCommand(IrcCommand::createPart(FROM_UTF8(r)));
m_sessions[u]->removeAutoJoinChannel(r);
m_sessions[u]->rooms -= 1;
}

View file

@ -1,40 +0,0 @@
#pragma once
#include "transport/config.h"
#include "transport/networkplugin.h"
#include "session.h"
#include <QtCore>
#include <QtNetwork>
#include "Swiften/EventLoop/Qt/QtEventLoop.h"
#include "ircnetworkplugin.h"
class SingleIRCNetworkPlugin : public QObject, public NetworkPlugin {
Q_OBJECT
public:
SingleIRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port);
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/);
void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password);
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);
private:
Config *config;
QTcpSocket *m_socket;
std::string m_server;
std::string m_identify;
};