X-Git-Url: https://git.hcoop.net/clinton/bobotpp.git/blobdiff_plain/cf8ea87372f220b09b01689b1729a88eb3b2a1d2..71cf268829070ae57d695fbea11404bc04113aa9:/source/Commands.C?ds=sidebyside diff --git a/source/Commands.C b/source/Commands.C index d007e33..b1e4f5f 100644 --- a/source/Commands.C +++ b/source/Commands.C @@ -14,40 +14,33 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301, USA. +#include "Commands.H" + +#include + +#include "BanEntry.H" +#include "Bot.H" +#include "ChannelList.H" #include "Macros.H" #include "Message.H" -#include "Commands.H" +#include "Server.H" +#include "ServerConnection.H" +#include "ServerList.H" +#include "ServerQueueItem.H" +#include "ShitEntry.H" +#include "ShitList.H" +#include "StringTokenizer.H" +#include "User.H" +#include "UserList.H" #include "Utils.H" -#define Ok (Message(0, "")) -#define NotOnChannel(c) (Message(-1, String("I am not on channel ") + (c))) -#define NotChannelOp(c) (Message(-2, String("I am not channel op on ") + (c))) -#define UserNotFound(w, c) (Message(-3, (w) + " is not on channel " + (c))) -#define UserNotOp(w, c) (Message(-4, (w) + " is not channel op on " + (c))) -#define UserProtected(w, c) (Message(-5, (w) + " is protected on " + (c))) -#define InvalidNick(n) (Message(-6, (n) + " is not a valid nickname")) -#define InvalidChannel(c) (Message(-7, (c) + " is not a valid channel name")) -#define MassOpNotAllowed (Message(-8, "Mass op is not allowed.")) -#define UserOnShitList(w) (Message(-9, String("User ") + w + " is on my shitlist")) -#define CanNotChangeTopic(c) (Message(-10, String("I can not change topic on ") + (c))) -#define TopicLocked(c) (Message(-11, String("Topic is locked on ") + (c))) -#define InvalidPort(p) (Message(-12, String((long)(p)) + " is an invalid port number")) -#define InvalidTime(t) (Message(-13, String((long)(t)) + " is an invalid time")) -#define CanNotChangeServer (Message(-14, "I cannot change server without loosing op on one of my channels")) -#define EmptyServerList (Message(-15, "Server list is empty")) -#define InvalidServerNumber(n) (Message(-16, String((long)(n)) + " is an invalid server number")) -#define InvalidParameters (Message(-17, "Invalid parameters")) -#define NotFound(w) (Message(-18, String("I can not find ") + (w))); -#define NotInUserlist(w) (Message(-19, (w) + " is not in my userlist")) -#define NotInShitlist(w) (Message(-20, (w) + " is not in my shitlist")) -#define AlreadyInUserlist(m, mc) (Message(-21, (m) + " is already in userlist on channel(s) " + (mc))) -#define AlreadyInShitlist(m, mc) (Message(-22, (m) + " is already in shitlist on channel(s) " + (mc))) -#define EmptyMessage (Message(-23, "Can not send an empty message")) -#define EmptyAddressee (Message(-24, "Can not send to nobody")) -#define NotToChannel (Message(-25, "Can not send to a channel. Use \"say\" instead.")) -#define NotConnected (Message(-26, "Not connected.")) +#ifdef USESCRIPTS +#include "BotInterp.H" +#endif + #define CHECK_CONNECTION if (!bot->serverConnection) return NotConnected @@ -62,7 +55,7 @@ Commands::Action(Bot *bot, String channel, String message) if (message.length() == 0) return InvalidParameters; - QUEUE->sendCTCP (channel, "ACTION", message); + Commands::CTCP (bot, channel, "ACTION", message); return Ok; } @@ -84,15 +77,19 @@ Commands::AddUser(Bot *bot, String who, String maskChannel, int level, if (!Utils::wildcard_p(who)) { - mask = bot->getUserhost("", who); - if (mask.length() == 0) - return NotFound(who); - } + mask = bot->getUserhost("", who); + if (mask.length() == 0) + { + return NotFound(who); + } + } // Aha! This was before the brace...segfault gone mask = Utils::make_wildcard(mask); if (bot->userList->isInUserList(mask, maskChannel)) - return AlreadyInUserlist(mask, maskChannel); + { + return AlreadyInUserlist(mask, maskChannel); + } bot->userList->addUser(mask, maskChannel, level, prot, aop, expire, password); @@ -178,17 +175,91 @@ Commands::Ban(Bot *bot, String channel, String who) (*it)->channelMask.matches(channel) && (*it)->prot >= User::NO_BAN) return UserProtected(who, channel); - - for (std::vector::iterator it = c->channelBanlist.begin(); - it != c->channelBanlist.end(); ++it) - if (m.matches((*it)->banMask) && (*it)->banMask.getMask() != m.getMask()) - QUEUE->sendChannelMode(channel, "-b", (*it)->banMask.getMask()); - QUEUE->sendChannelMode(channel, "+b", dest); + c->delBan (m); + c->addBan (m, -1); + + return Ok; +} + +Message +Commands::CTCP (Bot *bot, std::string target, std::string command, + std::string message) +{ + CHECK_CONNECTION; + + if (target == "") + { + return EmptyAddressee; + } + + if (command == "") + { + return InvalidParameters; + } + + if (message == "") + { + return EmptyMessage; + } + + if (Utils::channel_p (target) && !CHANNEL (target)) + { + return NotOnChannel (target); + } + + + // Send multi-line messages as seperate privmsgs + StringTokenizer st_message (message); + + while (st_message.more_tokens_p ('\n')) + { + QUEUE->sendCTCP (target, command, st_message.next_token ('\n')); + } + + return Ok; +} + +Message +Commands::CTCPReply (Bot *bot, std::string target, std::string command, + std::string message) +{ + CHECK_CONNECTION; + + if (target == "") + { + return EmptyAddressee; + } + + if (command == "") + { + return InvalidParameters; + } + + if (message == "") + { + return EmptyMessage; + } + + // CTCP-REPLY cannot go to a channel + if (Utils::channel_p (target)) + { + return NotToChannel; + } + + + // Send multi-line messages as seperate privmsgs + StringTokenizer st_message (message); + + while (st_message.more_tokens_p ('\n')) + { + QUEUE->sendCTCPReply (target, command, st_message.next_token ('\n')); + } return Ok; } + Message Commands::Cycle(Bot *bot, String channel) { @@ -228,16 +299,20 @@ Commands::Deban(Bot *bot, String channel, String who) dest = Utils::make_wildcard(dest); Mask m(dest); + + BanList::MatchList matches = c->channelBanlist.find_matches (m); - for (std::vector::iterator it = c->channelBanlist.begin(); - it != c->channelBanlist.end(); ++it) - if (m.matches((*it)->getMask())) { - // Let's see if the ban is in the shitlist - ShitEntry *se = bot->shitList->getShit((*it)->getMask(), channel); - if (!se || !se->isStillValid() || - se->getShitLevel() < ShitEntry::SHIT_NODEBAN) - QUEUE->sendChannelMode(channel, "-b", (*it)->getMask()); - } + for (BanList::MatchList::iterator it = matches.begin (); + it != matches.end(); + ++it) + if (m.matches(*it)) + { + // Let's see if the ban is in the shitlist + ShitEntry *se = bot->shitList->getShit(it->getMask(), channel); + if (!se || !se->isStillValid() || + se->getShitLevel() < ShitEntry::SHIT_NODEBAN) + c->delBan (m); + } return Ok; } @@ -300,6 +375,20 @@ Commands::DelShit(Bot *bot, String who, String maskChannel) return Ok; } +Commands::deop_wildcard::deop_wildcard +(Bot *b, Mask &m, String &c) + : bot (b), mask (m), channel (c) +{ } + +void +Commands::deop_wildcard::operator() (const User &user) +{ + if (mask.matches(user.nick + "!" + user.userhost) + && user.getProt() < User::NO_DEOP + && (user.mode & User::OP_MODE)) + QUEUE->sendChannelMode(channel, "-o", user.nick); +} + Message Commands::Deop(Bot *bot, String channel, String who) { @@ -314,27 +403,25 @@ Commands::Deop(Bot *bot, String channel, String who) return NotChannelOp(channel); if (!Utils::wildcard_p(who)) { - User *u = c->getUser(who); - if (!u) - return UserNotFound(who, channel); - if (!(u->mode & User::OP_MODE)) - return UserNotOp(who, channel); - if (u->getProt() >= User::NO_DEOP) - return UserProtected(who, channel); - QUEUE->sendChannelMode(channel, "-o", who); + try + { + User u = c->getUser(who); + + if (!(u.mode & User::OP_MODE)) + return UserNotOp(who, channel); + if (u.getProt() >= User::NO_DEOP) + return UserProtected(who, channel); + QUEUE->sendChannelMode(channel, "-o", who); + } + catch (const ChannelUserList::user_not_found &e) + { + return UserNotFound(e.name, channel); + } } else { - Mask m(who); - for (std::map >::iterator - it = c->channelMemory.begin(); - it != c->channelMemory.end(); ++it) { - if (m.matches((*it).second->nick + "!" + - (*it).second->userhost) && - (*it).second->getProt() < User::NO_DEOP && - ((*it).second->mode & User::OP_MODE)) - QUEUE->sendChannelMode(channel, "-o", (*it).second->nick); - } + Mask m (who); + deop_wildcard f (bot, m, channel); + c->for_each_channel_users (f); } - return Ok; } @@ -383,7 +470,7 @@ Commands::Join(Bot *bot, String channel, String key) // We don't trust the user... if (!CHANNEL(channel)) { if (bot->wantedChannels[channel]) - bot->wantedChannels[channel]->key = key; + bot->wantedChannels[channel]->key = static_cast (key); else { bot->wantedChannels[channel] = new wantedChannel("", "", key); } @@ -408,6 +495,19 @@ Commands::Keep(Bot *bot, String channel, String modes) return Ok; } +Commands::kick_wildcard::kick_wildcard +(Bot *b, Mask &m, String &c, String &r) + : bot (b), mask (m), channel (c), reason (r) +{ } + +void +Commands::kick_wildcard::operator() (const User &user) +{ + if (mask.matches(user.nick + "!" + user.userhost) && + user.getProt() < User::NO_KICK) + QUEUE->sendKick(channel, user.nick, reason); +} + Message Commands::Kick(Bot *bot, String channel, String who, String reason) { @@ -423,22 +523,22 @@ Commands::Kick(Bot *bot, String channel, String who, String reason) if (Utils::wildcard_p(who)) { Mask m(who); - for (std::map >::iterator it = - c->channelMemory.begin(); - it != c->channelMemory.end(); - ++it) - if (m.matches((*it).second->nick + "!" + - (*it).second->userhost) && - (*it).second->getProt() < User::NO_KICK) - QUEUE->sendKick(channel, (*it).second->nick, reason); + kick_wildcard f (bot, m, channel, reason); + c->for_each_channel_users (f); } else { - User * u = c->getUser(who); - if (!u) - return UserNotFound(who, channel); - if (u->getProt() < User::NO_KICK) - QUEUE->sendKick(channel, who, reason); - else - return UserProtected(who, channel); + try + { + User u = c->getUser(who); + + if (u.getProt() < User::NO_KICK) + QUEUE->sendKick(channel, who, reason); + else + return UserProtected(who, channel); + } + catch (const ChannelUserList::user_not_found &e) + { + return UserNotFound(e.name, channel); + } } return Ok; @@ -494,15 +594,30 @@ Commands::Msg(Bot *bot, String who, String message) CHECK_CONNECTION; if (who == "") - return EmptyAddressee; + { + return EmptyAddressee; + } if (Utils::channel_p(who)) - return NotToChannel; + { + if (!CHANNEL(who)) + { + return NotOnChannel (who); + } + } if (message == "") - return EmptyMessage; + { + return EmptyMessage; + } - QUEUE->sendPrivmsg(who, message); + // Send multi-line messages as seperate privmsgs + StringTokenizer st_message (message); + + while (st_message.more_tokens_p ('\n')) + { + QUEUE->sendPrivmsg(who, st_message.next_token ('\n')); + } return Ok; } @@ -517,6 +632,16 @@ Commands::NextServer(Bot *bot) if (!bot->canChangeServer()) return CanNotChangeServer; + +#ifdef USESCRIPTS + // Run hooks/disconnect + bot->botInterp->RunHooks + (Hook::DISCONNECT, + bot->serverConnection->server->getHostName (), + scm_list_n + (Utils::str2scm (bot->serverConnection->server->getHostName ()), + SCM_BOOL_T)); +#endif QUEUE->sendQuit("Changing server"); bot->nextServer(); @@ -529,7 +654,7 @@ Commands::Nick(Bot *bot, String nick) { CHECK_CONNECTION; - if (nick == "" || !Utils::valid_nickname_p(nick)) + if (nick == "" || !Utils::valid_nickname_p(bot, nick)) return InvalidNick(nick); bot->wantedNickName = nick; @@ -546,13 +671,19 @@ Commands::Notice(Bot *bot, String who, String message) if (who == "") return EmptyAddressee; - if (Utils::channel_p(who)) - return NotToChannel; + // if (Utils::channel_p(who)) + // return NotToChannel; if (message == "") return EmptyMessage; - QUEUE->sendNotice(who, message); + // Send multiple lines as multiple notices + StringTokenizer st_message (message); + + while (st_message.more_tokens_p ('\n')) + { + QUEUE->sendNotice(who, st_message.next_token ('\n')); + } return Ok; } @@ -572,16 +703,21 @@ Commands::Op(Bot *bot, String channel, String who) if (Utils::wildcard_p(who)) return MassOpNotAllowed; + + try + { + User u = c->getUser(who); - User *u = c->getUser(who); - if (!u) - return UserNotFound(who, channel); - - ShitEntry *se = bot->shitList->getShit(who, channel); - if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) - return UserOnShitList(who); - - QUEUE->sendChannelMode(channel, "+o", who); + ShitEntry *se = bot->shitList->getShit(who, channel); + if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) + return UserOnShitList(who); + + QUEUE->sendChannelMode(channel, "+o", who); + } + catch (const ChannelUserList::user_not_found &e) + { + return UserNotFound(e.name, channel); + } return Ok; } @@ -620,14 +756,7 @@ Commands::Reconnect(Bot *bot) Message Commands::Say(Bot *bot, String channel, String message) { - CHECK_CONNECTION; - -// if (!CHANNEL(channel)) -// return NotOnChannel(channel); - - QUEUE->sendPrivmsg(channel, message); - - return Ok; + return Commands::Msg (bot, channel, message); } @@ -680,35 +809,20 @@ Commands::TBan(Bot *bot, String channel, String who, int seconds) // Make sure all of the inputs are valid if (!c) - { - return NotOnChannel(channel); - } - + return NotOnChannel(channel); if (!bot->iAmOp(channel)) - { - return NotChannelOp(channel); - } - + return NotChannelOp(channel); if (seconds <= 0) - { - return InvalidTime(seconds); - } - + return InvalidTime(seconds); + // Look for user if (!Utils::wildcard_p(who)) - { - dest = bot->getUserhost(channel, who); - } + dest = bot->getUserhost(channel, who); else - { - dest = who; - } - + dest = who; + if (dest.length() == 0) - { - return UserNotFound(who, channel); - } - + return UserNotFound(who, channel); dest = Utils::make_wildcard(dest); Mask m(dest); @@ -726,20 +840,9 @@ Commands::TBan(Bot *bot, String channel, String who, int seconds) } } - // Clear existing bans on the user - for (std::vector::iterator it = c->channelBanlist.begin(); - it != c->channelBanlist.end(); ++it) - { - if (m.matches((*it)->banMask)) - { - QUEUE->sendChannelMode(channel, "-b", (*it)->banMask.getMask()); - } - } - // Ban them - CHANNEL(channel)->addBan(dest, seconds); - QUEUE->sendChannelMode(channel, "+b", dest); - bot->todoList->addDeban(channel, dest, seconds); + // c->delBan (dest); + c->addBan(dest, seconds); return Ok; } @@ -795,3 +898,31 @@ Commands::Unlock(Bot *bot, String channel) return Ok; } + +Message +Commands::Who (Bot *bot, String target) +{ + CHECK_CONNECTION; + + QUEUE->sendWho (target); + + return Ok; +} + +Message +Commands::Whois (Bot *bot, String nick) +{ + CHECK_CONNECTION; + + if (!Utils::valid_nickname_p (bot, nick)) + { + return InvalidNick (nick); + } + else + { + QUEUE->sendWhois (nick); + return Ok; + } +} + +