Added SingleIRCNetworkPlugin

This commit is contained in:
HanzZ 2011-11-23 22:00:24 +01:00
parent 29b5b7d27f
commit 5424e5c686
6 changed files with 219 additions and 30 deletions

View file

@ -15,11 +15,22 @@
#include <QtNetwork>
#include "Swiften/EventLoop/Qt/QtEventLoop.h"
#include "ircnetworkplugin.h"
#include "singleircnetworkplugin.h"
#include "log4cxx/logger.h"
#include "log4cxx/consoleappender.h"
#include "log4cxx/patternlayout.h"
#include "log4cxx/propertyconfigurator.h"
#include "log4cxx/helpers/properties.h"
#include "log4cxx/helpers/fileinputstream.h"
#include "log4cxx/helpers/transcoder.h"
using namespace boost::program_options;
using namespace Transport;
IRCNetworkPlugin * np = NULL;
using namespace log4cxx;
NetworkPlugin * np = NULL;
int main (int argc, char* argv[]) {
std::string host;
@ -72,8 +83,39 @@ int main (int argc, char* argv[]) {
}
QCoreApplication app(argc, argv);
if (CONFIG_STRING(&config, "logging.backend_config").empty()) {
LoggerPtr root = log4cxx::Logger::getRootLogger();
#ifndef _MSC_VER
root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n")));
#else
root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n")));
#endif
}
else {
log4cxx::helpers::Properties p;
log4cxx::helpers::FileInputStream *istream = new log4cxx::helpers::FileInputStream(CONFIG_STRING(&config, "logging.backend_config"));
p.load(istream);
LogString pid, jid;
log4cxx::helpers::Transcoder::decode(boost::lexical_cast<std::string>(getpid()), pid);
log4cxx::helpers::Transcoder::decode(CONFIG_STRING(&config, "service.jid"), jid);
#ifdef _MSC_VER
p.setProperty(L"pid", pid);
p.setProperty(L"jid", jid);
#else
p.setProperty("pid", pid);
p.setProperty("jid", jid);
#endif
log4cxx::PropertyConfigurator::configure(p);
}
Swift::QtEventLoop eventLoop;
np = new IRCNetworkPlugin(&config, &eventLoop, host, port);
if (config.getUnregistered().find("service.irc_server") == config.getUnregistered().end()) {
np = new IRCNetworkPlugin(&config, &eventLoop, host, port);
}
else {
np = new SingleIRCNetworkPlugin(&config, &eventLoop, host, port);
}
return app.exec();
}

View file

