cb21075d |
1 | // Commands.C -*- C++ -*- |
2 | // Copyright (c) 1998 Etienne BERNARD |
3 | // Copyright (C) 2002 Clinton Ebadi |
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 |
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
18 | |
19 | #include "Macros.H" |
20 | #include "Message.H" |
21 | #include "Commands.H" |
22 | #include "Utils.H" |
23 | |
24 | #define Ok (Message(0, "")) |
25 | #define NotOnChannel(c) (Message(-1, String("I am not on channel ") + (c))) |
26 | #define NotChannelOp(c) (Message(-2, String("I am not channel op on ") + (c))) |
27 | #define UserNotFound(w, c) (Message(-3, (w) + " is not on channel " + (c))) |
28 | #define UserNotOp(w, c) (Message(-4, (w) + " is not channel op on " + (c))) |
29 | #define UserProtected(w, c) (Message(-5, (w) + " is protected on " + (c))) |
30 | #define InvalidNick(n) (Message(-6, (n) + " is not a valid nickname")) |
31 | #define InvalidChannel(c) (Message(-7, (c) + " is not a valid channel name")) |
32 | #define MassOpNotAllowed (Message(-8, "Mass op is not allowed.")) |
33 | #define UserOnShitList(w) (Message(-9, String("User ") + w + " is on my shitlist")) |
34 | #define CanNotChangeTopic(c) (Message(-10, String("I can not change topic on ") + (c))) |
35 | #define TopicLocked(c) (Message(-11, String("Topic is locked on ") + (c))) |
36 | #define InvalidPort(p) (Message(-12, String((long)(p)) + " is an invalid port number")) |
37 | #define InvalidTime(t) (Message(-13, String((long)(t)) + " is an invalid time")) |
38 | #define CanNotChangeServer (Message(-14, "I cannot change server without loosing op on one of my channels")) |
39 | #define EmptyServerList (Message(-15, "Server list is empty")) |
40 | #define InvalidServerNumber(n) (Message(-16, String((long)(n)) + " is an invalid server number")) |
41 | #define InvalidParameters (Message(-17, "Invalid parameters")) |
42 | #define NotFound(w) (Message(-18, String("I can not find ") + (w))); |
43 | #define NotInUserlist(w) (Message(-19, (w) + " is not in my userlist")) |
44 | #define NotInShitlist(w) (Message(-20, (w) + " is not in my shitlist")) |
45 | #define AlreadyInUserlist(m, mc) (Message(-21, (m) + " is already in userlist on channel(s) " + (mc))) |
46 | #define AlreadyInShitlist(m, mc) (Message(-22, (m) + " is already in shitlist on channel(s) " + (mc))) |
47 | #define EmptyMessage (Message(-23, "Can not send an empty message")) |
48 | #define EmptyAddressee (Message(-24, "Can not send to nobody")) |
49 | #define NotToChannel (Message(-25, "Can not send to a channel. Use \"say\" instead.")) |
50 | #define NotConnected (Message(-26, "Not connected.")) |
51 | |
52 | #define CHECK_CONNECTION if (!bot->serverConnection) return NotConnected |
53 | |
54 | Message |
55 | Commands::Action(Bot *bot, String channel, String message) |
56 | { |
57 | CHECK_CONNECTION; |
58 | |
59 | if (!CHANNEL(channel)) |
60 | return NotOnChannel(channel); |
61 | |
62 | if (message.length() == 0) |
63 | return InvalidParameters; |
64 | |
65 | QUEUE->sendPrivmsg(channel, String("\001ACTION ") + |
66 | message + "\001"); |
67 | |
68 | return Ok; |
69 | } |
70 | |
71 | Message |
72 | Commands::AddUser(Bot *bot, String who, String maskChannel, int level, |
73 | int prot, bool aop, std::time_t expire, String password) |
74 | { |
75 | // Gah, fix this (makes bot segfault) |
76 | if (who.length() == 0 || |
77 | maskChannel.length() == 0 || |
78 | level < 0 || |
79 | level > User::FRIEND || |
80 | prot < 0 || |
81 | prot > User::NO_DEOP) |
82 | return InvalidParameters; |
83 | |
84 | String mask; |
85 | |
86 | if (!Utils::isWildcard(who)) |
87 | { |
88 | mask = bot->getUserhost("", who); |
89 | if (mask.length() == 0) |
90 | return NotFound(who); |
91 | } |
92 | // Aha! This was before the brace...segfault gone |
93 | mask = Utils::makeWildcard(mask); |
94 | |
95 | if (bot->userList->isInUserList(mask, maskChannel)) |
96 | return AlreadyInUserlist(mask, maskChannel); |
97 | |
98 | bot->userList->addUser(mask, maskChannel, level, prot, aop, |
99 | expire, password); |
100 | bot->rehash(); |
101 | |
102 | return Ok; |
103 | } |
104 | |
105 | |
106 | Message |
107 | Commands::AddServer(Bot *bot, String servername, int port) |
108 | { |
109 | if (port <= 0) |
110 | return InvalidPort(port); |
111 | |
112 | bot->serverList->addServer(new class Server(servername, port)); |
113 | |
114 | return Ok; |
115 | } |
116 | |
117 | |
118 | Message |
119 | Commands::AddShit(Bot *bot, String mask, String maskChannel, |
120 | int level, time_t expiration, String reason) |
121 | { |
122 | if (mask.length() == 0 || maskChannel.length() == 0 || |
123 | level < 0 || level > ShitEntry::SHIT_NODEBAN) |
124 | return InvalidParameters; |
125 | |
126 | if (reason == "") |
127 | reason = "You're on my shitlist, lamer"; |
128 | |
129 | String who = mask; |
130 | |
131 | if (!Utils::isWildcard(mask)) { |
132 | mask = bot->getUserhost("", who); |
133 | if (mask.length() == 0) |
134 | return NotFound(who); |
135 | mask = Utils::makeWildcard(mask); |
136 | if (bot->shitList->getShit(mask, maskChannel)) |
137 | return AlreadyInShitlist(mask, maskChannel); |
138 | } |
139 | |
140 | if (bot->userList->getMaxProt(mask, maskChannel) > 0) |
141 | return UserProtected(who, maskChannel); |
142 | |
143 | bot->shitList->addShit(mask, maskChannel, level, expiration, reason); |
144 | |
145 | return Ok; |
146 | } |
147 | |
148 | |
149 | Message |
150 | Commands::Ban(Bot *bot, String channel, String who) |
151 | { |
152 | CHECK_CONNECTION; |
153 | |
154 | Channel *c = CHANNEL(channel); |
155 | |
156 | if (!c) |
157 | return NotOnChannel(channel); |
158 | |
159 | if (!bot->iAmOp(channel)) |
160 | return NotChannelOp(channel); |
161 | |
162 | String dest; |
163 | |
164 | if (!Utils::isWildcard(who)) |
165 | dest = bot->getUserhost(channel, who); |
166 | else |
167 | dest = who; |
168 | |
169 | if (dest.length() == 0) |
170 | return NotFound(who); |
171 | |
172 | dest = Utils::makeWildcard(dest); |
173 | Mask m(dest); |
174 | |
175 | for (std::list<UserListItem *>::iterator it = bot->userList->l.begin(); |
176 | it != bot->userList->l.end(); |
177 | it++) |
178 | if (m.matches((*it)->mask) && |
179 | (*it)->channelMask.matches(channel) && |
180 | (*it)->prot >= User::NO_BAN) |
181 | return UserProtected(who, channel); |
182 | |
183 | for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin(); |
184 | it != c->channelBanlist.end(); ++it) |
185 | if (m.matches((*it)->banMask) && (*it)->banMask.getMask() != m.getMask()) |
186 | QUEUE->sendChannelMode(channel, "-b", (*it)->banMask.getMask()); |
187 | |
188 | QUEUE->sendChannelMode(channel, "+b", dest); |
189 | |
190 | return Ok; |
191 | } |
192 | |
193 | Message |
194 | Commands::Cycle(Bot *bot, String channel) |
195 | { |
196 | CHECK_CONNECTION; |
197 | |
198 | if (!CHANNEL(channel)) |
199 | return NotOnChannel(channel); |
200 | |
201 | QUEUE->sendPart(channel); |
202 | QUEUE->sendJoin(channel, bot->wantedChannels[channel]->key); |
203 | |
204 | return Ok; |
205 | } |
206 | |
207 | Message |
208 | Commands::Deban(Bot *bot, String channel, String who) |
209 | { |
210 | CHECK_CONNECTION; |
211 | |
212 | Channel *c = CHANNEL(channel); |
213 | |
214 | if (!c) |
215 | return NotOnChannel(channel); |
216 | |
217 | if (!bot->iAmOp(channel)) |
218 | return NotChannelOp(channel); |
219 | |
220 | String dest; |
221 | |
222 | if (!Utils::isWildcard(who)) |
223 | dest = bot->getUserhost(channel, who); |
224 | else |
225 | dest = who; |
226 | |
227 | if (dest.length() == 0) |
228 | return UserNotFound(who, channel); |
229 | |
230 | dest = Utils::makeWildcard(dest); |
231 | Mask m(dest); |
232 | |
233 | for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin(); |
234 | it != c->channelBanlist.end(); ++it) |
235 | if (m.matches((*it)->getMask())) { |
236 | // Let's see if the ban is in the shitlist |
237 | ShitEntry *se = bot->shitList->getShit((*it)->getMask(), channel); |
238 | if (!se || !se->isStillValid() || |
239 | se->getShitLevel() < ShitEntry::SHIT_NODEBAN) |
240 | QUEUE->sendChannelMode(channel, "-b", (*it)->getMask()); |
241 | } |
242 | |
243 | return Ok; |
244 | } |
245 | |
246 | Message |
247 | Commands::DelServer(Bot *bot, int number) |
248 | { |
249 | if (number < 0 || number >= bot->serverList->size()) |
250 | return InvalidServerNumber(number); |
251 | |
252 | bot->serverList->delServer(number); |
253 | |
254 | return Ok; |
255 | } |
256 | |
257 | Message |
258 | Commands::DelUser(Bot *bot, String who, String maskChannel) |
259 | { |
260 | if (who.length() == 0 || maskChannel.length() == 0) |
261 | return InvalidParameters; |
262 | |
263 | String dest; |
264 | |
265 | if (!Utils::isWildcard(who)) { |
266 | dest = bot->getUserhost("", who); |
267 | if (dest.length() == 0) |
268 | return NotFound(who); |
269 | dest = Utils::makeWildcard(who); |
270 | } |
271 | |
272 | if (!bot->userList->isInUserList(dest, maskChannel)) |
273 | return NotInUserlist(who); |
274 | |
275 | bot->userList->removeUser(dest, maskChannel); |
276 | bot->rehash(); |
277 | |
278 | return Ok; |
279 | } |
280 | |
281 | Message |
282 | Commands::DelShit(Bot *bot, String who, String maskChannel) |
283 | { |
284 | if (who.length() == 0 || maskChannel.length() == 0) |
285 | return InvalidParameters; |
286 | |
287 | String dest; |
288 | |
289 | if (!Utils::isWildcard(who)) { |
290 | dest = bot->getUserhost("", who); |
291 | if (dest.length() == 0) |
292 | return NotFound(who); |
293 | dest = Utils::makeWildcard(who); |
294 | } |
295 | |
296 | if (!bot->shitList->getShit(dest, maskChannel)) |
297 | return NotInShitlist(who); |
298 | |
299 | bot->shitList->delShit(dest, maskChannel); |
300 | |
301 | return Ok; |
302 | } |
303 | |
304 | Message |
305 | Commands::Deop(Bot *bot, String channel, String who) |
306 | { |
307 | CHECK_CONNECTION; |
308 | |
309 | Channel *c = CHANNEL(channel); |
310 | |
311 | if (!c) |
312 | return NotOnChannel(channel); |
313 | |
314 | if (!bot->iAmOp(channel)) |
315 | return NotChannelOp(channel); |
316 | |
317 | if (!Utils::isWildcard(who)) { |
318 | User *u = c->getUser(who); |
319 | if (!u) |
320 | return UserNotFound(who, channel); |
321 | if (!(u->mode & User::OP_MODE)) |
322 | return UserNotOp(who, channel); |
323 | if (u->getProt() >= User::NO_DEOP) |
324 | return UserProtected(who, channel); |
325 | QUEUE->sendChannelMode(channel, "-o", who); |
326 | } else { |
327 | Mask m(who); |
328 | for (std::map<String, User *, std::less<String> >::iterator |
329 | it = c->channelMemory.begin(); |
330 | it != c->channelMemory.end(); ++it) { |
331 | if (m.matches((*it).second->nick + "!" + |
332 | (*it).second->userhost) && |
333 | (*it).second->getProt() < User::NO_DEOP && |
334 | ((*it).second->mode & User::OP_MODE)) |
335 | QUEUE->sendChannelMode(channel, "-o", (*it).second->nick); |
336 | } |
337 | } |
338 | |
339 | return Ok; |
340 | } |
341 | |
342 | Message |
343 | Commands::Die(Bot *bot, String reason) |
344 | { |
345 | CHECK_CONNECTION; |
346 | |
347 | QUEUE->sendQuit(reason); |
348 | bot->stop = true; |
349 | |
350 | return Ok; |
351 | } |
352 | |
353 | Message |
354 | Commands::Do(Bot *bot, String command) |
355 | { |
356 | CHECK_CONNECTION; |
357 | |
358 | QUEUE->addLine(command, 0, 0, ServerQueueItem::OTHER); |
359 | return Ok; |
360 | } |
361 | |
362 | Message |
363 | Commands::Invite(Bot *bot, String channel, String who) |
364 | { |
365 | CHECK_CONNECTION; |
366 | |
367 | if (!bot->iAmOp(channel)) |
368 | return NotChannelOp(channel); |
369 | |
370 | QUEUE->sendInvite(channel, who); |
371 | |
372 | return Ok; |
373 | } |
374 | |
375 | Message |
376 | Commands::Join(Bot *bot, String channel, String key) |
377 | { |
378 | CHECK_CONNECTION; |
379 | |
380 | if (!Utils::isValidChannelName(channel)) |
381 | return InvalidChannel(channel); |
382 | |
383 | // We change the key only if we are not on the channel. |
384 | // We don't trust the user... |
385 | if (!CHANNEL(channel)) { |
386 | if (bot->wantedChannels[channel]) |
387 | bot->wantedChannels[channel]->key = key; |
388 | else { |
389 | bot->wantedChannels[channel] = new wantedChannel("", "", key); |
390 | } |
391 | } |
392 | QUEUE->sendJoin(channel, bot->wantedChannels[channel]->key); |
393 | |
394 | return Ok; |
395 | } |
396 | |
397 | Message |
398 | Commands::Keep(Bot *bot, String channel, String modes) |
399 | { |
400 | CHECK_CONNECTION; |
401 | |
402 | Channel *c = CHANNEL(channel); |
403 | |
404 | if (!c) |
405 | return NotOnChannel(channel); |
406 | |
407 | c->keepModes = modes; |
408 | |
409 | return Ok; |
410 | } |
411 | |
412 | Message |
413 | Commands::Kick(Bot *bot, String channel, String who, String reason) |
414 | { |
415 | CHECK_CONNECTION; |
416 | |
417 | Channel *c = CHANNEL(channel); |
418 | |
419 | if (!c) |
420 | return NotOnChannel(channel); |
421 | |
422 | if (!bot->iAmOp(channel)) |
423 | return NotChannelOp(channel); |
424 | |
425 | if (Utils::isWildcard(who)) { |
426 | Mask m(who); |
427 | for (std::map<String, User *, std::less<String> >::iterator it = |
428 | c->channelMemory.begin(); |
429 | it != c->channelMemory.end(); |
430 | ++it) |
431 | if (m.matches((*it).second->nick + "!" + |
432 | (*it).second->userhost) && |
433 | (*it).second->getProt() < User::NO_KICK) |
434 | QUEUE->sendKick(channel, (*it).second->nick, reason); |
435 | } else { |
436 | User * u = c->getUser(who); |
437 | if (!u) |
438 | return UserNotFound(who, channel); |
439 | if (u->getProt() < User::NO_KICK) |
440 | QUEUE->sendKick(channel, who, reason); |
441 | else |
442 | return UserProtected(who, channel); |
443 | } |
444 | |
445 | return Ok; |
446 | } |
447 | |
448 | Message |
449 | Commands::KickBan(Bot *bot, String channel, String who, String reason) |
450 | { |
451 | CHECK_CONNECTION; |
452 | |
453 | Message m = Commands::Ban(bot, channel, who); |
454 | |
455 | if (m.getCode() == 0) |
456 | m = Commands::Kick(bot, channel, who, reason); |
457 | |
458 | return m; |
459 | } |
460 | |
461 | Message |
462 | Commands::Lock(Bot *bot, String channel) |
463 | { |
464 | CHECK_CONNECTION; |
465 | |
466 | Channel *c = CHANNEL(channel); |
467 | |
468 | if (!c) |
469 | return NotOnChannel(channel); |
470 | |
471 | c->lockedTopic = true; |
472 | |
473 | return Ok; |
474 | } |
475 | |
476 | Message |
477 | Commands::Mode(Bot *bot, String channel, String mode) |
478 | { |
479 | CHECK_CONNECTION; |
480 | |
481 | if (!CHANNEL(channel)) |
482 | return NotOnChannel(channel); |
483 | |
484 | if (!bot->iAmOp(channel)) |
485 | return NotChannelOp(channel); |
486 | |
487 | QUEUE->sendChannelMode(String("MODE ") + channel + " " + mode); |
488 | |
489 | return Ok; |
490 | } |
491 | |
492 | Message |
493 | Commands::Msg(Bot *bot, String who, String message) |
494 | { |
495 | CHECK_CONNECTION; |
496 | |
497 | if (who == "") |
498 | return EmptyAddressee; |
499 | |
500 | if (Utils::isChannel(who)) |
501 | return NotToChannel; |
502 | |
503 | if (message == "") |
504 | return EmptyMessage; |
505 | |
506 | QUEUE->sendPrivmsg(who, message); |
507 | |
508 | return Ok; |
509 | } |
510 | |
511 | Message |
512 | Commands::NextServer(Bot *bot) |
513 | { |
514 | CHECK_CONNECTION; |
515 | |
516 | if (bot->serverList->size() == 0) |
517 | return EmptyServerList; |
518 | |
519 | if (!bot->canChangeServer()) |
520 | return CanNotChangeServer; |
521 | |
522 | QUEUE->sendQuit("Changing server"); |
523 | bot->nextServer(); |
524 | |
525 | return Ok; |
526 | } |
527 | |
528 | Message |
529 | Commands::Nick(Bot *bot, String nick) |
530 | { |
531 | CHECK_CONNECTION; |
532 | |
533 | if (nick == "" || !Utils::isValidNickName(nick)) |
534 | return InvalidNick(nick); |
535 | |
536 | bot->wantedNickName = nick; |
537 | QUEUE->sendNick(nick); |
538 | |
539 | return Ok; |
540 | } |
541 | |
542 | Message |
543 | Commands::Notice(Bot *bot, String who, String message) |
544 | { |
545 | CHECK_CONNECTION; |
546 | |
547 | if (who == "") |
548 | return EmptyAddressee; |
549 | |
550 | if (Utils::isChannel(who)) |
551 | return NotToChannel; |
552 | |
553 | if (message == "") |
554 | return EmptyMessage; |
555 | |
556 | QUEUE->sendNotice(who, message); |
557 | |
558 | return Ok; |
559 | } |
560 | |
561 | Message |
562 | Commands::Op(Bot *bot, String channel, String who) |
563 | { |
564 | CHECK_CONNECTION; |
565 | |
566 | Channel *c = CHANNEL(channel); |
567 | |
568 | if (!c) |
569 | return NotOnChannel(channel); |
570 | |
571 | if (!bot->iAmOp(channel)) |
572 | return NotChannelOp(channel); |
573 | |
574 | if (Utils::isWildcard(who)) |
575 | return MassOpNotAllowed; |
576 | |
577 | User *u = c->getUser(who); |
578 | if (!u) |
579 | return UserNotFound(who, channel); |
580 | |
581 | ShitEntry *se = bot->shitList->getShit(who, channel); |
582 | if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) |
583 | return UserOnShitList(who); |
584 | |
585 | QUEUE->sendChannelMode(channel, "+o", who); |
586 | |
587 | return Ok; |
588 | } |
589 | |
590 | |
591 | Message |
592 | Commands::Part(Bot *bot, String channel) |
593 | { |
594 | CHECK_CONNECTION; |
595 | |
596 | if (!CHANNEL(channel)) |
597 | return NotOnChannel(channel); |
598 | |
599 | wantedChannel *w = bot->wantedChannels[channel]; |
600 | bot->wantedChannels.erase(channel); |
601 | delete w; |
602 | QUEUE->sendPart(channel); |
603 | |
604 | return Ok; |
605 | } |
606 | |
607 | Message |
608 | Commands::Reconnect(Bot *bot) |
609 | { |
610 | CHECK_CONNECTION; |
611 | |
612 | if (!bot->canChangeServer()) |
613 | return CanNotChangeServer; |
614 | |
615 | QUEUE->sendQuit("Reconnecting"); |
616 | bot->reconnect(); |
617 | |
618 | return Ok; |
619 | } |
620 | |
621 | Message |
622 | Commands::Say(Bot *bot, String channel, String message) |
623 | { |
624 | CHECK_CONNECTION; |
625 | |
626 | // if (!CHANNEL(channel)) |
627 | // return NotOnChannel(channel); |
628 | |
629 | QUEUE->sendPrivmsg(channel, message); |
630 | |
631 | return Ok; |
632 | } |
633 | |
634 | |
635 | Message |
636 | Commands::Server(Bot *bot, int number) |
637 | { |
638 | CHECK_CONNECTION; |
639 | |
640 | if (number < 0 || number >= bot->serverList->size()) |
641 | return InvalidServerNumber(number); |
642 | |
643 | if (!bot->canChangeServer()) |
644 | return CanNotChangeServer; |
645 | |
646 | QUEUE->sendQuit("Changing server"); |
647 | QUEUE->flush(); |
648 | bot->connect(number); |
649 | |
650 | return Ok; |
651 | } |
652 | |
653 | Message |
654 | Commands::SetVersion(Bot *bot, String str) |
655 | { |
656 | if (str.length() == 0) |
657 | return InvalidParameters; |
658 | |
659 | bot->versionString = str; |
660 | return Ok; |
661 | } |
662 | |
663 | Message |
664 | Commands::TBan(Bot *bot, String channel, String who, int seconds) |
665 | { |
666 | CHECK_CONNECTION; |
667 | |
668 | Channel *c = CHANNEL(channel); |
669 | |
670 | if (!c) |
671 | return NotOnChannel(channel); |
672 | |
673 | if (!bot->iAmOp(channel)) |
674 | return NotChannelOp(channel); |
675 | |
676 | if (seconds <= 0) |
677 | return InvalidTime(seconds); |
678 | |
679 | String dest; |
680 | |
681 | if (!Utils::isWildcard(who)) |
682 | dest = bot->getUserhost(channel, who); |
683 | else |
684 | dest = who; |
685 | |
686 | if (dest.length() == 0) |
687 | return UserNotFound(who, channel); |
688 | |
689 | dest = Utils::makeWildcard(dest); |
690 | Mask m(dest); |
691 | |
692 | for (std::list<UserListItem *>::iterator it = bot->userList->l.begin(); |
693 | it != bot->userList->l.end(); |
694 | it++) |
695 | if (m.matches((*it)->mask) && |
696 | (*it)->channelMask.matches(channel) && |
697 | (*it)->prot >= User::NO_BAN) |
698 | return UserProtected(who, channel); |
699 | |
700 | for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin(); |
701 | it != c->channelBanlist.end(); ++it) |
702 | if (m.matches((*it)->banMask)) |
703 | QUEUE->sendChannelMode(channel, "-b", (*it)->banMask.getMask()); |
704 | |
705 | CHANNEL(channel)->addBan(dest, seconds); |
706 | QUEUE->sendChannelMode(channel, "+b", dest); |
707 | bot->todoList->addDeban(channel, dest, seconds); |
708 | } |
709 | |
710 | |
711 | Message |
712 | Commands::TKBan(Bot *bot, String channel, String who, int seconds, String reason) |
713 | { |
714 | CHECK_CONNECTION; |
715 | |
716 | Message m = Commands::TBan(bot, channel, who, seconds); |
717 | |
718 | if (m.getCode() == 0) |
719 | m = Commands::Kick(bot, channel, who, reason); |
720 | |
721 | return m; |
722 | } |
723 | |
724 | |
725 | Message |
726 | Commands::Topic(Bot *bot, String channel, String topic) |
727 | { |
728 | CHECK_CONNECTION; |
729 | |
730 | Channel *c = CHANNEL(channel); |
731 | |
732 | if (!c) |
733 | return NotOnChannel(channel); |
734 | |
735 | if (!bot->iAmOp(channel) && !(c->channelMode & Channel::TOPIC_RESTRICTED)) |
736 | return CanNotChangeTopic(channel); |
737 | |
738 | if (c->lockedTopic) |
739 | return TopicLocked(channel); |
740 | |
741 | QUEUE->sendTopic(channel, topic); |
742 | |
743 | return Ok; |
744 | } |
745 | |
746 | |
747 | Message |
748 | Commands::Unlock(Bot *bot, String channel) |
749 | { |
750 | CHECK_CONNECTION; |
751 | |
752 | Channel *c = CHANNEL(channel); |
753 | |
754 | if (!c) |
755 | return NotOnChannel(channel); |
756 | |
757 | c->lockedTopic = false; |
758 | |
759 | return Ok; |
760 | } |