diff options
| author | Adam <Adam@drink-coca-cola.info> | 2010-05-29 20:44:31 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2010-06-18 21:04:08 -0400 |
| commit | b8f9116b19eb511c4f5e6a683725f50bf732a7dd (patch) | |
| tree | a5848c9797ec4dc3477621fc42211f4985eaec7b | |
| parent | 435c9116e9997634eb7215e998c8f01a5e46fb2c (diff) | |
Rewrote all of the command handling to get rid of all the nasty strtoks() everywhere, and added a bot map by uid
| -rw-r--r-- | include/bots.h | 5 | ||||
| -rw-r--r-- | include/extern.h | 18 | ||||
| -rw-r--r-- | include/modules.h | 11 | ||||
| -rw-r--r-- | include/operserv.h | 2 | ||||
| -rw-r--r-- | src/bots.cpp | 15 | ||||
| -rw-r--r-- | src/botserv.cpp | 351 | ||||
| -rw-r--r-- | src/chanserv.cpp | 26 | ||||
| -rw-r--r-- | src/commands.cpp | 51 | ||||
| -rw-r--r-- | src/core/bs_botlist.cpp | 8 | ||||
| -rw-r--r-- | src/core/db_plain.cpp | 2 | ||||
| -rw-r--r-- | src/core/os_defcon.cpp | 4 | ||||
| -rw-r--r-- | src/hostserv.cpp | 34 | ||||
| -rw-r--r-- | src/init.cpp | 2 | ||||
| -rw-r--r-- | src/main.cpp | 4 | ||||
| -rw-r--r-- | src/memoserv.cpp | 25 | ||||
| -rw-r--r-- | src/messages.cpp | 84 | ||||
| -rw-r--r-- | src/misc.cpp | 2 | ||||
| -rw-r--r-- | src/modules/mysql/db_mysql_execute.cpp | 6 | ||||
| -rw-r--r-- | src/modules/mysql/db_mysql_write.cpp | 4 | ||||
| -rw-r--r-- | src/nickserv.cpp | 24 | ||||
| -rw-r--r-- | src/operserv.cpp | 24 | ||||
| -rw-r--r-- | src/protocol/inspircd12.cpp | 19 | ||||
| -rw-r--r-- | src/protocol/ratbox.cpp | 16 | ||||
| -rw-r--r-- | src/users.cpp | 38 |
24 files changed, 374 insertions, 401 deletions
diff --git a/include/bots.h b/include/bots.h index b73b39879..8952005e7 100644 --- a/include/bots.h +++ b/include/bots.h @@ -11,8 +11,11 @@ #include "commands.h" class BotInfo; + typedef unordered_map_namespace::unordered_map<ci::string, BotInfo *, hash_compare_ci_string> botinfo_map; -extern CoreExport botinfo_map BotList; +typedef unordered_map_namespace::unordered_map<std::string, BotInfo *, hash_compare_std_string> botinfo_uid_map; +extern CoreExport botinfo_map BotListByNick; +extern CoreExport botinfo_uid_map BotListByUID; /** Flags settable on a bot */ diff --git a/include/extern.h b/include/extern.h index 1e88561e3..416e974e8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -46,9 +46,8 @@ E BotInfo *OperServ; E void get_botserv_stats(long *nrec, long *memuse); E void bs_init(); -E void botserv(User *u, char *buf); -E void botmsgs(User *u, BotInfo *bi, char *buf); -E void botchanmsgs(User *u, ChannelInfo *ci, char *buf); +E void botserv(User *u, BotInfo *bi, const std::string &buf); +E void botchanmsgs(User *u, ChannelInfo *ci, const std::string &buf); E BotInfo *findbot(const char *nick); E BotInfo *findbot(const std::string &nick); E BotInfo *findbot(const ci::string &nick); @@ -115,7 +114,7 @@ E void get_chanserv_stats(long *nrec, long *memuse); E void reset_levels(ChannelInfo * ci); E void cs_init(); -E void chanserv(User * u, char *buf); +E void chanserv(User *u, const std::string &buf); E void expire_chans(); E void cs_remove_nick(const NickCore * nc); @@ -159,7 +158,7 @@ E int read_config(int reload); /* hostserv.c */ E void do_on_id(User *u); -E void hostserv(User *u, char *buf); +E void hostserv(User *u, const std::string &buf); E void HostServSyncVhosts(NickAlias *na); /**** encrypt.c ****/ @@ -254,7 +253,7 @@ E char *sstrdup(const char *s); /**** memoserv.c ****/ E void ms_init(); -E void memoserv(User * u, char *buf); +E void memoserv(User * u, const std::string &buf); E void rsend_notify(User *u, Memo *m, const char *chan); E void check_memos(User * u); E MemoInfo *getmemoinfo(const char *name, int *ischan, int *isforbid); @@ -267,7 +266,7 @@ E int m_nickcoll(const char *user); E int m_away(const char *source, const char *msg); E int m_kill(const std::string &nick, const char *msg); E int m_motd(const char *source); -E int m_privmsg(const char *source, const std::string &receiver, const char *msg); +E int m_privmsg(const std::string &source, const std::string &receiver, const std::string &message); E int m_stats(const char *source, int ac, const char **av); E int m_whois(const char *source, const char *who); E int m_time(const char *source, int ac, const char **av); @@ -358,7 +357,7 @@ E void change_core_display(NickCore * nc, const char *newdisplay); E int do_setmodes(User * u); E void ns_init(); -E void nickserv(User * u, char *buf); +E void nickserv(User * u, const std::string &buf); E int validate_user(User * u); E void expire_nicks(); E void expire_requests(); @@ -433,9 +432,6 @@ E void get_user_stats(long *nusers, long *memuse); E User *finduser(const char *nick); E User *finduser(const std::string &nick); E User *finduser(const ci::string &nick); -E User *find_byuid(const char *uid); -E User *find_byuid(const ci::string &uid); -E User *find_byuid(const std::string &uid); E Server *findserver_uid(Server * s, const char *name); E char *TS6SID; diff --git a/include/modules.h b/include/modules.h index 963e07a4c..0acd041f9 100644 --- a/include/modules.h +++ b/include/modules.h @@ -419,13 +419,14 @@ class CoreExport Module virtual void OnUserNickChange(User *u, const std::string &oldnick) { } /** Called immediatly when a user tries to run a command - * @param bi The bot the command is being run from * @param u The user - * @param cmd The command + * @param bi The bot the command is being run from + * @param command The command + * @param message The parameters used for the command * @param c The command class (if it exists) * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it */ - virtual EventReturn OnPreCommandRun(BotInfo *bi, User *u, const ci::string &cmd, Command *c) { return EVENT_CONTINUE; } + virtual EventReturn OnPreCommandRun(User *u, BotInfo *bi, const ci::string &command, const ci::string &message, Command *c) { return EVENT_CONTINUE; } /** Called before a command is due to be executed. * @param u The user executing the command @@ -473,7 +474,7 @@ class CoreExport Module * @param ci The channel it's being used in * @param params The params */ - virtual void OnBotFantasy(char *command, User *u, ChannelInfo *ci, char *params) { } + virtual void OnBotFantasy(const std::string &command, User *u, ChannelInfo *ci, const std::string ¶ms) { } /** Called on fantasy command without access * @param command The command @@ -481,7 +482,7 @@ class CoreExport Module * @param ci The channel it's being used in * @param params The params */ - virtual void OnBotNoFantasyAccess(const char *command, User *u, ChannelInfo *ci, const char *params) { } + virtual void OnBotNoFantasyAccess(const std::string &command, User *u, ChannelInfo *ci, const std::string ¶ms) { } /** Called after a bot joins a channel * @param ci The channael diff --git a/include/operserv.h b/include/operserv.h index ff2149372..c9848779b 100644 --- a/include/operserv.h +++ b/include/operserv.h @@ -30,7 +30,7 @@ extern CoreExport bool CheckDefCon(int level, DefconLevel Level); extern CoreExport void AddDefCon(int level, DefconLevel Level); extern CoreExport void DelDefCon(int level, DefconLevel Level); -extern CoreExport void operserv(User *u, char *buf); +extern CoreExport void operserv(User *u, const std::string &message); extern CoreExport void os_init(); extern CoreExport void oper_global(char *nick, const char *fmt, ...); diff --git a/src/bots.cpp b/src/bots.cpp index 3c23da7d4..e9021b188 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -12,7 +12,8 @@ #include "modules.h" #include "commands.h" -botinfo_map BotList; +botinfo_map BotListByNick; +botinfo_uid_map BotListByUID; BotInfo *BotServ = NULL; BotInfo *ChanServ = NULL; @@ -62,7 +63,9 @@ BotInfo::BotInfo(const std::string &nnick, const std::string &nuser, const std:: Global = this; } - BotList[this->nick.c_str()] = this; + BotListByNick[this->nick.c_str()] = this; + if (!this->uid.empty()) + BotListByUID[this->uid] = this; // If we're synchronised with the uplink already, call introduce_user() for this bot. if (Me && Me->GetUplink()->IsSynced()) @@ -85,17 +88,19 @@ BotInfo::~BotInfo() } } - BotList.erase(this->nick.c_str()); + BotListByNick.erase(this->nick.c_str()); + if (!this->uid.empty()) + BotListByUID.erase(this->uid); } void BotInfo::ChangeNick(const char *newnick) { - BotList.erase(this->nick.c_str()); + BotListByNick.erase(this->nick.c_str()); this->nick = newnick; - BotList[this->nick.c_str()] = this; + BotListByNick[this->nick.c_str()] = this; } void BotInfo::RejoinAll() diff --git a/src/botserv.cpp b/src/botserv.cpp index aefe37b08..7f64c0c63 100644 --- a/src/botserv.cpp +++ b/src/botserv.cpp @@ -39,7 +39,7 @@ void get_botserv_stats(long *nrec, long *memuse) { long count = 0, mem = 0; - for (botinfo_map::const_iterator it = BotList.begin(); it != BotList.end(); ++it) + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) { BotInfo *bi = it->second; @@ -71,46 +71,21 @@ void bs_init() /* Main BotServ routine. */ -void botserv(User * u, char *buf) +void botserv(User *u, BotInfo *bi, const std::string &buf) { - char *cmd, *s; - - cmd = strtok(buf, " "); - - if (!cmd) { - return; - } else if (stricmp(cmd, "\1PING") == 0) { - if (!(s = strtok(NULL, ""))) { - *s = 0; - } - ircdproto->SendCTCP(BotServ, u->nick.c_str(), "PING %s", s); - } else { - mod_run_cmd(BotServ, u, cmd); - } - -} - -/*************************************************************************/ - -/* Handles all messages sent to bots. (Currently only answers to pings ;) */ - -void botmsgs(User * u, BotInfo * bi, char *buf) -{ - char *cmd = strtok(buf, " "); - char *s; - - if (!cmd || !u || !bi) + if (!u || !bi || buf.empty()) return; - - if (!stricmp(cmd, "\1PING")) { - if (!(s = strtok(NULL, ""))) { - *s = 0; - } - ircdproto->SendCTCP(bi, u->nick.c_str(), "PING %s", s); + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(bi, u->nick.c_str(), "%s", command.c_str()); } - else if (cmd && !bi->Commands.empty()) + else { - mod_run_cmd(bi, u, cmd); + mod_run_cmd(bi, u, buf.c_str()); } } @@ -121,32 +96,36 @@ void botmsgs(User * u, BotInfo * bi, char *buf) * */ -void botchanmsgs(User * u, ChannelInfo * ci, char *buf) +void botchanmsgs(User *u, ChannelInfo *ci, const std::string &buf) { - int c; - char *cmd; - UserData *ud; - bool was_action = false; - std::string bbuf; - - if (!u || !buf || !ci || !ci->c) + if (!u || !ci || !ci->c || buf.empty()) return; - - /* Answer to ping if needed, without breaking the buffer. */ - if (!strnicmp(buf, "\1PING", 5)) { - ircdproto->SendCTCP(ci->bi, u->nick.c_str(), "PING %s", buf); + + /* Answer to ping if needed */ + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string ctcp = buf; + ctcp.erase(ctcp.begin()); + ctcp.erase(ctcp.end()); + ircdproto->SendCTCP(ci->bi, u->nick.c_str(), "%s", ctcp.c_str()); } - /* If it's a /me, cut the CTCP part at the beginning (not - * at the end, because one character just doesn't matter, - * but the ACTION may create strange behaviours with the - * caps or badwords kickers */ - if (!strnicmp(buf, "\1ACTION ", 8)) + bool was_action = false; + std::string realbuf = buf; + + /* If it's a /me, cut the CTCP part because the ACTION will cause + * problems with the caps or badwords kicker + */ + if (realbuf.find("\1ACTION ", 0, 8) && realbuf[buf.length() - 1] == '\1') { - buf += 8; + realbuf.erase(0, 8); + realbuf.erase(realbuf.end()); was_action = true; } + if (realbuf.empty()) + return; + /* Now we can make kicker stuff. We try to order the checks * from the fastest one to the slowest one, since there's * no need to process other kickers if an user is kicked before @@ -164,56 +143,61 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && ci->c->HasUserStatus(u, CMODE_VOICE)) Allow = true; - if (buf && !check_access(u, ci, CA_NOKICK) && Allow) + if (!check_access(u, ci, CA_NOKICK) && Allow) { /* Bolds kicker */ - if (ci->botflags.HasFlag(BS_KICK_BOLDS) && strchr(buf, 2)) { + if (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find_first_of(2) != std::string::npos) + { check_ban(ci, u, TTB_BOLDS); bot_kick(ci, u, BOT_REASON_BOLD); return; } /* Color kicker */ - if (ci->botflags.HasFlag(BS_KICK_COLORS) && strchr(buf, 3)) { + if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find_first_of(3) != std::string::npos) + { check_ban(ci, u, TTB_COLORS); bot_kick(ci, u, BOT_REASON_COLOR); return; } /* Reverses kicker */ - if (ci->botflags.HasFlag(BS_KICK_REVERSES) && strchr(buf, 22)) { + if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find_first_of(22) != std::string::npos) + { check_ban(ci, u, TTB_REVERSES); bot_kick(ci, u, BOT_REASON_REVERSE); return; } /* Underlines kicker */ - if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && strchr(buf, 31)) { + if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find_first_of(31) != std::string::npos) + { check_ban(ci, u, TTB_UNDERLINES); bot_kick(ci, u, BOT_REASON_UNDERLINE); return; } /* Caps kicker */ - if (ci->botflags.HasFlag(BS_KICK_CAPS) - && ((c = strlen(buf)) >= ci->capsmin)) { + if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= ci->capsmin) + { int i = 0; int l = 0; - char *s = buf; - - do { - if (isupper(*s)) - i++; - else if (islower(*s)) - l++; - } while (*s++); + for (unsigned j = 0; j < realbuf.length(); ++j) + { + if (isupper(realbuf[j])) + ++i; + else if (islower(realbuf[j])) + ++l; + } + /* i counts uppercase chars, l counts lowercase chars. Only * alphabetic chars (so islower || isupper) qualify for the * percentage of caps to kick for; the rest is ignored. -GD */ - if (i && l && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent) { + if (i && l && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent) + { check_ban(ci, u, TTB_CAPS); bot_kick(ci, u, BOT_REASON_CAPS); return; @@ -221,49 +205,42 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } /* Bad words kicker */ - if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) { - int mustkick = 0; - char *nbuf; - BadWord *bw; + if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) + { + bool mustkick = false; /* Normalize the buffer */ - nbuf = normalizeBuffer(buf); + const char *nbuf = normalizeBuffer(realbuf.c_str()); for (unsigned i = 0; i < ci->GetBadWordCount(); ++i) { - bw = ci->GetBadWord(i); - - if (bw->type == BW_ANY - && ((Config.BSCaseSensitive && strstr(nbuf, bw->word.c_str())) - || (!Config.BSCaseSensitive && stristr(nbuf, bw->word.c_str())))) { - mustkick = 1; - } else if (bw->type == BW_SINGLE) { - int len = bw->word.length(); - - if ((Config.BSCaseSensitive && nbuf == bw->word) - || (!Config.BSCaseSensitive - && (!stricmp(nbuf, bw->word.c_str())))) { - mustkick = 1; - /* two next if are quite odd isn't it? =) */ - } else if ((strchr(nbuf, ' ') == nbuf + len) - && - ((Config.BSCaseSensitive && nbuf == bw->word) - || (!Config.BSCaseSensitive - && (stristr(nbuf, bw->word.c_str()) == - nbuf)))) { - mustkick = 1; - } else { - if ((strrchr(nbuf, ' ') == - nbuf + strlen(nbuf) - len - 1) - && - ((Config.BSCaseSensitive - && (strstr(nbuf, bw->word.c_str()) == - nbuf + strlen(nbuf) - len)) - || (!Config.BSCaseSensitive - && (stristr(nbuf, bw->word.c_str()) == - nbuf + strlen(nbuf) - len)))) { - mustkick = 1; - } else { + BadWord *bw = ci->GetBadWord(i); + + if (bw->type == BW_ANY && ((Config.BSCaseSensitive && strstr(nbuf, bw->word.c_str())) || (!Config.BSCaseSensitive && stristr(nbuf, bw->word.c_str())))) + { + mustkick = true; + } + else if (bw->type == BW_SINGLE) + { + size_t len = bw->word.length(); + + if ((Config.BSCaseSensitive && nbuf == bw->word) || (!Config.BSCaseSensitive && (!stricmp(nbuf, bw->word.c_str())))) + { + mustkick = true; + } + else if ((strchr(nbuf, ' ') == nbuf + len) && ((Config.BSCaseSensitive && nbuf == bw->word) + || (!Config.BSCaseSensitive && (stristr(nbuf, bw->word.c_str()) == nbuf)))) + { + mustkick = true; + } + else + { + if ((strrchr(nbuf, ' ') == nbuf + strlen(nbuf) - len - 1) && ((Config.BSCaseSensitive && (strstr(nbuf, bw->word.c_str()) == nbuf + strlen(nbuf) - len)) || (!Config.BSCaseSensitive && (stristr(nbuf, bw->word.c_str()) == nbuf + strlen(nbuf) - len)))) + { + mustkick = true; + } + else + { char *wordbuf = new char[len + 3]; wordbuf[0] = ' '; @@ -271,69 +248,67 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) wordbuf[len + 2] = '\0'; memcpy(wordbuf + 1, bw->word.c_str(), len); - if ((Config.BSCaseSensitive - && (strstr(nbuf, wordbuf))) - || (!Config.BSCaseSensitive - && (stristr(nbuf, wordbuf)))) { - mustkick = 1; + if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf)))) + { + mustkick = true; } - /* free previous (sc)allocated memory (#850) */ delete [] wordbuf; } } - } else if (bw->type == BW_START) { - int len = bw->word.length(); - - if ((Config.BSCaseSensitive - && (!strncmp(nbuf, bw->word.c_str(), len))) - || (!Config.BSCaseSensitive - && (!strnicmp(nbuf, bw->word.c_str(), len)))) { - mustkick = 1; - } else { + } + else if (bw->type == BW_START) + { + size_t len = bw->word.length(); + + if ((Config.BSCaseSensitive && (!strncmp(nbuf, bw->word.c_str(), len))) || (!Config.BSCaseSensitive && (!strnicmp(nbuf, bw->word.c_str(), len)))) + { + mustkick = true; + } + else + { char *wordbuf = new char[len + 2]; memcpy(wordbuf + 1, bw->word.c_str(), len); wordbuf[0] = ' '; wordbuf[len + 1] = '\0'; - if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) - || (!Config.BSCaseSensitive - && (stristr(nbuf, wordbuf)))) - mustkick = 1; + if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf)))) + { + mustkick = true; + } delete [] wordbuf; } - } else if (bw->type == BW_END) { - int len = bw->word.length(); - - if ((Config.BSCaseSensitive - && - (!strncmp - (nbuf + strlen(nbuf) - len, bw->word.c_str(), len))) - || (!Config.BSCaseSensitive - && - (!strnicmp - (nbuf + strlen(nbuf) - len, bw->word.c_str(), - len)))) { - mustkick = 1; - } else { + } + else if (bw->type == BW_END) + { + size_t len = bw->word.length(); + + if ((Config.BSCaseSensitive && (!strncmp(nbuf + strlen(nbuf) - len, bw->word.c_str(), len))) + || (!Config.BSCaseSensitive && (!strnicmp(nbuf + strlen(nbuf) - len, bw->word.c_str(), len)))) + { + mustkick = true; + } + else + { char *wordbuf = new char[len + 2]; memcpy(wordbuf, bw->word.c_str(), len); wordbuf[len] = ' '; wordbuf[len + 1] = '\0'; - if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) - || (!Config.BSCaseSensitive - && (stristr(nbuf, wordbuf)))) - mustkick = 1; + if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf)))) + { + mustkick = true; + } delete [] wordbuf; } } - if (mustkick) { + if (mustkick) + { check_ban(ci, u, TTB_BADWORDS); if (Config.BSGentleBWReason) bot_kick(ci, u, BOT_REASON_BADWORD_GENTLE); @@ -352,21 +327,23 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } /* Flood kicker */ - if (ci->botflags.HasFlag(BS_KICK_FLOOD)) { + if (ci->botflags.HasFlag(BS_KICK_FLOOD)) + { time_t now = time(NULL); - ud = get_user_data(ci->c, u); - if (!ud) { + UserData *ud = get_user_data(ci->c, u); + if (!ud) return; - } - if (now - ud->last_start > ci->floodsecs) { + if (now - ud->last_start > ci->floodsecs) + { ud->last_start = time(NULL); ud->lines = 0; } ud->lines++; - if (ud->lines >= ci->floodlines) { + if (ud->lines >= ci->floodlines) + { check_ban(ci, u, TTB_FLOOD); bot_kick(ci, u, BOT_REASON_FLOOD); return; @@ -374,22 +351,27 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } /* Repeat kicker */ - if (ci->botflags.HasFlag(BS_KICK_REPEAT)) { - ud = get_user_data(ci->c, u); - if (!ud) { + if (ci->botflags.HasFlag(BS_KICK_REPEAT)) + { + UserData *ud = get_user_data(ci->c, u); + if (!ud) return; - } - if (ud->lastline && stricmp(ud->lastline, buf)) { + + if (ud->lastline && stricmp(ud->lastline, buf.c_str())) + { delete [] ud->lastline; - ud->lastline = sstrdup(buf); + ud->lastline = sstrdup(buf.c_str()); ud->times = 0; - } else { + } + else + { if (!ud->lastline) - ud->lastline = sstrdup(buf); + ud->lastline = sstrdup(buf.c_str()); ud->times++; } - if (ud->times >= ci->repeattimes) { + if (ud->times >= ci->repeattimes) + { check_ban(ci, u, TTB_REPEAT); bot_kick(ci, u, BOT_REASON_REPEAT); return; @@ -397,31 +379,31 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } } - /* return if the user is on the ignore list */ - if (get_ignore(u->nick.c_str()) != NULL) { + if (get_ignore(u->nick.c_str()) != NULL) + { return; } /* Fantaisist commands */ + if (ci->botflags.HasFlag(BS_FANTASY) && buf[0] == *Config.BSFantasyCharacter && !was_action) + { + spacesepstream sep(buf); + std::string token; - if (buf && ci->botflags.HasFlag(BS_FANTASY) && *buf == *Config.BSFantasyCharacter && !was_action) { - cmd = strtok(buf, " "); - - if (cmd && (cmd[0] == *Config.BSFantasyCharacter)) { - char *params = strtok(NULL, ""); - + if (sep.GetToken(token) && (token[0] == *Config.BSFantasyCharacter)) + { /* Strip off the fantasy character */ - cmd++; + token.erase(token.begin()); if (check_access(u, ci, CA_FANTASIA)) { - Command *command = FindCommand(ChanServ, cmd); + Command *command = FindCommand(ChanServ, token.c_str()); /* Command exists and can not be called by fantasy */ if (command && !command->HasFlag(CFLAG_DISABLE_FANTASY)) { - bbuf = std::string(cmd); + std::string bbuf = std::string(token); /* Some commands don't need the channel name added.. eg !help */ if (!command->HasFlag(CFLAG_STRIP_CHANNEL)) @@ -430,20 +412,20 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) bbuf += ci->name; } - if (params) + if (!sep.StreamEnd()) { bbuf += " "; - bbuf += params; + bbuf += sep.GetRemaining(); } - chanserv(u, const_cast<char *>(bbuf.c_str())); // XXX Unsafe cast, this needs reviewing -- CyberBotX + chanserv(u, bbuf); } - FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(cmd, u, ci, params)); + FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(token, u, ci, sep.GetRemaining())); } else { - FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(cmd, u, ci, params)); + FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(token, u, ci, sep.GetRemaining())); } } } @@ -463,9 +445,18 @@ BotInfo *findbot(const std::string &nick) BotInfo *findbot(const ci::string &nick) { - botinfo_map::const_iterator it = BotList.find(nick); + if (isdigit(nick[0]) && ircd->ts6) + { + botinfo_uid_map::const_iterator it = BotListByUID.find(nick.c_str()); + + if (it != BotListByUID.end()) + return it->second; + return NULL; + } + + botinfo_map::const_iterator it = BotListByNick.find(nick); - if (it != BotList.end()) + if (it != BotListByNick.end()) return it->second; return NULL; } diff --git a/src/chanserv.cpp b/src/chanserv.cpp index 36e82f6b9..256909bb9 100644 --- a/src/chanserv.cpp +++ b/src/chanserv.cpp @@ -259,21 +259,21 @@ void cs_init() /* Main ChanServ routine. */ -void chanserv(User * u, char *buf) +void chanserv(User *u, const std::string &buf) { - char *cmd, *s; - - cmd = strtok(buf, " "); - - if (!cmd) { + if (!u || buf.empty()) return; - } else if (stricmp(cmd, "\1PING") == 0) { - if (!(s = strtok(NULL, ""))) { - *s = 0; - } - ircdproto->SendCTCP(ChanServ, u->nick.c_str(), "PING %s", s); - } else { - mod_run_cmd(ChanServ, u, cmd); + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(ChanServ, u->nick.c_str(), "%s", command.c_str()); + } + else + { + mod_run_cmd(ChanServ, u, buf.c_str()); } } diff --git a/src/commands.cpp b/src/commands.cpp index c767f8cd1..3226bff59 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -29,23 +29,28 @@ Command *FindCommand(BotInfo *bi, const ci::string &name) return NULL; } -void mod_run_cmd(BotInfo *bi, User *u, const ci::string &cmd) +void mod_run_cmd(BotInfo *bi, User *u, const ci::string &message) { - if (!bi || !u || cmd.empty()) + if (!bi || !u || message.empty()) + return; + + spacesepstream sep(message); + ci::string command; + + if (!sep.GetToken(command)) return; - Command *c = FindCommand(bi, cmd); - int retVal = MOD_CONT; - ChannelInfo *ci; + Command *c = FindCommand(bi, command); + CommandReturn ret = MOD_CONT; EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(bi, u, cmd, c)); + FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(u, bi, command, sep.GetRemaining().c_str(), c)); if (MOD_RESULT == EVENT_STOP) return; if (!c) { - notice_lang(bi->nick, u, UNKNOWN_COMMAND_HELP, cmd.c_str(), bi->nick.c_str()); + notice_lang(bi->nick, u, UNKNOWN_COMMAND_HELP, command.c_str(), bi->nick.c_str()); return; } @@ -55,35 +60,34 @@ void mod_run_cmd(BotInfo *bi, User *u, const ci::string &cmd) if (!u->IsIdentified()) { notice_lang(bi->nick, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ); - Alog() << "Access denied for unregistered user " << u->nick << " with service " << bi->nick << " and command " << cmd; + Alog() << "Access denied for unregistered user " << u->nick << " with service " << bi->nick << " and command " << command; return; } } std::vector<ci::string> params; - std::string curparam; - char *s = NULL; - while ((s = strtok(NULL, " "))) + ci::string curparam, endparam; + while (sep.GetToken(curparam)) { // - 1 because params[0] corresponds with a maxparam of 1. if (params.size() >= (c->MaxParams - 1)) { - curparam += s; - curparam += " "; + endparam += curparam; + endparam += " "; } else { - params.push_back(s); + params.push_back(curparam); } } - if (!curparam.empty()) + if (!endparam.empty()) { // Remove trailing space - curparam.erase(curparam.size() - 1, curparam.size()); + endparam.erase(endparam.size() - 1, endparam.size()); // Add it - params.push_back(curparam.c_str()); + params.push_back(endparam); } if (params.size() < c->MinParams) @@ -100,20 +104,21 @@ void mod_run_cmd(BotInfo *bi, User *u, const ci::string &cmd) { if (ircdproto->IsChannelValid(params[0].c_str())) { - if ((ci = cs_findchan(params[0]))) + ChannelInfo *ci = cs_findchan(params[0]); + if (ci) { if ((ci->HasFlag(CI_FORBIDDEN)) && (!c->HasFlag(CFLAG_ALLOW_FORBIDDEN))) { notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str()); Alog() << "Access denied for user " << u->nick << " with service " << bi->nick - << " and command " << cmd << " because of FORBIDDEN channel " << ci->name; + << " and command " << command << " because of FORBIDDEN channel " << ci->name; return; } else if ((ci->HasFlag(CI_SUSPENDED)) && (!c->HasFlag(CFLAG_ALLOW_SUSPENDED))) { notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str()); Alog() << "Access denied for user " << u->nick << " with service " << bi->nick - <<" and command " << cmd << " because of SUSPENDED channel " << ci->name; + <<" and command " << command << " because of SUSPENDED channel " << ci->name; return; } } @@ -137,15 +142,15 @@ void mod_run_cmd(BotInfo *bi, User *u, const ci::string &cmd) if (!u->Account()->HasCommand(c->permission)) { notice_lang(bi->nick, u, ACCESS_DENIED); - Alog() << "Access denied for user " << u->nick << " with service " << bi->nick << " and command " << cmd; |
