1 // Commands.C -*- C++ -*-
2 // Copyright (c) 1998 Etienne BERNARD
3 // Copyright (C) 2002,2005 Clinton Ebadi
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
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.
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.
25 #define CHECK_CONNECTION if (!bot->serverConnection) return NotConnected
28 Commands::Action(Bot *bot, String channel, String message)
32 if (!CHANNEL(channel))
33 return NotOnChannel(channel);
35 if (message.length() == 0)
36 return InvalidParameters;
38 QUEUE->sendCTCP (channel, "ACTION", message);
44 Commands::AddUser(Bot *bot, String who, String maskChannel, int level,
45 int prot, bool aop, std::time_t expire, String password)
47 // Gah, fix this (makes bot segfault)
48 if (who.length() == 0 ||
49 maskChannel.length() == 0 ||
51 level > User::FRIEND ||
54 return InvalidParameters;
58 if (!Utils::wildcard_p(who))
60 mask = bot->getUserhost("", who);
61 if (mask.length() == 0)
66 // Aha! This was before the brace...segfault gone
67 mask = Utils::make_wildcard(mask);
69 if (bot->userList->isInUserList(mask, maskChannel))
71 return AlreadyInUserlist(mask, maskChannel);
74 bot->userList->addUser(mask, maskChannel, level, prot, aop,
83 Commands::AddServer(Bot *bot, String servername, int port)
86 return InvalidPort(port);
88 bot->serverList->addServer(new class Server(servername, port));
95 Commands::AddShit(Bot *bot, String mask, String maskChannel,
96 int level, time_t expiration, String reason)
98 if (mask.length() == 0 || maskChannel.length() == 0 ||
99 level < 0 || level > ShitEntry::SHIT_NODEBAN)
100 return InvalidParameters;
103 reason = "You're on my shitlist, lamer";
107 if (!Utils::wildcard_p(mask)) {
108 mask = bot->getUserhost("", who);
109 if (mask.length() == 0)
110 return NotFound(who);
111 mask = Utils::make_wildcard(mask);
112 if (bot->shitList->getShit(mask, maskChannel))
113 return AlreadyInShitlist(mask, maskChannel);
116 if (bot->userList->getMaxProt(mask, maskChannel) > 0)
117 return UserProtected(who, maskChannel);
119 bot->shitList->addShit(mask, maskChannel, level, expiration, reason);
126 Commands::Ban(Bot *bot, String channel, String who)
130 Channel *c = CHANNEL(channel);
133 return NotOnChannel(channel);
135 if (!bot->iAmOp(channel))
136 return NotChannelOp(channel);
140 if (!Utils::wildcard_p(who))
141 dest = bot->getUserhost(channel, who);
145 if (dest.length() == 0)
146 return NotFound(who);
148 dest = Utils::make_wildcard(dest);
151 for (std::list<UserListItem *>::iterator it = bot->userList->l.begin();
152 it != bot->userList->l.end();
154 if (m.matches((*it)->mask) &&
155 (*it)->channelMask.matches(channel) &&
156 (*it)->prot >= User::NO_BAN)
157 return UserProtected(who, channel);
159 for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
160 it != c->channelBanlist.end(); ++it)
161 if (m.matches((*it)->banMask) && (*it)->banMask.getMask() != m.getMask())
162 QUEUE->sendChannelMode(channel, "-b", (*it)->banMask.getMask());
164 QUEUE->sendChannelMode(channel, "+b", dest);
170 Commands::Cycle(Bot *bot, String channel)
174 if (!CHANNEL(channel))
175 return NotOnChannel(channel);
177 QUEUE->sendPart(channel);
178 QUEUE->sendJoin(channel, bot->wantedChannels[channel]->key);
184 Commands::Deban(Bot *bot, String channel, String who)
188 Channel *c = CHANNEL(channel);
191 return NotOnChannel(channel);
193 if (!bot->iAmOp(channel))
194 return NotChannelOp(channel);
198 if (!Utils::wildcard_p(who))
199 dest = bot->getUserhost(channel, who);
203 if (dest.length() == 0)
204 return UserNotFound(who, channel);
206 dest = Utils::make_wildcard(dest);
209 for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
210 it != c->channelBanlist.end(); ++it)
211 if (m.matches((*it)->getMask())) {
212 // Let's see if the ban is in the shitlist
213 ShitEntry *se = bot->shitList->getShit((*it)->getMask(), channel);
214 if (!se || !se->isStillValid() ||
215 se->getShitLevel() < ShitEntry::SHIT_NODEBAN)
216 QUEUE->sendChannelMode(channel, "-b", (*it)->getMask());
223 Commands::DelServer(Bot *bot, int number)
225 if (number < 0 || number >= bot->serverList->size())
226 return InvalidServerNumber(number);
228 bot->serverList->delServer(number);
234 Commands::DelUser(Bot *bot, String who, String maskChannel)
236 if (who.length() == 0 || maskChannel.length() == 0)
237 return InvalidParameters;
241 if (!Utils::wildcard_p(who)) {
242 dest = bot->getUserhost("", who);
243 if (dest.length() == 0)
244 return NotFound(who);
245 dest = Utils::make_wildcard(who);
248 if (!bot->userList->isInUserList(dest, maskChannel))
249 return NotInUserlist(who);
251 bot->userList->removeUser(dest, maskChannel);
258 Commands::DelShit(Bot *bot, String who, String maskChannel)
260 if (who.length() == 0 || maskChannel.length() == 0)
261 return InvalidParameters;
265 if (!Utils::wildcard_p(who)) {
266 dest = bot->getUserhost("", who);
267 if (dest.length() == 0)
268 return NotFound(who);
269 dest = Utils::make_wildcard(who);
272 if (!bot->shitList->getShit(dest, maskChannel))
273 return NotInShitlist(who);
275 bot->shitList->delShit(dest, maskChannel);
281 Commands::Deop(Bot *bot, String channel, String who)
285 Channel *c = CHANNEL(channel);
288 return NotOnChannel(channel);
290 if (!bot->iAmOp(channel))
291 return NotChannelOp(channel);
293 if (!Utils::wildcard_p(who)) {
294 User *u = c->getUser(who);
296 return UserNotFound(who, channel);
297 if (!(u->mode & User::OP_MODE))
298 return UserNotOp(who, channel);
299 if (u->getProt() >= User::NO_DEOP)
300 return UserProtected(who, channel);
301 QUEUE->sendChannelMode(channel, "-o", who);
304 for (std::map<String, User *, std::less<String> >::iterator
305 it = c->channelMemory.begin();
306 it != c->channelMemory.end(); ++it) {
307 if (m.matches((*it).second->nick + "!" +
308 (*it).second->userhost) &&
309 (*it).second->getProt() < User::NO_DEOP &&
310 ((*it).second->mode & User::OP_MODE))
311 QUEUE->sendChannelMode(channel, "-o", (*it).second->nick);
319 Commands::Die(Bot *bot, String reason)
323 QUEUE->sendQuit(reason);
330 Commands::Do(Bot *bot, String command)
334 QUEUE->addLine(command, 0, 0, ServerQueueItem::OTHER);
339 Commands::Invite(Bot *bot, String channel, String who)
343 if (!bot->iAmOp(channel))
344 return NotChannelOp(channel);
346 QUEUE->sendInvite(channel, who);
352 Commands::Join(Bot *bot, String channel, String key)
356 if (!Utils::valid_channel_name_p(channel))
357 return InvalidChannel(channel);
359 // We change the key only if we are not on the channel.
360 // We don't trust the user...
361 if (!CHANNEL(channel)) {
362 if (bot->wantedChannels[channel])
363 bot->wantedChannels[channel]->key = key;
365 bot->wantedChannels[channel] = new wantedChannel("", "", key);
368 QUEUE->sendJoin(channel, bot->wantedChannels[channel]->key);
374 Commands::Keep(Bot *bot, String channel, String modes)
378 Channel *c = CHANNEL(channel);
381 return NotOnChannel(channel);
383 c->keepModes = modes;
389 Commands::Kick(Bot *bot, String channel, String who, String reason)
393 Channel *c = CHANNEL(channel);
396 return NotOnChannel(channel);
398 if (!bot->iAmOp(channel))
399 return NotChannelOp(channel);
401 if (Utils::wildcard_p(who)) {
403 for (std::map<String, User *, std::less<String> >::iterator it =
404 c->channelMemory.begin();
405 it != c->channelMemory.end();
407 if (m.matches((*it).second->nick + "!" +
408 (*it).second->userhost) &&
409 (*it).second->getProt() < User::NO_KICK)
410 QUEUE->sendKick(channel, (*it).second->nick, reason);
412 User * u = c->getUser(who);
414 return UserNotFound(who, channel);
415 if (u->getProt() < User::NO_KICK)
416 QUEUE->sendKick(channel, who, reason);
418 return UserProtected(who, channel);
425 Commands::KickBan(Bot *bot, String channel, String who, String reason)
429 Message m = Commands::Ban(bot, channel, who);
431 if (m.getCode() == 0)
432 m = Commands::Kick(bot, channel, who, reason);
438 Commands::Lock(Bot *bot, String channel)
442 Channel *c = CHANNEL(channel);
445 return NotOnChannel(channel);
447 c->lockedTopic = true;
453 Commands::Mode(Bot *bot, String channel, String mode)
457 if (!CHANNEL(channel))
458 return NotOnChannel(channel);
460 if (!bot->iAmOp(channel))
461 return NotChannelOp(channel);
463 QUEUE->sendChannelMode(String("MODE ") + channel + " " + mode);
469 Commands::Msg(Bot *bot, String who, String message)
474 return EmptyAddressee;
476 if (Utils::channel_p(who))
482 QUEUE->sendPrivmsg(who, message);
488 Commands::NextServer(Bot *bot)
492 if (bot->serverList->size() == 0)
493 return EmptyServerList;
495 if (!bot->canChangeServer())
496 return CanNotChangeServer;
498 QUEUE->sendQuit("Changing server");
505 Commands::Nick(Bot *bot, String nick)
509 if (nick == "" || !Utils::valid_nickname_p(nick))
510 return InvalidNick(nick);
512 bot->wantedNickName = nick;
513 QUEUE->sendNick(nick);
519 Commands::Notice(Bot *bot, String who, String message)
524 return EmptyAddressee;
526 // if (Utils::channel_p(who))
527 // return NotToChannel;
532 QUEUE->sendNotice(who, message);
538 Commands::Op(Bot *bot, String channel, String who)
542 Channel *c = CHANNEL(channel);
545 return NotOnChannel(channel);
547 if (!bot->iAmOp(channel))
548 return NotChannelOp(channel);
550 if (Utils::wildcard_p(who))
551 return MassOpNotAllowed;
553 User *u = c->getUser(who);
555 return UserNotFound(who, channel);
557 ShitEntry *se = bot->shitList->getShit(who, channel);
558 if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP)
559 return UserOnShitList(who);
561 QUEUE->sendChannelMode(channel, "+o", who);
568 Commands::Part(Bot *bot, String channel)
572 if (!CHANNEL(channel))
573 return NotOnChannel(channel);
575 wantedChannel *w = bot->wantedChannels[channel];
576 bot->wantedChannels.erase(channel);
578 QUEUE->sendPart(channel);
584 Commands::Reconnect(Bot *bot)
588 if (!bot->canChangeServer())
589 return CanNotChangeServer;
591 QUEUE->sendQuit("Reconnecting");
598 Commands::Say(Bot *bot, String channel, String message)
602 // if (!CHANNEL(channel))
603 // return NotOnChannel(channel);
605 QUEUE->sendPrivmsg(channel, message);
612 Commands::Server(Bot *bot, int number)
616 if (number < 0 || number >= bot->serverList->size())
617 return InvalidServerNumber(number);
619 if (!bot->canChangeServer())
620 return CanNotChangeServer;
622 QUEUE->sendQuit("Changing server");
624 bot->connect(number);
630 Commands::SetFloodRate(Bot *bot, unsigned int num_messages)
632 if (num_messages > 0)
634 bot->MAX_MESSAGES = num_messages;
637 return InvalidParameters;
641 Commands::SetVersion(Bot *bot, String str)
643 if (str.length() == 0)
644 return InvalidParameters;
646 bot->versionString = str;
651 Commands::TBan(Bot *bot, String channel, String who, int seconds)
655 Channel *c = CHANNEL(channel);
658 // Make sure all of the inputs are valid
661 return NotOnChannel(channel);
664 if (!bot->iAmOp(channel))
666 return NotChannelOp(channel);
671 return InvalidTime(seconds);
675 if (!Utils::wildcard_p(who))
677 dest = bot->getUserhost(channel, who);
684 if (dest.length() == 0)
686 return UserNotFound(who, channel);
690 dest = Utils::make_wildcard(dest);
693 // Make sure the user isn't protected from bans
694 for (std::list<UserListItem *>::iterator it = bot->userList->l.begin();
695 it != bot->userList->l.end();
698 if (m.matches((*it)->mask) &&
699 (*it)->channelMask.matches(channel) &&
700 (*it)->prot >= User::NO_BAN)
702 return UserProtected(who, channel);
706 // Clear existing bans on the user
707 for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
708 it != c->channelBanlist.end(); ++it)
710 if (m.matches((*it)->banMask))
712 QUEUE->sendChannelMode(channel, "-b", (*it)->banMask.getMask());
717 CHANNEL(channel)->addBan(dest, seconds);
718 QUEUE->sendChannelMode(channel, "+b", dest);
719 bot->todoList->addDeban(channel, dest, seconds);
726 Commands::TKBan(Bot *bot, String channel, String who, int seconds, String reason)
730 Message m = Commands::TBan(bot, channel, who, seconds);
732 if (m.getCode() == 0)
733 m = Commands::Kick(bot, channel, who, reason);
740 Commands::Topic(Bot *bot, String channel, String topic)
744 Channel *c = CHANNEL(channel);
747 return NotOnChannel(channel);
749 if (!bot->iAmOp(channel) && !(c->channelMode & Channel::TOPIC_RESTRICTED))
750 return CanNotChangeTopic(channel);
753 return TopicLocked(channel);
755 QUEUE->sendTopic(channel, topic);
762 Commands::Unlock(Bot *bot, String channel)
766 Channel *c = CHANNEL(channel);
769 return NotOnChannel(channel);
771 c->lockedTopic = false;