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