cb21075d |
1 | // Commands.C -*- C++ -*- |
2 | // Copyright (c) 1998 Etienne BERNARD |
a6339323 |
3 | // Copyright (C) 2002,2005 Clinton Ebadi |
cb21075d |
4 | |
5 | // This program is free software; you can redistribute it and/or modify |
6 | // it under the terms of the GNU General Public License as published by |
7 | // the Free Software Foundation; either version 2 of the License, or |
8 | // any later version. |
9 | |
10 | // This program is distributed in the hope that it will be useful, |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | // GNU General Public License for more details. |
14 | |
15 | // You should have received a copy of the GNU General Public License |
16 | // along with this program; if not, write to the Free Software |
c6e7af05 |
17 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
18 | // 02110-1301, USA. |
cb21075d |
19 | |
cfa82921 |
20 | #include "Commands.H" |
21 | |
71cf2688 |
22 | #include <functional> |
23 | |
cfa82921 |
24 | #include "BanEntry.H" |
25 | #include "Bot.H" |
26 | #include "ChannelList.H" |
cb21075d |
27 | #include "Macros.H" |
28 | #include "Message.H" |
cfa82921 |
29 | #include "Server.H" |
30 | #include "ServerConnection.H" |
31 | #include "ServerList.H" |
32 | #include "ServerQueueItem.H" |
33 | #include "ShitEntry.H" |
34 | #include "ShitList.H" |
6b7614a8 |
35 | #include "StringTokenizer.H" |
cfa82921 |
36 | #include "User.H" |
37 | #include "UserList.H" |
38 | #include "Utils.H" |
39 | |
40 | #ifdef USESCRIPTS |
41 | #include "BotInterp.H" |
42 | #endif |
cb21075d |
43 | |
cb21075d |
44 | |
45 | #define CHECK_CONNECTION if (!bot->serverConnection) return NotConnected |
46 | |
47 | Message |
48 | Commands::Action(Bot *bot, String channel, String message) |
49 | { |
50 | CHECK_CONNECTION; |
51 | |
52 | if (!CHANNEL(channel)) |
53 | return NotOnChannel(channel); |
54 | |
55 | if (message.length() == 0) |
56 | return InvalidParameters; |
57 | |
672b7d4e |
58 | Commands::CTCP (bot, channel, "ACTION", message); |
cb21075d |
59 | |
60 | return Ok; |
61 | } |
62 | |
63 | Message |
64 | Commands::AddUser(Bot *bot, String who, String maskChannel, int level, |
65 | int prot, bool aop, std::time_t expire, String password) |
66 | { |
67 | // Gah, fix this (makes bot segfault) |
68 | if (who.length() == 0 || |
69 | maskChannel.length() == 0 || |
70 | level < 0 || |
71 | level > User::FRIEND || |
72 | prot < 0 || |
73 | prot > User::NO_DEOP) |
74 | return InvalidParameters; |
75 | |
76 | String mask; |
77 | |
a6339323 |
78 | if (!Utils::wildcard_p(who)) |
cb21075d |
79 | { |
0316e2c1 |
80 | mask = bot->getUserhost("", who); |
81 | if (mask.length() == 0) |
82 | { |
83 | return NotFound(who); |
84 | } |
85 | } |
cb21075d |
86 | // Aha! This was before the brace...segfault gone |
a6339323 |
87 | mask = Utils::make_wildcard(mask); |
cb21075d |
88 | |
89 | if (bot->userList->isInUserList(mask, maskChannel)) |
0316e2c1 |
90 | { |
91 | return AlreadyInUserlist(mask, maskChannel); |
92 | } |
cb21075d |
93 | |
94 | bot->userList->addUser(mask, maskChannel, level, prot, aop, |
95 | expire, password); |
96 | bot->rehash(); |
97 | |
98 | return Ok; |
99 | } |
100 | |
101 | |
102 | Message |
103 | Commands::AddServer(Bot *bot, String servername, int port) |
104 | { |
105 | if (port <= 0) |
106 | return InvalidPort(port); |
107 | |
108 | bot->serverList->addServer(new class Server(servername, port)); |
109 | |
110 | return Ok; |
111 | } |
112 | |
113 | |
114 | Message |
115 | Commands::AddShit(Bot *bot, String mask, String maskChannel, |
116 | int level, time_t expiration, String reason) |
117 | { |
118 | if (mask.length() == 0 || maskChannel.length() == 0 || |
119 | level < 0 || level > ShitEntry::SHIT_NODEBAN) |
120 | return InvalidParameters; |
121 | |
122 | if (reason == "") |
123 | reason = "You're on my shitlist, lamer"; |
124 | |
125 | String who = mask; |
126 | |
a6339323 |
127 | if (!Utils::wildcard_p(mask)) { |
cb21075d |
128 | mask = bot->getUserhost("", who); |
129 | if (mask.length() == 0) |
130 | return NotFound(who); |
a6339323 |
131 | mask = Utils::make_wildcard(mask); |
cb21075d |
132 | if (bot->shitList->getShit(mask, maskChannel)) |
133 | return AlreadyInShitlist(mask, maskChannel); |
134 | } |
135 | |
136 | if (bot->userList->getMaxProt(mask, maskChannel) > 0) |
137 | return UserProtected(who, maskChannel); |
138 | |
139 | bot->shitList->addShit(mask, maskChannel, level, expiration, reason); |
140 | |
141 | return Ok; |
142 | } |
143 | |
144 | |
145 | Message |
146 | Commands::Ban(Bot *bot, String channel, String who) |
147 | { |
148 | CHECK_CONNECTION; |
149 | |
150 | Channel *c = CHANNEL(channel); |
151 | |
152 | if (!c) |
153 | return NotOnChannel(channel); |
154 | |
155 | if (!bot->iAmOp(channel)) |
156 | return NotChannelOp(channel); |
157 | |
158 | String dest; |
159 | |
a6339323 |
160 | if (!Utils::wildcard_p(who)) |
cb21075d |
161 | dest = bot->getUserhost(channel, who); |
162 | else |
163 | dest = who; |
164 | |
165 | if (dest.length() == 0) |
166 | return NotFound(who); |
167 | |
a6339323 |
168 | dest = Utils::make_wildcard(dest); |
cb21075d |
169 | Mask m(dest); |
170 | |
171 | for (std::list<UserListItem *>::iterator it = bot->userList->l.begin(); |
172 | it != bot->userList->l.end(); |
173 | it++) |
174 | if (m.matches((*it)->mask) && |
175 | (*it)->channelMask.matches(channel) && |
176 | (*it)->prot >= User::NO_BAN) |
177 | return UserProtected(who, channel); |
cb21075d |
178 | |
f9723c92 |
179 | c->delBan (m); |
180 | c->addBan (m, -1); |
181 | |
cb21075d |
182 | return Ok; |
183 | } |
184 | |
672b7d4e |
185 | Message |
186 | Commands::CTCP (Bot *bot, std::string target, std::string command, |
187 | std::string message) |
188 | { |
189 | CHECK_CONNECTION; |
190 | |
191 | if (target == "") |
192 | { |
193 | return EmptyAddressee; |
194 | } |
195 | |
196 | if (command == "") |
197 | { |
198 | return InvalidParameters; |
199 | } |
200 | |
201 | if (message == "") |
202 | { |
203 | return EmptyMessage; |
204 | } |
205 | |
206 | if (Utils::channel_p (target) && !CHANNEL (target)) |
207 | { |
208 | return NotOnChannel (target); |
209 | } |
210 | |
211 | |
212 | // Send multi-line messages as seperate privmsgs |
213 | StringTokenizer st_message (message); |
214 | |
215 | while (st_message.more_tokens_p ('\n')) |
216 | { |
217 | QUEUE->sendCTCP (target, command, st_message.next_token ('\n')); |
218 | } |
219 | |
220 | return Ok; |
221 | } |
222 | |
223 | Message |
224 | Commands::CTCPReply (Bot *bot, std::string target, std::string command, |
225 | std::string message) |
226 | { |
227 | CHECK_CONNECTION; |
228 | |
229 | if (target == "") |
230 | { |
231 | return EmptyAddressee; |
232 | } |
233 | |
234 | if (command == "") |
235 | { |
236 | return InvalidParameters; |
237 | } |
238 | |
239 | if (message == "") |
240 | { |
241 | return EmptyMessage; |
242 | } |
243 | |
244 | // CTCP-REPLY cannot go to a channel |
245 | if (Utils::channel_p (target)) |
246 | { |
247 | return NotToChannel; |
248 | } |
249 | |
250 | |
251 | // Send multi-line messages as seperate privmsgs |
252 | StringTokenizer st_message (message); |
253 | |
254 | while (st_message.more_tokens_p ('\n')) |
255 | { |
256 | QUEUE->sendCTCPReply (target, command, st_message.next_token ('\n')); |
257 | } |
258 | |
259 | return Ok; |
260 | } |
261 | |
262 | |
cb21075d |
263 | Message |
264 | Commands::Cycle(Bot *bot, String channel) |
265 | { |
266 | CHECK_CONNECTION; |
267 | |
268 | if (!CHANNEL(channel)) |
269 | return NotOnChannel(channel); |
270 | |
271 | QUEUE->sendPart(channel); |
272 | QUEUE->sendJoin(channel, bot->wantedChannels[channel]->key); |
273 | |
274 | return Ok; |
275 | } |
276 | |
277 | Message |
278 | Commands::Deban(Bot *bot, String channel, String who) |
279 | { |
280 | CHECK_CONNECTION; |
281 | |
282 | Channel *c = CHANNEL(channel); |
283 | |
284 | if (!c) |
285 | return NotOnChannel(channel); |
286 | |
287 | if (!bot->iAmOp(channel)) |
288 | return NotChannelOp(channel); |
289 | |
290 | String dest; |
291 | |
a6339323 |
292 | if (!Utils::wildcard_p(who)) |
cb21075d |
293 | dest = bot->getUserhost(channel, who); |
294 | else |
295 | dest = who; |
296 | |
297 | if (dest.length() == 0) |
298 | return UserNotFound(who, channel); |
299 | |
a6339323 |
300 | dest = Utils::make_wildcard(dest); |
cb21075d |
301 | Mask m(dest); |
f9723c92 |
302 | |
303 | BanList::MatchList matches = c->channelBanlist.find_matches (m); |
cb21075d |
304 | |
f9723c92 |
305 | for (BanList::MatchList::iterator it = matches.begin (); |
306 | it != matches.end(); |
307 | ++it) |
308 | if (m.matches(*it)) |
309 | { |
310 | // Let's see if the ban is in the shitlist |
311 | ShitEntry *se = bot->shitList->getShit(it->getMask(), channel); |
312 | if (!se || !se->isStillValid() || |
313 | se->getShitLevel() < ShitEntry::SHIT_NODEBAN) |
314 | c->delBan (m); |
315 | } |
cb21075d |
316 | |
317 | return Ok; |
318 | } |
319 | |
320 | Message |
321 | Commands::DelServer(Bot *bot, int number) |
322 | { |
323 | if (number < 0 || number >= bot->serverList->size()) |
324 | return InvalidServerNumber(number); |
325 | |
326 | bot->serverList->delServer(number); |
327 | |
328 | return Ok; |
329 | } |
330 | |
331 | Message |
332 | Commands::DelUser(Bot *bot, String who, String maskChannel) |
333 | { |
334 | if (who.length() == 0 || maskChannel.length() == 0) |
335 | return InvalidParameters; |
336 | |
337 | String dest; |
338 | |
a6339323 |
339 | if (!Utils::wildcard_p(who)) { |
cb21075d |
340 | dest = bot->getUserhost("", who); |
341 | if (dest.length() == 0) |
342 | return NotFound(who); |
a6339323 |
343 | dest = Utils::make_wildcard(who); |
cb21075d |
344 | } |
345 | |
346 | if (!bot->userList->isInUserList(dest, maskChannel)) |
347 | return NotInUserlist(who); |
348 | |
349 | bot->userList->removeUser(dest, maskChannel); |
350 | bot->rehash(); |
351 | |
352 | return Ok; |
353 | } |
354 | |
355 | Message |
356 | Commands::DelShit(Bot *bot, String who, String maskChannel) |
357 | { |
358 | if (who.length() == 0 || maskChannel.length() == 0) |
359 | return InvalidParameters; |
360 | |
361 | String dest; |
362 | |
a6339323 |
363 | if (!Utils::wildcard_p(who)) { |
cb21075d |
364 | dest = bot->getUserhost("", who); |
365 | if (dest.length() == 0) |
366 | return NotFound(who); |
a6339323 |
367 | dest = Utils::make_wildcard(who); |
cb21075d |
368 | } |
369 | |
370 | if (!bot->shitList->getShit(dest, maskChannel)) |
371 | return NotInShitlist(who); |
372 | |
373 | bot->shitList->delShit(dest, maskChannel); |
374 | |
375 | return Ok; |
376 | } |
377 | |
71cf2688 |
378 | Commands::deop_wildcard::deop_wildcard |
379 | (Bot *b, Mask &m, String &c) |
380 | : bot (b), mask (m), channel (c) |
381 | { } |
382 | |
383 | void |
384 | Commands::deop_wildcard::operator() (const User &user) |
385 | { |
386 | if (mask.matches(user.nick + "!" + user.userhost) |
387 | && user.getProt() < User::NO_DEOP |
388 | && (user.mode & User::OP_MODE)) |
389 | QUEUE->sendChannelMode(channel, "-o", user.nick); |
390 | } |
391 | |
cb21075d |
392 | Message |
393 | Commands::Deop(Bot *bot, String channel, String who) |
394 | { |
395 | CHECK_CONNECTION; |
396 | |
397 | Channel *c = CHANNEL(channel); |
398 | |
399 | if (!c) |
400 | return NotOnChannel(channel); |
401 | |
402 | if (!bot->iAmOp(channel)) |
403 | return NotChannelOp(channel); |
404 | |
a6339323 |
405 | if (!Utils::wildcard_p(who)) { |
71cf2688 |
406 | try |
407 | { |
408 | User u = c->getUser(who); |
409 | |
410 | if (!(u.mode & User::OP_MODE)) |
411 | return UserNotOp(who, channel); |
412 | if (u.getProt() >= User::NO_DEOP) |
413 | return UserProtected(who, channel); |
414 | QUEUE->sendChannelMode(channel, "-o", who); |
415 | } |
416 | catch (const ChannelUserList::user_not_found &e) |
417 | { |
418 | return UserNotFound(e.name, channel); |
419 | } |
cb21075d |
420 | } else { |
71cf2688 |
421 | Mask m (who); |
422 | deop_wildcard f (bot, m, channel); |
423 | c->for_each_channel_users (f); |
cb21075d |
424 | } |
cb21075d |
425 | return Ok; |
426 | } |
427 | |
428 | Message |
429 | Commands::Die(Bot *bot, String reason) |
430 | { |
431 | CHECK_CONNECTION; |
432 | |
433 | QUEUE->sendQuit(reason); |
434 | bot->stop = true; |
435 | |
436 | return Ok; |
437 | } |
438 | |
439 | Message |
440 | Commands::Do(Bot *bot, String command) |
441 | { |
442 | CHECK_CONNECTION; |
443 | |
444 | QUEUE->addLine(command, 0, 0, ServerQueueItem::OTHER); |
445 | return Ok; |
446 | } |
447 | |
448 | Message |
449 | Commands::Invite(Bot *bot, String channel, String who) |
450 | { |
451 | CHECK_CONNECTION; |
452 | |
453 | if (!bot->iAmOp(channel)) |
454 | return NotChannelOp(channel); |
455 | |
456 | QUEUE->sendInvite(channel, who); |
457 | |
458 | return Ok; |
459 | } |
460 | |
461 | Message |
462 | Commands::Join(Bot *bot, String channel, String key) |
463 | { |
464 | CHECK_CONNECTION; |
465 | |
a6339323 |
466 | if (!Utils::valid_channel_name_p(channel)) |
cb21075d |
467 | return InvalidChannel(channel); |
468 | |
469 | // We change the key only if we are not on the channel. |
470 | // We don't trust the user... |
471 | if (!CHANNEL(channel)) { |
472 | if (bot->wantedChannels[channel]) |
71cf2688 |
473 | bot->wantedChannels[channel]->key = static_cast<std::string> (key); |
cb21075d |
474 | else { |
475 | bot->wantedChannels[channel] = new wantedChannel("", "", key); |
476 | } |
477 | } |
478 | QUEUE->sendJoin(channel, bot->wantedChannels[channel]->key); |
479 | |
480 | return Ok; |
481 | } |
482 | |
483 | Message |
484 | Commands::Keep(Bot *bot, String channel, String modes) |
485 | { |
486 | CHECK_CONNECTION; |
487 | |
488 | Channel *c = CHANNEL(channel); |
489 | |
490 | if (!c) |
491 | return NotOnChannel(channel); |
492 | |
493 | c->keepModes = modes; |
494 | |
495 | return Ok; |
496 | } |
497 | |
71cf2688 |
498 | Commands::kick_wildcard::kick_wildcard |
499 | (Bot *b, Mask &m, String &c, String &r) |
500 | : bot (b), mask (m), channel (c), reason (r) |
501 | { } |
502 | |
503 | void |
504 | Commands::kick_wildcard::operator() (const User &user) |
505 | { |
506 | if (mask.matches(user.nick + "!" + user.userhost) && |
507 | user.getProt() < User::NO_KICK) |
508 | QUEUE->sendKick(channel, user.nick, reason); |
509 | } |
510 | |
cb21075d |
511 | Message |
512 | Commands::Kick(Bot *bot, String channel, String who, String reason) |
513 | { |
514 | CHECK_CONNECTION; |
515 | |
516 | Channel *c = CHANNEL(channel); |
517 | |
518 | if (!c) |
519 | return NotOnChannel(channel); |
520 | |
521 | if (!bot->iAmOp(channel)) |
522 | return NotChannelOp(channel); |
523 | |
a6339323 |
524 | if (Utils::wildcard_p(who)) { |
cb21075d |
525 | Mask m(who); |
71cf2688 |
526 | kick_wildcard f (bot, m, channel, reason); |
527 | c->for_each_channel_users (f); |
cb21075d |
528 | } else { |
71cf2688 |
529 | try |
530 | { |
531 | User u = c->getUser(who); |
532 | |
533 | if (u.getProt() < User::NO_KICK) |
534 | QUEUE->sendKick(channel, who, reason); |
535 | else |
536 | return UserProtected(who, channel); |
537 | } |
538 | catch (const ChannelUserList::user_not_found &e) |
539 | { |
540 | return UserNotFound(e.name, channel); |
541 | } |
cb21075d |
542 | } |
543 | |
544 | return Ok; |
545 | } |
546 | |
547 | Message |
548 | Commands::KickBan(Bot *bot, String channel, String who, String reason) |
549 | { |
550 | CHECK_CONNECTION; |
551 | |
552 | Message m = Commands::Ban(bot, channel, who); |
553 | |
554 | if (m.getCode() == 0) |
555 | m = Commands::Kick(bot, channel, who, reason); |
556 | |
557 | return m; |
558 | } |
559 | |
560 | Message |
561 | Commands::Lock(Bot *bot, String channel) |
562 | { |
563 | CHECK_CONNECTION; |
564 | |
565 | Channel *c = CHANNEL(channel); |
566 | |
567 | if (!c) |
568 | return NotOnChannel(channel); |
569 | |
570 | c->lockedTopic = true; |
571 | |
572 | return Ok; |
573 | } |
574 | |
575 | Message |
576 | Commands::Mode(Bot *bot, String channel, String mode) |
577 | { |
578 | CHECK_CONNECTION; |
579 | |
580 | if (!CHANNEL(channel)) |
581 | return NotOnChannel(channel); |
582 | |
583 | if (!bot->iAmOp(channel)) |
584 | return NotChannelOp(channel); |
585 | |
586 | QUEUE->sendChannelMode(String("MODE ") + channel + " " + mode); |
587 | |
588 | return Ok; |
589 | } |
590 | |
591 | Message |
592 | Commands::Msg(Bot *bot, String who, String message) |
593 | { |
594 | CHECK_CONNECTION; |
595 | |
596 | if (who == "") |
5c73c60a |
597 | { |
598 | return EmptyAddressee; |
599 | } |
cb21075d |
600 | |
a6339323 |
601 | if (Utils::channel_p(who)) |
5c73c60a |
602 | { |
4cc479d8 |
603 | if (!CHANNEL(who)) |
604 | { |
605 | return NotOnChannel (who); |
606 | } |
5c73c60a |
607 | } |
cb21075d |
608 | |
609 | if (message == "") |
5c73c60a |
610 | { |
611 | return EmptyMessage; |
612 | } |
cb21075d |
613 | |
6b7614a8 |
614 | // Send multi-line messages as seperate privmsgs |
615 | StringTokenizer st_message (message); |
616 | |
617 | while (st_message.more_tokens_p ('\n')) |
618 | { |
619 | QUEUE->sendPrivmsg(who, st_message.next_token ('\n')); |
620 | } |
cb21075d |
621 | |
622 | return Ok; |
623 | } |
624 | |
625 | Message |
626 | Commands::NextServer(Bot *bot) |
627 | { |
628 | CHECK_CONNECTION; |
629 | |
630 | if (bot->serverList->size() == 0) |
631 | return EmptyServerList; |
632 | |
633 | if (!bot->canChangeServer()) |
634 | return CanNotChangeServer; |
ae97d6ec |
635 | |
636 | #ifdef USESCRIPTS |
637 | // Run hooks/disconnect |
638 | bot->botInterp->RunHooks |
639 | (Hook::DISCONNECT, |
640 | bot->serverConnection->server->getHostName (), |
641 | scm_list_n |
642 | (Utils::str2scm (bot->serverConnection->server->getHostName ()), |
643 | SCM_BOOL_T)); |
644 | #endif |
cb21075d |
645 | |
646 | QUEUE->sendQuit("Changing server"); |
647 | bot->nextServer(); |
648 | |
649 | return Ok; |
650 | } |
651 | |
652 | Message |
653 | Commands::Nick(Bot *bot, String nick) |
654 | { |
655 | CHECK_CONNECTION; |
656 | |
6b7614a8 |
657 | if (nick == "" || !Utils::valid_nickname_p(bot, nick)) |
cb21075d |
658 | return InvalidNick(nick); |
659 | |
660 | bot->wantedNickName = nick; |
661 | QUEUE->sendNick(nick); |
662 | |
663 | return Ok; |
664 | } |
665 | |
666 | Message |
667 | Commands::Notice(Bot *bot, String who, String message) |
668 | { |
669 | CHECK_CONNECTION; |
670 | |
671 | if (who == "") |
672 | return EmptyAddressee; |
673 | |
5aec4622 |
674 | // if (Utils::channel_p(who)) |
675 | // return NotToChannel; |
cb21075d |
676 | |
677 | if (message == "") |
678 | return EmptyMessage; |
679 | |
6b7614a8 |
680 | // Send multiple lines as multiple notices |
681 | StringTokenizer st_message (message); |
682 | |
683 | while (st_message.more_tokens_p ('\n')) |
684 | { |
685 | QUEUE->sendNotice(who, st_message.next_token ('\n')); |
686 | } |
cb21075d |
687 | |
688 | return Ok; |
689 | } |
690 | |
691 | Message |
692 | Commands::Op(Bot *bot, String channel, String who) |
693 | { |
694 | CHECK_CONNECTION; |
695 | |
696 | Channel *c = CHANNEL(channel); |
697 | |
698 | if (!c) |
699 | return NotOnChannel(channel); |
700 | |
701 | if (!bot->iAmOp(channel)) |
702 | return NotChannelOp(channel); |
703 | |
a6339323 |
704 | if (Utils::wildcard_p(who)) |
cb21075d |
705 | return MassOpNotAllowed; |
71cf2688 |
706 | |
707 | try |
708 | { |
709 | User u = c->getUser(who); |
cb21075d |
710 | |
71cf2688 |
711 | ShitEntry *se = bot->shitList->getShit(who, channel); |
712 | if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) |
713 | return UserOnShitList(who); |
714 | |
715 | QUEUE->sendChannelMode(channel, "+o", who); |
716 | } |
717 | catch (const ChannelUserList::user_not_found &e) |
718 | { |
719 | return UserNotFound(e.name, channel); |
720 | } |
cb21075d |
721 | |
722 | return Ok; |
723 | } |
724 | |
725 | |
726 | Message |
727 | Commands::Part(Bot *bot, String channel) |
728 | { |
729 | CHECK_CONNECTION; |
730 | |
731 | if (!CHANNEL(channel)) |
732 | return NotOnChannel(channel); |
733 | |
734 | wantedChannel *w = bot->wantedChannels[channel]; |
735 | bot->wantedChannels.erase(channel); |
736 | delete w; |
737 | QUEUE->sendPart(channel); |
738 | |
739 | return Ok; |
740 | } |
741 | |
742 | Message |
743 | Commands::Reconnect(Bot *bot) |
744 | { |
745 | CHECK_CONNECTION; |
746 | |
747 | if (!bot->canChangeServer()) |
748 | return CanNotChangeServer; |
749 | |
750 | QUEUE->sendQuit("Reconnecting"); |
751 | bot->reconnect(); |
752 | |
753 | return Ok; |
754 | } |
755 | |
756 | Message |
757 | Commands::Say(Bot *bot, String channel, String message) |
758 | { |
4cc479d8 |
759 | return Commands::Msg (bot, channel, message); |
cb21075d |
760 | } |
761 | |
762 | |
763 | Message |
764 | Commands::Server(Bot *bot, int number) |
765 | { |
766 | CHECK_CONNECTION; |
767 | |
768 | if (number < 0 || number >= bot->serverList->size()) |
769 | return InvalidServerNumber(number); |
770 | |
771 | if (!bot->canChangeServer()) |
772 | return CanNotChangeServer; |
773 | |
774 | QUEUE->sendQuit("Changing server"); |
775 | QUEUE->flush(); |
776 | bot->connect(number); |
777 | |
778 | return Ok; |
779 | } |
780 | |
e171dcce |
781 | Message |
782 | Commands::SetFloodRate(Bot *bot, unsigned int num_messages) |
783 | { |
784 | if (num_messages > 0) |
785 | { |
786 | bot->MAX_MESSAGES = num_messages; |
787 | return Ok; |
788 | } |
789 | return InvalidParameters; |
790 | } |
791 | |
cb21075d |
792 | Message |
793 | Commands::SetVersion(Bot *bot, String str) |
794 | { |
795 | if (str.length() == 0) |
796 | return InvalidParameters; |
797 | |
798 | bot->versionString = str; |
799 | return Ok; |
800 | } |
801 | |
802 | Message |
803 | Commands::TBan(Bot *bot, String channel, String who, int seconds) |
804 | { |
805 | CHECK_CONNECTION; |
806 | |
807 | Channel *c = CHANNEL(channel); |
cf8ea873 |
808 | String dest; |
cb21075d |
809 | |
cf8ea873 |
810 | // Make sure all of the inputs are valid |
cb21075d |
811 | if (!c) |
f9723c92 |
812 | return NotOnChannel(channel); |
cb21075d |
813 | if (!bot->iAmOp(channel)) |
f9723c92 |
814 | return NotChannelOp(channel); |
cb21075d |
815 | if (seconds <= 0) |
f9723c92 |
816 | return InvalidTime(seconds); |
817 | |
cf8ea873 |
818 | // Look for user |
a6339323 |
819 | if (!Utils::wildcard_p(who)) |
f9723c92 |
820 | dest = bot->getUserhost(channel, who); |
cb21075d |
821 | else |
f9723c92 |
822 | dest = who; |
823 | |
cb21075d |
824 | if (dest.length() == 0) |
f9723c92 |
825 | return UserNotFound(who, channel); |
cb21075d |
826 | |
a6339323 |
827 | dest = Utils::make_wildcard(dest); |
cb21075d |
828 | Mask m(dest); |
829 | |
cf8ea873 |
830 | // Make sure the user isn't protected from bans |
cb21075d |
831 | for (std::list<UserListItem *>::iterator it = bot->userList->l.begin(); |
832 | it != bot->userList->l.end(); |
833 | it++) |
cf8ea873 |
834 | { |
835 | if (m.matches((*it)->mask) && |
836 | (*it)->channelMask.matches(channel) && |
837 | (*it)->prot >= User::NO_BAN) |
838 | { |
839 | return UserProtected(who, channel); |
840 | } |
841 | } |
cb21075d |
842 | |
cb21075d |
843 | |
f9723c92 |
844 | // c->delBan (dest); |
845 | c->addBan(dest, seconds); |
cf8ea873 |
846 | |
847 | return Ok; |
cb21075d |
848 | } |
849 | |
850 | |
851 | Message |
852 | Commands::TKBan(Bot *bot, String channel, String who, int seconds, String reason) |
853 | { |
854 | CHECK_CONNECTION; |
855 | |
856 | Message m = Commands::TBan(bot, channel, who, seconds); |
857 | |
858 | if (m.getCode() == 0) |
859 | m = Commands::Kick(bot, channel, who, reason); |
860 | |
861 | return m; |
862 | } |
863 | |
864 | |
865 | Message |
866 | Commands::Topic(Bot *bot, String channel, String topic) |
867 | { |
868 | CHECK_CONNECTION; |
869 | |
870 | Channel *c = CHANNEL(channel); |
871 | |
872 | if (!c) |
873 | return NotOnChannel(channel); |
874 | |
875 | if (!bot->iAmOp(channel) && !(c->channelMode & Channel::TOPIC_RESTRICTED)) |
876 | return CanNotChangeTopic(channel); |
877 | |
878 | if (c->lockedTopic) |
879 | return TopicLocked(channel); |
880 | |
881 | QUEUE->sendTopic(channel, topic); |
882 | |
883 | return Ok; |
884 | } |
885 | |
886 | |
887 | Message |
888 | Commands::Unlock(Bot *bot, String channel) |
889 | { |
890 | CHECK_CONNECTION; |
891 | |
892 | Channel *c = CHANNEL(channel); |
893 | |
894 | if (!c) |
895 | return NotOnChannel(channel); |
896 | |
897 | c->lockedTopic = false; |
898 | |
899 | return Ok; |
900 | } |
c6e7af05 |
901 | |
902 | Message |
903 | Commands::Who (Bot *bot, String target) |
904 | { |
905 | CHECK_CONNECTION; |
906 | |
907 | QUEUE->sendWho (target); |
908 | |
909 | return Ok; |
910 | } |
911 | |
912 | Message |
913 | Commands::Whois (Bot *bot, String nick) |
914 | { |
915 | CHECK_CONNECTION; |
916 | |
917 | if (!Utils::valid_nickname_p (bot, nick)) |
918 | { |
919 | return InvalidNick (nick); |
920 | } |
921 | else |
922 | { |
923 | QUEUE->sendWhois (nick); |
924 | return Ok; |
925 | } |
926 | } |
927 | |
928 | |