/* kirc_commands.h - IRC Client Copyright (c) 2003-2004 by Michel Hermier Copyright (c) 2002 by Nick Betcher Copyright (c) 2003 by Jason Keirstead Kopete (c) 2002-2003 by the Kopete developers ************************************************************************* * * * 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. * * * ************************************************************************* */ #include "kircengine.h" #include #include using namespace KIRC; void Engine::bindCommands() { bind("ERROR", this, SLOT(error(KIRC::Message &)), 0, 0); bind("JOIN", this, SLOT(join(KIRC::Message &)), 0, 1); bind("KICK", this, SLOT(kick(KIRC::Message &)), 2, 2); bind("NICK", this, SLOT(nick(KIRC::Message &)), 0, 0); bind("MODE", this, SLOT(mode(KIRC::Message &)), 1, 1); bind("NOTICE", this, SLOT(notice(KIRC::Message &)), 1, 1); bind("PART", this, SLOT(part(KIRC::Message &)), 1, 1); bind("PING", this, SLOT(ping(KIRC::Message &)), 0, 0); bind("PONG", this, SLOT(pong(KIRC::Message &)), 0, 0); bind("PRIVMSG", this, SLOT(privmsg(KIRC::Message &)), 1, 1); bind("QUIT", this, SLOT(quit(KIRC::Message &)), 0, 0); // bind("SQUIT", this, SLOT(squit(KIRC::Message &)), 1, 1); bind("TOPIC", this, SLOT(topic(KIRC::Message &)), 1, 1); } void Engine::away(bool isAway, const QString &awayMessage) { if(isAway) if( !awayMessage.isEmpty() ) writeMessage("AWAY", QString::null, awayMessage); else writeMessage("AWAY", QString::null, QString::fromLatin1("I'm away.")); else writeMessage("AWAY", QString::null); } // FIXME: Really handle this message void Engine::error(Message &) { setStatus(Closing); } void Engine::ison(const QStringList &nickList) { if (!nickList.isEmpty()) { QString statement = QString::fromLatin1("ISON"); for (QStringList::ConstIterator it = nickList.begin(); it != nickList.end(); ++it) { if ((statement.length()+(*it).length())>509) // 512(max buf)-2("\r\n")-1() { writeMessage(statement); statement = QString::fromLatin1("ISON ") + (*it); } else statement.append(QChar(' ') + (*it)); } writeMessage(statement); } } void Engine::join(const QString &name, const QString &key) { QStringList args(name); if ( !key.isNull() ) args << key; writeMessage("JOIN", args); } void Engine::join(Message &msg) { /* RFC say: "( *( "," ) [ *( "," ) ] ) / "0"" * suspected: ": *(" "/"," )" * assumed ":" * This is the response of someone joining a channel. * Remember that this will be emitted when *you* /join a room for the first time */ if (msg.argsSize()==1) emit incomingJoinedChannel(Kopete::Message::unescape(msg.arg(0)), msg.nickFromPrefix()); else emit incomingJoinedChannel(Kopete::Message::unescape(msg.suffix()), msg.nickFromPrefix()); } void Engine::kick(const QString &user, const QString &channel, const QString &reason) { writeMessage("KICK", QStringList(channel) << user << reason); } void Engine::kick(Message &msg) { /* The given user is kicked. * " *( "," ) *( "," ) []" */ emit incomingKick( Kopete::Message::unescape(msg.arg(0)), msg.nickFromPrefix(), msg.arg(1), msg.suffix()); } void Engine::mode(const QString &target, const QString &mode) { writeMessage("MODE", QStringList(target) << mode); } void Engine::mode(Message &msg) { /* Change the mode of a user. * " *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )" */ QStringList args = msg.args(); args.pop_front(); if( Entity::isChannel( msg.arg(0) ) ) emit incomingChannelModeChange( msg.arg(0), msg.nickFromPrefix(), args.join(" ")); else emit incomingUserModeChange( msg.nickFromPrefix(), args.join(" ")); } void Engine::nick(const QString &newNickname) { m_PendingNick = newNickname; writeMessage("NICK", newNickname); } void Engine::nick(Message &msg) { /* Nick name of a user changed * "" */ QString oldNick = msg.prefix().section('!', 0, 0); QString newNick = msg.suffix(); if( codecs[ oldNick ] ) { QTextCodec *c = codecs[ oldNick ]; codecs.remove( oldNick ); codecs.insert( newNick, c ); } if (oldNick.lower() == m_Nickname.lower()) { emit successfullyChangedNick(oldNick, msg.suffix()); m_Nickname = msg.suffix(); } else emit incomingNickChange(oldNick, msg.suffix()); } void Engine::part(const QString &channel, const QString &reason) { /* This will part a channel with 'reason' as the reason for parting */ writeMessage("PART", channel, reason); } void Engine::part(Message &msg) { /* This signal emits when a user parts a channel * " *( "," ) [ ]" */ kdDebug(14120) << "User parting" << endl; emit incomingPartedChannel(msg.arg(0), msg.nickFromPrefix(), msg.suffix()); } void Engine::pass(const QString &password) { writeMessage("PASS", password); } void Engine::ping(Message &msg) { writeMessage("PONG", msg.arg(0), msg.suffix()); } void Engine::pong(Message &/*msg*/) { } void Engine::quit(const QString &reason, bool /*now*/) { kdDebug(14120) << k_funcinfo << reason << endl; if (isDisconnected()) return; if (isConnected()) writeMessage("QUIT", QString::null, reason); setStatus(Closing); } void Engine::quit(Message &msg) { /* This signal emits when a user quits irc. */ kdDebug(14120) << "User quiting" << endl; emit incomingQuitIRC(msg.prefix(), msg.suffix()); } void Engine::user(const QString &newUserName, const QString &hostname, const QString &newRealName) { /* RFC1459: " " * The USER command is used at the beginning of connection to specify * the username, hostname and realname of a new user. * hostname is usualy set to "127.0.0.1" */ m_Username = newUserName; m_realName = newRealName; writeMessage("USER", QStringList(m_Username) << hostname << m_Host, m_realName); } void Engine::user(const QString &newUserName, Q_UINT8 mode, const QString &newRealName) { /* RFC2812: " " * mode is a numeric value (from a bit mask). * 0x00 normal * 0x04 request +w * 0x08 request +i */ m_Username = newUserName; m_realName = newRealName; writeMessage("USER", QStringList(m_Username) << QString::number(mode) << QChar('*'), m_realName); } void Engine::topic(const QString &channel, const QString &topic) { writeMessage("TOPIC", channel, topic); } void Engine::topic(Message &msg) { /* The topic of a channel changed. emit the channel, new topic, and the person who changed it. * " [ ]" */ emit incomingTopicChange(msg.arg(0), msg.nickFromPrefix(), msg.suffix()); } void Engine::list() { writeMessage("LIST", QString::null); } void Engine::motd(const QString &server) { writeMessage("MOTD", server); } void Engine::privmsg(const QString &contact, const QString &message) { writeMessage("PRIVMSG", contact, message, codecForNick( contact ) ); } void Engine::privmsg(Message &msg) { /* This is a signal that indicates there is a new message. * This can be either from a channel or from a specific user. */ Message m = msg; if (!m.suffix().isEmpty()) { QString user = m.arg(0); QString message = m.suffix(); const QTextCodec *codec = codecForNick( user ); if (codec != defaultCodec) { m.decodeAgain( codec ); message = m.suffix(); } if (Entity::isChannel(user)) emit incomingMessage(m.nickFromPrefix(), Kopete::Message::unescape(m.arg(0)), message ); else emit incomingPrivMessage(m.nickFromPrefix(), Kopete::Message::unescape(m.arg(0)), message ); // emit receivedMessage(PrivateMessage, msg.entityFrom(), msg.entityTo(), message); } if( m.hasCtcpMessage() ) { invokeCtcpCommandOfMessage(m_ctcpQueries, m); } } void Engine::notice(const QString &target, const QString &message) { writeMessage("NOTICE", target, message); } void Engine::notice(Message &msg) { if(!msg.suffix().isEmpty()) emit incomingNotice(msg.prefix(), msg.suffix()); if(msg.hasCtcpMessage()) invokeCtcpCommandOfMessage(m_ctcpReplies, msg); } void Engine::whois(const QString &user) { writeMessage("WHOIS", user); }