Support more service.irc_server values and try another one when server disconnects us
This commit is contained in:
parent
b7f06ac352
commit
0e56fb8484
5 changed files with 47 additions and 15 deletions
|
@ -10,11 +10,23 @@ DEFINE_LOGGER(logger, "IRCNetworkPlugin");
|
|||
|
||||
IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
|
||||
this->config = config;
|
||||
m_currentServer = 0;
|
||||
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", "");
|
||||
std::string server = CONFIG_STRING_DEFAULTED(config, "service.irc_server", "");
|
||||
if (!server.empty()) {
|
||||
m_servers.push_back(server);
|
||||
}
|
||||
else {
|
||||
|
||||
std::list<std::string> list;
|
||||
list = CONFIG_LIST_DEFAULTED(config, "service.irc_server", list);
|
||||
|
||||
m_servers.insert(m_servers.begin(), list.begin(), list.end());
|
||||
}
|
||||
|
||||
if (CONFIG_HAS_KEY(config, "service.irc_identify")) {
|
||||
m_identify = CONFIG_STRING(config, "service.irc_identify");
|
||||
}
|
||||
|
@ -23,6 +35,14 @@ IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, con
|
|||
}
|
||||
}
|
||||
|
||||
void IRCNetworkPlugin::tryNextServer() {
|
||||
if (!m_servers.empty()) {
|
||||
int nextServer = (m_currentServer + 1) % m_servers.size();
|
||||
LOG4CXX_INFO(logger, "Server " << m_servers[m_currentServer] << " disconnected user. Next server to try will be " << m_servers[nextServer]);
|
||||
m_currentServer = nextServer;
|
||||
}
|
||||
}
|
||||
|
||||
void IRCNetworkPlugin::readData() {
|
||||
size_t availableBytes = m_socket->bytesAvailable();
|
||||
if (availableBytes == 0)
|
||||
|
@ -60,14 +80,14 @@ MyIrcSession *IRCNetworkPlugin::createSession(const std::string &user, const std
|
|||
}
|
||||
|
||||
void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
if (!m_server.empty()) {
|
||||
if (!m_servers.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, "");
|
||||
m_sessions[user] = createSession(user, m_servers[m_currentServer], legacyName, password, "");
|
||||
}
|
||||
else {
|
||||
// We are waiting for first room join to connect user to IRC network, because we don't know which
|
||||
|
@ -90,7 +110,7 @@ void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::s
|
|||
|
||||
std::string IRCNetworkPlugin::getSessionName(const std::string &user, const std::string &legacyName) {
|
||||
std::string u = user;
|
||||
if (!CONFIG_BOOL(config, "service.server_mode") && m_server.empty()) {
|
||||
if (!CONFIG_BOOL(config, "service.server_mode") && m_servers.empty()) {
|
||||
u = user + legacyName.substr(legacyName.find("@") + 1);
|
||||
if (u.find("/") != std::string::npos) {
|
||||
u = u.substr(0, u.find("/"));
|
||||
|
@ -146,7 +166,7 @@ void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std:
|
|||
|
||||
LOG4CXX_INFO(logger, user << ": Session name: " << session << ", Joining room " << target);
|
||||
if (m_sessions[session] == NULL) {
|
||||
if (m_server.empty()) {
|
||||
if (m_servers.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
|
||||
|
@ -182,7 +202,7 @@ void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std
|
|||
m_sessions[session]->removeAutoJoinChannel(target);
|
||||
m_sessions[session]->rooms -= 1;
|
||||
|
||||
if (m_sessions[session]->rooms <= 0 && m_server.empty()) {
|
||||
if (m_sessions[session]->rooms <= 0 && m_servers.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();
|
||||
|
|
|
@ -28,6 +28,8 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin {
|
|||
|
||||
void handleRoomSubjectChangedRequest(const std::string &user, const std::string &room, const std::string &message);
|
||||
|
||||
void tryNextServer();
|
||||
|
||||
public slots:
|
||||
void readData();
|
||||
void sendData(const std::string &string);
|
||||
|
@ -41,6 +43,7 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin {
|
|||
Config *config;
|
||||
QTcpSocket *m_socket;
|
||||
std::map<std::string, MyIrcSession *> m_sessions;
|
||||
std::string m_server;
|
||||
std::vector<std::string> m_servers;
|
||||
int m_currentServer;
|
||||
std::string m_identify;
|
||||
};
|
|
@ -14,6 +14,8 @@
|
|||
#include <IrcCommand>
|
||||
#include <IrcMessage>
|
||||
|
||||
#include "ircnetworkplugin.h"
|
||||
|
||||
#define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size())
|
||||
#define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size())
|
||||
|
||||
|
@ -21,7 +23,7 @@
|
|||
|
||||
DEFINE_LOGGER(logger, "IRCSession");
|
||||
|
||||
MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix, QObject* parent) : IrcSession(parent)
|
||||
MyIrcSession::MyIrcSession(const std::string &user, IRCNetworkPlugin *np, const std::string &suffix, QObject* parent) : IrcSession(parent)
|
||||
{
|
||||
this->np = np;
|
||||
this->user = user;
|
||||
|
@ -29,6 +31,7 @@ MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std
|
|||
m_connected = false;
|
||||
rooms = 0;
|
||||
connect(this, SIGNAL(disconnected()), SLOT(on_disconnected()));
|
||||
connect(this, SIGNAL(socketError(QAbstractSocket::SocketError)), SLOT(on_socketError(QAbstractSocket::SocketError)));
|
||||
connect(this, SIGNAL(connected()), SLOT(on_connected()));
|
||||
connect(this, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(onMessageReceived(IrcMessage*)));
|
||||
}
|
||||
|
@ -50,9 +53,15 @@ void MyIrcSession::on_connected() {
|
|||
}
|
||||
}
|
||||
|
||||
void MyIrcSession::on_socketError(QAbstractSocket::SocketError error) {
|
||||
on_disconnected();
|
||||
}
|
||||
|
||||
void MyIrcSession::on_disconnected() {
|
||||
if (suffix.empty())
|
||||
if (suffix.empty()) {
|
||||
np->handleDisconnected(user, 0, "");
|
||||
np->tryNextServer();
|
||||
}
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
|
@ -192,9 +201,7 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
|
|||
}
|
||||
break;
|
||||
case 432:
|
||||
if (m_connected) {
|
||||
np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Erroneous Nickname");
|
||||
}
|
||||
np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Erroneous Nickname");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
using namespace Transport;
|
||||
|
||||
class IRCNetworkPlugin;
|
||||
|
||||
class MyIrcSession : public IrcSession
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -37,7 +39,7 @@ public:
|
|||
|
||||
typedef std::map<std::string, boost::shared_ptr<AutoJoinChannel> > AutoJoinMap;
|
||||
|
||||
MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
|
||||
MyIrcSession(const std::string &user, IRCNetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
|
||||
std::map<std::string, bool> m_modes;
|
||||
std::string suffix;
|
||||
int rooms;
|
||||
|
@ -72,11 +74,12 @@ public:
|
|||
protected Q_SLOTS:
|
||||
void on_connected();
|
||||
void on_disconnected();
|
||||
void on_socketError(QAbstractSocket::SocketError error);
|
||||
|
||||
void onMessageReceived(IrcMessage* message);
|
||||
|
||||
protected:
|
||||
NetworkPlugin *np;
|
||||
IRCNetworkPlugin *np;
|
||||
std::string user;
|
||||
std::string m_identify;
|
||||
AutoJoinMap m_autoJoin;
|
||||
|
|
|
@ -53,7 +53,6 @@ const myType &safeAs(const boost::program_options::variable_value &var, const my
|
|||
#define CONFIG_BOOL_DEFAULTED(PTR, KEY, DEF) ((*PTR).hasKey(KEY) ? Transport::safeAs<bool>((*PTR)[KEY], DEF) : DEF)
|
||||
#define CONFIG_LIST_DEFAULTED(PTR, KEY, DEF) ((*PTR).hasKey(KEY) ? Transport::safeAs<std::list<std::string> >((*PTR)[KEY], DEF) : DEF)
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
/// Represents variable:value pairs.
|
||||
|
|
Loading…
Add table
Reference in a new issue