#include "coresession.h"
#include "coreirclisthelper.h"
-#include "networkconnection.h"
-#include "network.h"
-#include "identity.h"
+#include "coreidentity.h"
#include "ctcphandler.h"
#include "ircuser.h"
-#include "ircchannel.h"
+#include "coreircchannel.h"
#include "logger.h"
#include <QDebug>
-IrcServerHandler::IrcServerHandler(NetworkConnection *parent)
+IrcServerHandler::IrcServerHandler(CoreNetwork *parent)
: BasicHandler(parent),
_whois(false)
{
}
IrcServerHandler::~IrcServerHandler() {
-
}
/*! Handle a raw message string sent by the server. We try to find a suitable handler, otherwise we call a default handler. */
void IrcServerHandler::handleServerMsg(QByteArray msg) {
try {
if(msg.isEmpty()) {
- quWarning() << "Received empty string from server!";
+ qWarning() << "Received empty string from server!";
return;
}
QList<QByteArray> params = msg.split(' ');
if(!trailing.isEmpty()) params << trailing;
if(params.count() < 1) {
- quWarning() << "Received invalid string from server!";
+ qWarning() << "Received invalid string from server!";
return;
}
foo.remove(0, 1);
prefix = foo;
if(params.count() < 1) {
- quWarning() << "Received invalid string from server!";
+ qWarning() << "Received invalid string from server!";
return;
}
foo = serverDecode(params.takeFirst());
uint num = cmd.toUInt();
if(num > 0) {
if(params.count() == 0) {
- quWarning() << "Message received from server violates RFC and is ignored!";
+ qWarning() << "Message received from server violates RFC and is ignored!";
return;
}
params.removeFirst();
// many nets define their own WHOIS fields. we fetch those not in need of special attention here:
emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", "[Whois] " + params.join(" "), prefix);
} else {
- if(networkConnection()->coreSession()->ircListHelper()->requestInProgress(network()->networkId()))
- networkConnection()->coreSession()->ircListHelper()->reportError(params.join(" "));
+ if(coreSession()->ircListHelper()->requestInProgress(network()->networkId()))
+ coreSession()->ircListHelper()->reportError(params.join(" "));
else
emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", cmd + " " + params.join(" "), prefix);
}
//qDebug() << "IrcServerHandler::handleJoin()" << prefix << params;
ircuser->joinChannel(channel);
if(network()->isMe(ircuser)) {
- networkConnection()->setChannelJoined(channel);
+ network()->setChannelJoined(channel);
putCmd("MODE", params[0]); // we want to know the modes of the channel we just joined, so we ask politely
}
}
msg = victim->nick();
emit displayMsg(Message::Kick, BufferInfo::ChannelBuffer, channel, msg, prefix);
- //if(network()->isMe(victim)) networkConnection()->setKickedFromChannel(channel);
+ //if(network()->isMe(victim)) network()->setKickedFromChannel(channel);
}
void IrcServerHandler::handleMode(const QString &prefix, const QList<QByteArray> ¶ms) {
else
channel->removeUserMode(ircUser, QString(modes[c]));
} else {
- quWarning() << "Received MODE with too few parameters:" << serverDecode(params);
+ qWarning() << "Received MODE with too few parameters:" << serverDecode(params);
}
paramOffset++;
} else {
if(paramOffset < params.count()) {
value = params[paramOffset];
} else {
- quWarning() << "Received MODE with too few parameters:" << serverDecode(params);
+ qWarning() << "Received MODE with too few parameters:" << serverDecode(params);
}
paramOffset++;
}
IrcUser *ircuser = network()->updateNickFromMask(prefix);
if(!ircuser) {
- quWarning() << "IrcServerHandler::handleNick(): Unknown IrcUser!";
+ qWarning() << "IrcServerHandler::handleNick(): Unknown IrcUser!";
return;
}
QString newnick = serverDecode(params[0]);
? newnick
: prefix;
- emit nickChanged(newnick, oldnick);
+ coreSession()->renameBuffer(network()->networkId(), newnick, oldnick);
foreach(QString channel, ircuser->channels())
emit displayMsg(Message::Nick, BufferInfo::ChannelBuffer, channel, newnick, sender);
return;
QString target = serverDecode(params[0]);
- if(prefix.isEmpty() || target == "AUTH")
+
+ // special treatment for welcome messages like:
+ // :ChanServ!ChanServ@services. NOTICE egst :[#apache] Welcome, this is #apache. Please read the in-channel topic message. This channel is being logged by IRSeekBot. If you have any question please see http://blog.freenode.net/?p=68
+ if(!network()->isChannelName(target)) {
+ QString msg = serverDecode(params[1]);
+ QRegExp welcomeRegExp("^\\[([^\\]]+)\\] ");
+ if(welcomeRegExp.indexIn(msg) != -1) {
+ QString channelname = welcomeRegExp.cap(1);
+ msg = msg.mid(welcomeRegExp.matchedLength());
+ CoreIrcChannel *chan = static_cast<CoreIrcChannel *>(network()->ircChannel(channelname)); // we only have CoreIrcChannels in the core, so this cast is safe
+ if(chan && !chan->receivedWelcomeMsg()) {
+ chan->setReceivedWelcomeMsg();
+ emit displayMsg(Message::Notice, BufferInfo::ChannelBuffer, channelname, msg, prefix);
+ return;
+ }
+ }
+ }
+
+ if(prefix.isEmpty() || target == "AUTH") {
target = "";
- else if(!network()->isChannelName(target))
- target = nickFromMask(prefix);
+ } else {
+ if(!target.isEmpty() && network()->prefixes().contains(target[0]))
+ target = target.mid(1);
+ if(!network()->isChannelName(target))
+ target = nickFromMask(prefix);
+ }
- networkConnection()->ctcpHandler()->parse(Message::Notice, prefix, target, params[1]);
+ network()->ctcpHandler()->parse(Message::Notice, prefix, target, params[1]);
}
void IrcServerHandler::handlePart(const QString &prefix, const QList<QByteArray> ¶ms) {
IrcUser *ircuser = network()->updateNickFromMask(prefix);
QString channel = serverDecode(params[0]);
if(!ircuser) {
- quWarning() << "IrcServerHandler::handlePart(): Unknown IrcUser!";
+ qWarning() << "IrcServerHandler::handlePart(): Unknown IrcUser!";
return;
}
msg = userDecode(ircuser->nick(), params[1]);
emit displayMsg(Message::Part, BufferInfo::ChannelBuffer, channel, msg, prefix);
- if(network()->isMe(ircuser)) networkConnection()->setChannelParted(channel);
+ if(network()->isMe(ircuser)) network()->setChannelParted(channel);
}
void IrcServerHandler::handlePing(const QString &prefix, const QList<QByteArray> ¶ms) {
IrcUser *ircuser = network()->updateNickFromMask(prefix);
if(!ircuser) {
- quWarning() << "IrcServerHandler::handlePrivmsg(): Unknown IrcUser!";
+ qWarning() << "IrcServerHandler::handlePrivmsg(): Unknown IrcUser!";
return;
}
if(params.isEmpty()) {
- quWarning() << "IrcServerHandler::handlePrivmsg(): received PRIVMSG without target or message from:" << prefix;
+ qWarning() << "IrcServerHandler::handlePrivmsg(): received PRIVMSG without target or message from:" << prefix;
return;
}
? QByteArray("")
: params[1];
- // are we the target?
- if(network()->isMyNick(target))
- target = nickFromMask(ircuser->nick());
+ if(!network()->isChannelName(target))
+ target = nickFromMask(prefix);
// it's possible to pack multiple privmsgs into one param using ctcp
// - > we let the ctcpHandler do the work
- networkConnection()->ctcpHandler()->parse(Message::Plain, prefix, target, msg);
+ network()->ctcpHandler()->parse(Message::Plain, prefix, target, msg);
}
void IrcServerHandler::handleQuit(const QString &prefix, const QList<QByteArray> ¶ms) {
foreach(QString channel, ircuser->channels())
emit displayMsg(Message::Quit, BufferInfo::ChannelBuffer, channel, msg, prefix);
- network()->removeIrcUser(nickFromMask(prefix));
+ ircuser->quit();
}
void IrcServerHandler::handleTopic(const QString &prefix, const QList<QByteArray> ¶ms) {
if(me)
me->setAway(false);
- if(!params.isEmpty())
- emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params[0]));
+ if(!network()->autoAwayActive()) {
+ if(!params.isEmpty())
+ emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params[0]));
+ } else {
+ network()->setAutoAwayActive(false);
+ }
}
// 306 RPL_NOWAWAY
if(me)
me->setAway(true);
- if(!params.isEmpty())
+ if(!params.isEmpty() && !network()->autoAwayActive())
emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params[0]));
}
return;
QStringList p = serverDecode(params);
- if(networkConnection()->setAutoWhoDone(p[0])) {
+ if(network()->setAutoWhoDone(p[0])) {
return; // stay silent
}
p.takeLast(); // should be "End of WHO list"
default:
break;
}
- if(!networkConnection()->coreSession()->ircListHelper()->addChannel(network()->networkId(), channelName, userCount, topic))
+ if(!coreSession()->ircListHelper()->addChannel(network()->networkId(), channelName, userCount, topic))
emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Channel %1 has %2 users. Topic is: %3").arg(channelName).arg(userCount).arg(topic));
}
Q_UNUSED(prefix)
Q_UNUSED(params)
- if(!networkConnection()->coreSession()->ircListHelper()->endOfChannelList(network()->networkId()))
+ if(!coreSession()->ircListHelper()->endOfChannelList(network()->networkId()))
emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("End of channel list"));
}
/* RPL_??? - "<channel> <creation time (unix)>" */
void IrcServerHandler::handle329(const QString &prefix, const QList<QByteArray> ¶ms) {
Q_UNUSED(prefix);
+ Q_UNUSED(params)
+#ifdef __GNUC__
+# warning "Implement handle329 (Channel creation time)"
+#endif
// FIXME implement this...
}
return;
QString channel = serverDecode(params[0]);
- network()->ircChannel(channel)->setTopic(QString());
+ IrcChannel *chan = network()->ircChannel(channel);
+ if(chan)
+ chan->setTopic(QString());
+
emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("No topic is set for %1.").arg(channel));
}
QString channel = serverDecode(params[0]);
QString topic = channelDecode(channel, params[1]);
- network()->ircChannel(channel)->setTopic(topic);
+ IrcChannel *chan = network()->ircChannel(channel);
+ if(chan)
+ chan->setTopic(topic);
+
emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Topic for %1 is \"%2\"").arg(channel, topic));
}
ircuser->setRealName(serverDecode(params.last()).section(" ", 1));
}
- if(!networkConnection()->isAutoWhoInProgress(channel)) {
+ if(!network()->isAutoWhoInProgress(channel)) {
emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Who] %1").arg(serverDecode(params).join(" ")));
}
}
/* RPL_NAMREPLY */
void IrcServerHandler::handle353(const QString &prefix, const QList<QByteArray> ¶ms) {
Q_UNUSED(prefix);
- if(!checkParamCount("IrcServerHandler::handle353()", params, 2))
+ if(!checkParamCount("IrcServerHandler::handle353()", params, 3))
return;
// param[0] is either "=", "*" or "@" indicating a public, private or secret channel
IrcChannel *channel = network()->ircChannel(channelname);
if(!channel) {
- quWarning() << "IrcServerHandler::handle353(): received unknown target channel:" << channelname;
+ qWarning() << "IrcServerHandler::handle353(): received unknown target channel:" << channelname;
return;
}
/* */
void IrcServerHandler::tryNextNick(const QString &errnick) {
- QStringList desiredNicks = networkConnection()->coreSession()->identity(network()->identity())->nicks();
+ QStringList desiredNicks = coreSession()->identity(network()->identity())->nicks();
int nextNick = desiredNicks.indexOf(errnick) + 1;
if(desiredNicks.size() > nextNick) {
putCmd("NICK", serverEncode(desiredNicks[nextNick]));
bool IrcServerHandler::checkParamCount(const QString &methodName, const QList<QByteArray> ¶ms, int minParams) {
if(params.count() < minParams) {
- quWarning() << qPrintable(methodName) << "requires" << minParams << "parameters but received only" << params.count() << serverDecode(params);
+ qWarning() << qPrintable(methodName) << "requires" << minParams << "parameters but received only" << params.count() << serverDecode(params);
return false;
} else {
return true;