diff --git a/backends/libircclient-qt/CMakeLists.txt b/backends/libircclient-qt/CMakeLists.txt index 1c2f06b5..0aa33549 100644 --- a/backends/libircclient-qt/CMakeLists.txt +++ b/backends/libircclient-qt/CMakeLists.txt @@ -1,7 +1,8 @@ cmake_minimum_required(VERSION 2.6) FILE(GLOB SRC *.cpp) - +FILE(GLOB HEADERS *.h) +QT4_WRAP_CPP(SRC ${HEADERS}) ADD_EXECUTABLE(libircclient-qt_backend ${SRC}) -target_link_libraries(libircclient-qt_backend ${IRC_LIBRARIES} ${QT_LIBRARIES} transport) +target_link_libraries(libircclient-qt_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport) diff --git a/backends/libircclient-qt/main.cpp b/backends/libircclient-qt/main.cpp index 2bf7a927..7059b397 100644 --- a/backends/libircclient-qt/main.cpp +++ b/backends/libircclient-qt/main.cpp @@ -10,7 +10,7 @@ #include "transport/config.h" #include "transport/networkplugin.h" -#include "ircsession.h" +#include "session.h" #include #include "Swiften/EventLoop/Qt/QtEventLoop.h" @@ -27,14 +27,35 @@ class IRCNetworkPlugin : public NetworkPlugin { } void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) { + Swift::JID jid(legacyName); + MyIrcSession *session = new MyIrcSession(); + session->setNick(QString::fromStdString(jid.getNode())); + session->connectToServer(QString::fromStdString(jid.getDomain()), 6667); + std::cout << "CONNECTING IRC NETWORK " << jid.getNode() << " " << jid.getDomain() << "\n"; + m_sessions[user] = session; } void handleLogoutRequest(const std::string &user, const std::string &legacyName) { + if (m_sessions[user] == NULL) + return; + m_sessions[user]->disconnectFromServer(); + m_sessions[user]->deleteLater(); } void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message) { + } + void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { + std::cout << "JOIN\n"; + if (m_sessions[user] == NULL) + return; + m_sessions[user]->addAutoJoinChannel(QString::fromStdString(room)); + m_sessions[user]->join(QString::fromStdString(room), QString::fromStdString(password)); + } + + std::map m_sessions; + private: Config *config; }; diff --git a/backends/libircclient-qt/session.cpp b/backends/libircclient-qt/session.cpp new file mode 100644 index 00000000..4b43b540 --- /dev/null +++ b/backends/libircclient-qt/session.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com + * + * This example is free, and not covered by LGPL license. There is no + * restriction applied to their modification, redistribution, using and so on. + * You can study them, modify them, use them in your own program - either + * completely or partially. By using it you may give me some credits in your + * program, but you don't have to. + */ + +#include "session.h" +#include +#include + +MyIrcSession::MyIrcSession(QObject* parent) : Irc::Session(parent) +{ +} + +void MyIrcSession::on_connected() +{ + std::cout << "connected:\n"; +} + +void MyIrcSession::on_disconnected() +{ + std::cout << "disconnected:\n"; +} + +void MyIrcSession::on_bufferAdded(Irc::Buffer* buffer) +{ + qDebug() << "buffer added:" << buffer->receiver(); +} + +void MyIrcSession::on_bufferRemoved(Irc::Buffer* buffer) +{ + qDebug() << "buffer removed:" << buffer->receiver(); +} + +Irc::Buffer* MyIrcSession::createBuffer(const QString& receiver) +{ + return new MyIrcBuffer(receiver, this); +} + +MyIrcBuffer::MyIrcBuffer(const QString& receiver, Irc::Session* parent) + : Irc::Buffer(receiver, parent) +{ + connect(this, SIGNAL(receiverChanged(QString)), SLOT(on_receiverChanged(QString))); + connect(this, SIGNAL(joined(QString)), SLOT(on_joined(QString))); + connect(this, SIGNAL(parted(QString, QString)), SLOT(on_parted(QString, QString))); + connect(this, SIGNAL(quit(QString, QString)), SLOT(on_quit(QString, QString))); + connect(this, SIGNAL(nickChanged(QString, QString)), SLOT(on_nickChanged(QString, QString))); + connect(this, SIGNAL(modeChanged(QString, QString, QString)), SLOT(on_modeChanged(QString, QString, QString))); + connect(this, SIGNAL(topicChanged(QString, QString)), SLOT(on_topicChanged(QString, QString))); + connect(this, SIGNAL(invited(QString, QString, QString)), SLOT(on_invited(QString, QString, QString))); + connect(this, SIGNAL(kicked(QString, QString, QString)), SLOT(on_kicked(QString, QString, QString))); + connect(this, SIGNAL(messageReceived(QString, QString, Irc::Buffer::MessageFlags)), + SLOT(on_messageReceived(QString, QString, Irc::Buffer::MessageFlags))); + connect(this, SIGNAL(noticeReceived(QString, QString, Irc::Buffer::MessageFlags)), + SLOT(on_noticeReceived(QString, QString, Irc::Buffer::MessageFlags))); + connect(this, SIGNAL(ctcpRequestReceived(QString, QString, Irc::Buffer::MessageFlags)), + SLOT(on_ctcpRequestReceived(QString, QString, Irc::Buffer::MessageFlags))); + connect(this, SIGNAL(ctcpReplyReceived(QString, QString, Irc::Buffer::MessageFlags)), + SLOT(on_ctcpReplyReceived(QString, QString, Irc::Buffer::MessageFlags))); + connect(this, SIGNAL(ctcpActionReceived(QString, QString, Irc::Buffer::MessageFlags)), + SLOT(on_ctcpActionReceived(QString, QString, Irc::Buffer::MessageFlags))); + connect(this, SIGNAL(numericMessageReceived(QString, uint, QStringList)), SLOT(on_numericMessageReceived(QString, uint, QStringList))); + connect(this, SIGNAL(unknownMessageReceived(QString, QStringList)), SLOT(on_unknownMessageReceived(QString, QStringList))); +} + +void MyIrcBuffer::on_receiverChanged(const QString& receiver) +{ + qDebug() << "receiver changed:" << receiver; +} + +void MyIrcBuffer::on_joined(const QString& origin) +{ + qDebug() << "joined:" << receiver() << origin; +} + +void MyIrcBuffer::on_parted(const QString& origin, const QString& message) +{ + qDebug() << "parted:" << receiver() << origin << message; +} + +void MyIrcBuffer::on_quit(const QString& origin, const QString& message) +{ + qDebug() << "quit:" << receiver() << origin << message; +} + +void MyIrcBuffer::on_nickChanged(const QString& origin, const QString& nick) +{ + qDebug() << "nick changed:" << receiver() << origin << nick; +} + +void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, const QString& args) +{ + qDebug() << "mode changed:" << receiver() << origin << mode << args; +} + +void MyIrcBuffer::on_topicChanged(const QString& origin, const QString& topic) +{ + qDebug() << "topic changed:" << receiver() << origin << topic; +} + +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_messageReceived(const QString& origin, const QString& message, Irc::Buffer::MessageFlags flags) +{ + qDebug() << "message received:" << receiver() << origin << message + << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); +} + +void MyIrcBuffer::on_noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags) +{ + qDebug() << "notice received:" << receiver() << origin << notice + << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); +} + +void MyIrcBuffer::on_ctcpRequestReceived(const QString& origin, const QString& request, Irc::Buffer::MessageFlags flags) +{ + qDebug() << "ctcp request received:" << receiver() << origin << request + << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); +} + +void MyIrcBuffer::on_ctcpReplyReceived(const QString& origin, const QString& reply, Irc::Buffer::MessageFlags flags) +{ + qDebug() << "ctcp reply received:" << receiver() << origin << reply + << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); +} + +void MyIrcBuffer::on_ctcpActionReceived(const QString& origin, const QString& action, Irc::Buffer::MessageFlags flags) +{ + qDebug() << "ctcp action received:" << receiver() << origin << action + << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); +} + +void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, const QStringList& params) +{ + qDebug() << "numeric message received:" << receiver() << origin << code << params; +} + +void MyIrcBuffer::on_unknownMessageReceived(const QString& origin, const QStringList& params) +{ + qDebug() << "unknown message received:" << receiver() << origin << params; +} diff --git a/backends/libircclient-qt/session.h b/backends/libircclient-qt/session.h new file mode 100644 index 00000000..7e3326ee --- /dev/null +++ b/backends/libircclient-qt/session.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com + * + * This example is free, and not covered by LGPL license. There is no + * restriction applied to their modification, redistribution, using and so on. + * You can study them, modify them, use them in your own program - either + * completely or partially. By using it you may give me some credits in your + * program, but you don't have to. + */ + +#ifndef SESSION_H +#define SESSION_H + +#include +#include + +class MyIrcSession : public Irc::Session +{ + Q_OBJECT + +public: + MyIrcSession(QObject* parent = 0); + +protected Q_SLOTS: + void on_connected(); + void on_disconnected(); + + void on_bufferAdded(Irc::Buffer* buffer); + void on_bufferRemoved(Irc::Buffer* buffer); + +protected: + virtual Irc::Buffer* createBuffer(const QString& receiver); +}; + +class MyIrcBuffer : public Irc::Buffer +{ + Q_OBJECT + +public: + MyIrcBuffer(const QString& receiver, Irc::Session* parent); + +protected Q_SLOTS: + void on_receiverChanged(const QString& receiver); + void on_joined(const QString& origin); + void on_parted(const QString& origin, const QString& message); + void on_quit(const QString& origin, const QString& message); + void on_nickChanged(const QString& origin, const QString& nick); + void on_modeChanged(const QString& origin, const QString& mode, const QString& args); + void on_topicChanged(const QString& origin, const QString& topic); + void on_invited(const QString& origin, const QString& receiver, const QString& channel); + void on_kicked(const QString& origin, const QString& nick, const QString& message); + void on_messageReceived(const QString& origin, const QString& message, Irc::Buffer::MessageFlags flags); + void on_noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags); + void on_ctcpRequestReceived(const QString& origin, const QString& request, Irc::Buffer::MessageFlags flags); + void on_ctcpReplyReceived(const QString& origin, const QString& reply, Irc::Buffer::MessageFlags flags); + void on_ctcpActionReceived(const QString& origin, const QString& action, Irc::Buffer::MessageFlags flags); + void on_numericMessageReceived(const QString& origin, uint code, const QStringList& params); + void on_unknownMessageReceived(const QString& origin, const QStringList& params); +}; + +#endif // SESSION_H diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index db462f7f..26d7e53f 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -51,6 +51,7 @@ class NetworkPlugin { virtual void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) = 0; virtual void handleLogoutRequest(const std::string &user, const std::string &legacyName) = 0; virtual void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message) = 0; + virtual void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/) {} private: @@ -58,6 +59,7 @@ class NetworkPlugin { void handleLoginPayload(const std::string &payload); void handleLogoutPayload(const std::string &payload); void handleConvMessagePayload(const std::string &payload); + void handleJoinRoomPayload(const std::string &payload); void handleDataRead(const Swift::ByteArray&); void handleConnected(bool error); void handleDisconnected(); diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index f5ddb2bd..61253f45 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -57,6 +57,7 @@ class NetworkPluginServer { void handleConvMessagePayload(const std::string &payload); void handleUserCreated(User *user); + void handleRoomJoined(User *user, const std::string &room, const std::string &nickname, const std::string &password); void handleUserReadyToConnect(User *user); void handleUserDestroyed(User *user); diff --git a/include/transport/user.h b/include/transport/user.h index 87e80f99..0f5f6c07 100644 --- a/include/transport/user.h +++ b/include/transport/user.h @@ -77,6 +77,8 @@ class User { void handleDisconnected(const std::string &error); boost::signal onReadyToConnect; + boost::signal onRoomJoined; + boost::signal onRoomLeft; boost::signal onDisconnected; private: diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index df01f55e..4a3bd92e 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -65,7 +65,7 @@ void NetworkPlugin::handleMessage(const std::string &user, const std::string &le m.SerializeToString(&message); WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE); - std::cout << "SENDING MESSAGE\n"; +// std::cout << "SENDING MESSAGE\n"; send(message); } @@ -156,14 +156,24 @@ void NetworkPlugin::handleConvMessagePayload(const std::string &data) { handleMessageSendRequest(payload.username(), payload.buddyname(), payload.message()); } +void NetworkPlugin::handleJoinRoomPayload(const std::string &data) { + pbnetwork::Room payload; + if (payload.ParseFromString(data) == false) { + // TODO: ERROR + return; + } + + handleJoinRoomRequest(payload.username(), payload.room(), payload.nickname(), payload.password()); +} + void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { long expected_size = 0; m_data += data.toString(); - std::cout << "received data; size = " << m_data.size() << "\n"; +// std::cout << "received data; size = " << m_data.size() << "\n"; while (m_data.size() != 0) { if (m_data.size() >= 4) { expected_size = (((((m_data[0] << 8) | m_data[1]) << 8) | m_data[2]) << 8) | m_data[3]; - std::cout << "expected_size=" << expected_size << "\n"; +// std::cout << "expected_size=" << expected_size << "\n"; if (m_data.size() - 4 < expected_size) return; } @@ -193,6 +203,9 @@ void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { case pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE: handleConvMessagePayload(wrapper.payload()); break; + case pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM: + handleJoinRoomPayload(wrapper.payload()); + break; default: return; } @@ -201,11 +214,11 @@ void NetworkPlugin::handleDataRead(const Swift::ByteArray &data) { void NetworkPlugin::send(const std::string &data) { std::string header(" "); - std::cout << data.size() << "\n"; +// std::cout << data.size() << "\n"; boost::int32_t size = data.size(); for (int i = 0; i != 4; ++i) { header.at(i) = static_cast(size >> (8 * (3 - i))); - std::cout << std::hex << (int) header.at(i) << "\n"; +// std::cout << std::hex << (int) header.at(i) << "\n"; } m_conn->write(Swift::ByteArray(header + data)); @@ -218,7 +231,7 @@ void NetworkPlugin::sendPong() { wrap.SerializeToString(&message); send(message); - std::cout << "SENDING PONG\n"; +// std::cout << "SENDING PONG\n"; } } diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index f134988f..46bbfdf8 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -154,7 +154,7 @@ void NetworkPluginServer::handleConnectedPayload(const std::string &data) { // TODO: ERROR return; } - std::cout << payload.name() << "\n"; +// std::cout << payload.name() << "\n"; } void NetworkPluginServer::handleDisconnectedPayload(const std::string &data) { @@ -196,12 +196,12 @@ void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) { void NetworkPluginServer::handleConvMessagePayload(const std::string &data) { pbnetwork::ConversationMessage payload; - std::cout << "payload...\n"; +// std::cout << "payload...\n"; if (payload.ParseFromString(data) == false) { // TODO: ERROR return; } - std::cout << "payload 2...\n"; +// std::cout << "payload 2...\n"; User *user = m_userManager->getUser(payload.username()); if (!user) return; @@ -219,13 +219,13 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data) { void NetworkPluginServer::handleDataRead(boost::shared_ptr c, const Swift::ByteArray &data) { long expected_size = 0; m_data += data.toString(); - std::cout << "received data; size = " << m_data.size() << "\n"; +// std::cout << "received data; size = " << m_data.size() << "\n"; while (m_data.size() != 0) { if (m_data.size() >= 4) { unsigned char * head = (unsigned char*) m_data.c_str(); expected_size = (((((*head << 8) | *(head + 1)) << 8) | *(head + 2)) << 8) | *(head + 3); //expected_size = m_data[0]; - std::cout << "expected_size=" << expected_size << "\n"; +// std::cout << "expected_size=" << expected_size << "\n"; if (m_data.size() - 4 < expected_size) return; } @@ -286,6 +286,7 @@ void NetworkPluginServer::pingTimeout() { void NetworkPluginServer::handleUserCreated(User *user) { // UserInfo userInfo = user->getUserInfo(); user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user)); + user->onRoomJoined.connect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3)); } void NetworkPluginServer::handleUserReadyToConnect(User *user) { @@ -304,6 +305,23 @@ void NetworkPluginServer::handleUserReadyToConnect(User *user) { send(m_client, message); } +void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, const std::string &nickname, const std::string &password) { + UserInfo userInfo = user->getUserInfo(); + + pbnetwork::Room room; + room.set_username(user->getJID().toBare()); + room.set_nickname(nickname); + room.set_room(r); + room.set_password(password); + + std::string message; + room.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM); + + send(m_client, message); +} + void NetworkPluginServer::handleUserDestroyed(User *user) { UserInfo userInfo = user->getUserInfo(); diff --git a/src/pbnetwork.proto b/src/pbnetwork.proto index a1433050..78803eb1 100644 --- a/src/pbnetwork.proto +++ b/src/pbnetwork.proto @@ -39,17 +39,35 @@ message ConversationMessage { required string message = 3; } +message Room { + required string userName = 1; + required string nickname = 2; + required string room = 3; + optional string password = 4; +} + +message Participant { + required string userName = 1; + required string room = 2; + required string nickname = 3; + required int32 flag = 4; +} + message WrapperMessage { enum Type { - TYPE_CONNECTED = 1; - TYPE_DISCONNECTED = 2; - TYPE_LOGIN = 3; - TYPE_LOGOUT = 4; - TYPE_BUDDY_CHANGED = 6; - TYPE_BUDDY_REMOVED = 7; - TYPE_CONV_MESSAGE = 8; - TYPE_PING = 9; - TYPE_PONG = 10; + TYPE_CONNECTED = 1; + TYPE_DISCONNECTED = 2; + TYPE_LOGIN = 3; + TYPE_LOGOUT = 4; + TYPE_BUDDY_CHANGED = 6; + TYPE_BUDDY_REMOVED = 7; + TYPE_CONV_MESSAGE = 8; + TYPE_PING = 9; + TYPE_PONG = 10; + TYPE_JOIN_ROOM = 11; + TYPE_PART_ROOM = 12; + TYPE_PARTICIPANT_CHANGED = 13; + TYPE_PARTICIPANT_LEFT = 14; } required Type type = 1; optional bytes payload = 2; diff --git a/src/transport.cpp b/src/transport.cpp index 7a403a0b..5501eeab 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -169,8 +169,7 @@ void Component::handleDataWritten(const std::string &data) { } void Component::handlePresence(Swift::Presence::ref presence) { - bool isMUC = presence->getPayload() != NULL; - + bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; // filter out login/logout presence spam if (!presence->getTo().getNode().empty() && isMUC == false) return; diff --git a/src/user.cpp b/src/user.cpp index 5819f4bf..c1db53f6 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -27,6 +27,7 @@ #include "Swiften/Swiften.h" #include "Swiften/Server/ServerStanzaChannel.h" #include "Swiften/Elements/StreamError.h" +#include "Swiften/Elements/MUCPayload.h" namespace Transport { @@ -81,6 +82,13 @@ void User::handlePresence(Swift::Presence::ref presence) { } } } + std::cout << "HANDLE PRESENCE\n"; + bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; + if (isMUC) { + std::cout << "AAAAAAAAA\n"; + onRoomJoined(presence->getTo().getNode(), presence->getTo().getResource(), ""); + return; + } if (highest) { diff --git a/src/usermanager.cpp b/src/usermanager.cpp index c58daedf..63cfb23a 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -137,6 +137,10 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { } user->handlePresence(presence); + bool isMUC = presence->getPayload() != NULL || *presence->getTo().getNode().c_str() == '#'; + if (isMUC) + return; + if (presence->getType() == Swift::Presence::Unavailable) { if (user) { Swift::Presence::ref highest = m_component->getPresenceOracle()->getHighestPriorityPresence(presence->getFrom().toBare());