***************************************************************************/
#include "network.h"
-#include "signalproxy.h"
-#include "ircuser.h"
-#include "ircchannel.h"
-
#include <QDebug>
#include <QTextCodec>
QTextCodec *Network::_defaultCodecForServer = 0;
QTextCodec *Network::_defaultCodecForEncoding = 0;
QTextCodec *Network::_defaultCodecForDecoding = 0;
-
// ====================
// Public:
// ====================
-Network::Network(const NetworkId &networkid, QObject *parent) : SyncableObject(parent),
+Network::Network(const NetworkId &networkid, QObject *parent)
+ : SyncableObject(parent),
_proxy(0),
_networkId(networkid),
_identity(0),
_myNick(QString()),
+ _latency(0),
_networkName(QString("<not initialized>")),
_currentServer(QString()),
_connected(false),
setObjectName(QString::number(networkid.toInt()));
}
-// I think this is unnecessary since IrcUsers have us as their daddy :)
-
Network::~Network() {
emit aboutToBeDestroyed();
-// QHashIterator<QString, IrcUser *> ircuser(_ircUsers);
-// while (ircuser.hasNext()) {
-// ircuser.next();
-// delete ircuser.value();
-// }
-// qDebug() << "Destroying net" << networkName() << networkId();
-}
-
-
-NetworkId Network::networkId() const {
- return _networkId;
-}
-
-SignalProxy *Network::proxy() const {
- return _proxy;
-}
-
-void Network::setProxy(SignalProxy *proxy) {
- _proxy = proxy;
- //proxy->synchronize(this); // we should to this explicitly from the outside!
-}
-
-bool Network::isMyNick(const QString &nick) const {
- return (myNick().toLower() == nick.toLower());
-}
-
-bool Network::isMe(IrcUser *ircuser) const {
- return (ircuser->nick().toLower() == myNick().toLower());
}
bool Network::isChannelName(const QString &channelname) const {
return QString("#&!+").contains(channelname[0]);
}
-bool Network::isConnected() const {
- return _connected;
-}
-
-//Network::ConnectionState Network::connectionState() const {
-int Network::connectionState() const {
- return _connectionState;
-}
-
NetworkInfo Network::networkInfo() const {
NetworkInfo info;
info.networkName = networkName();
return QString();
}
-QString Network::prefixToMode(const QCharRef &prefix) {
- return prefixToMode(QString(prefix));
-}
-
QString Network::modeToPrefix(const QString &mode) {
if(prefixModes().contains(mode))
return QString(prefixes()[prefixModes().indexOf(mode)]);
return QString();
}
-QString Network::modeToPrefix(const QCharRef &mode) {
- return modeToPrefix(QString(mode));
-}
-
-QString Network::networkName() const {
- return _networkName;
-}
-
-QString Network::currentServer() const {
- return _currentServer;
-}
-
-QString Network::myNick() const {
- return _myNick;
-}
-
-IdentityId Network::identity() const {
- return _identity;
-}
-
QStringList Network::nicks() const {
// we don't use _ircUsers.keys() since the keys may be
// not up to date after a nick change
return nicks;
}
-QStringList Network::channels() const {
- return _ircChannels.keys();
-}
-
-QVariantList Network::serverList() const {
- return _serverList;
-}
-
-bool Network::useRandomServer() const {
- return _useRandomServer;
-}
-
-QStringList Network::perform() const {
- return _perform;
-}
-
-bool Network::useAutoIdentify() const {
- return _useAutoIdentify;
-}
-
-QString Network::autoIdentifyService() const {
- return _autoIdentifyService;
-}
-
-QString Network::autoIdentifyPassword() const {
- return _autoIdentifyPassword;
-}
-
-bool Network::useAutoReconnect() const {
- return _useAutoReconnect;
-}
-
-quint32 Network::autoReconnectInterval() const {
- return _autoReconnectInterval;
-}
-
-quint16 Network::autoReconnectRetries() const {
- return _autoReconnectRetries;
-}
-
-bool Network::unlimitedReconnectRetries() const {
- return _unlimitedReconnectRetries;
-}
-
-bool Network::rejoinChannels() const {
- return _rejoinChannels;
-}
-
QString Network::prefixes() {
if(_prefixes.isNull())
determinePrefixes();
return _prefixModes;
}
-bool Network::supports(const QString ¶m) const {
- return _supports.contains(param);
+// example Unreal IRCD: CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTG
+Network::ChannelModeType Network::channelModeType(const QString &mode) {
+ if(mode.isEmpty())
+ return NOT_A_CHANMODE;
+
+ QString chanmodes = support("CHANMODES");
+ if(chanmodes.isEmpty())
+ return NOT_A_CHANMODE;
+
+ ChannelModeType modeType = A_CHANMODE;
+ for(int i = 0; i < chanmodes.count(); i++) {
+ if(chanmodes[i] == mode[0])
+ break;
+ else if(chanmodes[i] == ',')
+ modeType = (ChannelModeType)(modeType << 1);
+ }
+ if(modeType > D_CHANMODE) {
+ qWarning() << "Network" << networkId() << "supplied invalid CHANMODES:" << chanmodes;
+ modeType = NOT_A_CHANMODE;
+ }
+ return modeType;
}
QString Network::support(const QString ¶m) const {
QString nick(nickFromMask(hostmask).toLower());
if(!_ircUsers.contains(nick)) {
IrcUser *ircuser = new IrcUser(hostmask, this);
- // mark IrcUser as already initialized to keep the SignalProxy from requesting initData
- //if(isInitialized())
- // ircuser->setInitialized();
+
if(proxy())
proxy()->synchronize(ircuser);
else
return _ircUsers[nick];
}
-IrcUser *Network::newIrcUser(const QByteArray &hostmask) {
- return newIrcUser(decodeServerString(hostmask));
-}
-
void Network::ircUserDestroyed() {
IrcUser *ircUser = static_cast<IrcUser *>(sender());
if(!ircUser)
return 0;
}
-IrcUser *Network::ircUser(const QByteArray &nickname) const {
- return ircUser(decodeServerString(nickname));
-}
-
-QList<IrcUser *> Network::ircUsers() const {
- return _ircUsers.values();
-}
-
-quint32 Network::ircUserCount() const {
- return _ircUsers.count();
-}
-
IrcChannel *Network::newIrcChannel(const QString &channelname) {
if(!_ircChannels.contains(channelname.toLower())) {
IrcChannel *channel = new IrcChannel(channelname, this);
- // mark IrcUser as already initialized to keep the SignalProxy from requesting initData
- //if(isInitialized())
- // channel->setInitialized();
if(proxy())
proxy()->synchronize(channel);
return _ircChannels[channelname.toLower()];
}
-IrcChannel *Network::newIrcChannel(const QByteArray &channelname) {
- return newIrcChannel(decodeServerString(channelname));
-}
-
IrcChannel *Network::ircChannel(QString channelname) const {
channelname = channelname.toLower();
if(_ircChannels.contains(channelname))
return 0;
}
-IrcChannel *Network::ircChannel(const QByteArray &channelname) const {
- return ircChannel(decodeServerString(channelname));
-}
-
-
-QList<IrcChannel *> Network::ircChannels() const {
- return _ircChannels.values();
-}
-
-quint32 Network::ircChannelCount() const {
- return _ircChannels.count();
-}
-
QByteArray Network::defaultCodecForServer() {
- if(_defaultCodecForServer) return _defaultCodecForServer->name();
+ if(_defaultCodecForServer)
+ return _defaultCodecForServer->name();
return QByteArray();
}
}
QByteArray Network::defaultCodecForEncoding() {
- if(_defaultCodecForEncoding) return _defaultCodecForEncoding->name();
+ if(_defaultCodecForEncoding)
+ return _defaultCodecForEncoding->name();
return QByteArray();
}
}
QByteArray Network::defaultCodecForDecoding() {
- if(_defaultCodecForDecoding) return _defaultCodecForDecoding->name();
+ if(_defaultCodecForDecoding)
+ return _defaultCodecForDecoding->name();
return QByteArray();
}
}
QByteArray Network::codecForServer() const {
- if(_codecForServer) return _codecForServer->name();
+ if(_codecForServer)
+ return _codecForServer->name();
return QByteArray();
}
}
QByteArray Network::codecForEncoding() const {
- if(_codecForEncoding) return _codecForEncoding->name();
+ if(_codecForEncoding)
+ return _codecForEncoding->name();
return QByteArray();
}
}
QByteArray Network::codecForDecoding() const {
- if(_codecForDecoding) return _codecForDecoding->name();
+ if(_codecForDecoding)
+ return _codecForDecoding->name();
else return QByteArray();
}
// FIXME use server encoding if appropriate
QString Network::decodeString(const QByteArray &text) const {
- if(_codecForDecoding) return ::decodeString(text, _codecForDecoding);
+ if(_codecForDecoding)
+ return ::decodeString(text, _codecForDecoding);
else return ::decodeString(text, _defaultCodecForDecoding);
}
}
QString Network::decodeServerString(const QByteArray &text) const {
- if(_codecForServer) return ::decodeString(text, _codecForServer);
- else return ::decodeString(text, _defaultCodecForServer);
+ if(_codecForServer)
+ return ::decodeString(text, _codecForServer);
+ else
+ return ::decodeString(text, _defaultCodecForServer);
}
QByteArray Network::encodeServerString(const QString &string) const {
}
void Network::setConnected(bool connected) {
+ if(_connected == connected)
+ return;
+
_connected = connected;
if(!connected) {
- removeChansAndUsers();
+ setMyNick(QString());
setCurrentServer(QString());
+ removeChansAndUsers();
}
emit connectedSet(connected);
}
void Network::setMyNick(const QString &nickname) {
_myNick = nickname;
+ if(!_myNick.isEmpty() && !ircUser(myNick())) {
+ newIrcUser(myNick());
+ }
emit myNickSet(nickname);
}
+void Network::setLatency(int latency) {
+ if(_latency == latency)
+ return;
+ _latency = latency;
+ emit latencySet(latency);
+}
+
void Network::setIdentity(IdentityId id) {
_identity = id;
emit identitySet(id);
return supports;
}
-QVariantList Network::initServerList() const {
- return serverList();
-}
+QVariantMap Network::initIrcUsersAndChannels() const {
+ QVariantMap usersAndChannels;
+ QVariantMap users;
+ QVariantMap channels;
+
+ QHash<QString, IrcUser *>::const_iterator userIter = _ircUsers.constBegin();
+ QHash<QString, IrcUser *>::const_iterator userIterEnd = _ircUsers.constEnd();
+ while(userIter != userIterEnd) {
+ users[userIter.value()->hostmask()] = userIter.value()->toVariantMap();
+ userIter++;
+ }
+ usersAndChannels["users"] = users;
-QStringList Network::initIrcUsers() const {
- QStringList hostmasks;
- foreach(IrcUser *ircuser, ircUsers()) {
- hostmasks << ircuser->hostmask();
+ QHash<QString, IrcChannel *>::const_iterator channelIter = _ircChannels.constBegin();
+ QHash<QString, IrcChannel *>::const_iterator channelIterEnd = _ircChannels.constEnd();
+ while(channelIter != channelIterEnd) {
+ channels[channelIter.value()->name()] = channelIter.value()->toVariantMap();
+ channelIter++;
}
- return hostmasks;
+ usersAndChannels["channels"] = channels;
+
+ return usersAndChannels;
}
-QStringList Network::initIrcChannels() const {
- return _ircChannels.keys();
+void Network::initSetIrcUsersAndChannels(const QVariantMap &usersAndChannels) {
+ Q_ASSERT(proxy());
+ if(isInitialized()) {
+ qWarning() << "Network" << networkId() << "received init data for users and channels allthough there allready are known users or channels!";
+ return;
+ }
+
+ QVariantMap users = usersAndChannels.value("users").toMap();
+
+ QVariantMap::const_iterator userIter = users.constBegin();
+ QVariantMap::const_iterator userIterEnd = users.constEnd();
+ IrcUser *ircUser = 0;
+ QString hostmask;
+ while(userIter != userIterEnd) {
+ hostmask = userIter.key();
+ ircUser = new IrcUser(hostmask, this);
+ ircUser->fromVariantMap(userIter.value().toMap());
+ ircUser->setInitialized();
+ proxy()->synchronize(ircUser);
+
+ connect(ircUser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickChanged(QString)));
+ connect(ircUser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
+
+ _ircUsers[nickFromMask(hostmask).toLower()] = ircUser;
+
+ emit ircUserAdded(hostmask);
+ emit ircUserAdded(ircUser);
+ emit ircUserInitDone(ircUser);
+
+ userIter++;
+ }
+
+
+ QVariantMap channels = usersAndChannels.value("channels").toMap();
+ QVariantMap::const_iterator channelIter = channels.constBegin();
+ QVariantMap::const_iterator channelIterEnd = channels.constEnd();
+ IrcChannel *ircChannel = 0;
+ QString channelName;
+
+ while(channelIter != channelIterEnd) {
+ channelName = channelIter.key();
+ ircChannel = new IrcChannel(channelName, this);
+ ircChannel->fromVariantMap(channelIter.value().toMap());
+ ircChannel->setInitialized();
+ proxy()->synchronize(ircChannel);
+
+ connect(ircChannel, SIGNAL(destroyed()), this, SLOT(channelDestroyed()));
+ _ircChannels[channelName.toLower()] = ircChannel;
+
+ emit ircChannelAdded(channelName);
+ emit ircChannelAdded(ircChannel);
+ emit ircChannelInitDone(ircChannel);
+
+ channelIter++;
+ }
+
}
void Network::initSetSupports(const QVariantMap &supports) {
}
}
-void Network::initSetServerList(const QVariantList & serverList) {
- setServerList(serverList);
-}
-
-void Network::initSetIrcUsers(const QStringList &hostmasks) {
- if(!_ircUsers.empty())
- return;
- foreach(QString hostmask, hostmasks) {
- newIrcUser(hostmask);
- }
-}
-
-void Network::initSetIrcChannels(const QStringList &channels) {
- // FIXME This does not work correctly, "received data for unknown User" triggers
- // So we disable this for now
- return;
-
- if(!_ircChannels.empty())
- return;
- foreach(QString channel, channels)
- newIrcChannel(channel);
-}
-
IrcUser *Network::updateNickFromMask(const QString &mask) {
QString nick(nickFromMask(mask).toLower());
IrcUser *ircuser;
void Network::ircUserInitDone() {
IrcUser *ircuser = static_cast<IrcUser *>(sender());
Q_ASSERT(ircuser);
+ connect(ircuser, SIGNAL(initDone()), this, SLOT(ircUserInitDone()));
emit ircUserInitDone(ircuser);
}
void Network::ircChannelInitDone() {
- IrcChannel *ircchannel = static_cast<IrcChannel *>(sender());
- Q_ASSERT(ircchannel);
- emit ircChannelInitDone(ircchannel);
+ IrcChannel *ircChannel = static_cast<IrcChannel *>(sender());
+ Q_ASSERT(ircChannel);
+ disconnect(ircChannel, SIGNAL(initDone()), this, SLOT(ircChannelInitDone()));
+ emit ircChannelInitDone(ircChannel);
}
void Network::removeIrcChannel(IrcChannel *channel) {
emit ircChannelRemoved(channel);
}
-void Network::requestConnect() const {
- if(!proxy()) return;
- if(proxy()->proxyMode() == SignalProxy::Client) emit connectRequested(); // on the client this triggers calling this slot on the core
- else {
- if(connectionState() != Disconnected) {
- qWarning() << "Requesting connect while already being connected!";
- return;
- }
- emit connectRequested(networkId()); // and this is for CoreSession :)
- }
-}
-
-void Network::requestDisconnect() const {
- if(!proxy()) return;
- if(proxy()->proxyMode() == SignalProxy::Client) emit disconnectRequested(); // on the client this triggers calling this slot on the core
- else {
- if(connectionState() == Disconnected) {
- qWarning() << "Requesting disconnect while not being connected!";
- return;
- }
- emit disconnectRequested(networkId()); // and this is for CoreSession :)
- }
-}
-
void Network::emitConnectionError(const QString &errorMsg) {
emit connectionError(errorMsg);
}
// ====================
void Network::determinePrefixes() {
// seems like we have to construct them first
- QString PREFIX = support("PREFIX");
+ QString prefix = support("PREFIX");
- if(PREFIX.startsWith("(") && PREFIX.contains(")")) {
- _prefixes = PREFIX.section(")", 1);
- _prefixModes = PREFIX.mid(1).section(")", 0, 0);
+ if(prefix.startsWith("(") && prefix.contains(")")) {
+ _prefixes = prefix.section(")", 1);
+ _prefixModes = prefix.mid(1).section(")", 0, 0);
} else {
QString defaultPrefixes("~&@%+");
QString defaultPrefixModes("qaohv");
+ if(prefix.isEmpty()) {
+ _prefixes = defaultPrefixes;
+ _prefixModes = defaultPrefixModes;
+ return;
+ }
+
// we just assume that in PREFIX are only prefix chars stored
for(int i = 0; i < defaultPrefixes.size(); i++) {
- if(PREFIX.contains(defaultPrefixes[i])) {
+ if(prefix.contains(defaultPrefixes[i])) {
_prefixes += defaultPrefixes[i];
_prefixModes += defaultPrefixModes[i];
}
// well... our assumption was obviously wrong...
// check if it's only prefix modes
for(int i = 0; i < defaultPrefixes.size(); i++) {
- if(PREFIX.contains(defaultPrefixModes[i])) {
+ if(prefix.contains(defaultPrefixModes[i])) {
_prefixes += defaultPrefixes[i];
_prefixModes += defaultPrefixModes[i];
}
<< " rejoinChannels = " << i.rejoinChannels << ")";
return dbg.space();
}
-
-
-
-