You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1986 lines
79 KiB
1986 lines
79 KiB
/*
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
*/
|
|
|
|
/*
|
|
Copyright (C) 2002 Dario Abatianni <eisfuchs@tigress.com>
|
|
Copyright (C) 2004 Peter Simonsson <psn@linux.se>
|
|
Copyright (C) 2006-2008 Eike Hein <hein@kde.org>
|
|
*/
|
|
|
|
#include "inputfilter.h"
|
|
#include "server.h"
|
|
#include "replycodes.h"
|
|
#include "konversationapplication.h"
|
|
#include "commit.h"
|
|
#include "version.h"
|
|
#include "query.h"
|
|
#include "channel.h"
|
|
#include "statuspanel.h"
|
|
#include "common.h"
|
|
#include "notificationhandler.h"
|
|
|
|
#include <tqdatastream.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqdatetime.h>
|
|
#include <tqregexp.h>
|
|
|
|
#include <klocale.h>
|
|
#include <tdeversion.h>
|
|
#include <kstringhandler.h>
|
|
#include <config.h>
|
|
#include <kdebug.h>
|
|
#include <kresolver.h>
|
|
|
|
InputFilter::InputFilter()
|
|
{
|
|
m_connecting = false;
|
|
}
|
|
|
|
InputFilter::~InputFilter()
|
|
{
|
|
}
|
|
|
|
void InputFilter::setServer(Server* newServer)
|
|
{
|
|
server=newServer;
|
|
}
|
|
|
|
void InputFilter::parseLine(const TQString& a_newLine)
|
|
{
|
|
TQString trailing;
|
|
TQString newLine(a_newLine);
|
|
|
|
// Remove white spaces at the end and beginning
|
|
newLine = newLine.stripWhiteSpace();
|
|
// Find end of middle parameter list
|
|
int pos = newLine.find(" :");
|
|
// Was there a trailing parameter?
|
|
if(pos != -1)
|
|
{
|
|
// Copy trailing parameter
|
|
trailing = newLine.mid(pos + 2);
|
|
// Cut trailing parameter from string
|
|
newLine = newLine.left(pos);
|
|
}
|
|
// Remove all unnecessary white spaces to make parsing easier
|
|
newLine = newLine.simplifyWhiteSpace();
|
|
|
|
TQString prefix;
|
|
|
|
// Do we have a prefix?
|
|
if(newLine[0] == ':')
|
|
{
|
|
// Find end of prefix
|
|
pos = newLine.find(' ');
|
|
// Copy prefix
|
|
prefix = newLine.mid(1, pos - 1);
|
|
// Remove prefix from line
|
|
newLine = newLine.mid(pos + 1);
|
|
}
|
|
|
|
// Find end of command
|
|
pos = newLine.find(' ');
|
|
// Copy command (all lowercase to make parsing easier)
|
|
TQString command = newLine.left(pos).lower();
|
|
// Are there parameters left in the string?
|
|
TQStringList parameterList;
|
|
|
|
if(pos != -1)
|
|
{
|
|
// Cut out the command
|
|
newLine = newLine.mid(pos + 1);
|
|
// The rest of the string will be the parameter list
|
|
parameterList = TQStringList::split(" ", newLine);
|
|
}
|
|
|
|
Q_ASSERT(server);
|
|
|
|
// Server command, if no "!" was found in prefix
|
|
if((prefix.find('!') == -1) && (prefix != server->getNickname()))
|
|
{
|
|
|
|
parseServerCommand(prefix, command, parameterList, trailing);
|
|
}
|
|
else
|
|
{
|
|
parseClientCommand(prefix, command, parameterList, trailing);
|
|
}
|
|
}
|
|
|
|
void InputFilter::parseClientCommand(const TQString &prefix, const TQString &command, const TQStringList ¶meterList, const TQString &_trailing)
|
|
{
|
|
KonversationApplication* konv_app = static_cast<KonversationApplication *>(TDEApplication::kApplication());
|
|
Q_ASSERT(konv_app);
|
|
Q_ASSERT(server);
|
|
// Extract nickname from prefix
|
|
int pos = prefix.find("!");
|
|
TQString sourceNick = prefix.left(pos);
|
|
TQString sourceHostmask = prefix.mid(pos + 1);
|
|
// remember hostmask for this nick, it could have changed
|
|
server->addHostmaskToNick(sourceNick,sourceHostmask);
|
|
TQString trailing = _trailing;
|
|
|
|
if(command=="privmsg")
|
|
{
|
|
bool isChan = isAChannel(parameterList[0]);
|
|
// CTCP message?
|
|
if(server->identifyMsg() && (trailing.at(0) == '+' || trailing.at(0) == '-')) {
|
|
trailing = trailing.mid(1);
|
|
}
|
|
|
|
if(trailing.at(0)==TQChar(0x01))
|
|
{
|
|
// cut out the CTCP command
|
|
TQString ctcp = trailing.mid(1,trailing.find(1,1)-1);
|
|
|
|
TQString ctcpCommand=ctcp.left(ctcp.find(" ")).lower();
|
|
TQString ctcpArgument=ctcp.mid(ctcp.find(" ")+1);
|
|
ctcpArgument=static_cast<KonversationApplication*>(kapp)->doAutoreplace(ctcpArgument,false);
|
|
|
|
// If it was a ctcp action, build an action string
|
|
if(ctcpCommand=="action" && isChan)
|
|
{
|
|
if(!isIgnore(prefix,Ignore::Channel))
|
|
{
|
|
Channel* channel = server->getChannelByName( parameterList[0] );
|
|
|
|
if(!channel) {
|
|
kdError() << "Didn't find the channel " << parameterList[0] << endl;
|
|
return;
|
|
}
|
|
|
|
channel->appendAction(sourceNick,ctcpArgument);
|
|
|
|
if(sourceNick != server->getNickname())
|
|
{
|
|
if(ctcpArgument.lower().find(TQRegExp("(^|[^\\d\\w])"
|
|
+ TQRegExp::escape(server->loweredNickname())
|
|
+ "([^\\d\\w]|$)")) !=-1 )
|
|
{
|
|
konv_app->notificationHandler()->nick(channel, sourceNick, ctcpArgument);
|
|
}
|
|
else
|
|
{
|
|
konv_app->notificationHandler()->message(channel, sourceNick, ctcpArgument);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// If it was a ctcp action, build an action string
|
|
else if(ctcpCommand=="action" && !isChan)
|
|
{
|
|
// Check if we ignore queries from this nick
|
|
if(!isIgnore(prefix,Ignore::Query))
|
|
{
|
|
NickInfoPtr nickinfo = server->obtainNickInfo(sourceNick);
|
|
nickinfo->setHostmask(sourceHostmask);
|
|
|
|
// create new query (server will check for dupes)
|
|
query = server->addQuery(nickinfo, false /* we didn't initiate this*/ );
|
|
|
|
// send action to query
|
|
query->appendAction(sourceNick,ctcpArgument);
|
|
|
|
if(sourceNick != server->getNickname() && query)
|
|
{
|
|
konv_app->notificationHandler()->queryMessage(query, sourceNick, ctcpArgument);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Answer ping requests
|
|
else if(ctcpCommand=="ping")
|
|
{
|
|
if(!isIgnore(prefix,Ignore::CTCP))
|
|
{
|
|
if(isChan)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received CTCP-PING request from %1 to channel %2, sending answer.")
|
|
.arg(sourceNick).arg(parameterList[0])
|
|
);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received CTCP-%1 request from %2, sending answer.")
|
|
.arg("PING").arg(sourceNick)
|
|
);
|
|
}
|
|
server->ctcpReply(sourceNick,TQString("PING %1").arg(ctcpArgument));
|
|
}
|
|
}
|
|
|
|
// Maybe it was a version request, so act appropriately
|
|
else if(ctcpCommand=="version")
|
|
{
|
|
if(!isIgnore(prefix,Ignore::CTCP))
|
|
{
|
|
if (isChan)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received Version request from %1 to channel %2.")
|
|
.arg(sourceNick).arg(parameterList[0])
|
|
);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received Version request from %1.")
|
|
.arg(sourceNick)
|
|
);
|
|
}
|
|
|
|
TQString reply;
|
|
if(Preferences::customVersionReplyEnabled())
|
|
{
|
|
reply = Preferences::customVersionReply().stripWhiteSpace();
|
|
}
|
|
else
|
|
{
|
|
// Do not internationalize the below version string
|
|
reply = TQString("Konversation %1 (C) 2002-2008 by the Konversation team")
|
|
.arg(TQString(KONVI_VERSION));
|
|
}
|
|
server->ctcpReply(sourceNick,"VERSION "+reply);
|
|
}
|
|
}
|
|
// DCC request?
|
|
else if(ctcpCommand=="dcc" && !isChan)
|
|
{
|
|
if(!isIgnore(prefix,Ignore::DCC))
|
|
{
|
|
// Extract DCC type and argument list
|
|
TQString dccType=ctcpArgument.lower().section(' ',0,0);
|
|
|
|
// Support file names with spaces
|
|
TQString dccArguments = ctcpArgument.mid(ctcpArgument.find(" ")+1);
|
|
TQStringList dccArgumentList;
|
|
|
|
if ((dccArguments.contains('\"') >= 2) && (dccArguments.startsWith("\""))) {
|
|
int lastQuotePos = dccArguments.findRev("\"");
|
|
if (dccArguments[lastQuotePos+1] == ' ') {
|
|
TQString fileName = dccArguments.mid(1, lastQuotePos-1);
|
|
dccArguments = dccArguments.mid(lastQuotePos+2);
|
|
|
|
dccArgumentList.append(fileName);
|
|
}
|
|
}
|
|
dccArgumentList += TQStringList::split(' ', dccArguments);
|
|
|
|
if(dccType=="send")
|
|
{
|
|
if(dccArgumentList.count()==4)
|
|
{
|
|
// incoming file
|
|
konv_app->notificationHandler()->dccIncoming(server->getStatusView(), sourceNick);
|
|
emit addDccGet(sourceNick,dccArgumentList);
|
|
}
|
|
else if(dccArgumentList.count()==5)
|
|
{
|
|
if(dccArgumentList[2]=="0")
|
|
{
|
|
// incoming file (Reverse DCC)
|
|
konv_app->notificationHandler()->dccIncoming(server->getStatusView(), sourceNick);
|
|
emit addDccGet(sourceNick,dccArgumentList);
|
|
}
|
|
else
|
|
{
|
|
// the receiver accepted the offer for Reverse DCC
|
|
emit startReverseDccSendTransfer(sourceNick,dccArgumentList);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("DCC"),
|
|
i18n("Received invalid DCC SEND request from %1.")
|
|
.arg(sourceNick)
|
|
);
|
|
}
|
|
}
|
|
else if(dccType=="accept")
|
|
{
|
|
// resume request was accepted
|
|
if(dccArgumentList.count()==3)
|
|
{
|
|
emit resumeDccGetTransfer(sourceNick,dccArgumentList);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("DCC"),
|
|
i18n("Received invalid DCC ACCEPT request from %1.")
|
|
.arg(sourceNick)
|
|
);
|
|
}
|
|
}
|
|
// Remote client wants our sent file resumed
|
|
else if(dccType=="resume")
|
|
{
|
|
if(dccArgumentList.count()==3)
|
|
{
|
|
emit resumeDccSendTransfer(sourceNick,dccArgumentList);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("DCC"),
|
|
i18n("Received invalid DCC RESUME request from %1.")
|
|
.arg(sourceNick)
|
|
);
|
|
}
|
|
}
|
|
else if(dccType=="chat")
|
|
{
|
|
|
|
if(dccArgumentList.count()==3)
|
|
{
|
|
// will be connected via Server to KonversationMainWindow::addDccChat()
|
|
emit addDccChat(server->getNickname(),sourceNick,dccArgumentList,false);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("DCC"),
|
|
i18n("Received invalid DCC CHAT request from %1.")
|
|
.arg(sourceNick)
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("DCC"),
|
|
i18n("Unknown DCC command %1 received from %2.")
|
|
.arg(ctcpArgument).arg(sourceNick)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else if (ctcpCommand=="clientinfo" && !isChan)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received CTCP-%1 request from %2, sending answer.")
|
|
.arg("CLIENTINFO").arg(sourceNick)
|
|
);
|
|
server->ctcpReply(sourceNick,TQString("CLIENTINFO ACTION CLIENTINFO DCC PING TIME VERSION"));
|
|
}
|
|
else if(ctcpCommand=="time" && !isChan)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received CTCP-%1 request from %2, sending answer.")
|
|
.arg("TIME").arg(sourceNick)
|
|
);
|
|
server->ctcpReply(sourceNick,TQString("TIME ")+TQDateTime::currentDateTime().toString());
|
|
}
|
|
|
|
// No known CTCP request, give a general message
|
|
else
|
|
{
|
|
if(!isIgnore(prefix,Ignore::CTCP))
|
|
{
|
|
if (isChan)
|
|
server->appendServerMessageToChannel(
|
|
parameterList[0],
|
|
"CTCP",
|
|
i18n("Received unknown CTCP-%1 request from %2 to Channel %3.")
|
|
.arg(ctcp).arg(sourceNick).arg(parameterList[0])
|
|
);
|
|
else
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received unknown CTCP-%1 request from %2.")
|
|
.arg(ctcp).arg(sourceNick)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
// No CTCP, so it's an ordinary channel or query message
|
|
else
|
|
{
|
|
parsePrivMsg (prefix, parameterList, trailing);
|
|
}
|
|
}
|
|
else if(command=="notice")
|
|
{
|
|
if(!isIgnore(prefix,Ignore::Notice))
|
|
{
|
|
// Channel notice?
|
|
if(isAChannel(parameterList[0]))
|
|
{
|
|
if(server->identifyMsg())
|
|
{
|
|
trailing = trailing.mid(1);
|
|
}
|
|
|
|
server->appendServerMessageToChannel(parameterList[0], i18n("Notice"),
|
|
i18n("-%1 to %2- %3")
|
|
.arg(sourceNick).arg(parameterList[0]).arg(trailing)
|
|
);
|
|
}
|
|
// Private notice
|
|
else
|
|
{
|
|
// Was this a CTCP reply?
|
|
if(trailing.at(0)==TQChar(0x01))
|
|
{
|
|
// cut 0x01 bytes from trailing string
|
|
TQString ctcp(trailing.mid(1,trailing.length()-2));
|
|
TQString replyReason(ctcp.section(' ',0,0));
|
|
TQString reply(ctcp.section(' ',1));
|
|
|
|
// pong reply, calculate turnaround time
|
|
if(replyReason.lower()=="ping")
|
|
{
|
|
int dateArrived=TQDateTime::currentDateTime().toTime_t();
|
|
int dateSent=reply.toInt();
|
|
int time = dateArrived-dateSent;
|
|
TQString unit = "seconds";
|
|
|
|
if (time==1)
|
|
unit = "second";
|
|
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received CTCP-PING reply from %1: %2 %3.")
|
|
.arg(sourceNick)
|
|
.arg(time)
|
|
.arg(unit)
|
|
);
|
|
}
|
|
// all other ctcp replies get a general message
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("CTCP"),
|
|
i18n("Received CTCP-%1 reply from %2: %3.")
|
|
.arg(replyReason).arg(sourceNick).arg(reply)
|
|
);
|
|
}
|
|
}
|
|
// No, so it was a normal notice
|
|
else
|
|
{
|
|
// Nickserv
|
|
if (trailing.startsWith("If this is your nick"))
|
|
{
|
|
// Identify command if specified
|
|
server->registerWithServices();
|
|
}
|
|
else if (server->identifyMsg())
|
|
trailing = trailing.mid(1);
|
|
|
|
if(trailing.lower() == "password accepted - you are now recognized"
|
|
|| trailing.lower() == "you have already identified")
|
|
{
|
|
NickInfoPtr nickInfo = server->getNickInfo(server->getNickname());
|
|
if(nickInfo)
|
|
nickInfo->setIdentified(true);
|
|
}
|
|
server->appendMessageToFrontmost(i18n("Notice"), i18n("-%1- %2").arg(sourceNick).arg(trailing));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(command=="join")
|
|
{
|
|
TQString channelName(trailing);
|
|
// Sometimes JOIN comes without ":" in front of the channel name
|
|
if(channelName.isEmpty())
|
|
channelName=parameterList[parameterList.count()-1];
|
|
|
|
// Did we join the channel, or was it someone else?
|
|
if(server->isNickname(sourceNick))
|
|
{
|
|
/*
|
|
TQString key;
|
|
// TODO: Try to remember channel keys for autojoins and manual joins, so
|
|
// we can get %k to work
|
|
|
|
if(channelName.find(' ')!=-1)
|
|
{
|
|
key=channelName.section(' ',1,1);
|
|
channelName=channelName.section(' ',0,0);
|
|
}
|
|
*/
|
|
|
|
// Join the channel
|
|
server->joinChannel(channelName, sourceHostmask);
|
|
|
|
server->resetNickList(channelName);
|
|
|
|
// Upon JOIN we're going to receive some NAMES input from the server which
|
|
// we need to be able to tell apart from manual invocations of /names
|
|
setAutomaticRequest("NAMES",channelName,true);
|
|
|
|
server->getChannelByName(channelName)->clearModeList();
|
|
|
|
// Request modes for the channel
|
|
server->queue("MODE "+channelName, Server::LowPriority);
|
|
|
|
// Initiate channel ban list
|
|
server->getChannelByName(channelName)->clearBanList();
|
|
setAutomaticRequest("BANLIST",channelName,true);
|
|
server->queue("MODE "+channelName+" +b", Server::LowPriority);
|
|
}
|
|
else
|
|
{
|
|
Channel* channel = server->nickJoinsChannel(channelName,sourceNick,sourceHostmask);
|
|
konv_app->notificationHandler()->join(channel, sourceNick);
|
|
}
|
|
}
|
|
else if(command=="kick")
|
|
{
|
|
server->nickWasKickedFromChannel(parameterList[0],parameterList[1],sourceNick,trailing);
|
|
}
|
|
else if(command=="part")
|
|
{
|
|
/* FIXME: Ugly workaround for a version of the PART line encountered on ircu:
|
|
* :Nick!user@host PART :#channel
|
|
* Quote: "The final colon is specified as a "last argument" designator, and
|
|
* is always valid before the final argument."
|
|
*/
|
|
|
|
TQString channel;
|
|
TQString reason;
|
|
|
|
if (parameterList[0].isEmpty())
|
|
{
|
|
channel = trailing;
|
|
}
|
|
else
|
|
{
|
|
channel = parameterList[0];
|
|
reason = trailing;
|
|
}
|
|
|
|
Channel* channelPtr = server->removeNickFromChannel(channel,sourceNick,reason);
|
|
|
|
if(sourceNick != server->getNickname())
|
|
{
|
|
konv_app->notificationHandler()->part(channelPtr, sourceNick);
|
|
}
|
|
}
|
|
else if(command=="quit")
|
|
{
|
|
server->removeNickFromServer(sourceNick,trailing);
|
|
if(sourceNick != server->getNickname())
|
|
{
|
|
konv_app->notificationHandler()->quit(server->getStatusView(), sourceNick);
|
|
}
|
|
}
|
|
else if(command=="nick")
|
|
{
|
|
TQString newNick(trailing);
|
|
|
|
// Message may not include ":" in front of the new nickname
|
|
if (newNick.isEmpty())
|
|
newNick=parameterList[parameterList.count()-1];
|
|
|
|
server->renameNick(sourceNick,newNick);
|
|
|
|
if (sourceNick != server->getNickname())
|
|
{
|
|
konv_app->notificationHandler()->nickChange(server->getStatusView(), sourceNick, newNick);
|
|
}
|
|
}
|
|
else if(command=="topic")
|
|
{
|
|
server->setChannelTopic(sourceNick,parameterList[0],trailing);
|
|
}
|
|
else if(command=="mode") // mode #channel -/+ mmm params
|
|
{
|
|
TQStringList params=parameterList;
|
|
if (!trailing.isEmpty())
|
|
params << trailing;
|
|
parseModes(sourceNick, params);
|
|
Channel* channel = server->getChannelByName(parameterList[0]);
|
|
if(sourceNick != server->getNickname())
|
|
{
|
|
konv_app->notificationHandler()->mode(channel, sourceNick);
|
|
}
|
|
}
|
|
else if(command=="invite")
|
|
{
|
|
TQString channel;
|
|
|
|
if (parameterList.count() > 1)
|
|
channel = parameterList[1];
|
|
else
|
|
channel = trailing;
|
|
|
|
server->appendMessageToFrontmost(i18n("Invite"),
|
|
i18n("%1 invited you to channel %2.")
|
|
.arg(sourceNick).arg(channel)
|
|
);
|
|
emit invitation(sourceNick,channel);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(command,parameterList.join(" ")+' '+trailing);
|
|
}
|
|
}
|
|
|
|
void InputFilter::parseServerCommand(const TQString &prefix, const TQString &command, const TQStringList ¶meterList, const TQString &trailing)
|
|
{
|
|
bool isNumeric;
|
|
int numeric = command.toInt(&isNumeric);
|
|
|
|
Q_ASSERT(server); if(!server) return;
|
|
|
|
if(!isNumeric)
|
|
{
|
|
if(command=="ping")
|
|
{
|
|
TQString text;
|
|
text = (!trailing.isEmpty()) ? trailing : parameterList.join(" ");
|
|
|
|
if(!trailing.isEmpty())
|
|
{
|
|
text = prefix + " :" + text;
|
|
}
|
|
|
|
if(!text.startsWith(" "))
|
|
{
|
|
text.prepend(' ');
|
|
}
|
|
|
|
// queue the reply to send it as soon as possible
|
|
server->queue("PONG"+text, Server::HighPriority);
|
|
|
|
}
|
|
else if(command=="error :closing link:")
|
|
{
|
|
kdDebug() << "link closed" << endl;
|
|
}
|
|
else if(command=="pong")
|
|
{
|
|
// double check if we are in lag measuring mode since some servers fail to send
|
|
// the LAG cookie back in PONG
|
|
if(trailing.startsWith("LAG") || getLagMeasuring())
|
|
{
|
|
server->pongReceived();
|
|
}
|
|
}
|
|
else if(command=="mode")
|
|
{
|
|
TQStringList params=parameterList;
|
|
if (!trailing.isEmpty())
|
|
params << trailing;
|
|
parseModes(prefix, params);
|
|
}
|
|
else if(command=="notice")
|
|
{
|
|
server->appendStatusMessage(i18n("Notice"),i18n("-%1- %2").arg(prefix).arg(trailing));
|
|
}
|
|
else if(command=="kick")
|
|
{
|
|
server->nickWasKickedFromChannel(parameterList[0],parameterList[1],prefix,trailing);
|
|
}
|
|
else if(command == "privmsg")
|
|
{
|
|
parsePrivMsg(prefix, parameterList, trailing);
|
|
}
|
|
// All yet unknown messages go into the frontmost window unaltered
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(command,parameterList.join(" ")+' '+trailing);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (numeric)
|
|
{
|
|
case RPL_WELCOME:
|
|
case RPL_YOURHOST:
|
|
case RPL_CREATED:
|
|
{
|
|
if(numeric==RPL_WELCOME)
|
|
{
|
|
TQString host;
|
|
|
|
if(trailing.contains("@"))
|
|
host = trailing.section("@",1);
|
|
|
|
// re-set nickname, since the server may have truncated it
|
|
if(parameterList[0]!=server->getNickname())
|
|
server->renameNick(server->getNickname(), parameterList[0]);
|
|
|
|
// Send the welcome signal, so the server class knows we are connected properly
|
|
emit welcome(host);
|
|
m_connecting = true;
|
|
}
|
|
server->appendStatusMessage(i18n("Welcome"),trailing);
|
|
break;
|
|
}
|
|
case RPL_MYINFO:
|
|
{
|
|
server->appendStatusMessage(i18n("Welcome"),
|
|
i18n("Server %1 (Version %2), User modes: %3, Channel modes: %4")
|
|
.arg(parameterList[1])
|
|
.arg(parameterList[2])
|
|
.arg(parameterList[3])
|
|
.arg(parameterList[4])
|
|
);
|
|
server->setAllowedChannelModes(parameterList[4]);
|
|
break;
|
|
}
|
|
//case RPL_BOUNCE: // RFC 1459 name, now seems to be obsoleted by ...
|
|
case RPL_ISUPPORT: // ... DALnet RPL_ISUPPORT
|
|
{
|
|
server->appendStatusMessage(i18n("Support"),parameterList.join(" "));
|
|
|
|
// The following behavoiur is neither documented in RFC 1459 nor in 2810-2813
|
|
// Nowadays, most ircds send server capabilities out via 005 (BOUNCE).
|
|
// refer to http://www.irc.org/tech_docs/005.html for a kind of documentation.
|
|
// More on http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
|
|
|
|
TQStringList::const_iterator it = parameterList.begin();
|
|
// don't want the user name
|
|
++it;
|
|
for (; it != parameterList.end(); ++it )
|
|
{
|
|
TQString property, value;
|
|
int pos;
|
|
if ((pos=(*it).find( '=' )) !=-1)
|
|
{
|
|
property = (*it).left(pos);
|
|
value = (*it).mid(pos+1);
|
|
}
|
|
else
|
|
{
|
|
property = *it;
|
|
}
|
|
if (property=="PREFIX")
|
|
{
|
|
pos = value.find(')',1);
|
|
if(pos==-1)
|
|
{
|
|
server->setPrefixes(TQString(), value);
|
|
// XXX if ) isn't in the string, NOTHING should be there. anyone got a server
|
|
if (value.length() || property.length())
|
|
server->appendStatusMessage("","XXX Server sent bad PREFIX in RPL_ISUPPORT, please report.");
|
|
}
|
|
else
|
|
{
|
|
server->setPrefixes (value.mid(1, pos-1), value.mid(pos+1));
|
|
}
|
|
}
|
|
else if (property=="CHANTYPES")
|
|
{
|
|
server->setChannelTypes(value);
|
|
}
|
|
else if (property == "CAPAB")
|
|
{
|
|
// Disable as we don't use this for anything yet
|
|
//server->queue("CAPAB IDENTIFY-MSG");
|
|
}
|
|
else
|
|
{
|
|
//kdDebug() << "Ignored server-capability: " << property << " with value '" << value << "'" << endl;
|
|
}
|
|
} // endfor
|
|
break;
|
|
}
|
|
case RPL_UMODEIS:
|
|
{
|
|
TQString message=TQString("%1 %2").arg(i18n("Your personal modes are:")).arg(parameterList.join(" ").section(' ',1) + ' '+trailing);
|
|
server->appendMessageToFrontmost("Info", message);
|
|
break;
|
|
}
|
|
case RPL_CHANNELMODEIS:
|
|
{
|
|
const TQString modeString=parameterList[2];
|
|
// This is the string the user will see
|
|
TQString modesAre;
|
|
TQString message = i18n("Channel modes: ") + modeString;
|
|
|
|
for(unsigned int index=0;index<modeString.length();index++)
|
|
{
|
|
TQString parameter;
|
|
int parameterCount=3;
|
|
char mode=modeString[index];
|
|
if(mode!='+')
|
|
{
|
|
if(!modesAre.isEmpty())
|
|
modesAre+=", ";
|
|
if(mode=='t')
|
|
modesAre+=i18n("topic protection");
|
|
else if(mode=='n')
|
|
modesAre+=i18n("no messages from outside");
|
|
else if(mode=='s')
|
|
modesAre+=i18n("secret");
|
|
else if(mode=='i')
|
|
modesAre+=i18n("invite only");
|
|
else if(mode=='p')
|
|
modesAre+=i18n("private");
|
|
else if(mode=='m')
|
|
modesAre+=i18n("moderated");
|
|
else if(mode=='k')
|
|
{
|
|
parameter=parameterList[parameterCount++];
|
|
message += ' ' + parameter;
|
|
modesAre+=i18n("password protected");
|
|
}
|
|
else if(mode=='a')
|
|
modesAre+=i18n("anonymous");
|
|
else if(mode=='r')
|
|
modesAre+=i18n("server reop");
|
|
else if(mode=='c')
|
|
modesAre+=i18n("no colors allowed");
|
|
else if(mode=='l')
|
|
{
|
|
parameter=parameterList[parameterCount++];
|
|
message += ' ' + parameter;
|
|
modesAre+=i18n("limited to %n user", "limited to %n users", parameter.toInt());
|
|
}
|
|
else
|
|
{
|
|
modesAre+=mode;
|
|
}
|
|
server->updateChannelModeWidgets(parameterList[1],mode,parameter);
|
|
}
|
|
} // endfor
|
|
if(!modesAre.isEmpty() && Preferences::useLiteralModes())
|
|
{
|
|
server->appendCommandMessageToChannel(parameterList[1],i18n("Mode"),message);
|
|
}
|
|
else
|
|
{
|
|
server->appendCommandMessageToChannel(parameterList[1],i18n("Mode"),
|
|
i18n("Channel modes: ") + modesAre
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
case RPL_CHANNELURLIS:
|
|
{// :niven.freenode.net 328 argonel #channel :http://www.buggeroff.com/
|
|
server->appendCommandMessageToChannel(parameterList[1], i18n("URL"),
|
|
i18n("Channel URL: %1").arg(trailing));
|
|
break;
|
|
}
|
|
case RPL_CHANNELCREATED:
|
|
{
|
|
TQDateTime when;
|
|
when.setTime_t(parameterList[2].toUInt());
|
|
server->appendCommandMessageToChannel(parameterList[1],i18n("Created"),
|
|
i18n("This channel was created on %1.")
|
|
.arg(when.toString(Qt::LocalDate))
|
|
);
|
|
|
|
if(Preferences::autoWhoContinuousEnabled())
|
|
{
|
|
emit endOfWho(parameterList[1]);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case RPL_WHOISACCOUNT:
|
|
{
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),i18n("%1 is logged in as %2.").arg(parameterList[1]).arg(parameterList[2]));
|
|
}
|
|
break;
|
|
}
|
|
case RPL_NAMREPLY:
|
|
{
|
|
TQStringList nickList;
|
|
|
|
if(!trailing.isEmpty())
|
|
{
|
|
nickList = TQStringList::split(" ", trailing);
|
|
}
|
|
else if(parameterList.count() > 3)
|
|
{
|
|
for(uint i = 3; i < parameterList.count(); i++) {
|
|
nickList.append(parameterList[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
kdDebug() << "Hmm seems something is broken... can't get to the names!" << endl;
|
|
}
|
|
|
|
// send list to channel
|
|
server->addPendingNickList(parameterList[2], nickList);
|
|
|
|
// Display message only if this was not an automatic request.
|
|
if(!getAutomaticRequest("NAMES",parameterList[2])==1)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Names"),trailing);
|
|
}
|
|
break;
|
|
}
|
|
case RPL_ENDOFNAMES:
|
|
{
|
|
if(getAutomaticRequest("NAMES",parameterList[1])==1)
|
|
{
|
|
// This code path was taken for the automatic NAMES input on JOIN, upcoming
|
|
// NAMES input for this channel will be manual invocations of /names
|
|
setAutomaticRequest("NAMES",parameterList[1],false);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Names"),i18n("End of NAMES list."));
|
|
}
|
|
break;
|
|
}
|
|
// Topic set messages
|
|
case RPL_NOTOPIC:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("TOPIC"),i18n("The channel %1 has no topic set.").arg(parameterList[1]) /*.arg(parameterList[2])*/); //FIXME ok, whats the second parameter supposed to be?
|
|
|
|
break;
|
|
}
|
|
case RPL_TOPIC:
|
|
{
|
|
TQString topic = Konversation::removeIrcMarkup(trailing);
|
|
|
|
// FIXME: This is an abuse of the automaticRequest system: We're
|
|
// using it in an inverted manner, i.e. the automaticRequest is
|
|
// set to true by a manual invocation of /topic. Bad bad bad -
|
|
// needs rethinking of automaticRequest.
|
|
if(getAutomaticRequest("TOPIC",parameterList[1])==0)
|
|
{
|
|
// Update channel window
|
|
server->setChannelTopic(parameterList[1],topic);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Topic"),i18n("The channel topic for %1 is: \"%2\"").arg(parameterList[1]).arg(topic));
|
|
}
|
|
|
|
break;
|
|
}
|
|
case RPL_TOPICSETBY:
|
|
{
|
|
// Inform user who set the topic and when
|
|
TQDateTime when;
|
|
when.setTime_t(parameterList[3].toUInt());
|
|
|
|
// See FIXME in RPL_TOPIC
|
|
if(getAutomaticRequest("TOPIC",parameterList[1])==0)
|
|
{
|
|
server->appendCommandMessageToChannel(parameterList[1],i18n("Topic"),
|
|
i18n("The topic was set by %1 on %2.")
|
|
.arg(parameterList[2]).arg(when.toString(Qt::LocalDate)),
|
|
false);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Topic"),i18n("The topic for %1 was set by %2 on %3.")
|
|
.arg(parameterList[1])
|
|
.arg(parameterList[2])
|
|
.arg(when.toString(Qt::LocalDate))
|
|
);
|
|
setAutomaticRequest("TOPIC",parameterList[1],false);
|
|
}
|
|
emit topicAuthor(parameterList[1], parameterList[2], when);
|
|
|
|
break;
|
|
}
|
|
case RPL_WHOISACTUALLY:
|
|
{
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),i18n("%1 is actually using the host %2.").arg(parameterList[1]).arg(parameterList[2]));
|
|
}
|
|
break;
|
|
}
|
|
case ERR_NOSUCHNICK:
|
|
{
|
|
// Display slightly different error message in case we performed a WHOIS for
|
|
// IP resolve purposes, and clear it from the automaticRequest list
|
|
if(getAutomaticRequest("DNS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("%1: No such nick/channel.").arg(parameterList[1]));
|
|
}
|
|
else if(getAutomaticRequest("WHOIS",parameterList[1])==0) //Display message only if this was not an automatic request.
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("No such nick: %1.").arg(parameterList[1]));
|
|
setAutomaticRequest("DNS", parameterList[1], false);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case ERR_NOSUCHCHANNEL:
|
|
{
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("%1: No such channel.").arg(parameterList[1]));
|
|
}
|
|
break;
|
|
}
|
|
// Nick already on the server, so try another one
|
|
case ERR_NICKNAMEINUSE:
|
|
{
|
|
// if we are already connected, don't try tro find another nick ourselves
|
|
if(server->isConnected())
|
|
{ // Show message
|
|
server->appendMessageToFrontmost(i18n("Nick"),i18n("Nickname already in use, try a different one."));
|
|
}
|
|
else // not connected yet, so try to find a nick that's not in use
|
|
{
|
|
// Get the next nick from the list or ask for a new one
|
|
TQString newNick = server->getNextNickname();
|
|
|
|
// The user chose to disconnect
|
|
if (newNick.isNull())
|
|
{
|
|
server->disconnect();
|
|
}
|
|
else
|
|
{
|
|
// Update Server window
|
|
server->obtainNickInfo(server->getNickname()) ;
|
|
server->renameNick(server->getNickname(), newNick);
|
|
// Show message
|
|
server->appendMessageToFrontmost(i18n("Nick"), i18n("Nickname already in use. Trying %1.").arg(newNick));
|
|
// Send nickchange request to the server
|
|
server->queue("NICK "+newNick);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case ERR_ERRONEUSNICKNAME:
|
|
{
|
|
if(server->isConnected())
|
|
{ // We are already connected. Just print the error message
|
|
server->appendMessageToFrontmost(i18n("Nick"), trailing);
|
|
}
|
|
else // Find a new nick as in ERR_NICKNAMEINUSE
|
|
{
|
|
TQString newNick = server->getNextNickname();
|
|
|
|
// The user chose to disconnect
|
|
if (newNick.isNull())
|
|
{
|
|
server->disconnect();
|
|
}
|
|
else
|
|
{
|
|
server->obtainNickInfo(server->getNickname()) ;
|
|
server->renameNick(server->getNickname(), newNick);
|
|
server->appendMessageToFrontmost(i18n("Nick"), i18n("Erroneus nickname. Changing nick to %1." ).arg(newNick)) ;
|
|
server->queue("NICK "+newNick);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case ERR_NOTONCHANNEL:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("You are not on %1.").arg(parameterList[1]));
|
|
|
|
break;
|
|
}
|
|
case RPL_MOTDSTART:
|
|
{
|
|
if(!m_connecting || !Preferences::skipMOTD())
|
|
server->appendStatusMessage(i18n("MOTD"),i18n("Message of the day:"));
|
|
break;
|
|
}
|
|
case RPL_MOTD:
|
|
{
|
|
if(!m_connecting || !Preferences::skipMOTD())
|
|
server->appendStatusMessage(i18n("MOTD"),trailing);
|
|
break;
|
|
}
|
|
case RPL_ENDOFMOTD:
|
|
{
|
|
if(!m_connecting || !Preferences::skipMOTD())
|
|
server->appendStatusMessage(i18n("MOTD"),i18n("End of message of the day"));
|
|
|
|
if(m_connecting)
|
|
server->autoCommandsAndChannels();
|
|
|
|
m_connecting = false;
|
|
break;
|
|
}
|
|
case ERR_NOMOTD:
|
|
{
|
|
if(m_connecting)
|
|
server->autoCommandsAndChannels();
|
|
|
|
m_connecting = false;
|
|
break;
|
|
}
|
|
case RPL_YOUREOPER:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Notice"),i18n("You are now an IRC operator on this server."));
|
|
|
|
break;
|
|
}
|
|
case RPL_GLOBALUSERS: // Current global users: 589 Max: 845
|
|
{
|
|
TQString current(trailing.section(' ',3));
|
|
//TQString max(trailing.section(' ',5,5));
|
|
server->appendStatusMessage(i18n("Users"),i18n("Current users on the network: %1").arg(current));
|
|
break;
|
|
}
|
|
case RPL_LOCALUSERS: // Current local users: 589 Max: 845
|
|
{
|
|
TQString current(trailing.section(' ',3));
|
|
//TQString max(trailing.section(' ',5,5));
|
|
server->appendStatusMessage(i18n("Users"),i18n("Current users on %1: %2.").arg(prefix).arg(current));
|
|
break;
|
|
}
|
|
case RPL_ISON:
|
|
{
|
|
// Tell server to start the next notify timer round
|
|
emit notifyResponse(trailing);
|
|
break;
|
|
}
|
|
case RPL_AWAY:
|
|
{
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[1]);
|
|
if(nickInfo)
|
|
{
|
|
nickInfo->setAway(true);
|
|
if( nickInfo->getAwayMessage() == trailing )
|
|
break;
|
|
nickInfo->setAwayMessage(trailing);
|
|
}
|
|
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Away"),i18n("%1 is away: %2")
|
|
.arg(parameterList[1]).arg(trailing)
|
|
);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case RPL_INVITING:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Invite"),
|
|
i18n("You invited %1 to channel %2.")
|
|
.arg(parameterList[1]).arg(parameterList[2])
|
|
);
|
|
break;
|
|
}
|
|
//Sample WHOIS response
|
|
//"/WHOIS psn"
|
|
//[19:11] :zahn.freenode.net 311 PhantomsDad psn ~psn h106n2fls23o1068.bredband.comhem.se * :Peter Simonsson
|
|
//[19:11] :zahn.freenode.net 319 PhantomsDad psn :#kde-devel #koffice
|
|
//[19:11] :zahn.freenode.net 312 PhantomsDad psn irc.freenode.net :http://freenode.net/
|
|
//[19:11] :zahn.freenode.net 301 PhantomsDad psn :away
|
|
//[19:11] :zahn.freenode.net 320 PhantomsDad psn :is an identified user
|
|
//[19:11] :zahn.freenode.net 317 PhantomsDad psn 4921 1074973024 :seconds idle, signon time
|
|
//[19:11] :zahn.freenode.net 318 PhantomsDad psn :End of /WHOIS list.
|
|
case RPL_WHOISUSER:
|
|
{
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[1]);
|
|
if(nickInfo)
|
|
{
|
|
nickInfo->setHostmask(i18n("%1@%2").arg(parameterList[2]).arg(parameterList[3]));
|
|
nickInfo->setRealName(trailing);
|
|
}
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
// escape html tags
|
|
TQString escapedRealName(trailing);
|
|
escapedRealName.replace("<","<").replace(">",">");
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is %2@%3 (%4)")
|
|
.arg(parameterList[1])
|
|
.arg(parameterList[2])
|
|
.arg(parameterList[3])
|
|
.arg(escapedRealName), false); // Don't parse any urls
|
|
}
|
|
else
|
|
{
|
|
// This WHOIS was requested by Server for DNS resolve purposes; try to resolve the host
|
|
if(getAutomaticRequest("DNS",parameterList[1])==1)
|
|
{
|
|
KNetwork::KResolverResults resolved = KNetwork::KResolver::resolve(parameterList[3],"");
|
|
if(resolved.error() == KResolver::NoError && resolved.size() > 0)
|
|
{
|
|
TQString ip = resolved.first().address().nodeName();
|
|
server->appendMessageToFrontmost(i18n("DNS"),
|
|
i18n("Resolved %1 (%2) to address: %3")
|
|
.arg(parameterList[1])
|
|
.arg(parameterList[3])
|
|
.arg(ip)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),
|
|
i18n("Unable to resolve address for %1 (%2)")
|
|
.arg(parameterList[1])
|
|
.arg(parameterList[3])
|
|
);
|
|
}
|
|
|
|
// Clear this from the automaticRequest list so it works repeatedly
|
|
setAutomaticRequest("DNS", parameterList[1], false);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
// From a WHOIS.
|
|
//[19:11] :zahn.freenode.net 320 PhantomsDad psn :is an identified user
|
|
case RPL_WHOISIDENTIFY:
|
|
case RPL_IDENTIFIED:
|
|
{
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[1]);
|
|
if(nickInfo)
|
|
{
|
|
nickInfo->setIdentified(true);
|
|
}
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
// Prints "psn is an identified user"
|
|
//server->appendStatusMessage(i18n("Whois"),parameterList.join(" ").section(' ',1)+' '+trailing);
|
|
// The above line works fine, but can't be i18n'ised. So use the below instead.. I hope this is okay.
|
|
server->appendMessageToFrontmost(i18n("Whois"), i18n("%1 is an identified user.").arg(parameterList[1]));
|
|
}
|
|
break;
|
|
}
|
|
// Sample WHO response
|
|
//"/WHO #lounge"
|
|
//[21:39] [352] #lounge jasmine bots.worldforge.org irc.worldforge.org jasmine H 0 jasmine
|
|
//[21:39] [352] #lounge ~Nottingha worldforge.org irc.worldforge.org SherwoodSpirit H 0 Arboreal Entity
|
|
case RPL_WHOREPLY:
|
|
{
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[5]);
|
|
// G=away G@=away,op G+=away,voice
|
|
bool bAway = parameterList[6].upper().startsWith("G");
|
|
if(nickInfo)
|
|
{
|
|
nickInfo->setHostmask(i18n("%1@%2").arg(parameterList[2]).arg(parameterList[3]));
|
|
//Strip off the "0 "
|
|
nickInfo->setRealName(trailing.section(" ", 1));
|
|
nickInfo->setAway(bAway);
|
|
if(!bAway)
|
|
{
|
|
nickInfo->setAwayMessage(TQString());
|
|
}
|
|
}
|
|
// Display message only if this was not an automatic request.
|
|
if(!whoRequestList.isEmpty()) // for safe
|
|
{
|
|
if(getAutomaticRequest("WHO",whoRequestList.front())==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Who"),
|
|
i18n("%1 is %2@%3 (%4)%5").arg(parameterList[5])
|
|
.arg(parameterList[2])
|
|
.arg(parameterList[3])
|
|
.arg(trailing.section(" ", 1))
|
|
.arg(bAway?i18n(" (Away)"):TQString())
|
|
, false); // Don't parse as url
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case RPL_ENDOFWHO:
|
|
{
|
|
if(!whoRequestList.isEmpty())
|
|
{ // for safety
|
|
TQStringList::iterator it = whoRequestList.find(parameterList[1].lower());
|
|
|
|
if(it != whoRequestList.end())
|
|
{
|
|
if(getAutomaticRequest("WHO", *it) == 0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Who"),
|
|
i18n("End of /WHO list for %1")
|
|
.arg(parameterList[1]));
|
|
}
|
|
else
|
|
{
|
|
setAutomaticRequest("WHO", *it, false);
|
|
}
|
|
|
|
whoRequestList.remove(it);
|
|
}
|
|
else
|
|
{
|
|
// whoReauestList seems to be broken.
|
|
kdDebug() << "InputFilter::parseServerCommand(): RPL_ENDOFWHO: malformed ENDOFWHO. retrieved: "
|
|
<< parameterList[1] << " expected: " << whoRequestList.front()
|
|
<< endl;
|
|
whoRequestList.clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
kdDebug() << "InputFilter::parseServerCommand(): RPL_ENDOFWHO: unexpected ENDOFWHO. retrieved: "
|
|
<< parameterList[1]
|
|
<< endl;
|
|
}
|
|
|
|
emit endOfWho(parameterList[1]);
|
|
break;
|
|
}
|
|
case RPL_WHOISCHANNELS:
|
|
{
|
|
TQStringList userChannels,voiceChannels,opChannels,halfopChannels,ownerChannels,adminChannels;
|
|
|
|
// get a list of all channels the user is in
|
|
TQStringList channelList=TQStringList::split(' ',trailing);
|
|
channelList.sort();
|
|
|
|
// split up the list in channels where they are operator / user / voice
|
|
for(unsigned int index=0; index < channelList.count(); index++)
|
|
{
|
|
TQString lookChannel=channelList[index];
|
|
if(lookChannel.startsWith("*") || lookChannel.startsWith("&"))
|
|
{
|
|
adminChannels.append(lookChannel.mid(1));
|
|
server->setChannelNick(lookChannel.mid(1), parameterList[1], 16);
|
|
}
|
|
// See bug #97354 part 2
|
|
else if((lookChannel.startsWith("!") || lookChannel.startsWith("~")) && server->isAChannel(lookChannel.mid(1)))
|
|
{
|
|
ownerChannels.append(lookChannel.mid(1));
|
|
server->setChannelNick(lookChannel.mid(1), parameterList[1], 8);
|
|
}
|
|
// See bug #97354 part 1
|
|
else if(lookChannel.startsWith("@+"))
|
|
{
|
|
opChannels.append(lookChannel.mid(2));
|
|
server->setChannelNick(lookChannel.mid(2), parameterList[1], 4);
|
|
}
|
|
else if(lookChannel.startsWith("@"))
|
|
{
|
|
opChannels.append(lookChannel.mid(1));
|
|
server->setChannelNick(lookChannel.mid(1), parameterList[1], 4);
|
|
}
|
|
else if(lookChannel.startsWith("%"))
|
|
{
|
|
halfopChannels.append(lookChannel.mid(1));
|
|
server->setChannelNick(lookChannel.mid(1), parameterList[1], 2);
|
|
}
|
|
else if(lookChannel.startsWith("+"))
|
|
{
|
|
voiceChannels.append(lookChannel.mid(1));
|
|
server->setChannelNick(lookChannel.mid(1), parameterList[1], 1);
|
|
}
|
|
else
|
|
{
|
|
userChannels.append(lookChannel);
|
|
server->setChannelNick(lookChannel, parameterList[1], 0);
|
|
}
|
|
} // endfor
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
if(userChannels.count())
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is a user on channels: %2")
|
|
.arg(parameterList[1])
|
|
.arg(userChannels.join(" "))
|
|
);
|
|
}
|
|
if(voiceChannels.count())
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 has voice on channels: %2")
|
|
.arg(parameterList[1]).arg(voiceChannels.join(" "))
|
|
);
|
|
}
|
|
if(halfopChannels.count())
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is a halfop on channels: %2")
|
|
.arg(parameterList[1]).arg(halfopChannels.join(" "))
|
|
);
|
|
}
|
|
if(opChannels.count())
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is an operator on channels: %2")
|
|
.arg(parameterList[1]).arg(opChannels.join(" "))
|
|
);
|
|
}
|
|
if(ownerChannels.count())
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is owner of channels: %2")
|
|
.arg(parameterList[1]).arg(ownerChannels.join(" "))
|
|
);
|
|
}
|
|
if(adminChannels.count())
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is admin on channels: %2")
|
|
.arg(parameterList[1]).arg(adminChannels.join(" "))
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case RPL_WHOISSERVER:
|
|
{
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[1]);
|
|
if(nickInfo)
|
|
{
|
|
nickInfo->setNetServer(parameterList[2]);
|
|
nickInfo->setNetServerInfo(trailing);
|
|
// Clear the away state on assumption that if nick is away, this message will be followed
|
|
// by a 301 RPL_AWAY message. Not necessary a invalid assumption, but what can we do?
|
|
nickInfo->setAway(false);
|
|
nickInfo->setAwayMessage(TQString());
|
|
}
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is online via %2 (%3).").arg(parameterList[1])
|
|
.arg(parameterList[2]).arg(trailing)
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
case RPL_WHOISHELPER:
|
|
{
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 is available for help.")
|
|
.arg(parameterList[1])
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
case RPL_WHOISOPERATOR:
|
|
{
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
if (trailing.lower().simplifyWhiteSpace().startsWith("is an irc operator"))
|
|
server->appendMessageToFrontmost(i18n("Whois"),i18n("%1 is an IRC Operator.").arg(parameterList[1]));
|
|
else
|
|
server->appendMessageToFrontmost(i18n("Whois"),TQString("%1 %2").arg(parameterList[1]).arg(trailing));
|
|
}
|
|
break;
|
|
}
|
|
case RPL_WHOISIDLE:
|
|
{
|
|
// get idle time in seconds
|
|
long seconds=parameterList[2].toLong();
|
|
long minutes=seconds/60;
|
|
long hours =minutes/60;
|
|
long days =hours/24;
|
|
|
|
// if idle time is longer than a day
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
if(days)
|
|
{
|
|
const TQString daysString = i18n("1 day", "%n days", days);
|
|
const TQString hoursString = i18n("1 hour", "%n hours", (hours % 24));
|
|
const TQString minutesString = i18n("1 minute", "%n minutes", (minutes % 60));
|
|
const TQString secondsString = i18n("1 second", "%n seconds", (seconds % 60));
|
|
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 = name of person, %2 = (x days), %3 = (x hours), %4 = (x minutes), %5 = (x seconds)",
|
|
"%1 has been idle for %2, %3, %4, and %5.")
|
|
.arg(parameterList[1])
|
|
.arg(daysString).arg(hoursString).arg(minutesString).arg(secondsString)
|
|
);
|
|
// or longer than an hour
|
|
}
|
|
else if(hours)
|
|
{
|
|
const TQString hoursString = i18n("1 hour", "%n hours", hours);
|
|
const TQString minutesString = i18n("1 minute", "%n minutes", (minutes % 60));
|
|
const TQString secondsString = i18n("1 second", "%n seconds", (seconds % 60));
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 = name of person, %2 = (x hours), %3 = (x minutes), %4 = (x seconds)",
|
|
"%1 has been idle for %2, %3, and %4.")
|
|
.arg(parameterList[1])
|
|
.arg(hoursString).arg(minutesString).arg(secondsString)
|
|
);
|
|
// or longer than a minute
|
|
}
|
|
else if(minutes)
|
|
{
|
|
const TQString minutesString = i18n("1 minute", "%n minutes", minutes);
|
|
const TQString secondsString = i18n("1 second", "%n seconds", (seconds % 60));
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 = name of person, %2 = (x minutes), %3 = (x seconds)",
|
|
"%1 has been idle for %2 and %3.")
|
|
.arg(parameterList[1])
|
|
.arg(minutesString).arg(secondsString)
|
|
);
|
|
// or just some seconds
|
|
}
|
|
else
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 has been idle for 1 second.", "%1 has been idle for %n seconds.", seconds)
|
|
.arg(parameterList[1])
|
|
);
|
|
}
|
|
}
|
|
|
|
if(parameterList.count()==4)
|
|
{
|
|
TQDateTime when;
|
|
when.setTime_t(parameterList[3].toUInt());
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[1]);
|
|
if(nickInfo)
|
|
{
|
|
nickInfo->setOnlineSince(when);
|
|
}
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),
|
|
i18n("%1 has been online since %2.")
|
|
.arg(parameterList[1]).arg(when.toString(Qt::LocalDate))
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case RPL_ENDOFWHOIS:
|
|
{
|
|
//NickInfo* nickInfo = server->getNickInfo(parameterList[1]);
|
|
// Display message only if this was not an automatic request.
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Whois"),i18n("End of WHOIS list."));
|
|
}
|
|
// was this an automatic request?
|
|
if(getAutomaticRequest("WHOIS",parameterList[1])!=0)
|
|
{
|
|
setAutomaticRequest("WHOIS",parameterList[1],false);
|
|
}
|
|
break;
|
|
}
|
|
case RPL_USERHOST:
|
|
{
|
|
// iterate over all nick/masks in reply
|
|
TQStringList uhosts=TQStringList::split(" ",trailing);
|
|
|
|
for(unsigned int index=0;index<uhosts.count();index++)
|
|
{
|
|
// extract nickname and hostmask from reply
|
|
TQString nick(uhosts[index].section('=',0,0));
|
|
TQString mask(uhosts[index].section('=',1));
|
|
|
|
// get away and IRC operator flags
|
|
bool away=(mask[0]=='-');
|
|
bool ircOp=(nick[nick.length()-1]=='*');
|
|
|
|
// cut flags from nick/hostmask
|
|
mask=mask.mid(1);
|
|
if(ircOp)
|
|
{
|
|
nick=nick.left(nick.length()-1);
|
|
}
|
|
|
|
// inform server of this user's data
|
|
emit userhost(nick,mask,away,ircOp);
|
|
|
|
// display message only if this was no automatic request
|
|
if(getAutomaticRequest("USERHOST",nick)==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Userhost"),
|
|
i18n("%1 = nick, %2 = shows if nick is op, %3 = hostmask, %4 = shows away", "%1%2 is %3%4.")
|
|
.arg(nick)
|
|
.arg((ircOp) ? i18n(" (IRC Operator)") : TQString())
|
|
.arg(mask)
|
|
.arg((away) ? i18n(" (away)") : TQString()));
|
|
}
|
|
|
|
// was this an automatic request?
|
|
if(getAutomaticRequest("USERHOST",nick)!=0)
|
|
{
|
|
setAutomaticRequest("USERHOST",nick,false);
|
|
}
|
|
} // for
|
|
break;
|
|
}
|
|
case RPL_LISTSTART: //FIXME This reply is obsolete!!!
|
|
{
|
|
if(getAutomaticRequest("LIST",TQString())==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("List"),i18n("List of channels:"));
|
|
}
|
|
break;
|
|
}
|
|
case RPL_LIST:
|
|
{
|
|
if(getAutomaticRequest("LIST",TQString())==0)
|
|
{
|
|
TQString message;
|
|
message=i18n("%1 (%n user): %2", "%1 (%n users): %2", parameterList[2].toInt());
|
|
server->appendMessageToFrontmost(i18n("List"),message.arg(parameterList[1]).arg(trailing));
|
|
}
|
|
else // send them to /LIST window
|
|
{
|
|
emit addToChannelList(parameterList[1],parameterList[2].toInt(),trailing);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case RPL_LISTEND:
|
|
{
|
|
// was this an automatic request?
|
|
if(getAutomaticRequest("LIST",TQString())==0)
|
|
{
|
|
server->appendMessageToFrontmost(i18n("List"),i18n("End of channel list."));
|
|
}
|
|
else
|
|
{
|
|
setAutomaticRequest("LIST",TQString(),false);
|
|
}
|
|
break;
|
|
}
|
|
case RPL_NOWAWAY:
|
|
{
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[0]);
|
|
if (nickInfo) nickInfo->setAway(true);
|
|
|
|
server->setAway(true);
|
|
|
|
break;
|
|
}
|
|
case RPL_UNAWAY:
|
|
{
|
|
NickInfo* nickInfo = server->getNickInfo(parameterList[0]);
|
|
|
|
if (nickInfo)
|
|
{
|
|
nickInfo->setAway(false);
|
|
nickInfo->setAwayMessage(TQString());
|
|
}
|
|
|
|
server->setAway(false);
|
|
|
|
break;
|
|
}
|
|
case RPL_BANLIST:
|
|
{
|
|
if (getAutomaticRequest("BANLIST", parameterList[1]))
|
|
{
|
|
server->addBan(parameterList[1], parameterList.join(" ").section(' ', 2, 4));
|
|
} else {
|
|
TQDateTime when;
|
|
when.setTime_t(parameterList[4].toUInt());
|
|
|
|
server->appendMessageToFrontmost(i18n("BanList:%1").arg(parameterList[1]), i18n("BanList message: e.g. *!*@aol.com set by MrGrim on <date>", "%1 set by %2 on %3").arg(parameterList[2]).arg(parameterList[3].section('!', 0, 0)).arg(when.toString(Qt::LocalDate)));
|
|
}
|
|
break;
|
|
}
|
|
case RPL_ENDOFBANLIST:
|
|
{
|
|
if (getAutomaticRequest("BANLIST", parameterList[1]))
|
|
{
|
|
setAutomaticRequest("BANLIST", parameterList[1], false);
|
|
} else {
|
|
server->appendMessageToFrontmost(i18n("BanList:%1").arg(parameterList[1]), i18n("End of Ban List."));
|
|
}
|
|
break;
|
|
}
|
|
case ERR_NOCHANMODES:
|
|
{
|
|
ChatWindow *chatwindow = server->getChannelByName(parameterList[1]);
|
|
if(chatwindow)
|
|
{
|
|
chatwindow->appendServerMessage(i18n("Channel"), trailing);
|
|
}
|
|
else // We couldn't join the channel , so print the error. with [#channel] : <Error Message>
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Channel"), trailing);
|
|
}
|
|
break;
|
|
}
|
|
case ERR_NOSUCHSERVER:
|
|
{
|
|
//Some servers don't know their name, so they return an error instead of the PING data
|
|
if (getLagMeasuring() && trailing.startsWith(prefix))
|
|
{
|
|
server->pongReceived();
|
|
}
|
|
break;
|
|
}
|
|
case ERR_UNAVAILRESOURCE:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("%1 is currently unavailable.").arg(parameterList[1]));
|
|
|
|
break;
|
|
}
|
|
case RPL_HIGHCONNECTCOUNT:
|
|
case RPL_LUSERCLIENT:
|
|
case RPL_LUSEROP:
|
|
case RPL_LUSERUNKNOWN:
|
|
case RPL_LUSERCHANNELS:
|
|
case RPL_LUSERME:
|
|
{
|
|
server->appendStatusMessage(i18n("Users"), parameterList.join(" ").section(' ',1) + ' '+trailing);
|
|
break;
|
|
}
|
|
case ERR_UNKNOWNCOMMAND:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("%1: Unknown command.").arg(parameterList[1]));
|
|
|
|
break;
|
|
}
|
|
case ERR_NOTREGISTERED:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("Not registered."));
|
|
|
|
break;
|
|
}
|
|
case ERR_NEEDMOREPARAMS:
|
|
{
|
|
server->appendMessageToFrontmost(i18n("Error"),i18n("%1: This command requires more parameters.").arg(parameterList[1]));
|
|
|
|
break;
|
|
}
|
|
case RPL_CAPAB: // Special freenode reply afaik
|
|
{
|
|
// Disable as we don't use this for anything yet
|
|
if(trailing.contains("IDENTIFY-MSG"))
|
|
{
|
|
server->enableIdentifyMsg(true);
|
|
break;
|
|
}
|
|
|
|
/* don't break; - this is also used as RPL_DATASTR on ircu and some others */
|
|
}
|
|
// FALLTHROUGH to default to let the error display otherwise
|
|
default:
|
|
{
|
|
// All yet unknown messages go into the frontmost window without the
|
|
// preceding nickname
|
|
server->appendMessageToFrontmost(command, parameterList.join(" ").section(' ',1) + ' '+trailing);
|
|
}
|
|
} // end of numeric switch
|
|
}
|
|
}
|
|
|
|
void InputFilter::parseModes(const TQString &sourceNick, const TQStringList ¶meterList)
|
|
{
|
|
const TQString modestring=parameterList[1];
|
|
|
|
if (!isAChannel(parameterList[0]))
|
|
{
|
|
TQString message;
|
|
if (parameterList[0] == server->getNickname())
|
|
{
|
|
if (sourceNick == server->getNickname())
|
|
{
|
|
//XXX someone might care about the potentially unnecessary plural here
|
|
message = i18n("You have set personal modes: ") + modestring;
|
|
}
|
|
else
|
|
{ //XXX someone might care about the potentially unnecessary plural here
|
|
message = TQString("%1 %2 %3").arg(sourceNick).arg(i18n("has changed your personal modes:")).arg(modestring);
|
|
}
|
|
}
|
|
if (!message.isEmpty())
|
|
server->appendStatusMessage(i18n("Mode"), message);
|
|
return;
|
|
}
|
|
|
|
bool plus=false;
|
|
int parameterIndex=0;
|
|
// List of modes that need a parameter (note exception with -k and -l)
|
|
// Mode q is quiet on freenode and acts like b... if this is a channel mode on other
|
|
// networks then more logic is needed here. --MrGrim
|
|
TQString parameterModes="aAoOvhkbleIq";
|
|
TQString message = sourceNick + i18n(" sets mode: ") + modestring;
|
|
|
|
for(unsigned int index=0;index<modestring.length();index++)
|
|
{
|
|
unsigned char mode=modestring[index];
|
|
TQString parameter;
|
|
|
|
// Check if this is a mode or a +/- qualifier
|
|
if(mode=='+' || mode=='-')
|
|
{
|
|
plus=(mode=='+');
|
|
}
|
|
else
|
|
{
|
|
// Check if this was a parameter mode
|
|
if(parameterModes.find(mode)!=-1)
|
|
{
|
|
// Check if the mode actually wants a parameter. -k and -l do not!
|
|
if(plus || (!plus && (mode!='k') && (mode!='l')))
|
|
{
|
|
// Remember the mode parameter
|
|
parameter=parameterList[2+parameterIndex];
|
|
message += ' ' + parameter;
|
|
// Switch to next parameter
|
|
++parameterIndex;
|
|
}
|
|
}
|
|
// Let the channel update its modes
|
|
if(parameter.isEmpty()) // XXX Check this to ensure the braces are in the correct place
|
|
{
|
|
kdDebug() << "in updateChannelMode. sourceNick: '" << sourceNick << "' parameterlist: '"
|
|
<< parameterList.join(", ") << "'"
|
|
<< endl;
|
|
}
|
|
server->updateChannelMode(sourceNick,parameterList[0],mode,plus,parameter);
|
|
}
|
|
} // endfor
|
|
|
|
if (Preferences::useLiteralModes())
|
|
{
|
|
server->appendCommandMessageToChannel(parameterList[0],i18n("Mode"),message);
|
|
}
|
|
}
|
|
|
|
// # & + and ! are *often*, but not necessarily, Channel identifiers. + and ! are non-RFC,
|
|
// so if a server doesn't offer 005 and supports + and ! channels, I think thats broken behaviour
|
|
// on their part - not ours. --Argonel
|
|
bool InputFilter::isAChannel(const TQString &check)
|
|
{
|
|
Q_ASSERT(server);
|
|
// if we ever see the assert, we need the ternary
|
|
return server? server->isAChannel(check) : TQString("#&").contains(check.at(0));
|
|
}
|
|
|
|
bool InputFilter::isIgnore(const TQString &sender, Ignore::Type type)
|
|
{
|
|
bool doIgnore = false;
|
|
|
|
TQPtrList<Ignore> list = Preferences::ignoreList();
|
|
|
|
for(unsigned int index =0; index<list.count(); index++)
|
|
{
|
|
Ignore* item = list.at(index);
|
|
TQRegExp ignoreItem(TQString(TQRegExp::escape(item->getName())).replace("\\*", "(.*)"),false);
|
|
if (ignoreItem.exactMatch(sender) && (item->getFlags() & type))
|
|
doIgnore = true;
|
|
if (ignoreItem.exactMatch(sender) && (item->getFlags() & Ignore::Exception))
|
|
return false;
|
|
}
|
|
|
|
return doIgnore;
|
|
}
|
|
|
|
void InputFilter::reset()
|
|
{
|
|
automaticRequest.clear();
|
|
whoRequestList.clear();
|
|
}
|
|
|
|
void InputFilter::setAutomaticRequest(const TQString& command, const TQString& name, bool yes)
|
|
{
|
|
automaticRequest[command][name.lower()] += (yes) ? 1 : -1;
|
|
if(automaticRequest[command][name.lower()]<0)
|
|
{
|
|
kdDebug() << "InputFilter::automaticRequest( " << command << ", " << name
|
|
<< " ) was negative! Resetting!"
|
|
<< endl;
|
|
automaticRequest[command][name.lower()]=0;
|
|
}
|
|
}
|
|
|
|
int InputFilter::getAutomaticRequest(const TQString& command, const TQString& name)
|
|
{
|
|
return automaticRequest[command][name.lower()];
|
|
}
|
|
|
|
void InputFilter::addWhoRequest(const TQString& name) { whoRequestList << name.lower(); }
|
|
|
|
bool InputFilter::isWhoRequestUnderProcess(const TQString& name) { return (whoRequestList.contains(name.lower())>0); }
|
|
|
|
void InputFilter::setLagMeasuring(bool state) { lagMeasuring=state; }
|
|
|
|
bool InputFilter::getLagMeasuring() { return lagMeasuring; }
|
|
|
|
void InputFilter::parsePrivMsg(const TQString& prefix,
|
|
const TQStringList& parameterList,
|
|
const TQString& trailing)
|
|
{
|
|
int pos = prefix.find("!");
|
|
TQString source;
|
|
TQString sourceHostmask;
|
|
TQString message(trailing);
|
|
|
|
if(pos > 0)
|
|
{
|
|
source = prefix.left(pos);
|
|
sourceHostmask = prefix.mid(pos + 1);
|
|
}
|
|
else
|
|
{
|
|
source = prefix;
|
|
}
|
|
|
|
KonversationApplication* konv_app = static_cast<KonversationApplication*>(kapp);
|
|
message = konv_app->doAutoreplace(message, false);
|
|
|
|
if(isAChannel(parameterList[0]))
|
|
{
|
|
if(!isIgnore(prefix, Ignore::Channel))
|
|
{
|
|
Channel* channel = server->getChannelByName(parameterList[0]);
|
|
if(channel)
|
|
{
|
|
channel->append(source, message);
|
|
|
|
if(source != server->getNickname())
|
|
{
|
|
TQRegExp regexp("(^|[^\\d\\w])" +
|
|
TQRegExp::escape(server->loweredNickname()) +
|
|
"([^\\d\\w]|$)");
|
|
regexp.setCaseSensitive(false);
|
|
if(message.find(regexp) !=-1 )
|
|
{
|
|
konv_app->notificationHandler()->nick(channel,
|
|
source, message);
|
|
}
|
|
else
|
|
{
|
|
konv_app->notificationHandler()->message(channel,
|
|
source, message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!isIgnore(prefix,Ignore::Query))
|
|
{
|
|
NickInfoPtr nickinfo = server->obtainNickInfo(source);
|
|
nickinfo->setHostmask(sourceHostmask);
|
|
|
|
// Create a new query (server will check for dupes)
|
|
query = server->addQuery(nickinfo, false /*we didn't initiate this*/ );
|
|
|
|
// send action to query
|
|
query->appendQuery(source, message);
|
|
|
|
if(source != server->getNickname() && query)
|
|
{
|
|
TQRegExp regexp("(^|[^\\d\\w])" +
|
|
TQRegExp::escape(server->loweredNickname()) +
|
|
"([^\\d\\w]|$)");
|
|
regexp.setCaseSensitive(false);
|
|
if(message.find(regexp) !=-1 )
|
|
{
|
|
konv_app->notificationHandler()->nick(query,
|
|
source, message);
|
|
}
|
|
else
|
|
{
|
|
konv_app->notificationHandler()->queryMessage(query,
|
|
source, message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#include "inputfilter.moc"
|
|
|
|
// kate: space-indent on; tab-width 4; indent-width 4; mixed-indent off; replace-tabs on;
|
|
// vim: set et sw=4 ts=4 cino=l1,cs,U1:
|