From c669820481b8c431f4238d6b2d958e9dbfec411a Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 15 Jan 2011 16:11:31 -0500 Subject: [PATCH] Added an amsg kicker --- include/extern.h | 2 + include/language.h | 5 +++ include/modules.h | 11 +++++- include/services.h | 6 ++- modules/core/bs_kick.cpp | 66 +++++++++++++++++++++++++++++++++ modules/extra/db_mysql_live.cpp | 39 ++++++++++--------- modules/protocol/unreal32.cpp | 2 +- src/botserv.cpp | 12 +++--- src/language.cpp | 18 +++++++++ 9 files changed, 135 insertions(+), 26 deletions(-) diff --git a/include/extern.h b/include/extern.h index f32520c44..b2e33dd83 100644 --- a/include/extern.h +++ b/include/extern.h @@ -52,6 +52,8 @@ E BotInfo *findbot(const Anope::string &nick); */ E Anope::string normalizeBuffer(const Anope::string &); +E void check_ban(ChannelInfo *ci, User *u, int ttbtype); +E void bot_kick(ChannelInfo *ci, User *u, LanguageString message, ...); E void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason); E void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason); diff --git a/include/language.h b/include/language.h index 03c8698b3..c61a870d9 100644 --- a/include/language.h +++ b/include/language.h @@ -725,6 +725,7 @@ enum LanguageString BOT_REASON_REVERSE, BOT_REASON_UNDERLINE, BOT_REASON_ITALIC, + BOT_REASON_AMSGS, BOT_BOT_SYNTAX, BOT_BOT_ALREADY_EXISTS, BOT_BOT_CREATION_FAILED, @@ -846,6 +847,9 @@ enum LanguageString BOT_KICK_ITALICS_ON, BOT_KICK_ITALICS_ON_BAN, BOT_KICK_ITALICS_OFF, + BOT_KICK_AMSGS_ON, + BOT_KICK_AMSGS_ON_BAN, + BOT_KICK_AMSGS_OFF, BOT_BADWORDS_SYNTAX, BOT_BADWORDS_DISABLED, BOT_BADWORDS_REACHED_LIMIT, @@ -1504,6 +1508,7 @@ enum LanguageString BOT_HELP_KICK_REPEAT, BOT_HELP_KICK_BADWORDS, BOT_HELP_KICK_ITALICS, + BOT_HELP_KICK_AMSGS, BOT_HELP_BADWORDS, BOT_HELP_SAY, BOT_HELP_ACT, diff --git a/include/modules.h b/include/modules.h index ae5bbeee3..fd032fe87 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1056,6 +1056,15 @@ class CoreExport Module : public Extensible * @return EVENT_STOP to halt processing */ virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, const Anope::string &message) { return EVENT_CONTINUE; } + + /** Called when we receive a PRIVMSG for a registered channel we are in + * @param u The source of the message + * @param ci The channel + * @param msg The message + * @param Allow set to false to make the flood kickers halt + * @return MOD_STOP to stop processing completely + */ + virtual EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow) { return EVENT_CONTINUE; } }; /** Implementation-specific flags which may be set in ModuleManager::Attach() @@ -1108,7 +1117,7 @@ enum Implementation I_OnServerQuit, I_OnTopicUpdated, I_OnEncrypt, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd, - I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, + I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_END }; diff --git a/include/services.h b/include/services.h index 5db510fde..80160d676 100644 --- a/include/services.h +++ b/include/services.h @@ -734,6 +734,8 @@ enum BotServFlag BS_KICK_REPEAT, /* BotServ kicks for italics */ BS_KICK_ITALICS, + /* BotServ kicks for amsgs */ + BS_KICK_AMSGS, /* Send fantasy replies back to the channel via PRIVMSG */ BS_MSG_PRIVMSG, /* Send fantasy replies back to the channel via NOTICE */ @@ -746,7 +748,8 @@ enum BotServFlag const Anope::string BotServFlagStrings[] = { "BS_BEGIN", "BS_DONTKICKOPS", "BS_DONTKICKVOICES", "BS_FANTASY", "BS_SYMBIOSIS", "BS_GREET", "BS_NOBOT", "BS_KICK_BOLDs", "BS_KICK_COLORS", "BS_KICK_REVERSES", "BS_KICK_UNDERLINES", "BS_KICK_BADWORDS", "BS_KICK_CAPS", - "BS_KICK_FLOOD", "BS_KICK_REPEAT", "BS_KICK_ITALICS", "BS_MSG_PRIVMSG", "BS_MSG_NOTICE", "BS_MSG_NOTICEOPS", "" + "BS_KICK_FLOOD", "BS_KICK_REPEAT", "BS_KICK_ITALICS", "BS_KICK_AMSGS", "BS_MSG_PRIVMSG", "BS_MSG_NOTICE", + "BS_MSG_NOTICEOPS", "" }; /* Indices for TTB (Times To Ban) */ @@ -761,6 +764,7 @@ enum TTB_FLOOD, TTB_REPEAT, TTB_ITALICS, + TTB_AMSGS, TTB_SIZE }; diff --git a/modules/core/bs_kick.cpp b/modules/core/bs_kick.cpp index 1618e1d1b..fef71e9f6 100644 --- a/modules/core/bs_kick.cpp +++ b/modules/core/bs_kick.cpp @@ -365,6 +365,36 @@ class CommandBSKick : public Command source.Reply(BOT_KICK_ITALICS_OFF); } } + else if (option.equals_ci("AMSGS")) + { + if (value.equals_ci("ON")) + { + if (!ttb.empty()) + { + Anope::string error; + ci->ttb[TTB_AMSGS] = convertTo(ttb, error, false); + if (!error.empty() || ci->ttb[TTB_AMSGS] < 0) + { + Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_ITALICS]; + ci->ttb[TTB_AMSGS] = 0; + source.Reply(BOT_KICK_AMSGS_ON_BAN, ci->ttb[TTB_AMSGS]); + return MOD_CONT; + } + } + else + ci->ttb[TTB_AMSGS] = 0; + ci->botflags.SetFlag(BS_KICK_AMSGS); + if (ci->ttb[TTB_AMSGS]) + source.Reply(BOT_KICK_AMSGS_ON_BAN, ci->ttb[TTB_AMSGS]); + else + source.Reply(BOT_KICK_AMSGS_ON); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_AMSGS); + source.Reply(BOT_KICK_AMSGS_OFF); + } + } else source.Reply(BOT_KICK_UNKNOWN, option.c_str()); } @@ -393,6 +423,8 @@ class CommandBSKick : public Command source.Reply(BOT_HELP_KICK_UNDERLINES); else if (subcommand.equals_ci("ITALICS")) source.Reply(BOT_HELP_KICK_ITALICS); + else if (subcommand.equals_ci("AMSGS")) + source.Reply(BOT_HELP_KICK_AMSGS); else return false; @@ -421,6 +453,40 @@ class BSKick : public Module this->SetType(CORE); this->AddCommand(BotServ, &commandbskick); + + ModuleManager::Attach(I_OnPrivmsg, this); + } + + EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow) + { + Anope::string m, ch; + time_t time; + + if (u->GetExtRegular("bs_kick_lastmsg", m) && u->GetExtRegular("bs_kick_lasttime", time) && u->GetExtRegular("bs_kick_lastchan", ch)) + { + if (time == Anope::CurTime && m == msg && ch != ci->name) + { + for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();) + { + Channel *c = (*it)->chan; + ++it; + + if (c->ci != NULL) + { + check_ban(c->ci, u, TTB_AMSGS); + bot_kick(c->ci, u, BOT_REASON_AMSGS); + } + } + + return EVENT_CONTINUE; + } + } + + u->Extend("bs_kick_lastmsg", new ExtensibleItemRegular(msg)); + u->Extend("bs_kick_lasttime", new ExtensibleItemRegular(Anope::CurTime)); + u->Extend("bs_kick_lastchan", new ExtensibleItemRegular(ci->name)); + + return EVENT_CONTINUE; } }; diff --git a/modules/extra/db_mysql_live.cpp b/modules/extra/db_mysql_live.cpp index f110b631d..bf5a1e6f7 100644 --- a/modules/extra/db_mysql_live.cpp +++ b/modules/extra/db_mysql_live.cpp @@ -85,30 +85,33 @@ class MySQLLiveModule : public Module, public Pipe EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector ¶ms) { - CommandMutex *cm = new CommandMutex(); - try + if (this->SQL) { - cm->mutex.Lock(); - cm->command = command; - cm->source = source; - cm->params = params; + CommandMutex *cm = new CommandMutex(); + try + { + cm->mutex.Lock(); + cm->command = command; + cm->source = source; + cm->params = params; - commands.push_back(cm); + commands.push_back(cm); - // Give processing to the command thread - Log(LOG_DEBUG_2) << "db_mysql_live: Waiting for command thread " << cm->command->name << " from " << source.u->nick; - threadEngine.Start(cm); - main_mutex.Lock(); - } - catch (const CoreException &ex) - { - delete cm; - Log() << "db_mysql_live: Unable to thread for command: " << ex.GetReason(); + // Give processing to the command thread + Log(LOG_DEBUG_2) << "db_mysql_live: Waiting for command thread " << cm->command->name << " from " << source.u->nick; + threadEngine.Start(cm); + main_mutex.Lock(); - return EVENT_CONTINUE; + return EVENT_STOP; + } + catch (const CoreException &ex) + { + delete cm; + Log() << "db_mysql_live: Unable to thread for command: " << ex.GetReason(); + } } - return EVENT_STOP; + return EVENT_CONTINUE; } void OnNotify() diff --git a/modules/protocol/unreal32.cpp b/modules/protocol/unreal32.cpp index 6db84639b..d02987038 100644 --- a/modules/protocol/unreal32.cpp +++ b/modules/protocol/unreal32.cpp @@ -1043,7 +1043,7 @@ class ProtoUnreal : public Module message_mode("G", OnMode), message_nick("&", OnNick), message_part("D", OnPart), message_ping("8", OnPing), message_pong("PONG", event_pong), - message_pong2("9", event_pong), message_privmsg("!", OnPrivmsg), + message_pong2("9", event_pong), message_privmsg("!", ::OnPrivmsg), message_quit(",", OnQuit), message_server("'", OnServer), message_squit("-", OnSQuit), message_topic(")", OnTopic), message_svsmode("SVSMODE", OnMode), diff --git a/src/botserv.cpp b/src/botserv.cpp index 6eaa330c9..78e29451a 100644 --- a/src/botserv.cpp +++ b/src/botserv.cpp @@ -16,9 +16,6 @@ static UserData *get_user_data(Channel *c, User *u); -static void check_ban(ChannelInfo *ci, User *u, int ttbtype); -static void bot_kick(ChannelInfo *ci, User *u, LanguageString message, ...); - E void moduleAddBotServCmds(); /*************************************************************************/ @@ -116,6 +113,11 @@ void botchanmsgs(User *u, ChannelInfo *ci, const Anope::string &buf) Allow = true; else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && ci->c->HasUserStatus(u, CMODE_VOICE)) Allow = true; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPrivmsg, OnPrivmsg(u, ci, realbuf, Allow)); + if (MOD_RESULT == EVENT_STOP) + return; if (!check_access(u, ci, CA_NOKICK) && Allow) { @@ -452,7 +454,7 @@ static UserData *get_user_data(Channel *c, User *u) * @param u The user * @param ttbtype The type of bot kicker the user should be checked against */ -static void check_ban(ChannelInfo *ci, User *u, int ttbtype) +void check_ban(ChannelInfo *ci, User *u, int ttbtype) { BanData *bd = get_ban_data(ci->c, u); @@ -485,7 +487,7 @@ static void check_ban(ChannelInfo *ci, User *u, int ttbtype) /* This makes a bot kick an user. Works somewhat like notice_lang in fact ;) */ -static void bot_kick(ChannelInfo *ci, User *u, LanguageString message, ...) +void bot_kick(ChannelInfo *ci, User *u, LanguageString message, ...) { va_list args; char buf[1024]; diff --git a/src/language.cpp b/src/language.cpp index 2e2e3004b..f6a2d432e 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -1648,6 +1648,8 @@ const char *const language_strings[LANG_STRING_COUNT] = { _("Don't use underlines on this channel!"), /* BOT_REASON_ITALIC */ _("Don't use italics on this channel!"), + /* BOT_REASON_AMSGS */ + _("Don't use AMSGs!"), /* BOT_BOT_SYNTAX */ _("BOT ADD nick user host real\n" "BOT CHANGE oldnick newnick [user [host [real]]]\n" @@ -1910,6 +1912,13 @@ const char *const language_strings[LANG_STRING_COUNT] = { "%d kicks for the same user."), /* BOT_KICK_ITALICS_OFF */ _("Bot won't kick italics anymore."), + /* BOT_KICK_AMSGS_ON */ + _("Bot will now kick for \002amsgs\002"), + /* BOT_KICK_AMSGS_ON_BAN */ + _("Bot will not kick for \002amsgs\002, and will place a ban after\n" + "%d kicks for the same user."), + /* BOT_KICK_AMSGS_OFF */ + _("Bot won't kick for \002amsgs\002 anymore."), /* BOT_BADWORDS_SYNTAX */ _("BADWORDS channel {ADD|DEL|LIST|CLEAR} [word | entry-list] [SINGLE|START|END]"), /* BOT_BADWORDS_DISABLED */ @@ -4948,6 +4957,7 @@ const char *const language_strings[LANG_STRING_COUNT] = { " \n" "Configures bot kickers. option can be one of:\n" " \n" + " AMSGS Sets if the bot kicks for amsgs\n" " BOLDS Sets if the bot kicks bolds\n" " BADWORDS Sets if the bot kicks bad words\n" " CAPS Sets if the bot kicks caps\n" @@ -5041,6 +5051,14 @@ const char *const language_strings[LANG_STRING_COUNT] = { "ttb is the number of times a user can be kicked\n" "before it get banned. Don't give ttb to disable\n" "the ban system once activated."), + /* BOT_HELP_KICK_AMSGS */ + _("Syntax: \002KICK \037channel\037 AMSGS {\037ON|OFF\037} [\037ttb\037]\002\n" + "Sets the amsg kicker on or off. When enabled, the bot will\n" + "kick users who send the same message to multiple channels\n" + "where BotServ bots are.\n" + "Ttb is the number of times a user can be kicked\n" + "before it get banned. Don't give ttb to disable\n" + "the ban system once activated."), /* BOT_HELP_BADWORDS */ _("Syntax: BADWORDS channel ADD word [SINGLE | START | END]\n" " BADWORDS channel DEL {word | entry-num | list}\n"