1 /*
2 Copyright (C) 2008-2020 The Communi Project
3
4 You may use this file under the terms of BSD license as follows:
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of the copyright holder nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "irccommand.h"
30 #include "irccommand_p.h"
31 #include "ircconnection.h"
32 #include "ircmessage.h"
33 #include "ircconnection_p.h"
34 #include "irccore_p.h"
35 #include <QTextCodec>
36 #include <QMetaEnum>
37 #include <QDebug>
38
39 IRC_BEGIN_NAMESPACE
40
41 /*!
42 \file irccommand.h
43 \brief \#include <IrcCommand>
44 */
45
46 /*!
47 \class IrcCommand irccommand.h <IrcCommand>
48 \ingroup core
49 \brief Provides the most common commands.
50
51 The IrcCommand class supports the most common IRC commands out of the box,
52 and can be extended for custom commands as well. See IrcCommand::Type for
53 the list of built-in command types. IRC commands, as in IrcCommand instances,
54 are sent to the IRC server via IrcConnection::sendCommand().
55
56 \section creating-commands Creating commands
57
58 It is recommended to create IrcCommand instances via static
59 IrcCommand::createXxx() methods.
60
61 \warning IrcCommand instances must be allocated on the heap, since
62 IrcConnection::sendCommand() takes ownership of the command and deletes
63 it once it has been sent.
64
65 \section custom-commands Custom commands
66
67 A "custom command" here refers to command types not listed in IrcCommand::Type,
68 the list of built-in command types. There are two ways to send custom commands:
69 \li by passing the string representation of a command directly to
70 IrcConnection::sendRaw() or IrcConnection::sendData(), or
71 \li by subclassing IrcCommand and reimplementing
72 IrcCommand::toString(), which eventually creates the string representation
73 of the command.
74
75 Example implementation of a custom command:
76 \code
77 class IrcServerCommand : public IrcCommand
78 {
79 Q_OBJECTT
80 public:
81 explicit IrcServerCommand(QObject* parent = 0) : IrcCommand(parent)
82 {
83 }
84
85 // provided for convenience, to ensure correct parameter order
86 static IrcCommand* create(const QString& serverName, int hopCount, const QString& info)
87 {
88 IrcCommand* command = new IrcServerCommand;
89 command->setParameters(QStringList() << serverName << QString::number(hopCount) << info);
90 return command;
91 }
92
93 // reimplemented from IrcCommand::toString()
94 virtual toString() const
95 {
96 // SERVER <servername> <hopcount> <info>
97 return QString("SERVER %1 %2 %3").arg(params.value(0), params.value(1), params.value(2));
98 }
99 };
100 \endcode
101
102 \sa IrcConnection::sendCommand(), IrcConnection::sendRaw(), IrcCommand::Type
103 */
104
105 /*!
106 \enum IrcCommand::Type
107 This enum describes the built-in command types.
108 */
109
110 /*!
111 \var IrcCommand::Admin
112 \brief An admin command (ADMIN) is used to query server admin info.
113 */
114
115 /*!
116 \var IrcCommand::Away
117 \brief An away command (AWAY) is used to set the away status.
118 */
119
120 /*!
121 \var IrcCommand::Capability
122 \brief A capability command (CAP) is used to manage connection capabilities.
123 */
124
125 /*!
126 \var IrcCommand::CtcpAction
127 \brief A CTCP action command is used to send an action message to channels and users.
128 */
129
130 /*!
131 \var IrcCommand::CtcpReply
132 \brief A CTCP reply command is used to send a reply to a request.
133 */
134
135 /*!
136 \var IrcCommand::CtcpRequest
137 \brief A CTCP request command is used to send a request.
138 */
139
140 /*!
141 \var IrcCommand::Custom
142 \brief A custom command
143 */
144
145 /*!
146 \var IrcCommand::Info
147 \brief An info command (INFO) is used to query server info.
148 */
149
150 /*!
151 \var IrcCommand::Invite
152 \brief An invite command (INVITE) is used to invite users to a channel.
153 */
154
155 /*!
156 \var IrcCommand::Join
157 \brief A join command (JOIN) is used to start listening a specific channel.
158 */
159
160 /*!
161 \var IrcCommand::Kick
162 \brief A kick command (KICK) is used to forcibly remove a user from a channel.
163 */
164
165 /*!
166 \var IrcCommand::Knock
167 \brief A knock command (KNOCK) is used to request channel invitation.
168 */
169
170 /*!
171 \var IrcCommand::List
172 \brief A list command (LIST) is used to list channels and their topics.
173 */
174
175 /*!
176 \var IrcCommand::Message
177 \brief A message command (PRIVMSG) is used to send private messages to channels and users.
178 */
179
180 /*!
181 \var IrcCommand::Mode
182 \brief A mode command (MODE) is used to change the mode of users and channels.
183 */
184
185 /*!
186 \var IrcCommand::Motd
187 \brief A message of the day command (MOTD) is used to query the message of the day.
188 */
189
190 /*!
191 \var IrcCommand::Names
192 \brief A names command (NAMES) is used to list all nicknames on a channel.
193 */
194
195 /*!
196 \var IrcCommand::Nick
197 \brief A nick command (NICK) is used to give user a nickname or change the previous one.
198 */
199
200 /*!
201 \var IrcCommand::Notice
202 \brief A notice command (NOTICE) is used to send notice messages to channels and users.
203 */
204
205 /*!
206 \var IrcCommand::Part
207 \brief A part command (PART) causes the client to be removed from the channel.
208 */
209
210 /*!
211 \var IrcCommand::Quit
212 \brief A quit command (QUIT) is used to end a client connection.
213 */
214
215 /*!
216 \var IrcCommand::Quote
217 \brief A quote command is used to send a raw message to the server.
218 */
219
220 /*!
221 \var IrcCommand::Stats
222 \brief A stats command (STATS) is used to query server statistics.
223 */
224
225 /*!
226 \var IrcCommand::Time
227 \brief A time command (TIME) is used to query local server time.
228 */
229
230 /*!
231 \var IrcCommand::Topic
232 \brief A topic command (TOPIC) is used to change or view the topic of a channel.
233 */
234
235 /*!
236 \var IrcCommand::Trace
237 \brief A trace command (TRACE) is used to trace the connection path to a target.
238 */
239
240 /*!
241 \var IrcCommand::Users
242 \brief A users command (USERS) is used to query server users.
243 */
244
245 /*!
246 \var IrcCommand::Version
247 \brief A version command (VERSION) is used to query user or server version.
248 */
249
250 /*!
251 \var IrcCommand::Who
252 \brief A who command (WHO) is used to generate a query which returns a list of matching users.
253 */
254
255 /*!
256 \var IrcCommand::Whois
257 \brief A whois command (WHOIS) is used to query information about a particular user.
258 */
259
260 /*!
261 \var IrcCommand::Whowas
262 \brief A whowas command (WHOWAS) is used to query information about a user that no longer exists.
263 */
264
265 extern bool irc_is_supported_encoding(const QByteArray& encoding); // ircmessagedecoder.cpp
266
267 #ifndef IRC_DOXYGEN
IrcCommandPrivate()268 IrcCommandPrivate::IrcCommandPrivate() : encoding("UTF-8")
269 {
270 }
271
params(int index) const272 QString IrcCommandPrivate::params(int index) const
273 {
274 return QStringList(parameters.mid(index)).join(QLatin1String(" "));
275 }
276
createCommand(IrcCommand::Type type,const QStringList & parameters)277 IrcCommand* IrcCommandPrivate::createCommand(IrcCommand::Type type, const QStringList& parameters)
278 {
279 IrcCommand* command = new IrcCommand;
280 command->setType(type);
281 command->setParameters(parameters);
282 return command;
283 }
284 #endif // IRC_DOXYGEN
285
286 /*!
287 Constructs a new IrcCommand with \a parent.
288 */
IrcCommand(QObject * parent)289 IrcCommand::IrcCommand(QObject* parent) : QObject(parent), d_ptr(new IrcCommandPrivate)
290 {
291 }
292
293 /*!
294 Destructs the IRC command.
295 */
~IrcCommand()296 IrcCommand::~IrcCommand()
297 {
298 }
299
300 /*!
301 \since 3.3
302
303 This property holds the connection that this command was sent to.
304
305 The connection is only set if the command has been passed to IrcConnection::sendCommand().
306 It is mostly usable to know the associated connection in IrcCommandFilter::commandFilter().
307
308 \par Access function:
309 \li \ref IrcConnection* <b>connection</b>() const
310 */
connection() const311 IrcConnection* IrcCommand::connection() const
312 {
313 Q_D(const IrcCommand);
314 return d->connection;
315 }
316
317 /*!
318 \since 3.5
319
320 This property holds the network that this command was sent to.
321
322 The network is only set if the command has been passed to IrcConnection::sendCommand().
323
324 \par Access function:
325 \li \ref IrcNetwork* <b>network</b>() const
326 */
network() const327 IrcNetwork* IrcCommand::network() const
328 {
329 Q_D(const IrcCommand);
330 return d->connection ? d->connection->network() : nullptr;
331 }
332
333 /*!
334 This property holds the command type.
335
336 \par Access functions:
337 \li IrcCommand::Type <b>type</b>() const
338 \li void <b>setType</b>(IrcCommand::Type type)
339 */
type() const340 IrcCommand::Type IrcCommand::type() const
341 {
342 Q_D(const IrcCommand);
343 return d->type;
344 }
345
setType(Type type)346 void IrcCommand::setType(Type type)
347 {
348 Q_D(IrcCommand);
349 d->type = type;
350 }
351
352 /*!
353 This property holds the command parameters.
354
355 \par Access functions:
356 \li QStringList <b>parameters</b>() const
357 \li void <b>setParameters</b>(const QStringList& parameters)
358 */
parameters() const359 QStringList IrcCommand::parameters() const
360 {
361 Q_D(const IrcCommand);
362 return d->parameters;
363 }
364
setParameters(const QStringList & parameters)365 void IrcCommand::setParameters(const QStringList& parameters)
366 {
367 Q_D(IrcCommand);
368 d->parameters = parameters;
369 }
370
371 /*!
372 This property holds the encoding that is used when
373 sending the command via IrcConnection::sendCommand().
374
375 See QTextCodec::availableCodes() for the list of
376 supported encodings. The default value is \c "UTF-8".
377
378 \par Access functions:
379 \li QByteArray <b>encoding</b>() const
380 \li void <b>setEncoding</b>(const QByteArray& encoding)
381
382 \sa QTextCodec::availableCodecs()
383 */
encoding() const384 QByteArray IrcCommand::encoding() const
385 {
386 Q_D(const IrcCommand);
387 return d->encoding;
388 }
389
setEncoding(const QByteArray & encoding)390 void IrcCommand::setEncoding(const QByteArray& encoding)
391 {
392 Q_D(IrcCommand);
393 if (!irc_is_supported_encoding(encoding)) {
394 qWarning() << "IrcCommand::setEncoding(): unsupported encoding" << encoding;
395 return;
396 }
397 d->encoding = encoding;
398 }
399
400 /*!
401 Returns the command as a string.
402
403 Reimplement for custom commands.
404 \sa IrcCommand::Custom
405 */
toString() const406 QString IrcCommand::toString() const
407 {
408 Q_D(const IrcCommand);
409 const QString p0 = d->parameters.value(0);
410 const QString p1 = d->parameters.value(1);
411 const QString p2 = d->parameters.value(2);
412
413 switch (d->type) {
414 case Admin: return QString("ADMIN %1").arg(p0); // server
415 case Away: return QString("AWAY :%1").arg(d->params(0)); // reason
416 case Capability: return QString("CAP %1 :%2").arg(p0, d->params(1)); // subcmd, caps
417 case CtcpAction: return QString("PRIVMSG %1 :\1ACTION %2\1").arg(p0, d->params(1)); // target, msg
418 case CtcpRequest: return QString("PRIVMSG %1 :\1%2\1").arg(p0, d->params(1)); // target, msg
419 case CtcpReply: return QString("NOTICE %1 :\1%2\1").arg(p0, d->params(1)); // target, msg
420 case Info: return QString("INFO %1").arg(p0); // server
421 case Invite: return QString("INVITE %1 %2").arg(p0, p1); // user, chan
422 case Join: return p1.isNull() ? QString("JOIN %1").arg(p0) : QString("JOIN %1 %2").arg(p0, p1); // chan, key
423 case Kick: return p2.isNull() ? QString("KICK %1 %2").arg(p0, p1) : QString("KICK %1 %2 :%3").arg(p0, p1, d->params(2)); // chan, user, reason
424 case Knock: return QString("KNOCK %1 %2").arg(p0, p1); // chan, msg
425 case List: return p1.isNull() ? QString("LIST %1").arg(p0) : QString("LIST %1 %2").arg(p0, p1); // chan, server
426 case Message: return QString("PRIVMSG %1 :%2").arg(p0, d->params(1)); // target, msg
427 case Mode: return QString("MODE ") + d->parameters.join(" "); // target, mode, arg
428 case Monitor: return QString("MONITOR %1 %2").arg(p0, p1); // cmd, target
429 case Motd: return QString("MOTD %1").arg(p0); // server
430 case Names: return QString("NAMES %1").arg(p0); // chan
431 case Nick: return QString("NICK %1").arg(p0); // nick
432 case Notice: return QString("NOTICE %1 :%2").arg(p0, d->params(1)); // target, msg
433 case Part: return p1.isNull() ? QString("PART %1").arg(p0) : QString("PART %1 :%2").arg(p0, d->params(1)); // chan, reason
434 case Ping: return QString("PING %1").arg(p0); // argument
435 case Pong: return QString("PONG %1").arg(p0); // argument
436 case Quit: return QString("QUIT :%1").arg(d->params(0)); // reason
437 case Quote: return d->parameters.join(" ");
438 case Stats: return QString("STATS %1 %2").arg(p0, p1); // query, server
439 case Time: return QString("TIME %1").arg(p0); // server
440 case Topic: return p1.isNull() ? QString("TOPIC %1").arg(p0) : QString("TOPIC %1 :%2").arg(p0, d->params(1)); // chan, topic
441 case Trace: return QString("TRACE %1").arg(p0); // target
442 case Users: return QString("USERS %1").arg(p0); // server
443 case Version: return p0.isNull() ? QString("VERSION") : QString("PRIVMSG %1 :\1VERSION\1").arg(p0); // user
444 case Who: return QString("WHO %1").arg(p0); // user
445 case Whois: return QString("WHOIS %1 %1").arg(p0); // user
446 case Whowas: return QString("WHOWAS %1 %1").arg(p0); // user
447
448 case Custom: qWarning("Reimplement IrcCommand::toString() for IrcCommand::Custom");
449 Q_FALLTHROUGH();
450 default: return QString();
451 }
452 }
453
454 /*!
455 Creates a new message from this command for \a prefix and \a connection.
456
457 Notice that IRC servers do not echo sent message commands back to the client.
458 This function is particularly useful for converting sent message commands as
459 messages for presentation purposes.
460
461 \code
462 if (command->type() == IrcCommand::Message) {
463 IrcMessage* message = command->toMessage(connection->nickName(), connection);
464 receiveMessage(message);
465 message->deleteLater();
466 }
467 \endcode
468 */
toMessage(const QString & prefix,IrcConnection * connection) const469 IrcMessage* IrcCommand::toMessage(const QString& prefix, IrcConnection* connection) const
470 {
471 return IrcMessage::fromData(":" + prefix.toUtf8() + " " + toString().toUtf8(), connection);
472 }
473
474 /*!
475 Creates a new ADMIN command with type IrcCommand::Admin and optional parameter \a server.
476
477 This command shows admin info for the specified \a server,
478 or the current server if not specified.
479 */
createAdmin(const QString & server)480 IrcCommand* IrcCommand::createAdmin(const QString& server)
481 {
482 return IrcCommandPrivate::createCommand(Admin, QStringList() << server);
483 }
484
485 /*!
486 Creates a new AWAY command with type IrcCommand::Away and optional parameter \a reason.
487
488 Provides the server with \a reason to automatically send in reply to a private
489 message directed at the user. If \a reason is omitted, the away status is removed.
490 */
createAway(const QString & reason)491 IrcCommand* IrcCommand::createAway(const QString& reason)
492 {
493 return IrcCommandPrivate::createCommand(Away, QStringList() << reason);
494 }
495
496 /*!
497 Creates a new capability command with type IrcCommand::Capability and parameters \a subCommand and a \a capability.
498
499 Available subcommands are: LS, LIST, REQ, ACK, NAK, CLEAR and END.
500
501 \sa \ref ircv3
502 */
createCapability(const QString & subCommand,const QString & capability)503 IrcCommand* IrcCommand::createCapability(const QString& subCommand, const QString& capability)
504 {
505 return createCapability(subCommand, QStringList() << capability);
506 }
507
508 /*!
509 Creates a new capability command with type IrcCommand::Capability and parameters \a subCommand and optional \a capabilities.
510
511 Available subcommands are: LS, LIST, REQ, ACK, NAK, CLEAR and END.
512
513 \sa \ref ircv3
514 */
createCapability(const QString & subCommand,const QStringList & capabilities)515 IrcCommand* IrcCommand::createCapability(const QString& subCommand, const QStringList& capabilities)
516 {
517 return IrcCommandPrivate::createCommand(Capability, QStringList() << subCommand << capabilities.join(QLatin1String(" ")));
518 }
519
520 /*!
521 Creates a new CTCP action command with type IrcCommand::CtcpAction and parameters \a target and \a action.
522 */
createCtcpAction(const QString & target,const QString & action)523 IrcCommand* IrcCommand::createCtcpAction(const QString& target, const QString& action)
524 {
525 return IrcCommandPrivate::createCommand(CtcpAction, QStringList() << target << action);
526 }
527
528 /*!
529 Creates a new CTCP reply command with type IrcCommand::CtcpReply and parameters \a target and \a reply.
530 */
createCtcpReply(const QString & target,const QString & reply)531 IrcCommand* IrcCommand::createCtcpReply(const QString& target, const QString& reply)
532 {
533 return IrcCommandPrivate::createCommand(CtcpReply, QStringList() << target << reply);
534 }
535
536 /*!
537 Creates a new CTCP request command with type IrcCommand::CtcpRequest and parameters \a target and \a request.
538 */
createCtcpRequest(const QString & target,const QString & request)539 IrcCommand* IrcCommand::createCtcpRequest(const QString& target, const QString& request)
540 {
541 return IrcCommandPrivate::createCommand(CtcpRequest, QStringList() << target << request);
542 }
543
544 /*!
545 Creates a new INFO command with type IrcCommand::Info and optional parameter \a server.
546
547 This command shows info for the specified \a server,
548 or the current server if not specified.
549 */
createInfo(const QString & server)550 IrcCommand* IrcCommand::createInfo(const QString& server)
551 {
552 return IrcCommandPrivate::createCommand(Info, QStringList() << server);
553 }
554
555 /*!
556 Creates a new INVITE command with type IrcCommand::Invite and parameters \a user and \a channel.
557
558 This command invites \a user to the \a channel. The channel does not have to exist, but
559 if it does, only members of the channel are allowed to invite other clients. if the
560 channel mode +i (invite-only) is set, only channel operators may invite other clients.
561 */
createInvite(const QString & user,const QString & channel)562 IrcCommand* IrcCommand::createInvite(const QString& user, const QString& channel)
563 {
564 return IrcCommandPrivate::createCommand(Invite, QStringList() << user << channel);
565 }
566
567 /*!
568 Creates a new JOIN command with type IrcCommand::Join and parameters \a channel and optional \a key.
569
570 This command joins the \a channel using \a key if specified.
571 If the channel does not exist, it will be created.
572 */
createJoin(const QString & channel,const QString & key)573 IrcCommand* IrcCommand::createJoin(const QString& channel, const QString& key)
574 {
575 return IrcCommandPrivate::createCommand(Join, QStringList() << channel << key);
576 }
577
578 /*!
579 This overload is provided for convenience.
580 */
createJoin(const QStringList & channels,const QStringList & keys)581 IrcCommand* IrcCommand::createJoin(const QStringList& channels, const QStringList& keys)
582 {
583 if (keys.isEmpty() || keys.join("").isEmpty())
584 return IrcCommandPrivate::createCommand(Join, QStringList() << channels.join(","));
585 return IrcCommandPrivate::createCommand(Join, QStringList() << channels.join(",") << keys.join(","));
586 }
587
588 /*!
589 Creates a new KICK command with type IrcCommand::Kick and parameters \a channel, \a user and optional \a reason.
590
591 This command forcibly removes \a user from \a channel,
592 and may only be issued by channel operators.
593 */
createKick(const QString & channel,const QString & user,const QString & reason)594 IrcCommand* IrcCommand::createKick(const QString& channel, const QString& user, const QString& reason)
595 {
596 return IrcCommandPrivate::createCommand(Kick, QStringList() << channel << user << reason);
597 }
598
599 /*!
600 Creates a new KNOCK command with type IrcCommand::Knock and parameters \a channel and optional \a message.
601
602 This command sends an invitation request to a \a channel with an optional \a message.
603
604 \note The command is not formally defined by an RFC, but is supported by most major IRC daemons.
605 Support is indicated in a RPL_ISUPPORT reply (numeric 005) with the KNOCK keyword.
606 */
createKnock(const QString & channel,const QString & message)607 IrcCommand* IrcCommand::createKnock(const QString& channel, const QString& message)
608 {
609 return IrcCommandPrivate::createCommand(Knock, QStringList() << channel << message);
610 }
611
612 /*!
613 Creates a new LIST command with type IrcCommand::List and optional parameters \a channels and \a server.
614
615 This command lists all channels on the server. If \a channels are given, it will list the channel topics.
616 If \a server is given, the command will be forwarded to \a server for evaluation.
617 */
createList(const QStringList & channels,const QString & server)618 IrcCommand* IrcCommand::createList(const QStringList& channels, const QString& server)
619 {
620 return IrcCommandPrivate::createCommand(List, QStringList() << channels.join(",") << server);
621 }
622
623 /*!
624 Creates a new PRIVMSG command with type IrcCommand::Message and parameters \a target and \a message.
625
626 This command sends \a message to \a target, which is usually a user or channel.
627 */
createMessage(const QString & target,const QString & message)628 IrcCommand* IrcCommand::createMessage(const QString& target, const QString& message)
629 {
630 return IrcCommandPrivate::createCommand(Message, QStringList() << target << message);
631 }
632
633 /*!
634 Creates a new MODE command with type IrcCommand::Mode and parameters \a target and optional \a mode and \a arg.
635
636 This command is used to set both user and channel modes.
637 */
createMode(const QString & target,const QString & mode,const QString & arg)638 IrcCommand* IrcCommand::createMode(const QString& target, const QString& mode, const QString& arg)
639 {
640 return IrcCommandPrivate::createCommand(Mode, QStringList() << target << mode << arg);
641 }
642
643 /*!
644 \since 3.4
645
646 Creates a new MONITOR command with type IrcCommand::Monitor and parameters \a command and and optional \a target.
647
648 Available commands are:
649 \li \c + - Adds the given list of targets to the list of targets being monitored.
650 \li \c + - Removes the given list of targets from the list of targets being monitored.
651 No output will be returned for use of this command.
652 \li \c C - Clears the list of targets being monitored. No output will be returned for use of this command.
653 \li \c L - Outputs the current list of targets being monitored. All output will use RPL_MONLIST,
654 and the output will be terminated with RPL_ENDOFMONLIST.
655 \li \c S - Outputs for each target in the list being monitored, whether the client is online or offline.
656 All targets that are online will be sent using RPL_MONONLINE, all targets that are offline will
657 be sent using RPL_MONOFFLINE.
658
659 \sa \ref ircv3
660 */
createMonitor(const QString & command,const QString & target)661 IrcCommand* IrcCommand::createMonitor(const QString& command, const QString& target)
662 {
663 return IrcCommandPrivate::createCommand(Monitor, QStringList() << command << target);
664 }
665
666 /*!
667 \since 3.4
668
669 Creates a new MONITOR command with type IrcCommand::Monitor and parameters \a command and \a targets.
670
671 Available commands are:
672 \li \c + - Adds the given list of targets to the list of targets being monitored.
673 \li \c + - Removes the given list of targets from the list of targets being monitored.
674 No output will be returned for use of this command.
675 \li \c C - Clears the list of targets being monitored. No output will be returned for use of this command.
676 \li \c L - Outputs the current list of targets being monitored. All output will use RPL_MONLIST,
677 and the output will be terminated with RPL_ENDOFMONLIST.
678 \li \c S - Outputs for each target in the list being monitored, whether the client is online or offline.
679 All targets that are online will be sent using RPL_MONONLINE, all targets that are offline will
680 be sent using RPL_MONOFFLINE.
681
682 \sa \ref ircv3
683 */
createMonitor(const QString & command,const QStringList & targets)684 IrcCommand* IrcCommand::createMonitor(const QString& command, const QStringList& targets)
685 {
686 return IrcCommandPrivate::createCommand(Monitor, QStringList() << command << targets.join(","));
687 }
688
689 /*!
690 Creates a new MOTD command with type IrcCommand::Motd and optional parameter \a server.
691
692 This command shows the message of the day on the specified \a server,
693 or the current server if not specified.
694 */
createMotd(const QString & server)695 IrcCommand* IrcCommand::createMotd(const QString& server)
696 {
697 return IrcCommandPrivate::createCommand(Motd, QStringList() << server);
698 }
699
700 /*!
701 Creates a new NAMES command with type IrcCommand::Names and parameter \a channel.
702
703 This command lists all users on the \a channel, optionally limiting to the given \a server.
704
705 If \a channel is omitted, all users are shown, grouped by channel name with
706 all users who are not on a channel being shown as part of channel "*".
707 If \a server is specified, the command is sent to \a server for evaluation.
708 */
createNames(const QString & channel,const QString & server)709 IrcCommand* IrcCommand::createNames(const QString& channel, const QString& server)
710 {
711 return IrcCommandPrivate::createCommand(Names, QStringList() << channel << server);
712 }
713
714 /*!
715 This overload is provided for convenience.
716 */
createNames(const QStringList & channels,const QString & server)717 IrcCommand* IrcCommand::createNames(const QStringList& channels, const QString& server)
718 {
719 return IrcCommandPrivate::createCommand(Names, QStringList() << channels.join(",") << server);
720 }
721
722 /*!
723 Creates a new NICK command with type IrcCommand::Nick and parameter \a nick.
724
725 This command allows a client to change their IRC nickname.
726 */
createNick(const QString & nick)727 IrcCommand* IrcCommand::createNick(const QString& nick)
728 {
729 return IrcCommandPrivate::createCommand(Nick, QStringList() << nick);
730 }
731
732 /*!
733 Creates a new NOTICE command with type IrcCommand::Notice and parameters \a target and \a message.
734
735 This command sends \a notice to \a target, which is usually a user or channel.
736
737 \note The command works similarly to PRIVMSG, except automatic replies must never be sent in reply to NOTICE messages.
738 */
createNotice(const QString & target,const QString & message)739 IrcCommand* IrcCommand::createNotice(const QString& target, const QString& message)
740 {
741 return IrcCommandPrivate::createCommand(Notice, QStringList() << target << message);
742 }
743
744 /*!
745 Creates a new PART command with type IrcCommand::Part and parameters \a channel and optional \a reason.
746
747 This command causes the client to leave the specified channel.
748 */
createPart(const QString & channel,const QString & reason)749 IrcCommand* IrcCommand::createPart(const QString& channel, const QString& reason)
750 {
751 return IrcCommandPrivate::createCommand(Part, QStringList() << channel << reason);
752 }
753
754 /*!
755 This overload is provided for convenience.
756 */
createPart(const QStringList & channels,const QString & reason)757 IrcCommand* IrcCommand::createPart(const QStringList& channels, const QString& reason)
758 {
759 return IrcCommandPrivate::createCommand(Part, QStringList() << channels.join(",") << reason);
760 }
761
762 /*!
763 Creates a new PING command with type IrcCommand::Ping and \a argument.
764 */
createPing(const QString & argument)765 IrcCommand* IrcCommand::createPing(const QString& argument)
766 {
767 return IrcCommandPrivate::createCommand(Ping, QStringList() << argument);
768 }
769
770 /*!
771 Creates a new PONG command with type IrcCommand::Pong and \a argument.
772 */
createPong(const QString & argument)773 IrcCommand* IrcCommand::createPong(const QString& argument)
774 {
775 return IrcCommandPrivate::createCommand(Pong, QStringList() << argument);
776 }
777
778 /*!
779 Creates a new QUIT command with type IrcCommand::Quit and optional parameter \a reason.
780 */
createQuit(const QString & reason)781 IrcCommand* IrcCommand::createQuit(const QString& reason)
782 {
783 return IrcCommandPrivate::createCommand(Quit, QStringList() << reason);
784 }
785
786 /*!
787 Creates a new QUOTE command with type IrcCommand::Quote and \a raw.
788 */
createQuote(const QString & raw)789 IrcCommand* IrcCommand::createQuote(const QString& raw)
790 {
791 return IrcCommandPrivate::createCommand(Quote, QStringList() << raw);
792 }
793
794 /*!
795 Creates a new QUOTE command with type IrcCommand::Quote and \a parameters.
796 */
createQuote(const QStringList & parameters)797 IrcCommand* IrcCommand::createQuote(const QStringList& parameters)
798 {
799 return IrcCommandPrivate::createCommand(Quote, parameters);
800 }
801
802 /*!
803 Creates a new STATS command with type IrcCommand::Stats and parameters \a query and optional \a server.
804
805 This command queries statistics about the specified \a server,
806 or the current server if not specified.
807 */
createStats(const QString & query,const QString & server)808 IrcCommand* IrcCommand::createStats(const QString& query, const QString& server)
809 {
810 return IrcCommandPrivate::createCommand(Stats, QStringList() << query << server);
811 }
812
813 /*!
814 Creates a new TIME command with type IrcCommand::Time and optional parameter \a server.
815
816 This command queries local time of the specified \a server,
817 or the current server if not specified.
818 */
createTime(const QString & server)819 IrcCommand* IrcCommand::createTime(const QString& server)
820 {
821 return IrcCommandPrivate::createCommand(Time, QStringList() << server);
822 }
823
824 /*!
825 Creates a new TOPIC command with type IrcCommand::Topic and parameters \a channel and optional \a topic.
826
827 This command allows the client to query or set the channel topic on \a channel.
828 If \a topic is given, it sets the channel topic to \a topic.
829 If channel mode +t is set, only a channel operator may set the topic.
830 */
createTopic(const QString & channel,const QString & topic)831 IrcCommand* IrcCommand::createTopic(const QString& channel, const QString& topic)
832 {
833 return IrcCommandPrivate::createCommand(Topic, QStringList() << channel << topic);
834 }
835
836 /*!
837 Creates a new TRACE command with type IrcCommand::Trace and optional parameter \a target.
838
839 This command traces the connection path across the IRC network
840 to the current server or to a specific \a target (server or client)
841 in a similar method to traceroute.
842 */
createTrace(const QString & target)843 IrcCommand* IrcCommand::createTrace(const QString& target)
844 {
845 return IrcCommandPrivate::createCommand(Trace, QStringList() << target);
846 }
847
848 /*!
849 Creates a new USERS command with type IrcCommand::Users and optional parameter \a server.
850
851 This command queries the users of the specified \a server,
852 or the current server if not specified.
853 */
createUsers(const QString & server)854 IrcCommand* IrcCommand::createUsers(const QString& server)
855 {
856 return IrcCommandPrivate::createCommand(Users, QStringList() << server);
857 }
858
859 /*!
860 Creates a new command with type IrcCommand::Version and optional parameter \a user.
861
862 This command queries the version of the specified \a user's client (CTCP REQUEST VERSION),
863 or the current server (VERSION) if not specified.
864 */
createVersion(const QString & user)865 IrcCommand* IrcCommand::createVersion(const QString& user)
866 {
867 return IrcCommandPrivate::createCommand(Version, QStringList() << user);
868 }
869
870 /*!
871 Creates a new WHO command with type IrcCommand::Who and parameters \a mask and optional \a operators.
872
873 This command returns a list of users who match \a mask,
874 optionally matching only IRC \a operators.
875 */
createWho(const QString & mask,bool operators)876 IrcCommand* IrcCommand::createWho(const QString& mask, bool operators)
877 {
878 return IrcCommandPrivate::createCommand(Who, QStringList() << mask << (operators ? "o" : ""));
879 }
880
881 /*!
882 Creates a new WHOIS command with type IrcCommand::Whois and parameter \a user.
883
884 This command returns information about \a user.
885 */
createWhois(const QString & user)886 IrcCommand* IrcCommand::createWhois(const QString& user)
887 {
888 return IrcCommandPrivate::createCommand(Whois, QStringList() << user);
889 }
890
891 /*!
892 Creates a new WHOWAS command with type IrcCommand::Whowas and parameters \a user and optional \a count.
893
894 This command returns information about a \a user that is no longer online
895 (due to client disconnection, or nickname changes). If given, the server
896 will return information from the last \a count times the nickname has been used.
897 */
createWhowas(const QString & user,int count)898 IrcCommand* IrcCommand::createWhowas(const QString& user, int count)
899 {
900 return IrcCommandPrivate::createCommand(Whowas, QStringList() << user << QString::number(count));
901 }
902
903 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug debug,IrcCommand::Type type)904 QDebug operator<<(QDebug debug, IrcCommand::Type type)
905 {
906 const int index = IrcCommand::staticMetaObject.indexOfEnumerator("Type");
907 QMetaEnum enumerator = IrcCommand::staticMetaObject.enumerator(index);
908 const char* key = enumerator.valueToKey(type);
909 debug << (key ? key : "Unknown");
910 return debug;
911 }
912
operator <<(QDebug debug,const IrcCommand * command)913 QDebug operator<<(QDebug debug, const IrcCommand* command)
914 {
915 if (!command)
916 return debug << "IrcCommand(0x0) ";
917 debug.nospace() << command->metaObject()->className() << '(' << (void*) command;
918 if (!command->objectName().isEmpty())
919 debug.nospace() << ", name=" << qPrintable(command->objectName());
920 debug.nospace() << ", type=" << command->type();
921 QString str = command->toString();
922 if (!str.isEmpty())
923 debug.nospace() << ", " << str.left(20);
924 debug.nospace() << ')';
925 return debug.space();
926 }
927 #endif // QT_NO_DEBUG_STREAM
928
929 #include "moc_irccommand.cpp"
930
931 IRC_END_NAMESPACE
932