summaryrefslogtreecommitdiff
path: root/noncore/net/opieirc/ircmessageparser.cpp
Unidiff
Diffstat (limited to 'noncore/net/opieirc/ircmessageparser.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opieirc/ircmessageparser.cpp158
1 files changed, 108 insertions, 50 deletions
diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp
index f8ccbb6..fde156c 100644
--- a/noncore/net/opieirc/ircmessageparser.cpp
+++ b/noncore/net/opieirc/ircmessageparser.cpp
@@ -1,4 +1,6 @@
1#include <qtextstream.h> 1#include <qtextstream.h>
2#include <qdatetime.h>
3
2#include "ircmessageparser.h" 4#include "ircmessageparser.h"
3#include "ircversion.h" 5#include "ircversion.h"
4 6
@@ -27,36 +29,55 @@ IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = {
27 { 0 , 0 } 29 { 0 , 0 }
28}; 30};
29 31
30/* Lookup table for numerical commands */ 32/* Lookup table for numerical commands
33 * According to:
34 * http://www.faqs.org/rfcs/rfc1459.html
35 * http://www.faqs.org/rfcs/rfc2812.html
36*/
37
31IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = { 38IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = {
32 { 1, FUNC(parseNumericalSecondParam) }, // RPL_WELCOME 39 { 1, "%1", "1", FUNC(parseNumericalServerName) }, // RPL_WELCOME
33 { 2, FUNC(parseNumericalSecondParam) }, // RPL_YOURHOST 40 { 2, "%1", "1", 0 }, // RPL_YOURHOST
34 { 3, FUNC(parseNumericalSecondParam) }, // RPL_CREATED 41 { 3, "%1", "1", 0 }, // RPL_CREATED
35 { 4, FUNC(parseNumericalAllParams) }, // RPL_MYINFO 42 { 4, QT_TR_NOOP("Server %1 version %2 supports usermodes '%3' and channelmodes '%4'"), "1:4", FUNC(parseNumericalServerFeatures) }, // RPL_MYINFO
36 { 5, FUNC(parseNumericalSecondParam) }, // RPL_BOUNCE, RPL_PROTOCTL 43 { 5, 0, 0, FUNC(parseNumericalServerProtocol) }, // RPL_BOUNCE, RPL_PROTOCTL
37 { 250, FUNC(parseNumericalAllParams) }, // RPL_STATSCONN 44 { 250, "%1", "1", 0 }, // RPL_STATSCONN
38 { 251, FUNC(parseNumericalSecondParam) }, // RPL_LUSERCLIENT 45 { 251, "%1", "1", 0 }, // RPL_LUSERCLIENT
39 { 252, FUNC(parseNumericalAllParams) }, // RPL_LUSEROP 46 { 252, QT_TR_NOOP("There are %1 operators connected"), "1", 0 }, // RPL_LUSEROP
40 { 253, FUNC(parseNumericalAllParams) }, // RPL_LUSERUNKNOWN 47 { 253, QT_TR_NOOP("There are %1 unknown connection(s)"), "1", 0 }, // RPL_LUSERUNKNOWN
41 { 254, FUNC(parseNumericalAllParams) }, // RPL_LUSERCHANNELS 48 { 254, QT_TR_NOOP("There are %1 channels formed"), "1", 0 }, // RPL_LUSERCHANNELS
42 { 255, FUNC(parseNumericalSecondParam) }, // RPL_LUSERME 49 { 255, "%1", "1", 0 }, // RPL_LUSERME
43 { 265, FUNC(parseNumericalAllParams) }, // RPL_LOCALUSERS 50 { 263, QT_TR_NOOP("Please wait a while and try again"), 0, 0 }, // RPL_TRYAGAIN
44 { 266, FUNC(parseNumericalAllParams) }, // RPL_GLOBALUSERS 51 { 265, "%1", "1", 0 }, // RPL_LOCALUSERS
45 { 332, FUNC(parseNumericalTopic) }, // RPL_TOPIC 52 { 266, "%1", "1", 0 }, // RPL_GLOBALUSERS
46 { 333, FUNC(parseNumericalTopicWhoTime) }, // RPL_TOPICWHOTIME 53 { 311, QT_TR_NOOP("Whois %1 (%2@%3)\nReal name: %4"), "1:3,5" }, // RPL_WHOISUSER
47 { 353, FUNC(parseNumericalNames) }, // RPL_NAMREPLY 54 { 312, QT_TR_NOOP("%1 is using server %2"), "1,2", 0 }, // RPL_WHOISSERVER
48 { 366, FUNC(parseNumericalEndOfNames) }, // RPL_ENDOFNAMES 55 { 317, 0, 0, FUNC(parseNumericalWhoisIdle) }, // RPL_WHOISIDLE
49 { 372, FUNC(parseNumericalSecondParam) }, // RPL_MOTD 56 { 318, "%1 :%2", "1,2", 0 }, // RPL_ENDOFWHOIS
50 { 375, FUNC(parseNumericalSecondParam) }, // RPL_MOTDSTART 57 { 320, "%1 %2", "1,2", 0}, // RPL_WHOISVIRT
51 { 376, FUNC(parseNumericalSecondParam) }, // RPL_ENDOFMOTD 58 { 332, 0, 0, FUNC(parseNumericalTopic) }, // RPL_TOPIC
52 { 377, FUNC(parseNumericalSecondParam) }, // RPL_MOTD2 59 { 333, 0, 0, FUNC(parseNumericalTopicWhoTime) }, // RPL_TOPICWHOTIME*/
53 { 378, FUNC(parseNumericalSecondParam) }, // RPL_MOTD3 60 { 353, QT_TR_NOOP("Names for %1: %2"), "2,3", FUNC(parseNumericalNames) }, // RPL_NAMREPLY
54 { 401, FUNC(parseNumericalNoSuchNick) }, // ERR_NOSUCHNICK 61 { 366, "%1 :%2", "1,2", FUNC(parseNumericalEndOfNames) }, // RPL_ENDOFNAMES
55 { 406, FUNC(parseNumericalNoSuchNick) }, // ERR_WASNOSUCHNICK 62 { 369, "%1 :%2", "1,2", 0 }, // RPL_ENDOFWHOWAS
56 { 412, FUNC(parseNumericalSecondParam) }, // ERR_NOTEXTTOSEND 63 { 372, "%1", "1", 0 }, // RPL_MOTD
57 { 422, FUNC(parseNumericalSecondParam) }, // ERR_NOMOTD 64 { 375, "%1", "1", 0 }, // RPL_MOTDSTART
58 { 433, FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE 65 { 376, "%1", "1", 0 }, // RPL_ENDOFMOTD
59 { 0, 0 } 66 { 377, "%1", "1", 0 }, // RPL_MOTD2
67 { 378, "%1", "1", 0 }, // RPL_MOTD3
68 { 391, QT_TR_NOOP("Time on server %1 is %2"), "1,2", 0 }, // RPL_TIME
69 { 401, QT_TR_NOOP("Channel or nick %1 doesn't exists"), "1", 0 }, // ERR_NOSUCHNICK
70 { 406, QT_TR_NOOP("There is no history information for %1"), "1" }, // ERR_WASNOSUCHNICK
71 { 409, "%1", "1", 0 }, // ERR_NOORIGIN
72 { 411, "%1", "1", 0 }, // ERR_NORECIPIENT
73 { 412, "%1", "1", 0 }, // ERR_NOTEXTTOSEND
74 { 421, QT_TR_NOOP("Unknown command: %1"), "1", 0 }, // ERR_NOMOTD
75 { 422, QT_TR_NOOP("You're not on channel %1"), "1", 0}, // ERR_NOTONCHANNEL
76 { 422, "%1", "1", 0 }, // ERR_NOMOTD
77 { 433, QT_TR_NOOP("Can't change nick to %1: %2"), "1,2", FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE
78 { 477, "%1", "1", 0 }, // ERR_NOCHANMODES || ERR_NEEDREGGEDNICK
79 { 482, QT_TR_NOOP("[%1] Operation not permitted, you don't have enough channel privileges"), "1", 0 }, //ERR_CHANOPRIVSNEEDED
80 { 0, 0, 0, 0 }
60}; 81};
61 82
62 83
@@ -70,7 +91,7 @@ void IRCMessageParser::parse(IRCMessage *message) {
70 if (message->isNumerical()) { 91 if (message->isNumerical()) {
71 for (int i=0; i<numericalParserProcTable[i].commandNumber; i++) { 92 for (int i=0; i<numericalParserProcTable[i].commandNumber; i++) {
72 if (message->commandNumber() == numericalParserProcTable[i].commandNumber) { 93 if (message->commandNumber() == numericalParserProcTable[i].commandNumber) {
73 (this->*(numericalParserProcTable[i].proc))(message); 94 parseNumerical(message, i);
74 return; 95 return;
75 } 96 }
76 } 97 }
@@ -94,8 +115,50 @@ void IRCMessageParser::parse(IRCMessage *message) {
94 } 115 }
95} 116}
96 117
97void IRCMessageParser::nullFunc(IRCMessage *) { 118void IRCMessageParser::parseNumerical(IRCMessage *message, int position) {
98 /* Do nothing */ 119 QString out = tr(numericalParserProcTable[position].message);
120 QString paramString = numericalParserProcTable[position].params;
121
122 if(!out.isEmpty() && !paramString.isEmpty()) {
123 QStringList params = message->params(numericalParserProcTable[position].params);
124
125 QStringList::Iterator end = params.end();
126 for (QStringList::Iterator it = params.begin(); it != end; ++it) {
127 out = out.arg(*it);
128 }
129
130 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
131 }
132
133 if(numericalParserProcTable[position].proc)
134 (this->*(numericalParserProcTable[position].proc))(message);
135}
136
137void IRCMessageParser::parseNumericalServerName(IRCMessage *message) {
138 emit outputReady(IRCOutput(OUTPUT_TITLE, tr("Connected to")+" <b>" + message->prefix() + "</b>"));
139}
140
141void IRCMessageParser::parseNumericalServerFeatures(IRCMessage *message) {
142 m_session->setValidUsermodes(message->param(2));
143 m_session->setValidChannelmodes(message->param(3));
144
145}
146
147void IRCMessageParser::parseNumericalServerProtocol(IRCMessage *message) {
148 /* XXX: Add some usefull features here */
149 QString out = message->allParameters();
150 out = out.mid(out.find(' ')+1);
151 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
152}
153void IRCMessageParser::parseNumericalWhoisIdle(IRCMessage *message) {
154 QDateTime dt;
155 QTime t;
156 t = t.addSecs(message->param(2).toInt());
157 dt.setTime_t(message->param(3).toInt());
158
159 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 has been idle for %2").arg(message->param(1)).arg(t.toString())));
160 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 signed on %2").arg(message->param(1)).arg(dt.toString())));
161
99} 162}
100 163
101void IRCMessageParser::parseLiteralPing(IRCMessage *message) { 164void IRCMessageParser::parseLiteralPing(IRCMessage *message) {
@@ -209,22 +272,22 @@ void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
209} 272}
210 273
211void IRCMessageParser::parseLiteralNick(IRCMessage *message) { 274void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
212
213 IRCPerson mask(message->prefix()); 275 IRCPerson mask(message->prefix());
214 /* this way of handling nick changes really sucks */ 276 m_session->updateNickname(mask.nick(), message->param(0));
277 /* this way of handling nick changes really sucks
215 if (mask.nick() == m_session->m_server->nick()) { 278 if (mask.nick() == m_session->m_server->nick()) {
216 /* We are changing our nickname */ 279 We are changing our nickname
217 m_session->m_server->setNick(message->param(0)); 280 m_session->m_server->setNick(message->param(0));
218 IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg( message->param(0))); 281 IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg( message->param(0)));
219 output.addParam(0); 282 output.addParam(0);
220 emit outputReady(output); 283 emit outputReady(output);
221 } else { 284 } else {
222 /* Someone else is */ 285 Someone else is
223 IRCPerson *person = m_session->getPerson(mask.nick()); 286 RCPerson *person = m_session->getPerson(mask.nick());
224 if (person) { 287 if (person) {
225 //IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0))); 288 //IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0)));
226 289
227 /* new code starts here -- this removes the person from all channels */ 290 new code starts here -- this removes the person from all channels
228 QList<IRCChannel> channels; 291 QList<IRCChannel> channels;
229 m_session->getChannelsByPerson(person, channels); 292 m_session->getChannelsByPerson(person, channels);
230 QListIterator<IRCChannel> it(channels); 293 QListIterator<IRCChannel> it(channels);
@@ -237,11 +300,11 @@ void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
237 output.addParam(person); 300 output.addParam(person);
238 emit outputReady(output); 301 emit outputReady(output);
239 } 302 }
240 /* new code ends here */ 303 new code ends here
241 } else { 304 } else {
242 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person"))); 305 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
243 } 306 }
244 } 307 }*/
245} 308}
246 309
247void IRCMessageParser::parseLiteralQuit(IRCMessage *message) { 310void IRCMessageParser::parseLiteralQuit(IRCMessage *message) {
@@ -324,7 +387,7 @@ void IRCMessageParser::parseCTCPPing(IRCMessage *message) {
324 387
325void IRCMessageParser::parseCTCPVersion(IRCMessage *message) { 388void IRCMessageParser::parseCTCPVersion(IRCMessage *message) {
326 IRCPerson mask(message->prefix()); 389 IRCPerson mask(message->prefix());
327 m_session->m_connection->sendCTCP(mask.nick(), APP_VERSION " " APP_COPYSTR); 390 m_session->m_connection->sendCTCP(mask.nick(), "VERSION " APP_VERSION " " APP_COPYSTR);
328 emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP VERSION from ")+mask.nick())); 391 emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP VERSION from ")+mask.nick()));
329} 392}
330 393
@@ -463,15 +526,6 @@ void IRCMessageParser::parseLiteralKick(IRCMessage *message) {
463 } 526 }
464} 527}
465 528
466
467void IRCMessageParser::parseNumericalSecondParam(IRCMessage *message) {
468 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->param(1)));
469}
470
471void IRCMessageParser::parseNumericalAllParams(IRCMessage *message) {
472 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters()));
473}
474
475void IRCMessageParser::parseNumericalNames(IRCMessage *message) { 529void IRCMessageParser::parseNumericalNames(IRCMessage *message) {
476 /* Name list sent when joining a channel */ 530 /* Name list sent when joining a channel */
477 IRCChannel *channel = m_session->getChannel(message->param(2).lower()); 531 IRCChannel *channel = m_session->getChannel(message->param(2).lower());
@@ -532,6 +586,10 @@ void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) {
532 586
533 587
534void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) { 588void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) {
589 /* If we are connnected this error is not critical */
590 if(m_session->isLoggedIn())
591 return;
592
535 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname"))); 593 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname")));
536 m_session->endSession(); 594 m_session->endSession();
537} 595}