/* 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, TQT_SLOT(error(KIRC::Message &)), 0, 0); bind("JOIN", this, TQT_SLOT(join(KIRC::Message &)), 0, 1); bind("KICK", this, TQT_SLOT(kick(KIRC::Message &)), 2, 2); bind("NICK", this, TQT_SLOT(nick(KIRC::Message &)), 0, 0); bind("MODE", this, TQT_SLOT(mode(KIRC::Message &)), 1, 1); bind("NOTICE", this, TQT_SLOT(notice(KIRC::Message &)), 1, 1); bind("PART", this, TQT_SLOT(part(KIRC::Message &)), 1, 1); bind("PING", this, TQT_SLOT(ping(KIRC::Message &)), 0, 0); bind("PONG", this, TQT_SLOT(pong(KIRC::Message &)), 0, 0); bind("PRIVMSG", this, TQT_SLOT(privmsg(KIRC::Message &)), 1, 1); bind("QUIT", this, TQT_SLOT(quit(KIRC::Message &)), 0, 0); // bind("SQUIT", this, TQT_SLOT(squit(KIRC::Message &)), 1, 1); bind("TOPIC", this, TQT_SLOT(topic(KIRC::Message &)), 1, 1); } void Engine::away(bool isAway, const TQString &awayMessage) { if(isAway) if( !awayMessage.isEmpty() ) writeMessage("AWAY", TQString::null, awayMessage); else writeMessage("AWAY", TQString::null, TQString::fromLatin1("I'm away.")); else writeMessage("AWAY", TQString::null); } // FIXME: Really handle this message void Engine::error(Message &) { setStatus(Closing); } void Engine::ison(const TQStringList &nickList) { if (!nickList.isEmpty()) { TQString statement = TQString::fromLatin1("ISON"); for (TQStringList::ConstIterator it = nickList.begin(); it != nickList.end(); ++it) { if ((statement.length()+(*it).length())>509) // 512(max buf)-2("\r\n")-1() { writeMessage(statement); statement = TQString::fromLatin1("ISON ") + (*it); } else statement.append(TQChar(' ') + (*it)); } writeMessage(statement); } } void Engine::join(const TQString &name, const TQString &key) { TQStringList 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 TQString &user, const TQString &channel, const TQString &reason) { writeMessage("KICK", TQStringList(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 TQString &target, const TQString &mode) { writeMessage("MODE", TQStringList(target) << mode); } void Engine::mode(Message &msg) { /* Change the mode of a user. * " *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )" */ TQStringList 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 TQString &newNickname) { m_PendingNick = newNickname; writeMessage("NICK", newNickname); } void Engine::nick(Message &msg) { /* Nick name of a user changed * "" */ TQString oldNick = msg.prefix().section('!', 0, 0); TQString newNick = msg.suffix(); if( codecs[ oldNick ] ) { TQTextCodec *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 TQString &channel, const TQString &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 TQString &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 TQString &reason, bool /*now*/) { kdDebug(14120) << k_funcinfo << reason << endl; if (isDisconnected()) return; if (isConnected()) writeMessage("QUIT", TQString::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 TQString &newUserName, const TQString &hostname, const TQString &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", TQStringList(m_Username) << hostname << m_Host, m_realName); } void Engine::user(const TQString &newUserName, Q_UINT8 mode, const TQString &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", TQStringList(m_Username) << TQString::number(mode) << TQChar('*'), m_realName); } void Engine::topic(const TQString &channel, const TQString &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", TQString::null); } void Engine::motd(const TQString &server) { writeMessage("MOTD", server); } void Engine::privmsg(const TQString &contact, const TQString &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()) { TQString user = m.arg(0); TQString message = m.suffix(); const TQTextCodec *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 TQString &target, const TQString &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 TQString &user) { writeMessage("WHOIS", user); }