Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ircmessageparser.cpp

Go to the documentation of this file.
00001 #include <qtextstream.h>
00002 #include <qdatetime.h>
00003 
00004 #include <opie2/ofiledialog.h>
00005 #include <opie2/ofileselector.h>
00006 #include <opie2/odebug.h>
00007 
00008 #include "ircmessageparser.h"
00009 #include "ircversion.h"
00010 #include "ircchannelperson.h"
00011 #include "dcctransfertab.h"
00012 #include "ircservertab.h"
00013 
00014 /* Lookup table for literal commands */
00015 IRCLiteralMessageParserStruct IRCMessageParser::literalParserProcTable[] = {
00016     { "PING",    FUNC(parseLiteralPing) },
00017     { "NOTICE",  FUNC(parseLiteralNotice) },
00018     { "JOIN",    FUNC(parseLiteralJoin) },
00019     { "PRIVMSG", FUNC(parseLiteralPrivMsg) },
00020     { "NICK",    FUNC(parseLiteralNick) },
00021     { "PART",    FUNC(parseLiteralPart) },
00022     { "QUIT",    FUNC(parseLiteralQuit) },
00023     { "ERROR",   FUNC(parseLiteralError) },
00024     { "ERROR:",  FUNC(parseLiteralError) },
00025     { "MODE",    FUNC(parseLiteralMode) },
00026     { "KICK",    FUNC(parseLiteralKick) },
00027     { "TOPIC",   FUNC(parseLiteralTopic) },
00028     { 0 , 0 }
00029 };
00030 
00031 /* Lookup table for literal commands */
00032 IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = {
00033     { "PING",    FUNC(parseCTCPPing) },
00034     { "VERSION", FUNC(parseCTCPVersion) },
00035     { "ACTION",  FUNC(parseCTCPAction) },
00036     { "DCC",     FUNC(parseCTCPDCC) },
00037     { 0 , 0 }
00038 };
00039 
00040 /* Lookup table for numerical commands
00041  * According to:
00042  * http://www.faqs.org/rfcs/rfc1459.html
00043  * http://www.faqs.org/rfcs/rfc2812.html
00044 */
00045 
00046 IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = {
00047     { 1, "%1", "1", FUNC(parseNumericalServerName) },       // RPL_WELCOME
00048     { 2, "%1", "1", 0 },                                    // RPL_YOURHOST
00049     { 3, "%1", "1", 0 },                                    // RPL_CREATED
00050     { 4, QT_TR_NOOP("Server %1 version %2 supports usermodes '%3' and channelmodes '%4'"), "1:4", FUNC(parseNumericalServerFeatures) },   // RPL_MYINFO
00051     { 5,  0, 0,  FUNC(parseNumericalServerProtocol) },      // RPL_BOUNCE, RPL_PROTOCTL
00052     { 250, "%1", "1", 0 },                                  // RPL_STATSCONN
00053     { 251, "%1", "1",  0 },                                 // RPL_LUSERCLIENT
00054     { 252, QT_TR_NOOP("There are %1 operators connected"), "1", 0 },    // RPL_LUSEROP
00055     { 253, QT_TR_NOOP("There are %1 unknown connection(s)"), "1", 0 },  // RPL_LUSERUNKNOWN
00056     { 254, QT_TR_NOOP("There are %1 channels formed"), "1", 0 },        // RPL_LUSERCHANNELS
00057     { 255, "%1", "1", 0 },                                  // RPL_LUSERME
00058     { 263, QT_TR_NOOP("Please wait a while and try again"), 0, 0 }, // RPL_TRYAGAIN
00059     { 265, "%1", "1", 0 },                                  // RPL_LOCALUSERS
00060     { 266, "%1", "1", 0 },                                  // RPL_GLOBALUSERS
00061     { 311, QT_TR_NOOP("Whois %1 (%2@%3)\nReal name: %4"), "1:3,5", 0 },    // RPL_WHOISUSER
00062     { 312, QT_TR_NOOP("%1 is using server %2"), "1,2", 0 },             // RPL_WHOISSERVER
00063     { 317, 0, 0, FUNC(parseNumericalWhoisIdle) },           // RPL_WHOISIDLE 
00064     { 318, "%1 :%2", "1,2", 0 },                            // RPL_ENDOFWHOIS
00065     { 319, QT_TR_NOOP("%1 is on channels: %2"), "1,2", 0 },             // RPL_WHOISCHANNELS
00066     { 320, "%1 %2", "1,2", 0},                              // RPL_WHOISVIRT
00067     { 332, 0, 0, FUNC(parseNumericalTopic) },               // RPL_TOPIC
00068     { 333, 0, 0, FUNC(parseNumericalTopicWhoTime) },        // RPL_TOPICWHOTIME*/
00069     { 353, QT_TR_NOOP("Names for %1: %2"), "2,3", FUNC(parseNumericalNames) },  // RPL_NAMREPLY
00070     { 366, "%1 :%2", "1,2", FUNC(parseNumericalEndOfNames) },       // RPL_ENDOFNAMES
00071     { 369, "%1 :%2", "1,2", 0 },                            // RPL_ENDOFWHOWAS
00072     { 372, "%1", "1", 0 },                                  // RPL_MOTD
00073     { 375, "%1", "1", 0 },                                  // RPL_MOTDSTART
00074     { 376, "%1", "1", 0 },                                  // RPL_ENDOFMOTD
00075     { 377, "%1", "1", 0 },                                  // RPL_MOTD2
00076     { 378, "%1", "1", 0 },                                  // RPL_MOTD3
00077     { 391, QT_TR_NOOP("Time on server %1 is %2"), "1,2", 0 },           // RPL_TIME
00078     { 401, QT_TR_NOOP("Channel or nick %1 doesn't exists"), "1", 0 },   // ERR_NOSUCHNICK
00079     { 403, QT_TR_NOOP("Channel %1 doesn't exists"), "1", 0 },           // ERR_ERR_NOSUCHCHANNEL
00080     { 406, QT_TR_NOOP("There is no history information for %1"), "1", 0 }, // ERR_WASNOSUCHNICK
00081     { 409, "%1", "1", 0 },                                  // ERR_NOORIGIN
00082     { 411, "%1", "1", 0 },                                  // ERR_NORECIPIENT
00083     { 412, "%1", "1", 0 },                                  // ERR_NOTEXTTOSEND
00084     { 421, QT_TR_NOOP("Unknown command: %1"), "1", 0 },     // ERR_ERR_UNKNOWNCOMMAND
00085     { 422, "%1", "1", 0 },                                  // ERR_NOMOTD
00086     { 433, QT_TR_NOOP("Can't change nick to %1: %2"), "1,2", FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE
00087     { 442, QT_TR_NOOP("You're not on channel %1"), "1", 0}, // ERR_NOTONCHANNEL
00088     { 477, "%1", "1", 0 },                                  // ERR_NOCHANMODES || ERR_NEEDREGGEDNICK
00089     { 482, QT_TR_NOOP("[%1] Operation not permitted, you don't have enough channel privileges"), "1", 0 }, //ERR_CHANOPRIVSNEEDED
00090     { 0, 0, 0, 0 }
00091 };
00092 
00093 
00094 IRCMessageParser::IRCMessageParser(IRCSession *session) {
00095     m_session = session;
00096 }
00097 
00098 void IRCMessageParser::parse(IRCMessage *message) {
00099     /* Find out what kind of message we have here and call the appropriate handler using
00100        the parser tables. If no handler can be found, print out an error message */
00101     if (message->isNumerical()) {
00102         for (int i=0; i<numericalParserProcTable[i].commandNumber; i++) {
00103             if (message->commandNumber() == numericalParserProcTable[i].commandNumber) {
00104                 parseNumerical(message, i);
00105                 return;
00106             }
00107         }
00108         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled numeric command: %1").arg( QString::number(message->commandNumber()) )));
00109     } else if (message->isCTCP()) {
00110         for (int i=0; ctcpParserProcTable[i].commandName; i++) {
00111             if (message->ctcpCommand() == ctcpParserProcTable[i].commandName) {
00112                 parseCTCP(message, i);
00113                 return;
00114             }
00115         }
00116         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled ctcp command: %1").arg( message->ctcpCommand())) );
00117     } else {
00118         for (int i=0; literalParserProcTable[i].commandName; i++) {
00119             if (message->command() == literalParserProcTable[i].commandName) {
00120                 (this->*(literalParserProcTable[i].proc))(message);
00121                 return;
00122             }
00123         }
00124         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled literal command: %1").arg( message->command()) ));
00125     }
00126 }
00127 
00128 void IRCMessageParser::parseNumerical(IRCMessage *message, int position) {
00129     QString out = tr(numericalParserProcTable[position].message);
00130     QString paramString = numericalParserProcTable[position].params;
00131     
00132     if(!out.isEmpty() && !paramString.isEmpty()) {
00133         QStringList params = message->params(numericalParserProcTable[position].params);
00134     
00135         QStringList::Iterator end = params.end();
00136         for (QStringList::Iterator it = params.begin(); it != end; ++it) {
00137             out = out.arg(*it);
00138         }
00139     
00140         emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
00141     }
00142     
00143     if(numericalParserProcTable[position].proc)
00144         (this->*(numericalParserProcTable[position].proc))(message);
00145 }
00146 
00147 void IRCMessageParser::parseCTCP(IRCMessage *message, int position) {
00148     if(ctcpParserProcTable[position].proc)
00149         (this->*(ctcpParserProcTable[position].proc))(message);
00150 }
00151 
00152         
00153 
00154 void IRCMessageParser::parseNumericalServerName(IRCMessage *message) {
00155     emit outputReady(IRCOutput(OUTPUT_TITLE, tr("Connected to")+" <b>" + message->prefix() + "</b>"));
00156     /* Register EFFECTIVE nickname, some networks (as irc-hispano) use nick:password
00157      * for authentication and the parser gets confused */
00158     m_session->m_server->setNick(message->param(0));
00159 
00160 }
00161 
00162 void IRCMessageParser::parseNumericalServerFeatures(IRCMessage *message) {
00163     m_session->setValidUsermodes(message->param(2));
00164     m_session->setValidChannelmodes(message->param(3));
00165 
00166 }
00167 
00168 void IRCMessageParser::parseNumericalServerProtocol(IRCMessage *message) {
00169     /* XXX: Add some usefull features here */
00170     QString out = message->allParameters();
00171     out = out.mid(out.find(' ')+1);
00172     emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
00173 }
00174 void IRCMessageParser::parseNumericalWhoisIdle(IRCMessage *message) {
00175     QDateTime dt;
00176     QTime t;
00177     t = t.addSecs(message->param(2).toInt());
00178     dt.setTime_t(message->param(3).toInt());
00179     
00180     emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 has been idle for %2").arg(message->param(1)).arg(t.toString())));
00181     emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 signed on %2").arg(message->param(1)).arg(dt.toString())));
00182     
00183 }
00184 
00185 void IRCMessageParser::parseLiteralPing(IRCMessage *message) {
00186     m_session->m_connection->sendLine("PONG " + message->allParameters());
00187 }
00188 
00189 void IRCMessageParser::parseLiteralNotice(IRCMessage *message) {
00190     emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters()));
00191 }
00192 
00193 void IRCMessageParser::parseLiteralJoin(IRCMessage *message) {
00194     QString channelName = message->param(0).lower();
00195     IRCPerson mask(message->prefix());
00196     IRCChannel *channel = m_session->getChannel(channelName);
00197     if (!channel) {
00198         /* We joined */
00199         if (mask.nick() == m_session->m_server->nick()) {
00200             channel = new IRCChannel(channelName);
00201             m_session->addChannel(channel);
00202         } else {
00203             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nonexistant channel join - desynchronized?")));
00204         }
00205     } else {
00206         /* Someone else joined */
00207         if (mask.nick() != m_session->m_server->nick()) {
00208             if (!channel->getPerson(mask.nick())) {
00209                 IRCPerson *person = m_session->getPerson(mask.nick());
00210                 if (!person) {
00211                     person = new IRCPerson(message->prefix());
00212                     m_session->addPerson(person);
00213                 }
00214                 IRCChannelPerson *chanperson = new IRCChannelPerson(person);
00215                 channel->addPerson(chanperson);
00216                 IRCOutput output(OUTPUT_OTHERJOIN ,tr("%1 joined channel %2").arg( mask.nick() ).arg( channelName ));
00217                 output.addParam(channel);
00218                 output.addParam(chanperson);
00219                 emit outputReady(output);
00220             } else {
00221                emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Person has already joined the channel - desynchronized?")));
00222             }
00223         } else {
00224            emit outputReady(IRCOutput(OUTPUT_ERROR, tr("You already joined the channel - desynchronized?")));
00225         }
00226     }
00227 }
00228 
00229 void IRCMessageParser::parseLiteralPart(IRCMessage *message) {
00230     QString channelName = message->param(0).lower();
00231     IRCChannel *channel = m_session->getChannel(channelName);
00232     IRCPerson mask(message->prefix());
00233     if (channel) {
00234         if (mask.nick() == m_session->m_server->nick()) {
00235             m_session->removeChannel(channel);
00236             IRCOutput output(OUTPUT_SELFPART, tr("You left channel %1").arg( channelName ));
00237             output.addParam(channel);
00238             emit outputReady(output);
00239             delete channel;
00240         } else {
00241             IRCChannelPerson *person = channel->getPerson(mask.nick());
00242             if (person) {
00243                 channel->removePerson(person);
00244                 IRCOutput output(OUTPUT_OTHERPART, tr("%1 left channel %2").arg( mask.nick() ).arg( channelName) );
00245                 output.addParam(channel);
00246                 output.addParam(person);
00247                 emit outputReady(output);
00248                 delete person;
00249             } else {
00250                 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Parting person not found - desynchronized?")));
00251             }
00252         }
00253     } else {
00254         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel for part not found - desynchronized?")));
00255     }
00256 }
00257 
00258 void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
00259     if (m_session->m_server->nick().lower() == message->param(0).lower() ) {
00260         /* IRC Query message detected, verify sender and display it */
00261         IRCPerson mask(message->prefix());
00262         IRCPerson *person = m_session->getPerson(mask.nick());
00263         if (!person) {
00264             /* Person not yet known, create and add to the current session */
00265             person = new IRCPerson(message->prefix());
00266             m_session->addPerson(person);
00267         }
00268         IRCOutput output(OUTPUT_QUERYPRIVMSG, message->param(1));
00269         output.addParam(person);
00270         emit outputReady(output);
00271     } 
00272     else 
00273         if (IRCChannel::isValid(message->param(0))) {
00274             /* IRC Channel message detected, verify sender, channel and display it */
00275             IRCChannel *channel = m_session->getChannel(message->param(0).lower());
00276             if (channel) {
00277                 IRCPerson mask(message->prefix());
00278                 IRCChannelPerson *person = channel->getPerson(mask.nick());
00279                 if (person) {
00280                     IRCOutput output(OUTPUT_CHANPRIVMSG, message->param(1));
00281                     output.addParam(channel);
00282                     output.addParam(person);
00283                     emit outputReady(output);
00284                 } 
00285                 else {
00286                     emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown sender")));
00287                 }
00288             } 
00289             else {
00290                 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown channel %1").arg(message->param(0).lower()) ));
00291             }
00292         } 
00293         else {emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received PRIVMSG of unknown type")));
00294     }
00295 }
00296 
00297 void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
00298     IRCPerson mask(message->prefix());
00299     m_session->updateNickname(mask.nick(), message->param(0));
00300     /* this way of handling nick changes really sucks 
00301     if (mask.nick() == m_session->m_server->nick()) {
00302          We are changing our nickname 
00303         m_session->m_server->setNick(message->param(0));
00304         IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg( message->param(0)));
00305         output.addParam(0);
00306         emit outputReady(output);
00307     } else {
00308          Someone else is 
00309         RCPerson *person = m_session->getPerson(mask.nick());
00310         if (person) {
00311             //IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0)));
00312 
00313              new code starts here -- this removes the person from all channels 
00314             QList<IRCChannel> channels;
00315             m_session->getChannelsByPerson(person, channels);
00316             QListIterator<IRCChannel> it(channels);
00317             for (;it.current(); ++it) {
00318               IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick());
00319               it.current()->removePerson(chanperson);
00320               chanperson->person->setNick(message->param(0));
00321               it.current()->addPerson(chanperson);
00322               IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0)));
00323               output.addParam(person);
00324               emit outputReady(output);
00325             }
00326              new code ends here 
00327         } else {
00328             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
00329         }
00330     }*/
00331 }
00332 
00333 void IRCMessageParser::parseLiteralQuit(IRCMessage *message) {
00334     IRCPerson mask(message->prefix());
00335     IRCPerson *person = m_session->getPerson(mask.nick());
00336     if (person) {
00337         QList<IRCChannel> channels;
00338         m_session->getChannelsByPerson(person, channels);
00339         QListIterator<IRCChannel> it(channels);
00340         for (;it.current(); ++it) {
00341             IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick());
00342             it.current()->removePerson(chanperson);
00343             delete chanperson;
00344         }
00345         m_session->removePerson(person);
00346         IRCOutput output(OUTPUT_QUIT, tr("%1 has quit (%2)" ).arg( mask.nick() ).arg( message->param(0) ));
00347         output.addParam(person);
00348         emit outputReady(output);
00349         delete person;
00350     } else {
00351          emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person quit - desynchronized?")));
00352     }
00353 }
00354 
00355 void IRCMessageParser::parseLiteralTopic(IRCMessage *message) {
00356     IRCPerson mask(message->prefix());
00357     IRCChannel *channel = m_session->getChannel(message->param(0).lower());
00358     if (channel) {
00359         IRCOutput output(OUTPUT_TOPIC, mask.nick() + tr(" changed topic to ") + "\"" + message->param(1) + "\"");
00360         output.addParam(channel);
00361         emit outputReady(output);
00362     } else {
00363         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel topic - desynchronized?")));
00364     }
00365 }
00366 
00367 void IRCMessageParser::parseLiteralError(IRCMessage *message) {
00368     emit outputReady(IRCOutput(OUTPUT_ERROR, message->allParameters()));
00369 }
00370 
00371 void IRCMessageParser::parseCTCPPing(IRCMessage *message) {
00372     IRCPerson mask(message->prefix());
00373     if(message->isCTCPReply()) {
00374         unsigned int sentTime = message->param(0).toUInt();
00375         QDateTime tm;
00376         tm.setTime_t(0);
00377         unsigned int receivedTime = tm.secsTo(QDateTime::currentDateTime());
00378         emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING reply from %1: %2 seconds").arg(mask.nick()).arg(receivedTime-sentTime)));
00379         return;
00380     } 
00381     m_session->m_connection->sendCTCPReply(mask.nick(), "PING", message->allParameters());
00382     emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING request from %1").arg(mask.nick())));
00383 
00384     //IRCPerson mask(message->prefix());
00385     QString dest = message->ctcpDestination();
00386     if (dest.startsWith("#")) {
00387         IRCChannel *channel = m_session->getChannel(dest.lower());
00388         if (channel) {
00389             IRCChannelPerson *person = channel->getPerson(mask.nick());
00390             if (person) {
00391                 IRCOutput output(OUTPUT_CHANACTION, tr("Received a CTCP PING from ")+ mask.nick()) ;
00392                 output.addParam(channel);
00393                 output.addParam(person);
00394                 emit outputReady(output);
00395             } else {
00396                 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown person - Desynchronized?")));
00397             }
00398         } else {
00399             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown channel - Desynchronized?")));
00400         }
00401     } else {
00402         if (message->ctcpDestination() == m_session->m_server->nick()) {
00403             IRCPerson *person = m_session->getPerson(mask.nick());
00404             if (!person) {
00405                 /* Person not yet known, create and add to the current session */
00406                 person = new IRCPerson(message->prefix());
00407                 m_session->addPerson(person);
00408             }
00409             IRCOutput output(OUTPUT_QUERYACTION, tr("Received a CTCP PING from ")+ mask.nick() );
00410             output.addParam(person);
00411             emit outputReady(output);
00412         } else {
00413             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with bad recipient")));
00414         }
00415     }
00416 
00417 }
00418 
00419 void IRCMessageParser::parseCTCPVersion(IRCMessage *message) {
00420     IRCPerson mask(message->prefix());
00421     IRCOutput output(OUTPUT_CTCP);
00422     if(message->isCTCPRequest()) {
00423         m_session->m_connection->sendCTCPReply(mask.nick(), "VERSION", APP_VERSION " "  APP_COPYSTR);
00424         output.setMessage(tr("Received a CTCP VERSION request from ") + mask.nick());
00425     }
00426 
00427     else { 
00428         output.setMessage("Received CTCP VERSION reply from " + mask.nick() + ":" + message->param(0));
00429     }
00430     emit outputReady(output);
00431 }
00432 
00433 void IRCMessageParser::parseCTCPAction(IRCMessage *message) {
00434     IRCPerson mask(message->prefix());
00435     QString dest = message->ctcpDestination();
00436     if (dest.startsWith("#")) {
00437         IRCChannel *channel = m_session->getChannel(dest.lower());
00438         if (channel) {
00439             IRCChannelPerson *person = channel->getPerson(mask.nick());
00440             if (person) {
00441                 IRCOutput output(OUTPUT_CHANACTION, "*" + mask.nick() + message->param(0));
00442                 output.addParam(channel);
00443                 output.addParam(person);
00444                 emit outputReady(output);
00445             } else {
00446                 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown person - Desynchronized?")));
00447             }
00448         } else {
00449             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown channel - Desynchronized?")));
00450         }
00451     } else {
00452         if (message->ctcpDestination() == m_session->m_server->nick()) {
00453             IRCPerson *person = m_session->getPerson(mask.nick());
00454             if (!person) {
00455                 /* Person not yet known, create and add to the current session */
00456                 person = new IRCPerson(message->prefix());
00457                 m_session->addPerson(person);
00458             }
00459             IRCOutput output(OUTPUT_QUERYACTION, "*" + mask.nick() + message->param(0));
00460             output.addParam(person);
00461             emit outputReady(output);
00462         } else {
00463             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with bad recipient")));
00464         }
00465     }
00466 }
00467 
00468 void IRCMessageParser::parseCTCPDCC(IRCMessage *message) {
00469     QStringList params = QStringList::split(' ', message->param(0).stripWhiteSpace());
00470     
00471     if(params[0] == "SEND") {
00472         QString nickname = IRCPerson(message->prefix()).nick();
00473         if( params.count() != 5) {
00474             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Malformed DCC request from %1").arg(nickname)));
00475             return;
00476         }
00477         bool accepted = DCCTransferTab::confirm(static_cast<QWidget*>(m_session->parent()), nickname, params[1], params[4].toUInt());
00478         if(!accepted)
00479             return;
00480         QString filename = Opie::Ui::OFileDialog::getSaveFileName(Opie::Ui::OFileSelector::EXTENDED_ALL,
00481                 QString::null, params[1], MimeTypes(), 0, tr("Save As"));
00482         if(filename.isEmpty())
00483             return;
00484 
00485         odebug << "Receiving file " << filename << " from " << nickname << oendl;
00486         static_cast<IRCServerTab*>(m_session->parent())->mainwindow()->addDCC(DCCTransfer::Recv, params[2].toUInt(), params[3].toUInt(),
00487                 filename, nickname, params[4].toUInt());
00488     }
00489 }
00490 
00491 void IRCMessageParser::parseLiteralMode(IRCMessage *message) {
00492     IRCPerson mask(message->prefix());
00493 
00494     if (IRCChannel::isValid(message->param(0))) {
00495         IRCChannel *channel = m_session->getChannel(message->param(0).lower());
00496         if (channel) {
00497             QString temp, parameters = message->allParameters().right(message->allParameters().length() - channel->channelname().length() - 1);
00498             QTextIStream stream(&parameters);
00499             bool set = FALSE;
00500             while (!stream.atEnd()) {
00501                 stream >> temp;
00502                 if (temp.startsWith("+")) {
00503                     set = TRUE;
00504                     temp = temp.right(1);
00505                 } 
00506                 else
00507                     if (temp.startsWith("-")) {
00508                         set = FALSE;
00509                         temp = temp.right(1);
00510                     } 
00511                     else {
00512                         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change has unknown type")));
00513                         return;
00514                     }
00515                 if (temp == "o") {
00516                     stream >> temp;
00517                     IRCChannelPerson *person = channel->getPerson(temp);
00518                     if (person) {
00519                         IRCOutput output(OUTPUT_CHANPERSONMODE, person->setOp(mask.nick(), set));
00520                         output.addParam(channel);
00521                         output.addParam(person);
00522                         emit outputReady(output);
00523                     } 
00524                     else {
00525                         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?")));
00526                     }
00527                 } 
00528                 else 
00529                     if (temp == "v") {
00530                         stream >> temp;
00531                         IRCChannelPerson *person = channel->getPerson(temp);
00532                         if (person) {
00533                             IRCOutput output(OUTPUT_CHANPERSONMODE, person->setVoice(mask.nick(), set));
00534                             output.addParam(channel);
00535                             output.addParam(person);
00536                             emit outputReady(output);
00537                         }
00538                         else {
00539                             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?")));
00540                         }
00541                     } 
00542                     else {
00543                         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown flag")));
00544                     }
00545                 }
00546         } else {
00547             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown kannel - Desynchronized?")));
00548         }
00549     } else {
00550         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("User modes not supported yet")));
00551     }
00552 }
00553 
00554 void IRCMessageParser::parseLiteralKick(IRCMessage *message) {
00555     IRCPerson mask(message->prefix());
00556     IRCChannel *channel = m_session->getChannel(message->param(0).lower());
00557     if (channel) {
00558         IRCChannelPerson *person = channel->getPerson(message->param(1));
00559         if (person) {
00560             if (person->nick() == m_session->m_server->nick()) {
00561                 m_session->removeChannel(channel);
00562                 IRCOutput output(OUTPUT_SELFKICK, tr("You were kicked from ") + channel->channelname() + tr(" by ") + mask.nick() + " (" + message->param(2) + ")");
00563                 output.addParam(channel);
00564                 emit outputReady(output);
00565             } else {
00566               /* someone else got kicked */
00567                 channel->removePerson(person);
00568                 IRCOutput output(OUTPUT_OTHERKICK, person->nick() + tr(" was kicked from ") + channel->channelname() + tr(" by ") + mask.nick()+ " (" + message->param(2) + ")");
00569                 output.addParam(channel);
00570                 output.addParam(person);
00571                 emit outputReady(output);
00572             }
00573         } else {
00574             emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person kick - desynchronized?")));
00575         }
00576     } else {
00577          emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel kick - desynchronized?")));
00578     }
00579 }
00580 
00581 void IRCMessageParser::parseNumericalNames(IRCMessage *message) {
00582     /* Name list sent when joining a channel */
00583     IRCChannel *channel = m_session->getChannel(message->param(2).lower());
00584     if (channel != 0) {
00585         QString people = message->param(3);
00586         QTextIStream stream(&people);
00587         QString temp;
00588 
00589         while (!stream.atEnd()) {
00590             stream >> temp;
00591 
00592             char flagch = temp.at(0).latin1();
00593             int flag = 0;
00594             QString nick;
00595             /* Parse person flags */
00596             if (flagch == '@' || flagch == '+' || flagch=='%' || flagch == '*') {
00597 
00598                 nick = temp.right(temp.length()-1);
00599                 switch (flagch) {
00600                     case '@': flag = IRCChannelPerson::PERSON_FLAG_OP;     break;
00601                     case '+': flag = IRCChannelPerson::PERSON_FLAG_VOICE;  break;
00602                     case '%': flag = IRCChannelPerson::PERSON_FLAG_HALFOP; break;
00603                     default : flag = 0; break;
00604                 }
00605             } else {
00606                 nick = temp;
00607             }
00608 
00609             IRCPerson *person = m_session->getPerson(nick);
00610             if (person == 0) {
00611                 person = new IRCPerson();
00612                 person->setNick(nick);
00613                 m_session->addPerson(person);
00614             }
00615             IRCChannelPerson *chan_person = new IRCChannelPerson(person);
00616             chan_person->setFlags(flag);
00617             channel->addPerson(chan_person);
00618         }
00619     } else {
00620         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel")));
00621     }
00622 }
00623 
00624 void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) {
00625     /* Done syncing to channel */
00626     IRCChannel *channel = m_session->getChannel(message->param(1).lower());
00627     if (channel) {
00628         channel->setHasPeople(TRUE);
00629         /* Yes, we want the names before anything happens inside the GUI */
00630         IRCOutput output(OUTPUT_SELFJOIN, tr("You joined channel ") + channel->channelname());
00631         output.addParam(channel);
00632         emit outputReady(output);
00633     } else {
00634         emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel")));
00635     }
00636 }
00637 
00638 
00639 void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) {
00640     /* If we are connnected this error is not critical */
00641     if(m_session->isLoggedIn())
00642         return;
00643     
00644     emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname")));
00645     m_session->endSession();
00646 }
00647 
00648 void IRCMessageParser::parseNumericalNoSuchNick(IRCMessage *) {
00649     emit outputReady(IRCOutput(OUTPUT_ERROR, tr("No such nickname")));
00650 }
00651 
00652 void IRCMessageParser::parseNumericalTopic(IRCMessage *message) {
00653     IRCChannel *channel = m_session->getChannel(message->param(1).lower());
00654     if (channel) {
00655         IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + channel->channelname() + " is \"" + message->param(2) + "\""));
00656         output.addParam(channel);
00657         emit outputReady(output);
00658     } else {
00659         IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + message->param(1) + " is \"" + message->param(2) + "\""));
00660         output.addParam(0);
00661         emit outputReady(output);
00662     }
00663 }
00664 
00665 void IRCMessageParser::parseNumericalTopicWhoTime(IRCMessage *) {
00666 }
00667 
00668     

Generated on Sat Nov 5 16:17:41 2005 for OPIE by  doxygen 1.4.2