@ -13,6 +13,12 @@
#include <iostream>
#include "Swiften/Elements/StatusShow.h"
#include "log4cxx/logger.h"
using namespace log4cxx;
static LoggerPtr logger = log4cxx::Logger::getLogger("IRCSession");
MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix, QObject* parent) : Irc::Session(parent)
{
this->np = np;
@ -23,24 +29,24 @@ MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std
}
void MyIrcSession::on_connected(){
std::cout << "connected:\n";
// std::cout << "connected:\n";
}
void MyIrcSession::on_disconnected()
{
std::cout << "disconnected:\n";
// std::cout << "disconnected:\n";
if (suffix.empty())
np->handleDisconnected(user, 0, "");
}
void MyIrcSession::on_bufferAdded(Irc::Buffer* buffer)
{
qDebug() << "buffer added:" << buffer->receiver();
// qDebug() << "buffer added:" << buffer->receiver();
}
void MyIrcSession::on_bufferRemoved(Irc::Buffer* buffer)
{
qDebug() << "buffer removed:" << buffer->receiver();
// qDebug() << "buffer removed:" << buffer->receiver();
}
Irc::Buffer* MyIrcSession::createBuffer(const QString& receiver)
@ -80,7 +86,7 @@ MyIrcBuffer::MyIrcBuffer(const QString& receiver, const std::string &user, Netwo
void MyIrcBuffer::on_receiverChanged(const QString& receiver)
{
qDebug() << "receiver changed:" << receiver;
// qDebug() << "receiver changed:" << receiver;
}
bool MyIrcBuffer::correctNickname(std::string &nickname) {
@ -94,7 +100,7 @@ bool MyIrcBuffer::correctNickname(std::string &nickname) {
}
void MyIrcBuffer::on_joined(const QString& origin) {
qDebug() << "joined:" << receiver() << origin;
LOG4CXX_INFO(logger, user << ": " << origin.toStdString() << " joined " << receiver().toStdString() + suffix);
bool flags = 0;
std::string nickname = origin.toStdString();
flags = correctNickname(nickname);
@ -102,6 +108,7 @@ void MyIrcBuffer::on_joined(const QString& origin) {
}
void MyIrcBuffer::on_parted(const QString& origin, const QString& message) {
LOG4CXX_INFO(logger, user << ": " << origin.toStdString() << " parted " << receiver().toStdString() + suffix);
qDebug() << "parted:" << receiver() << origin << message;
bool flags = 0;
std::string nickname = origin.toStdString();
@ -109,14 +116,12 @@ void MyIrcBuffer::on_parted(const QString& origin, const QString& message) {
np->handleParticipantChanged(user, nickname, receiver().toStdString() + suffix,(int) flags, pbnetwork::STATUS_NONE, message.toStdString());
}
void MyIrcBuffer::on_quit(const QString& origin, const QString& message)
{
qDebug() << "quit:" << receiver() << origin << message;
void MyIrcBuffer::on_quit(const QString& origin, const QString& message) {
on_parted(origin, message);
}
void MyIrcBuffer::on_nickChanged(const QString& origin, const QString& nick) {
qDebug() << "nick changed:" << receiver() << origin << nick;
LOG4CXX_INFO(logger, user << ": " << origin.toStdString() << " changed nickname to " << nick.toStdString());
std::string nickname = origin.toStdString();
bool flags = p->m_modes[receiver().toStdString() + nickname];
// std::cout << receiver().toStdString() + nickname << " " << flags << "\n";
@ -125,10 +130,10 @@ void MyIrcBuffer::on_nickChanged(const QString& origin, const QString& nick) {
void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, const QString& args) {
// mode changed: "#testik" "HanzZ" "+o" "hanzz_k"
qDebug() << "mode changed:" << receiver() << origin << mode << args;
std::string nickname = args.toStdString();
if (nickname.empty())
return;
LOG4CXX_INFO(logger, user << ": " << nickname << " changed mode to " << mode.toStdString());
if (mode == "+o") {
p->m_modes[receiver().toStdString() + nickname] = 1;
}
@ -141,29 +146,28 @@ void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, con
void MyIrcBuffer::on_topicChanged(const QString& origin, const QString& topic) {
//topic changed: "#testik" "HanzZ" "test"
qDebug() << "topic changed:" << receiver() << origin << topic;
np->handleSubject(user, receiver().toStdString() + suffix, topic.toStdString(), origin.toStdString());
LOG4CXX_INFO(logger, user << ": " << origin.toStdString() << " topic changed to " << topic.toStdString());
np->handleSubject(user, receiver().toStdString() + suffix, topic.toStdString(), origin.toStdString());
}
void MyIrcBuffer::on_invited(const QString& origin, const QString& receiver, const QString& channel)
{
qDebug() << "invited:" << Irc::Buffer::receiver() << origin << receiver << channel;
void MyIrcBuffer::on_invited(const QString& origin, const QString& receiver, const QString& channel) {
qDebug() << "invited:" << Irc::Buffer::receiver() << origin << receiver << channel;
}
void MyIrcBuffer::on_kicked(const QString& origin, const QString& nick, const QString& message)
{
qDebug() << "kicked:" << receiver() << origin << nick << message;
void MyIrcBuffer::on_kicked(const QString& origin, const QString& nick, const QString& message) {
qDebug() << "kicked:" << receiver() << origin << nick << message;
}
void MyIrcBuffer::on_messageReceived(const QString& origin, const QString& message, Irc::Buffer::MessageFlags flags) {
qDebug() << "message received:" << receiver() << origin << message << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)");
// qDebug() << "message received:" << receiver() << origin << message << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)");
if (!receiver().startsWith("#") && (flags & Irc::Buffer::EchoFlag))
return;
std::string r = receiver().toStdString();
// if (!suffix.empty()) {
// r = receiver().replace('@', '%').toStdString();
// }
LOG4CXX_INFO(logger, user << ": Message from " << r);
if (r.find("#") == 0) {
np->handleMessage(user, r + suffix, message.toStdString(), origin.toStdString());
}
@ -223,7 +227,8 @@ void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, co
}
break;
}
qDebug() << "numeric message received:" << receiver() << origin << code << params;
LOG4CXX_INFO(logger, user << ": Numeric message received " << receiver().toStdString() << " " << origin.toStdString() << " " << code);
//qDebug() << "numeric message received:" << receiver() << origin << code << params;
}
void MyIrcBuffer::on_unknownMessageReceived(const QString& origin, const QStringList& params)

View file

@ -0,0 +1,104 @@
#include "singleircnetworkplugin.h"
#include "log4cxx/logger.h"
using namespace log4cxx;
static LoggerPtr logger = log4cxx::Logger::getLogger("SingleIRCNetworkPlugin");
SingleIRCNetworkPlugin::SingleIRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
this->config = config;
m_server = config->getUnregistered().find("service.irc_server")->second;
m_socket = new QTcpSocket();
m_socket->connectToHost(QString::fromStdString(host), port);
connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
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->setNick(QString::fromStdString(legacyName));
session->connectToServer(QString::fromStdString(m_server), 6667);
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]->disconnectFromServer();
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]->message(QString::fromStdString(r), QString::fromStdString(message));
}
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(QString::fromStdString(room));
m_sessions[user]->join(QString::fromStdString(room), QString::fromStdString(password));
m_sessions[user]->rooms += 1;
// update nickname, because we have nickname per session, no nickname per room.
handleRoomNicknameChanged(user, room, m_sessions[user]->nick().toStdString());
}
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]->part(QString::fromStdString(r));
m_sessions[u]->removeAutoJoinChannel(QString::fromStdString(r));
m_sessions[u]->rooms -= 1;
}

View file

@ -0,0 +1,39 @@
#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;
};

View file

@ -5,6 +5,7 @@ server = 127.0.0.1
port = 5222
server_mode = 1
backend_host=localhost
pidfile=./test.pid
# < this option doesn't work yet
backend_port=10001
admin_username=admin
@ -12,13 +13,14 @@ admin_password=test
#cert=server.pfx #patch to PKCS#12 certificate
#cert_password=test #password to that certificate if any
users_per_backend=10
backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend
#backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend
#backend=/usr/bin/mono /home/hanzz/code/networkplugin-csharp/msnp-sharp-backend/bin/Debug/msnp-sharp-backend.exe
#backend=/home/hanzz/code/libtransport/backends/frotz/spectrum2_frotz_backend
#backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend
backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend
#protocol=prpl-msn
protocol=any
#protocol=prpl-icq
irc_server=irc.freenode.org
[backend]
#default_avatar=catmelonhead.jpg

View file

@ -329,10 +329,7 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID
}
// Register or change password
if (payload->getUsername()->empty() ||
(payload->getPassword()->empty() && CONFIG_STRING(m_config, "service.protocol") != "twitter" && CONFIG_STRING(m_config, "service.protocol") != "bonjour")
)
{
if (payload->getUsername()->empty()) {
sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify);
return true;
}