summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opieirc/ircmessageparser.cpp33
-rw-r--r--noncore/net/opieirc/ircmessageparser.h3
-rw-r--r--noncore/net/opieirc/ircoutput.h3
-rw-r--r--noncore/net/opieirc/ircservertab.cpp12
4 files changed, 49 insertions, 2 deletions
diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp
index 5c70753..d1b70a5 100644
--- a/noncore/net/opieirc/ircmessageparser.cpp
+++ b/noncore/net/opieirc/ircmessageparser.cpp
@@ -1,62 +1,65 @@
#include <qtextstream.h>
#include "ircmessageparser.h"
#include "ircversion.h"
/* Lookup table for literal commands */
IRCLiteralMessageParserStruct IRCMessageParser::literalParserProcTable[] = {
{ "PING", FUNC(parseLiteralPing) },
{ "NOTICE", FUNC(parseLiteralNotice) },
{ "JOIN", FUNC(parseLiteralJoin) },
{ "PRIVMSG", FUNC(parseLiteralPrivMsg) },
{ "NICK", FUNC(parseLiteralNick) },
{ "PART", FUNC(parseLiteralPart) },
{ "QUIT", FUNC(parseLiteralQuit) },
{ "ERROR", FUNC(parseLiteralError) },
{ "ERROR:", FUNC(parseLiteralError) },
{ "MODE", FUNC(parseLiteralMode) },
{ "KICK", FUNC(parseLiteralKick) },
+ { "TOPIC", FUNC(parseLiteralTopic) },
{ 0 , 0 }
};
/* Lookup table for literal commands */
IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = {
{ "PING", FUNC(parseCTCPPing) },
{ "VERSION", FUNC(parseCTCPVersion) },
{ "ACTION", FUNC(parseCTCPAction) },
{ 0 , 0 }
};
/* Lookup table for numerical commands */
IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = {
{ 1, FUNC(parseNumerical001) }, // RPL_WELCOME
{ 2, FUNC(parseNumerical002) }, // RPL_YOURHOST
{ 3, FUNC(parseNumerical003) }, // RPL_CREATED
{ 4, FUNC(parseNumerical004) }, // RPL_MYINFO
{ 5, FUNC(parseNumerical005) }, // RPL_BOUNCE, RPL_PROTOCTL
{ 251, FUNC(parseNumericalStats) }, // RPL_LUSERCLIENT
{ 254, FUNC(nullFunc)}, // RPL_LUSERCHANNELS
{ 255, FUNC(parseNumericalStats) }, // RPL_LUSERNAME
+ { 332, FUNC(parseNumericalTopic) }, // RPL_TOPIC
+ { 333, FUNC(parseNumericalTopicWhoTime) }, // RPL_TOPICWHOTIME
{ 353, FUNC(parseNumericalNames) }, // RPL_NAMREPLY
{ 366, FUNC(parseNumericalEndOfNames) }, // RPL_ENDOFNAMES
{ 375, FUNC(parseNumericalStats) }, // RPL_MOTDSTART
{ 372, FUNC(parseNumericalStats) }, // RPL_MOTD
{ 376, FUNC(parseNumericalStats) }, // RPL_ENDOFMOTD
{ 377, FUNC(parseNumericalStats) }, // RPL_MOTD2
{ 378, FUNC(parseNumericalStats) }, // RPL_MOTD3
{ 401, FUNC(parseNumericalNoSuchNick) }, // ERR_NOSUCHNICK
{ 406, FUNC(parseNumericalNoSuchNick) }, // ERR_WASNOSUCHNICK
{ 412, FUNC(parseNumericalStats) }, // ERR_NOTEXTTOSEND
{ 433, FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE
{ 0, 0 }
};
IRCMessageParser::IRCMessageParser(IRCSession *session) {
m_session = session;
}
void IRCMessageParser::parse(IRCMessage *message) {
/* Find out what kind of message we have here and call the appropriate handler using
the parser tables. If no handler can be found, print out an error message */
if (message->isNumerical()) {
for (int i=0; i<numericalParserProcTable[i].commandNumber; i++) {
if (message->commandNumber() == numericalParserProcTable[i].commandNumber) {
@@ -170,49 +173,49 @@ void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
IRCPerson *person = m_session->getPerson(mask.nick());
if (!person) {
/* Person not yet known, create and add to the current session */
person = new IRCPerson(message->prefix());
m_session->addPerson(person);
}
IRCOutput output(OUTPUT_QUERYPRIVMSG, message->param(1));
output.addParam(person);
emit outputReady(output);
} else if (message->param(0).at(0) == '#') {
/* IRC Channel message detected, verify sender, channel and display it */
IRCChannel *channel = m_session->getChannel(message->param(0));
if (channel) {
IRCPerson mask(message->prefix());
IRCChannelPerson *person = channel->getPerson(mask.nick());
if (person) {
IRCOutput output(OUTPUT_CHANPRIVMSG, message->param(1));
output.addParam(channel);
output.addParam(person);
emit outputReady(output);
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown sender")));
}
} else {
- emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown channel")));
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown channel ") + message->param(0)));
}
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received PRIVMSG of unknown type")));
}
}
void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
IRCPerson mask(message->prefix());
if (mask.nick() == m_session->m_server->nick()) {
/* We are changing our nickname */
m_session->m_server->setNick(message->param(0));
IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as ")+message->param(0));
output.addParam(0);
emit outputReady(output);
} else {
/* Someone else is */
IRCPerson *person = m_session->getPerson(mask.nick());
if (person) {
IRCOutput output(OUTPUT_NICKCHANGE, mask.nick() + tr(" is now known as ") + message->param(0));
output.addParam(person);
emit outputReady(output);
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
@@ -221,48 +224,60 @@ void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
}
void IRCMessageParser::parseLiteralQuit(IRCMessage *message) {
IRCPerson mask(message->prefix());
IRCPerson *person = m_session->getPerson(mask.nick());
if (person) {
QList<IRCChannel> channels;
m_session->getChannelsByPerson(person, channels);
QListIterator<IRCChannel> it(channels);
for (;it.current(); ++it) {
IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick());
it.current()->removePerson(chanperson);
delete chanperson;
}
m_session->removePerson(person);
IRCOutput output(OUTPUT_QUIT, mask.nick() + tr(" has quit ") + "(" + message->param(0) + ")");
output.addParam(person);
emit outputReady(output);
delete person;
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person quit - desynchronized?")));
}
}
+void IRCMessageParser::parseLiteralTopic(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+ IRCChannel *channel = m_session->getChannel(message->param(0));
+ if (channel) {
+ IRCOutput output(OUTPUT_TOPIC, mask.nick() + tr(" changed topic to ") + "\"" + message->param(1) + "\"");
+ output.addParam(channel);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel topic - desynchronized?")));
+ }
+}
+
void IRCMessageParser::parseLiteralError(IRCMessage *message) {
emit outputReady(IRCOutput(OUTPUT_ERROR, message->allParameters()));
}
void IRCMessageParser::parseCTCPPing(IRCMessage *message) {
IRCPerson mask(message->prefix());
m_session->m_connection->sendCTCP(mask.nick(), "PING " + message->allParameters());
emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING from ")+mask.nick()));
}
void IRCMessageParser::parseCTCPVersion(IRCMessage *message) {
IRCPerson mask(message->prefix());
m_session->m_connection->sendCTCP(mask.nick(), APP_VERSION " " APP_COPYSTR);
emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP VERSION from ")+mask.nick()));
}
void IRCMessageParser::parseCTCPAction(IRCMessage *message) {
IRCPerson mask(message->prefix());
QString dest = message->ctcpDestination();
if (dest.startsWith("#")) {
IRCChannel *channel = m_session->getChannel(dest);
if (channel) {
IRCChannelPerson *person = channel->getPerson(mask.nick());
if (person) {
@@ -463,24 +478,40 @@ void IRCMessageParser::parseNumericalNames(IRCMessage *message) {
void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) {
/* Done syncing to channel */
IRCChannel *channel = m_session->getChannel(message->param(1));
if (channel) {
channel->setHasPeople(TRUE);
/* Yes, we want the names before anything happens inside the GUI */
IRCOutput output(OUTPUT_SELFJOIN, tr("You joined channel ") + channel->channelname());
output.addParam(channel);
emit outputReady(output);
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel")));
}
}
void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname")));
m_session->endSession();
}
void IRCMessageParser::parseNumericalNoSuchNick(IRCMessage *) {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("No such nickname")));
}
+
+void IRCMessageParser::parseNumericalTopic(IRCMessage *message) {
+ IRCChannel *channel = m_session->getChannel(message->param(1));
+ if (channel) {
+ IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + channel->channelname() + " is \"" + message->param(2) + "\""));
+ output.addParam(channel);
+ emit outputReady(output);
+ } else {
+ IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + message->param(1) + " is \"" + message->param(2) + "\""));
+ output.addParam(0);
+ emit outputReady(output);
+ }
+}
+
+void IRCMessageParser::parseNumericalTopicWhoTime(IRCMessage *message) {
+}
diff --git a/noncore/net/opieirc/ircmessageparser.h b/noncore/net/opieirc/ircmessageparser.h
index f774047..c4dd96c 100644
--- a/noncore/net/opieirc/ircmessageparser.h
+++ b/noncore/net/opieirc/ircmessageparser.h
@@ -51,46 +51,49 @@ typedef struct IRCNumericalMessageParserStruct {
class IRCMessageParser : public QObject {
Q_OBJECT
public:
/* Create an IRCMessageParser object */
IRCMessageParser(IRCSession *session);
/* Parse a server message and take the appropriate actions */
void parse(IRCMessage *message);
signals:
/* Used to send commands to the UI (such as displaying text etc) */
void outputReady(IRCOutput output);
private:
/* Parser functions */
void nullFunc(IRCMessage *message);
void parseLiteralPing(IRCMessage *message);
void parseLiteralNotice(IRCMessage *message);
void parseLiteralJoin(IRCMessage *message);
void parseLiteralPrivMsg(IRCMessage *message);
void parseLiteralNick(IRCMessage *message);
void parseLiteralPart(IRCMessage *message);
void parseLiteralQuit(IRCMessage *message);
void parseLiteralError(IRCMessage *message);
void parseLiteralMode(IRCMessage *message);
void parseLiteralKick(IRCMessage *message);
+ void parseLiteralTopic(IRCMessage *message);
void parseNumerical001(IRCMessage *message);
void parseNumerical002(IRCMessage *message);
void parseNumerical003(IRCMessage *message);
void parseNumerical004(IRCMessage *message);
void parseNumerical005(IRCMessage *message);
void parseNumericalStats(IRCMessage *message);
void parseNumericalNames(IRCMessage *message);
void parseNumericalEndOfNames(IRCMessage *message);
void parseNumericalNicknameInUse(IRCMessage *message);
void parseNumericalNoSuchNick(IRCMessage *message);
+ void parseNumericalTopic(IRCMessage *message);
+ void parseNumericalTopicWhoTime(IRCMessage *message);
void parseCTCPPing(IRCMessage *message);
void parseCTCPVersion(IRCMessage *message);
void parseCTCPAction(IRCMessage *message);
protected:
IRCSession *m_session;
/* Parser tables */
static IRCLiteralMessageParserStruct literalParserProcTable[];
static IRCNumericalMessageParserStruct numericalParserProcTable[];
static IRCCTCPMessageParserStruct ctcpParserProcTable[];
};
#endif /* __IRCMESSAGEPARSER_H */
diff --git a/noncore/net/opieirc/ircoutput.h b/noncore/net/opieirc/ircoutput.h
index e8cc524..9c0b8bb 100644
--- a/noncore/net/opieirc/ircoutput.h
+++ b/noncore/net/opieirc/ircoutput.h
@@ -23,49 +23,50 @@
#include <qstring.h>
#include <qlist.h>
#include "ircchannel.h"
/* Types of possible IRC output */
enum IRCOutputType {
OUTPUT_ERROR = -1, /* parameters : none */
OUTPUT_SERVERMESSAGE = 0, /* parameters : none */
OUTPUT_CLIENTMESSAGE = 1, /* parameters : none */
OUTPUT_CHANPRIVMSG = 2, /* parameters : channel (IRCChannel), person (IRCChannelPerson) */
OUTPUT_QUERYPRIVMSG = 3, /* parameters : person (IRCPerson) */
OUTPUT_NICKCHANGE = 4, /* parameters : person (IRCPerson) */
OUTPUT_SELFJOIN = 5, /* parameters : channel (IRCChannel) */
OUTPUT_OTHERJOIN = 6, /* parameters : channel (IRCChannel), person (IRCChannelPerson) */
OUTPUT_SELFPART = 7, /* parameters : channel (IRCChannel) */
OUTPUT_OTHERPART = 8, /* parameters : channel (IRCChannel), person (IRCChannelPerson) */
OUTPUT_QUIT = 9, /* parameters : person (IRCPerson) */
OUTPUT_CONNCLOSE = 10, /* parameters : none */
OUTPUT_CTCP = 11, /* parameters : none */
OUTPUT_SELFKICK = 12, /* parameters : channel (IRCChannel) */
OUTPUT_OTHERKICK = 13, /* parameters : channel (IRCChannel) person (IRCChannelPerson) */
OUTPUT_CHANACTION = 14, /* parameters : channel (IRCChannel) person (IRCChannelPerson) */
OUTPUT_QUERYACTION = 15, /* parameters : person (IRCPerson) */
- OUTPUT_CHANPERSONMODE = 16 /* parameters : channel (IRCCHannel) person (IRCChannelPerson) */
+ OUTPUT_CHANPERSONMODE = 16, /* parameters : channel (IRCCHannel) person (IRCChannelPerson) */
+ OUTPUT_TOPIC = 17 /* parameters : channel (IRCChannel) */
};
/* The IRCOutput class is used as a kind of message which is sent by the
IRC parser to inform the GUI of changes. This could for example be a
channel message or a nickname change */
class IRCOutput {
public:
IRCOutput(IRCOutputType type, QString message);
/* Used to add a parameter to this IRCOutput. Parameters are dependent
on which IRCOutputType we are using (see above) */
void addParam(void *data);
IRCOutputType type();
QString message();
/* Return the message with all HTML code escaped (for example &lt; instead of '<') */
QString htmlMessage();
static QString toHTML(QString message);
void *getParam(int index);
protected:
IRCOutputType m_type;
QString m_message;
QList<void> m_parameters;
diff --git a/noncore/net/opieirc/ircservertab.cpp b/noncore/net/opieirc/ircservertab.cpp
index 4be60ef..aea58a3 100644
--- a/noncore/net/opieirc/ircservertab.cpp
+++ b/noncore/net/opieirc/ircservertab.cpp
@@ -198,48 +198,60 @@ void IRCServerTab::display(IRCOutput output) {
m_queryTabs.append(queryTab);
m_mainWindow->addTab(queryTab);
}
queryTab->display(output);
}
break;
case OUTPUT_SELFPART: {
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
if (channelTab)
m_mainWindow->killTab(channelTab);
}
break;
case OUTPUT_SELFKICK: {
appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>");
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
if (channelTab)
m_mainWindow->killTab(channelTab);
}
break;
case OUTPUT_CHANACTION: {
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
channelTab->appendText("<font color=\"" + m_otherColor + "\">"+output.htmlMessage()+"</font><br>");
}
break;
+ case OUTPUT_TOPIC: {
+ IRCChannel *channel = (IRCChannel *) output.getParam(0);
+ if (channel) {
+ IRCChannelTab *channelTab = getTabForChannel(channel);
+ if (channelTab) {
+ channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
+ return;
+ }
+ }
+ appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
+ }
+ break;
case OUTPUT_QUIT: {
QString nick = ((IRCPerson *)output.getParam(0))->nick();
QListIterator<IRCChannelTab> it(m_channelTabs);
for (; it.current(); ++it) {
if (it.current()->list()->hasPerson(nick)) {
it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
it.current()->list()->update();
}
}
}
break;
case OUTPUT_OTHERJOIN:
case OUTPUT_OTHERKICK:
case OUTPUT_CHANPERSONMODE:
case OUTPUT_OTHERPART: {
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
channelTab->list()->update();
}
break;
case OUTPUT_CTCP:
appendText("<font color=\"" + m_notificationColor + "\">" + output.htmlMessage() + "</font><br>");
break;
case OUTPUT_ERROR: