From a22f8d3b2de88b9bb6f80f0c2780846ae23ab389 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 15 Jul 2010 22:55:02 -0400 Subject: Moved some files and diretories around, made cmake skip files it knows it can't compile because of missing dependices. --- modules/core/bs_act.cpp | 85 +++ modules/core/bs_assign.cpp | 95 +++ modules/core/bs_badwords.cpp | 282 ++++++++ modules/core/bs_bot.cpp | 411 ++++++++++++ modules/core/bs_botlist.cpp | 93 +++ modules/core/bs_help.cpp | 53 ++ modules/core/bs_info.cpp | 233 +++++++ modules/core/bs_kick.cpp | 388 +++++++++++ modules/core/bs_say.cpp | 91 +++ modules/core/bs_set.cpp | 215 ++++++ modules/core/bs_unassign.cpp | 73 +++ modules/core/cs_access.cpp | 623 ++++++++++++++++++ modules/core/cs_akick.cpp | 584 +++++++++++++++++ modules/core/cs_ban.cpp | 111 ++++ modules/core/cs_clear.cpp | 178 +++++ modules/core/cs_drop.cpp | 116 ++++ modules/core/cs_forbid.cpp | 129 ++++ modules/core/cs_getkey.cpp | 75 +++ modules/core/cs_help.cpp | 73 +++ modules/core/cs_info.cpp | 158 +++++ modules/core/cs_invite.cpp | 94 +++ modules/core/cs_kick.cpp | 97 +++ modules/core/cs_list.cpp | 176 +++++ modules/core/cs_modes.cpp | 451 +++++++++++++ modules/core/cs_register.cpp | 131 ++++ modules/core/cs_saset.cpp | 122 ++++ modules/core/cs_saset_noexpire.cpp | 82 +++ modules/core/cs_set.cpp | 127 ++++ modules/core/cs_set_bantype.cpp | 110 ++++ modules/core/cs_set_description.cpp | 104 +++ modules/core/cs_set_entrymsg.cpp | 111 ++++ modules/core/cs_set_founder.cpp | 138 ++++ modules/core/cs_set_keeptopic.cpp | 109 +++ modules/core/cs_set_mlock.cpp | 182 +++++ modules/core/cs_set_opnotice.cpp | 109 +++ modules/core/cs_set_peace.cpp | 109 +++ modules/core/cs_set_persist.cpp | 154 +++++ modules/core/cs_set_private.cpp | 109 +++ modules/core/cs_set_restricted.cpp | 112 ++++ modules/core/cs_set_secure.cpp | 109 +++ modules/core/cs_set_securefounder.cpp | 115 ++++ modules/core/cs_set_secureops.cpp | 109 +++ modules/core/cs_set_signkick.cpp | 109 +++ modules/core/cs_set_successor.cpp | 140 ++++ modules/core/cs_set_topiclock.cpp | 109 +++ modules/core/cs_set_xop.cpp | 139 ++++ modules/core/cs_status.cpp | 74 +++ modules/core/cs_suspend.cpp | 195 ++++++ modules/core/cs_topic.cpp | 98 +++ modules/core/cs_unban.cpp | 88 +++ modules/core/cs_xop.cpp | 661 +++++++++++++++++++ modules/core/db_plain.cpp | 1166 +++++++++++++++++++++++++++++++++ modules/core/enc_md5.cpp | 373 +++++++++++ modules/core/enc_none.cpp | 67 ++ modules/core/enc_old.cpp | 381 +++++++++++ modules/core/enc_sha1.cpp | 229 +++++++ modules/core/enc_sha256.cpp | 316 +++++++++ modules/core/hs_del.cpp | 73 +++ modules/core/hs_delall.cpp | 78 +++ modules/core/hs_group.cpp | 66 ++ modules/core/hs_help.cpp | 51 ++ modules/core/hs_list.cpp | 132 ++++ modules/core/hs_off.cpp | 62 ++ modules/core/hs_on.cpp | 76 +++ modules/core/hs_set.cpp | 165 +++++ modules/core/hs_setall.cpp | 164 +++++ modules/core/ms_cancel.cpp | 87 +++ modules/core/ms_check.cpp | 106 +++ modules/core/ms_del.cpp | 162 +++++ modules/core/ms_help.cpp | 52 ++ modules/core/ms_info.cpp | 215 ++++++ modules/core/ms_list.cpp | 176 +++++ modules/core/ms_read.cpp | 159 +++++ modules/core/ms_rsend.cpp | 90 +++ modules/core/ms_send.cpp | 61 ++ modules/core/ms_sendall.cpp | 77 +++ modules/core/ms_set.cpp | 272 ++++++++ modules/core/ms_staff.cpp | 74 +++ modules/core/ns_access.cpp | 181 +++++ modules/core/ns_alist.cpp | 155 +++++ modules/core/ns_drop.cpp | 130 ++++ modules/core/ns_forbid.cpp | 122 ++++ modules/core/ns_getemail.cpp | 83 +++ modules/core/ns_getpass.cpp | 94 +++ modules/core/ns_ghost.cpp | 103 +++ modules/core/ns_group.cpp | 287 ++++++++ modules/core/ns_help.cpp | 67 ++ modules/core/ns_identify.cpp | 125 ++++ modules/core/ns_info.cpp | 191 ++++++ modules/core/ns_list.cpp | 219 +++++++ modules/core/ns_logout.cpp | 96 +++ modules/core/ns_recover.cpp | 124 ++++ modules/core/ns_register.cpp | 395 +++++++++++ modules/core/ns_release.cpp | 106 +++ modules/core/ns_resetpass.cpp | 169 +++++ modules/core/ns_saset.cpp | 245 +++++++ modules/core/ns_saset_noexpire.cpp | 84 +++ modules/core/ns_sendpass.cpp | 100 +++ modules/core/ns_set.cpp | 229 +++++++ modules/core/ns_set_autoop.cpp | 128 ++++ modules/core/ns_set_email.cpp | 157 +++++ modules/core/ns_set_greet.cpp | 127 ++++ modules/core/ns_set_hide.cpp | 197 ++++++ modules/core/ns_set_kill.cpp | 180 +++++ modules/core/ns_set_language.cpp | 140 ++++ modules/core/ns_set_message.cpp | 146 +++++ modules/core/ns_set_private.cpp | 134 ++++ modules/core/ns_set_secure.cpp | 134 ++++ modules/core/ns_status.cpp | 77 +++ modules/core/ns_suspend.cpp | 199 ++++++ modules/core/ns_update.cpp | 67 ++ modules/core/os_akill.cpp | 410 ++++++++++++ modules/core/os_chankill.cpp | 117 ++++ modules/core/os_chanlist.cpp | 99 +++ modules/core/os_clearmodes.cpp | 189 ++++++ modules/core/os_defcon.cpp | 499 ++++++++++++++ modules/core/os_global.cpp | 62 ++ modules/core/os_help.cpp | 51 ++ modules/core/os_ignore.cpp | 203 ++++++ modules/core/os_jupe.cpp | 78 +++ modules/core/os_kick.cpp | 80 +++ modules/core/os_mode.cpp | 71 ++ modules/core/os_modinfo.cpp | 100 +++ modules/core/os_modlist.cpp | 230 +++++++ modules/core/os_modload.cpp | 73 +++ modules/core/os_modunload.cpp | 75 +++ modules/core/os_news.cpp | 476 ++++++++++++++ modules/core/os_noop.cpp | 89 +++ modules/core/os_oline.cpp | 83 +++ modules/core/os_quit.cpp | 62 ++ modules/core/os_reload.cpp | 64 ++ modules/core/os_restart.cpp | 62 ++ modules/core/os_session.cpp | 509 ++++++++++++++ modules/core/os_set.cpp | 312 +++++++++ modules/core/os_shutdown.cpp | 61 ++ modules/core/os_snline.cpp | 431 ++++++++++++ modules/core/os_sqline.cpp | 412 ++++++++++++ modules/core/os_staff.cpp | 82 +++ modules/core/os_stats.cpp | 392 +++++++++++ modules/core/os_svsnick.cpp | 99 +++ modules/core/os_szline.cpp | 409 ++++++++++++ modules/core/os_umode.cpp | 86 +++ modules/core/os_update.cpp | 54 ++ modules/core/os_userlist.cpp | 100 +++ modules/core/ss_main.cpp | 63 ++ 145 files changed, 24743 insertions(+) create mode 100644 modules/core/bs_act.cpp create mode 100644 modules/core/bs_assign.cpp create mode 100644 modules/core/bs_badwords.cpp create mode 100644 modules/core/bs_bot.cpp create mode 100644 modules/core/bs_botlist.cpp create mode 100644 modules/core/bs_help.cpp create mode 100644 modules/core/bs_info.cpp create mode 100644 modules/core/bs_kick.cpp create mode 100644 modules/core/bs_say.cpp create mode 100644 modules/core/bs_set.cpp create mode 100644 modules/core/bs_unassign.cpp create mode 100644 modules/core/cs_access.cpp create mode 100644 modules/core/cs_akick.cpp create mode 100644 modules/core/cs_ban.cpp create mode 100644 modules/core/cs_clear.cpp create mode 100644 modules/core/cs_drop.cpp create mode 100644 modules/core/cs_forbid.cpp create mode 100644 modules/core/cs_getkey.cpp create mode 100644 modules/core/cs_help.cpp create mode 100644 modules/core/cs_info.cpp create mode 100644 modules/core/cs_invite.cpp create mode 100644 modules/core/cs_kick.cpp create mode 100644 modules/core/cs_list.cpp create mode 100644 modules/core/cs_modes.cpp create mode 100644 modules/core/cs_register.cpp create mode 100644 modules/core/cs_saset.cpp create mode 100644 modules/core/cs_saset_noexpire.cpp create mode 100644 modules/core/cs_set.cpp create mode 100644 modules/core/cs_set_bantype.cpp create mode 100644 modules/core/cs_set_description.cpp create mode 100644 modules/core/cs_set_entrymsg.cpp create mode 100644 modules/core/cs_set_founder.cpp create mode 100644 modules/core/cs_set_keeptopic.cpp create mode 100644 modules/core/cs_set_mlock.cpp create mode 100644 modules/core/cs_set_opnotice.cpp create mode 100644 modules/core/cs_set_peace.cpp create mode 100644 modules/core/cs_set_persist.cpp create mode 100644 modules/core/cs_set_private.cpp create mode 100644 modules/core/cs_set_restricted.cpp create mode 100644 modules/core/cs_set_secure.cpp create mode 100644 modules/core/cs_set_securefounder.cpp create mode 100644 modules/core/cs_set_secureops.cpp create mode 100644 modules/core/cs_set_signkick.cpp create mode 100644 modules/core/cs_set_successor.cpp create mode 100644 modules/core/cs_set_topiclock.cpp create mode 100644 modules/core/cs_set_xop.cpp create mode 100644 modules/core/cs_status.cpp create mode 100644 modules/core/cs_suspend.cpp create mode 100644 modules/core/cs_topic.cpp create mode 100644 modules/core/cs_unban.cpp create mode 100644 modules/core/cs_xop.cpp create mode 100644 modules/core/db_plain.cpp create mode 100644 modules/core/enc_md5.cpp create mode 100644 modules/core/enc_none.cpp create mode 100644 modules/core/enc_old.cpp create mode 100644 modules/core/enc_sha1.cpp create mode 100644 modules/core/enc_sha256.cpp create mode 100644 modules/core/hs_del.cpp create mode 100644 modules/core/hs_delall.cpp create mode 100644 modules/core/hs_group.cpp create mode 100644 modules/core/hs_help.cpp create mode 100644 modules/core/hs_list.cpp create mode 100644 modules/core/hs_off.cpp create mode 100644 modules/core/hs_on.cpp create mode 100644 modules/core/hs_set.cpp create mode 100644 modules/core/hs_setall.cpp create mode 100644 modules/core/ms_cancel.cpp create mode 100644 modules/core/ms_check.cpp create mode 100644 modules/core/ms_del.cpp create mode 100644 modules/core/ms_help.cpp create mode 100644 modules/core/ms_info.cpp create mode 100644 modules/core/ms_list.cpp create mode 100644 modules/core/ms_read.cpp create mode 100644 modules/core/ms_rsend.cpp create mode 100644 modules/core/ms_send.cpp create mode 100644 modules/core/ms_sendall.cpp create mode 100644 modules/core/ms_set.cpp create mode 100644 modules/core/ms_staff.cpp create mode 100644 modules/core/ns_access.cpp create mode 100644 modules/core/ns_alist.cpp create mode 100644 modules/core/ns_drop.cpp create mode 100644 modules/core/ns_forbid.cpp create mode 100644 modules/core/ns_getemail.cpp create mode 100644 modules/core/ns_getpass.cpp create mode 100644 modules/core/ns_ghost.cpp create mode 100644 modules/core/ns_group.cpp create mode 100644 modules/core/ns_help.cpp create mode 100644 modules/core/ns_identify.cpp create mode 100644 modules/core/ns_info.cpp create mode 100644 modules/core/ns_list.cpp create mode 100644 modules/core/ns_logout.cpp create mode 100644 modules/core/ns_recover.cpp create mode 100644 modules/core/ns_register.cpp create mode 100644 modules/core/ns_release.cpp create mode 100644 modules/core/ns_resetpass.cpp create mode 100644 modules/core/ns_saset.cpp create mode 100644 modules/core/ns_saset_noexpire.cpp create mode 100644 modules/core/ns_sendpass.cpp create mode 100644 modules/core/ns_set.cpp create mode 100644 modules/core/ns_set_autoop.cpp create mode 100644 modules/core/ns_set_email.cpp create mode 100644 modules/core/ns_set_greet.cpp create mode 100644 modules/core/ns_set_hide.cpp create mode 100644 modules/core/ns_set_kill.cpp create mode 100644 modules/core/ns_set_language.cpp create mode 100644 modules/core/ns_set_message.cpp create mode 100644 modules/core/ns_set_private.cpp create mode 100644 modules/core/ns_set_secure.cpp create mode 100644 modules/core/ns_status.cpp create mode 100644 modules/core/ns_suspend.cpp create mode 100644 modules/core/ns_update.cpp create mode 100644 modules/core/os_akill.cpp create mode 100644 modules/core/os_chankill.cpp create mode 100644 modules/core/os_chanlist.cpp create mode 100644 modules/core/os_clearmodes.cpp create mode 100644 modules/core/os_defcon.cpp create mode 100644 modules/core/os_global.cpp create mode 100644 modules/core/os_help.cpp create mode 100644 modules/core/os_ignore.cpp create mode 100644 modules/core/os_jupe.cpp create mode 100644 modules/core/os_kick.cpp create mode 100644 modules/core/os_mode.cpp create mode 100644 modules/core/os_modinfo.cpp create mode 100644 modules/core/os_modlist.cpp create mode 100644 modules/core/os_modload.cpp create mode 100644 modules/core/os_modunload.cpp create mode 100644 modules/core/os_news.cpp create mode 100644 modules/core/os_noop.cpp create mode 100644 modules/core/os_oline.cpp create mode 100644 modules/core/os_quit.cpp create mode 100644 modules/core/os_reload.cpp create mode 100644 modules/core/os_restart.cpp create mode 100644 modules/core/os_session.cpp create mode 100644 modules/core/os_set.cpp create mode 100644 modules/core/os_shutdown.cpp create mode 100644 modules/core/os_snline.cpp create mode 100644 modules/core/os_sqline.cpp create mode 100644 modules/core/os_staff.cpp create mode 100644 modules/core/os_stats.cpp create mode 100644 modules/core/os_svsnick.cpp create mode 100644 modules/core/os_szline.cpp create mode 100644 modules/core/os_umode.cpp create mode 100644 modules/core/os_update.cpp create mode 100644 modules/core/os_userlist.cpp create mode 100644 modules/core/ss_main.cpp (limited to 'modules/core') diff --git a/modules/core/bs_act.cpp b/modules/core/bs_act.cpp new file mode 100644 index 000000000..aa054d11b --- /dev/null +++ b/modules/core/bs_act.cpp @@ -0,0 +1,85 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandBSAct : public Command +{ + public: + CommandBSAct() : Command("ACT", 2, 2) + { + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + ci::string message = params[1]; + + if (!check_access(u, ci, CA_SAY)) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (!ci->bi) + { + notice_help(Config.s_BotServ, u, BOT_NOT_ASSIGNED); + return MOD_CONT; + } + + if (!ci->c || !ci->c->FindUser(ci->bi)) + { + notice_lang(Config.s_BotServ, u, BOT_NOT_ON_CHANNEL, ci->name.c_str()); + return MOD_CONT; + } + + size_t i = 0; + while ((i = message.find_first_of("\001"), i) && i != std::string::npos) + message.erase(i, 1); + + ircdproto->SendAction(ci->bi, ci->name.c_str(), "%s", message.c_str()); + ci->bi->lastmsg = time(NULL); + if (Config.LogBot && Config.LogChannel && LogChan && !debug && findchan(Config.LogChannel)) + ircdproto->SendPrivmsg(ci->bi, Config.LogChannel, "ACT %s %s %s", u->nick.c_str(), ci->name.c_str(), message.c_str()); + return MOD_CONT; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_BotServ, u, "ACT", BOT_ACT_SYNTAX); + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_BotServ, u, BOT_HELP_ACT); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ACT); + } +}; + +class BSAct : public Module +{ + public: + BSAct(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSAct()); + } +}; + +MODULE_INIT(BSAct) diff --git a/modules/core/bs_assign.cpp b/modules/core/bs_assign.cpp new file mode 100644 index 000000000..0695a7e6d --- /dev/null +++ b/modules/core/bs_assign.cpp @@ -0,0 +1,95 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandBSAssign : public Command +{ + public: + CommandBSAssign() : Command("ASSIGN", 2, 2) + { + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + const char *chan = params[0].c_str(); + const char *nick = params[1].c_str(); + BotInfo *bi; + ChannelInfo *ci; + + if (readonly) + { + notice_lang(Config.s_BotServ, u, BOT_ASSIGN_READONLY); + return MOD_CONT; + } + + if (!(bi = findbot(nick))) + { + notice_lang(Config.s_BotServ, u, BOT_DOES_NOT_EXIST, nick); + return MOD_CONT; + } + + ci = cs_findchan(chan); + + if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->Account()->HasPriv("botserv/administration"))) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (bi->HasFlag(BI_PRIVATE) && !u->Account()->HasCommand("botserv/assign/private")) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (ci->bi && ci::string(ci->bi->nick.c_str()) == nick) + { + notice_lang(Config.s_BotServ, u, BOT_ASSIGN_ALREADY, ci->bi->nick.c_str(), chan); + return MOD_CONT; + } + + bi->Assign(u, ci); + notice_lang(Config.s_BotServ, u, BOT_ASSIGN_ASSIGNED, bi->nick.c_str(), ci->name.c_str()); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_BotServ, u, BOT_HELP_ASSIGN); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ASSIGN); + } +}; + +class BSAssign : public Module +{ + public: + BSAssign(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSAssign); + } +}; + +MODULE_INIT(BSAssign) diff --git a/modules/core/bs_badwords.cpp b/modules/core/bs_badwords.cpp new file mode 100644 index 000000000..822847a6a --- /dev/null +++ b/modules/core/bs_badwords.cpp @@ -0,0 +1,282 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class BadwordsListCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + bool SentHeader; + public: + BadwordsListCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, false), u(_u), ci(_ci), SentHeader(false) + { + } + + ~BadwordsListCallback() + { + if (!SentHeader) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetBadWordCount()) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str()); + } + + DoList(u, ci, Number - 1, ci->GetBadWord(Number - 1)); + } + + static void DoList(User *u, ChannelInfo *ci, unsigned Number, BadWord *bw) + { + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, Number + 1, bw->word.c_str(), ((bw->type == BW_SINGLE) ? "(SINGLE)" : ((bw->type == BW_START) ? "(START)" : ((bw->type == BW_END) ? "(END)" : "")))); + } +}; + +class BadwordsDelCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + unsigned Deleted; + public: + BadwordsDelCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, true), u(_u), ci(_ci), Deleted(0) + { + } + + ~BadwordsDelCallback() + { + if (!Deleted) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); + else if (Deleted == 1) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name.c_str()); + else + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, Deleted, ci->name.c_str()); + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetBadWordCount()) + return; + + ++Deleted; + ci->EraseBadWord(Number - 1); + } +}; + +class CommandBSBadwords : public Command +{ + private: + CommandReturn DoList(User *u, ChannelInfo *ci, const ci::string &word) + { + if (!ci->GetBadWordCount()) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, ci->name.c_str()); + else if (!word.empty() && strspn(word.c_str(), "1234567890,-") == word.length()) + { + BadwordsListCallback list(u, ci, word.c_str()); + list.Process(); + } + else + { + bool SentHeader = false; + + for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) + { + BadWord *bw = ci->GetBadWord(i); + + if (!word.empty() && !Anope::Match(bw->word, word.c_str(), false)) + continue; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str()); + } + + BadwordsListCallback::DoList(u, ci, i, bw); + } + + if (!SentHeader) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); + } + + return MOD_CONT; + } + + CommandReturn DoAdd(User *u, ChannelInfo *ci, const ci::string &word) + { + size_t pos = word.find_last_of(" "); + BadWordType type = BW_ANY; + ci::string realword = word; + + if (pos != ci::string::npos) + { + ci::string opt = ci::string(word, pos + 1); + if (!opt.empty()) + { + if (opt == "SINGLE") + type = BW_SINGLE; + else if (opt == "START") + type = BW_START; + else if (opt == "END") + type = BW_END; + } + realword = ci::string(word, 0, pos); + } + + if (ci->GetBadWordCount() >= Config.BSBadWordsMax) + { + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_REACHED_LIMIT, Config.BSBadWordsMax); + return MOD_CONT; + } + + for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) + { + BadWord *bw = ci->GetBadWord(i); + + if (!bw->word.empty() && ((Config.BSCaseSensitive && !stricmp(bw->word.c_str(), realword.c_str())) || (!Config.BSCaseSensitive && bw->word == realword.c_str()))) + { + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_ALREADY_EXISTS, bw->word.c_str(), ci->name.c_str()); + return MOD_CONT; + } + } + + ci->AddBadWord(realword.c_str(), type); + + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_ADDED, realword.c_str(), ci->name.c_str()); + + return MOD_CONT; + } + + CommandReturn DoDelete(User *u, ChannelInfo *ci, const ci::string &word) + { + /* Special case: is it a number/list? Only do search if it isn't. */ + if (!word.empty() && isdigit(word[0]) && strspn(word.c_str(), "1234567890,-") == word.length()) + { + BadwordsDelCallback list(u, ci, word.c_str()); + list.Process(); + } + else + { + unsigned i, end; + BadWord *badword; + + for (i = 0, end = ci->GetBadWordCount(); i < end; ++i) + { + badword = ci->GetBadWord(i); + + if (badword->word == word) + break; + } + + if (i == end) + { + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NOT_FOUND, word.c_str(), ci->name.c_str()); + return MOD_CONT; + } + + ci->EraseBadWord(i); + + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED, badword->word.c_str(), ci->name.c_str()); + } + + return MOD_CONT; + } + + CommandReturn DoClear(User *u, ChannelInfo *ci) + { + ci->ClearBadWords(); + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_CLEAR); + return MOD_CONT; + } + public: + CommandBSBadwords() : Command("BADWORDS", 2, 3) + { + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + const char *chan = params[0].c_str(); + ci::string cmd = params[1]; + ci::string word = params.size() > 2 ? params[2].c_str() : ""; + ChannelInfo *ci; + bool need_args = cmd == "LIST" || cmd == "CLEAR"; + + if (!need_args && word.empty()) + { + this->OnSyntaxError(u, cmd); + return MOD_CONT; + } + + ci = cs_findchan(chan); + + if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->Account()->HasPriv("botserv/administration"))) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (readonly) + { + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DISABLED); + return MOD_CONT; + } + + if (cmd == "ADD") + return this->DoAdd(u, ci, word); + else if (cmd == "DEL") + return this->DoDelete(u, ci, word); + else if (cmd == "LIST") + return this->DoList(u, ci, word); + else if (cmd == "CLEAR") + return this->DoClear(u, ci); + else + this->OnSyntaxError(u, ""); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_BotServ, u, BOT_HELP_BADWORDS); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BADWORDS); + } +}; + +class BSBadwords : public Module +{ + public: + BSBadwords(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSBadwords); + } +}; + +MODULE_INIT(BSBadwords) diff --git a/modules/core/bs_bot.cpp b/modules/core/bs_bot.cpp new file mode 100644 index 000000000..3af9fa685 --- /dev/null +++ b/modules/core/bs_bot.cpp @@ -0,0 +1,411 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandBSBot : public Command +{ + private: + CommandReturn DoAdd(User *u, const std::vector ¶ms) + { + const char *nick = params[1].c_str(); + const char *user = params[2].c_str(); + const char *host = params[3].c_str(); + const char *real = params[4].c_str(); + const char *ch = NULL; + BotInfo *bi; + + if (findbot(nick)) + { + notice_lang(Config.s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick); + return MOD_CONT; + } + + if (strlen(nick) > Config.NickLen) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + if (strlen(user) > Config.UserLen) + { + notice_lang(Config.s_BotServ, u, BOT_LONG_IDENT, Config.UserLen); + return MOD_CONT; + } + + if (strlen(user) > Config.HostLen) + { + notice_lang(Config.s_BotServ, u, BOT_LONG_HOST, Config.HostLen); + return MOD_CONT; + } + + /* Check the nick is valid re RFC 2812 */ + if (isdigit(nick[0]) || nick[0] == '-') + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + for (ch = nick; *ch && ch - nick < Config.NickLen; ++ch) + if (!isvalidnick(*ch)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + /* check for hardcored ircd forbidden nicks */ + if (!ircdproto->IsNickValid(nick)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + /* Check the host is valid re RFC 2812 */ + if (!isValidHost(host, 3)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_HOST); + return MOD_CONT; + } + + for (ch = user; *ch && ch - user < Config.UserLen; ++ch) + if (!isalnum(*ch)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_IDENT, Config.UserLen); + return MOD_CONT; + } + + /* We check whether the nick is registered, and inform the user + * if so. You need to drop the nick manually before you can use + * it as a bot nick from now on -GD + */ + if (findnick(nick)) + { + notice_lang(Config.s_BotServ, u, NICK_ALREADY_REGISTERED, nick); + return MOD_CONT; + } + + if (!(bi = new BotInfo(nick, user, host, real))) + { + notice_lang(Config.s_BotServ, u, BOT_BOT_CREATION_FAILED); + return MOD_CONT; + } + + notice_lang(Config.s_BotServ, u, BOT_BOT_ADDED, bi->nick.c_str(), bi->GetIdent().c_str(), bi->host, bi->realname); + + FOREACH_MOD(I_OnBotCreate, OnBotCreate(bi)); + return MOD_CONT; + } + + CommandReturn DoChange(User *u, const std::vector ¶ms) + { + const char *oldnick = params[1].c_str(); + const char *nick = params.size() > 2 ? params[2].c_str() : NULL; + const char *user = params.size() > 3 ? params[3].c_str() : NULL; + const char *host = params.size() > 4 ? params[4].c_str() : NULL; + const char *real = params.size() > 5 ? params[5].c_str() : NULL; + const char *ch = NULL; + BotInfo *bi; + + if (!oldnick || !nick) + { + this->OnSyntaxError(u, "CHANGE"); + return MOD_CONT; + } + + if (!(bi = findbot(oldnick))) + { + notice_lang(Config.s_BotServ, u, BOT_DOES_NOT_EXIST, oldnick); + return MOD_CONT; + } + + if (stricmp(oldnick, nick) && nickIsServices(oldnick, 0)) + { + notice_lang(Config.s_BotServ, u, BOT_DOES_NOT_EXIST, oldnick); + return MOD_CONT; + } + + if (strlen(nick) > Config.NickLen) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + if (user && strlen(user) > Config.UserLen) + { + notice_lang(Config.s_BotServ, u, BOT_LONG_IDENT, Config.UserLen); + return MOD_CONT; + } + + if (host && strlen(host) > Config.HostLen) + { + notice_lang(Config.s_BotServ, u, BOT_LONG_HOST, Config.HostLen); + return MOD_CONT; + } + + if (stricmp(oldnick, nick) && nickIsServices(nick, 0)) + { + notice_lang(Config.s_BotServ, u, BOT_DOES_NOT_EXIST, oldnick); + return MOD_CONT; + } + + /* Checks whether there *are* changes. + * Case sensitive because we may want to change just the case. + * And we must finally check that the nick is not already + * taken by another bot. + */ + if (bi->nick == nick && (user ? bi->GetIdent() == user : 1) && (host ? !strcmp(bi->host, host) : 1) && (real ? !strcmp(bi->realname, real) : 1)) + { + notice_lang(Config.s_BotServ, u, BOT_BOT_ANY_CHANGES); + return MOD_CONT; + } + + /* Check the nick is valid re RFC 2812 */ + if (isdigit(nick[0]) || nick[0] == '-') + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + for (ch = nick; *ch && ch - nick < Config.NickLen; ++ch) + if (!isvalidnick(*ch)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + /* check for hardcored ircd forbidden nicks */ + if (!ircdproto->IsNickValid(nick)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_NICK); + return MOD_CONT; + } + + if (host && !isValidHost(host, 3)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_HOST); + return MOD_CONT; + } + + if (user) + for (ch = user; *ch && ch - user < Config.UserLen; ++ch) + if (!isalnum(*ch)) + { + notice_lang(Config.s_BotServ, u, BOT_BAD_IDENT, Config.UserLen); + return MOD_CONT; + } + + ci::string ci_bi_nick(bi->nick.c_str()); + if (ci_bi_nick != nick && findbot(nick)) + { + notice_lang(Config.s_BotServ, u, BOT_BOT_ALREADY_EXISTS, nick); + return MOD_CONT; + } + + if (ci_bi_nick != nick) + { + /* We check whether the nick is registered, and inform the user + * if so. You need to drop the nick manually before you can use + * it as a bot nick from now on -GD + */ + if (findnick(nick)) + { + notice_lang(Config.s_BotServ, u, NICK_ALREADY_REGISTERED, nick); + return MOD_CONT; + } + + /* The new nick is really different, so we remove the Q line for + the old nick. */ + if (ircd->sqline) + { + XLine x(bi->nick.c_str()); + ircdproto->SendSQLineDel(&x); + } + + /* We check whether user with this nick is online, and kill it if so */ + EnforceQlinedNick(nick, Config.s_BotServ); + } + + if (user) + ircdproto->SendQuit(bi, "Quit: Be right back"); + else + { + ircdproto->SendChangeBotNick(bi, nick); + XLine x(bi->nick.c_str(), "Reserved for services"); + ircdproto->SendSQLine(&x); + } + + if (bi->nick != nick) + bi->SetNewNick(nick); + + if (user && bi->GetIdent() != user) + bi->SetIdent(user); + if (host && strcmp(bi->host, host)) + bi->host = sstrdup(host); + if (real && strcmp(bi->realname, real)) + bi->realname = sstrdup(real); + + if (user) + { + ircdproto->SendClientIntroduction(bi->nick, bi->GetIdent(), bi->host, bi->realname, ircd->pseudoclient_mode, bi->GetUID()); + XLine x(bi->nick.c_str(), "Reserved for services"); + ircdproto->SendSQLine(&x); + bi->RejoinAll(); + } + + notice_lang(Config.s_BotServ, u, BOT_BOT_CHANGED, oldnick, bi->nick.c_str(), bi->GetIdent().c_str(), bi->host, bi->realname); + + FOREACH_MOD(I_OnBotChange, OnBotChange(bi)); + return MOD_CONT; + } + + CommandReturn DoDel(User *u, const std::vector ¶ms) + { + const char *nick = params[1].c_str(); + BotInfo *bi; + + if (!nick) + { + this->OnSyntaxError(u, "DEL"); + return MOD_CONT; + } + + if (!(bi = findbot(nick))) + { + notice_lang(Config.s_BotServ, u, BOT_DOES_NOT_EXIST, nick); + return MOD_CONT; + } + + if (nickIsServices(nick, 0)) + { + notice_lang(Config.s_BotServ, u, BOT_DOES_NOT_EXIST, nick); + return MOD_CONT; + } + + FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi)); + + ircdproto->SendQuit(bi, "Quit: Help! I'm being deleted by %s!", u->nick.c_str()); + XLine x(bi->nick.c_str()); + ircdproto->SendSQLineDel(&x); + + delete bi; + notice_lang(Config.s_BotServ, u, BOT_BOT_DELETED, nick); + return MOD_CONT; + } + public: + CommandBSBot() : Command("BOT", 1, 6) + { + this->SetFlag(CFLAG_STRIP_CHANNEL); + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + ci::string cmd = params[0]; + + if (readonly) + { + notice_lang(Config.s_BotServ, u, BOT_BOT_READONLY); + return MOD_CONT; + } + + if (cmd == "ADD") + { + // ADD nick user host real - 5 + if (!u->Account()->HasCommand("botserv/bot/add")) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (params.size() < 5) + { + this->OnSyntaxError(u, "ADD"); + return MOD_CONT; + } + + std::vector tempparams = params; + // ADD takes less params than CHANGE, so we need to take 6 if given and append it with a space to 5. + if (tempparams.size() >= 6) + tempparams[4] = tempparams[4] + " " + tempparams[5]; + + return this->DoAdd(u, tempparams); + } + else if (cmd == "CHANGE") + { + // CHANGE oldn newn user host real - 6 + // but only oldn and newn are required + if (!u->Account()->HasCommand("botserv/bot/change")) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (params.size() < 3) + { + this->OnSyntaxError(u, "CHANGE"); + return MOD_CONT; + } + + return this->DoChange(u, params); + } + else if (cmd == "DEL") + { + // DEL nick + if (!u->Account()->HasCommand("botserv/bot/del")) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (params.size() < 1) + { + this->OnSyntaxError(u, "DEL"); + return MOD_CONT; + } + + return this->DoDel(u, params); + } + else + this->OnSyntaxError(u, ""); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_lang(Config.s_BotServ, u, BOT_SERVADMIN_HELP_BOT); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOT); + } +}; + +class BSBot : public Module +{ + public: + BSBot(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSBot()); + } +}; + +MODULE_INIT(BSBot) diff --git a/modules/core/bs_botlist.cpp b/modules/core/bs_botlist.cpp new file mode 100644 index 000000000..44848b5cb --- /dev/null +++ b/modules/core/bs_botlist.cpp @@ -0,0 +1,93 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandBSBotList : public Command +{ + public: + CommandBSBotList() : Command("BOTLIST", 0, 0) + { + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + unsigned count = 0; + + if (BotListByNick.empty()) + { + notice_lang(Config.s_BotServ, u, BOT_BOTLIST_EMPTY); + return MOD_CONT; + } + + for (botinfo_map::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it) + { + BotInfo *bi = it->second; + + if (!bi->HasFlag(BI_PRIVATE)) + { + if (!count) + notice_lang(Config.s_BotServ, u, BOT_BOTLIST_HEADER); + ++count; + u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host); + } + } + + if (u->Account()->HasCommand("botserv/botlist") && count < BotListByNick.size()) + { + notice_lang(Config.s_BotServ, u, BOT_BOTLIST_PRIVATE_HEADER); + + for (botinfo_map::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it) + { + BotInfo *bi = it->second; + + if (bi->HasFlag(BI_PRIVATE)) + { + u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host); + ++count; + } + } + } + + if (!count) + notice_lang(Config.s_BotServ, u, BOT_BOTLIST_EMPTY); + else + notice_lang(Config.s_BotServ, u, BOT_BOTLIST_FOOTER, count); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_BotServ, u, BOT_HELP_BOTLIST); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOTLIST); + } +}; + +class BSBotList : public Module +{ + public: + BSBotList(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSBotList()); + } +}; + +MODULE_INIT(BSBotList) diff --git a/modules/core/bs_help.cpp b/modules/core/bs_help.cpp new file mode 100644 index 000000000..7183c6fe9 --- /dev/null +++ b/modules/core/bs_help.cpp @@ -0,0 +1,53 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandBSHelp : public Command +{ + public: + CommandBSHelp() : Command("HELP", 1, 1) + { + this->SetFlag(CFLAG_ALLOW_UNREGISTERED); + this->SetFlag(CFLAG_STRIP_CHANNEL); + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + mod_help_cmd(findbot(Config.s_BotServ), u, params[0].c_str()); + return MOD_CONT; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + // Abuse syntax error to display general list help. + notice_help(Config.s_BotServ, u, BOT_HELP); + for (CommandMap::const_iterator it = BotServ->Commands.begin(), it_end = BotServ->Commands.end(); it != it_end; ++it) + if (!Config.HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission))) + it->second->OnServHelp(u); + notice_help(Config.s_BotServ, u, BOT_HELP_FOOTER, Config.BSMinUsers); + } +}; + +class BSHelp : public Module +{ + public: + BSHelp(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSHelp()); + } +}; + +MODULE_INIT(BSHelp) diff --git a/modules/core/bs_info.cpp b/modules/core/bs_info.cpp new file mode 100644 index 000000000..7d8e6aea7 --- /dev/null +++ b/modules/core/bs_info.cpp @@ -0,0 +1,233 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandBSInfo : public Command +{ + private: + void send_bot_channels(User * u, BotInfo * bi) + { + char buf[307], *end; + + *buf = 0; + end = buf; + + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it) + { + ChannelInfo *ci = it->second; + + if (ci->bi == bi) + { + if (strlen(buf) + strlen(ci->name.c_str()) > 300) + { + u->SendMessage(Config.s_BotServ, "%s", buf); + *buf = 0; + end = buf; + } + end += snprintf(end, sizeof(buf) - (end - buf), " %s ", ci->name.c_str()); + } + } + + if (*buf) + u->SendMessage(Config.s_BotServ, "%s", buf); + return; + } + public: + CommandBSInfo() : Command("INFO", 1, 1) + { + this->SetFlag(CFLAG_STRIP_CHANNEL); + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + BotInfo *bi; + ChannelInfo *ci; + const char *query = params[0].c_str(); + + int need_comma = 0; + char buf[BUFSIZE], *end; + const char *commastr = getstring(u, COMMA_SPACE); + + if ((bi = findbot(query))) + { + struct tm *tm; + + notice_lang(Config.s_BotServ, u, BOT_INFO_BOT_HEADER, bi->nick.c_str()); + notice_lang(Config.s_BotServ, u, BOT_INFO_BOT_MASK, bi->GetIdent().c_str(), bi->host); + notice_lang(Config.s_BotServ, u, BOT_INFO_BOT_REALNAME, bi->realname); + tm = localtime(&bi->created); + strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); + notice_lang(Config.s_BotServ, u, BOT_INFO_BOT_CREATED, buf); + notice_lang(Config.s_BotServ, u, BOT_INFO_BOT_OPTIONS, getstring(u, (bi->HasFlag(BI_PRIVATE) ? BOT_INFO_OPT_PRIVATE : BOT_INFO_OPT_NONE))); + notice_lang(Config.s_BotServ, u, BOT_INFO_BOT_USAGE, bi->chans.size()); + + if (u->Account()->HasPriv("botserv/administration")) + this->send_bot_channels(u, bi); + } + else if ((ci = cs_findchan(query))) + { + if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration")) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_HEADER, ci->name.c_str()); + if (ci->bi) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_BOT, ci->bi->nick.c_str()); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_BOT_NONE); + + if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) + { + if (ci->ttb[TTB_BADWORDS]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_BADWORDS_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_BADWORDS]); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_BADWORDS, getstring(u, BOT_INFO_ACTIVE)); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_BADWORDS, getstring(u, BOT_INFO_INACTIVE)); + if (ci->botflags.HasFlag(BS_KICK_BOLDS)) + { + if (ci->ttb[TTB_BOLDS]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_BOLDS_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_BOLDS]); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_BOLDS, getstring(u, BOT_INFO_ACTIVE)); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_BOLDS, getstring(u, BOT_INFO_INACTIVE)); + if (ci->botflags.HasFlag(BS_KICK_CAPS)) + { + if (ci->ttb[TTB_CAPS]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_CAPS_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_CAPS_ON, getstring(u, BOT_INFO_ACTIVE), ci->capsmin, ci->capspercent); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_CAPS_OFF, getstring(u, BOT_INFO_INACTIVE)); + if (ci->botflags.HasFlag(BS_KICK_COLORS)) + { + if (ci->ttb[TTB_COLORS]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_COLORS_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_COLORS]); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_COLORS, getstring(u, BOT_INFO_ACTIVE)); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_COLORS, getstring(u, BOT_INFO_INACTIVE)); + if (ci->botflags.HasFlag(BS_KICK_FLOOD)) + { + if (ci->ttb[TTB_FLOOD]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_FLOOD_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_FLOOD_ON, getstring(u, BOT_INFO_ACTIVE), ci->floodlines, ci->floodsecs); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_FLOOD_OFF, getstring(u, BOT_INFO_INACTIVE)); + if (ci->botflags.HasFlag(BS_KICK_REPEAT)) + { + if (ci->ttb[TTB_REPEAT]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_REPEAT_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_REPEAT], ci->repeattimes); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_REPEAT_ON, getstring(u, BOT_INFO_ACTIVE), ci->repeattimes); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_REPEAT_OFF, getstring(u, BOT_INFO_INACTIVE)); + if (ci->botflags.HasFlag(BS_KICK_REVERSES)) + { + if (ci->ttb[TTB_REVERSES]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_REVERSES_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_REVERSES]); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_REVERSES, getstring(u, BOT_INFO_ACTIVE)); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_REVERSES, getstring(u, BOT_INFO_INACTIVE)); + if (ci->botflags.HasFlag(BS_KICK_UNDERLINES)) + { + if (ci->ttb[TTB_UNDERLINES]) + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_UNDERLINES_BAN, getstring(u, BOT_INFO_ACTIVE), ci->ttb[TTB_UNDERLINES]); + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_UNDERLINES, getstring(u, BOT_INFO_ACTIVE)); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_KICK_UNDERLINES, getstring(u, BOT_INFO_INACTIVE)); + + end = buf; + *end = 0; + if (ci->botflags.HasFlag(BS_DONTKICKOPS)) + { + end += snprintf(end, sizeof(buf) - (end - buf), "%s", getstring(u, BOT_INFO_OPT_DONTKICKOPS)); + need_comma = 1; + } + if (ci->botflags.HasFlag(BS_DONTKICKVOICES)) + { + end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? commastr : "", getstring(u, BOT_INFO_OPT_DONTKICKVOICES)); + need_comma = 1; + } + if (ci->botflags.HasFlag(BS_FANTASY)) + { + end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? commastr : "", getstring(u, BOT_INFO_OPT_FANTASY)); + need_comma = 1; + } + if (ci->botflags.HasFlag(BS_GREET)) + { + end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? commastr : "", getstring(u, BOT_INFO_OPT_GREET)); + need_comma = 1; + } + if (ci->botflags.HasFlag(BS_NOBOT)) + { + end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? commastr : "", getstring(u, BOT_INFO_OPT_NOBOT)); + need_comma = 1; + } + if (ci->botflags.HasFlag(BS_SYMBIOSIS)) + { + end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? commastr : "", getstring(u, BOT_INFO_OPT_SYMBIOSIS)); + need_comma = 1; + } + notice_lang(Config.s_BotServ, u, BOT_INFO_CHAN_OPTIONS, *buf ? buf : getstring(u, BOT_INFO_OPT_NONE)); + } + else + notice_lang(Config.s_BotServ, u, BOT_INFO_NOT_FOUND, query); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_BotServ, u, BOT_HELP_INFO); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_BotServ, u, "INFO", BOT_INFO_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_INFO); + } +}; + +class BSInfo : public Module +{ + public: + BSInfo(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSInfo()); + } +}; + +MODULE_INIT(BSInfo) diff --git a/modules/core/bs_kick.cpp b/modules/core/bs_kick.cpp new file mode 100644 index 000000000..2f2784d93 --- /dev/null +++ b/modules/core/bs_kick.cpp @@ -0,0 +1,388 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandBSKick : public Command +{ + public: + CommandBSKick() : Command("KICK", 3, 6) + { + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + const char *chan = params[0].c_str(); + ci::string option = params[1]; + ci::string value = params[2]; + const char *ttb = params.size() > 3 ? params[3].c_str() : NULL; + + ChannelInfo *ci = cs_findchan(chan); + + if (readonly) + notice_lang(Config.s_BotServ, u, BOT_KICK_DISABLED); + else if (!chan || option.empty() || value.empty()) + syntax_error(Config.s_BotServ, u, "KICK", BOT_KICK_SYNTAX); + else if (value != "ON" && value != "OFF") + syntax_error(Config.s_BotServ, u, "KICK", BOT_KICK_SYNTAX); + else if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration")) + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + else if (!ci->bi) + notice_help(Config.s_BotServ, u, BOT_NOT_ASSIGNED); + else + { + if (option == "BADWORDS") + { + if (value == "ON") + { + if (ttb) + { + errno = 0; + ci->ttb[TTB_BADWORDS] = strtol(ttb, NULL, 10); + /* Only error if errno returns ERANGE or EINVAL or we are less then 0 - TSL */ + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_BADWORDS] < 0) + { + /* leaving the debug behind since we might want to know what these are */ + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_BADWORDS]; + /* reset the value back to 0 - TSL */ + ci->ttb[TTB_BADWORDS] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_BADWORDS] = 0; + ci->botflags.SetFlag(BS_KICK_BADWORDS); + if (ci->ttb[TTB_BADWORDS]) + notice_lang(Config.s_BotServ, u, BOT_KICK_BADWORDS_ON_BAN, ci->ttb[TTB_BADWORDS]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_BADWORDS_ON); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_BADWORDS); + notice_lang(Config.s_BotServ, u, BOT_KICK_BADWORDS_OFF); + } + } + else if (option == "BOLDS") + { + if (value == "ON") + { + if (ttb) + { + errno = 0; + ci->ttb[TTB_BOLDS] = strtol(ttb, NULL, 10); + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_BOLDS] < 0) + { + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_BOLDS]; + ci->ttb[TTB_BOLDS] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_BOLDS] = 0; + ci->botflags.SetFlag(BS_KICK_BOLDS); + if (ci->ttb[TTB_BOLDS]) + notice_lang(Config.s_BotServ, u, BOT_KICK_BOLDS_ON_BAN, ci->ttb[TTB_BOLDS]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_BOLDS_ON); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_BOLDS); + notice_lang(Config.s_BotServ, u, BOT_KICK_BOLDS_OFF); + } + } + else if (option == "CAPS") + { + if (value == "ON") + { + const char *min = params.size() > 4 ? params[4].c_str() : NULL; + const char *percent = params.size() > 5 ? params[5].c_str() : NULL; + + if (ttb) + { + errno = 0; + ci->ttb[TTB_CAPS] = strtol(ttb, NULL, 10); + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_CAPS] < 0) + { + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_CAPS]; + ci->ttb[TTB_CAPS] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_CAPS] = 0; + + if (!min) + ci->capsmin = 10; + else + ci->capsmin = atol(min); + if (ci->capsmin < 1) + ci->capsmin = 10; + + if (!percent) + ci->capspercent = 25; + else + ci->capspercent = atol(percent); + if (ci->capspercent < 1 || ci->capspercent > 100) + ci->capspercent = 25; + + ci->botflags.SetFlag(BS_KICK_CAPS); + if (ci->ttb[TTB_CAPS]) + notice_lang(Config.s_BotServ, u, BOT_KICK_CAPS_ON_BAN, ci->capsmin, ci->capspercent, ci->ttb[TTB_CAPS]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_CAPS_ON, ci->capsmin, ci->capspercent); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_CAPS); + notice_lang(Config.s_BotServ, u, BOT_KICK_CAPS_OFF); + } + } + else if (option == "COLORS") + { + if (value == "ON") + { + if (ttb) + { + errno = 0; + ci->ttb[TTB_COLORS] = strtol(ttb, NULL, 10); + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_COLORS] < 0) + { + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_COLORS]; + ci->ttb[TTB_COLORS] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_COLORS] = 0; + ci->botflags.SetFlag(BS_KICK_COLORS); + if (ci->ttb[TTB_COLORS]) + notice_lang(Config.s_BotServ, u, BOT_KICK_COLORS_ON_BAN, ci->ttb[TTB_COLORS]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_COLORS_ON); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_COLORS); + notice_lang(Config.s_BotServ, u, BOT_KICK_COLORS_OFF); + } + } + else if (option == "FLOOD") + { + if (value == "ON") + { + const char *lines = params.size() > 4 ? params[4].c_str() : NULL; + const char *secs = params.size() > 5 ? params[5].c_str() : NULL; + + if (ttb) + { + errno = 0; + ci->ttb[TTB_FLOOD] = strtol(ttb, NULL, 10); + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_FLOOD] < 0) + { + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_FLOOD]; + ci->ttb[TTB_FLOOD] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_FLOOD] = 0; + + if (!lines) + ci->floodlines = 6; + else + ci->floodlines = atol(lines); + if (ci->floodlines < 2) + ci->floodlines = 6; + + if (!secs) + ci->floodsecs = 10; + else + ci->floodsecs = atol(secs); + if (ci->floodsecs < 1 || ci->floodsecs > Config.BSKeepData) + ci->floodsecs = 10; + + ci->botflags.SetFlag(BS_KICK_FLOOD); + if (ci->ttb[TTB_FLOOD]) + notice_lang(Config.s_BotServ, u, BOT_KICK_FLOOD_ON_BAN, ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_FLOOD_ON, ci->floodlines, ci->floodsecs); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_FLOOD); + notice_lang(Config.s_BotServ, u, BOT_KICK_FLOOD_OFF); + } + } + else if (option == "REPEAT") + { + if (value == "ON") + { + const char *times = params.size() > 4 ? params[4].c_str() : NULL; + + if (ttb) + { + errno = 0; + ci->ttb[TTB_REPEAT] = strtol(ttb, NULL, 10); + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_REPEAT] < 0) + { + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_REPEAT]; + ci->ttb[TTB_REPEAT] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_REPEAT] = 0; + + if (!times) + ci->repeattimes = 3; + else + ci->repeattimes = atol(times); + if (ci->repeattimes < 2) + ci->repeattimes = 3; + + ci->botflags.SetFlag(BS_KICK_REPEAT); + if (ci->ttb[TTB_REPEAT]) + notice_lang(Config.s_BotServ, u, BOT_KICK_REPEAT_ON_BAN, ci->repeattimes, ci->ttb[TTB_REPEAT]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_REPEAT_ON, ci->repeattimes); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_REPEAT); + notice_lang(Config.s_BotServ, u, BOT_KICK_REPEAT_OFF); + } + } + else if (option == "REVERSES") + { + if (value == "ON") + { + if (ttb) + { + errno = 0; + ci->ttb[TTB_REVERSES] = strtol(ttb, NULL, 10); + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_REVERSES] < 0) + { + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_REVERSES]; + ci->ttb[TTB_REVERSES] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_REVERSES] = 0; + ci->botflags.SetFlag(BS_KICK_REVERSES); + if (ci->ttb[TTB_REVERSES]) + notice_lang(Config.s_BotServ, u, BOT_KICK_REVERSES_ON_BAN, ci->ttb[TTB_REVERSES]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_REVERSES_ON); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_REVERSES); + notice_lang(Config.s_BotServ, u, BOT_KICK_REVERSES_OFF); + } + } + else if (option == "UNDERLINES") + { + if (value == "ON") + { + if (ttb) + { + errno = 0; + ci->ttb[TTB_UNDERLINES] = strtol(ttb, NULL, 10); + if (errno == ERANGE || errno == EINVAL || ci->ttb[TTB_UNDERLINES] < 0) + { + Alog(LOG_DEBUG) << "errno is " << errno << " ERANGE " << ERANGE << " EINVAL " << EINVAL << " ttb " << ci->ttb[TTB_UNDERLINES]; + ci->ttb[TTB_UNDERLINES] = 0; + notice_lang(Config.s_BotServ, u, BOT_KICK_BAD_TTB, ttb); + return MOD_CONT; + } + } + else + ci->ttb[TTB_UNDERLINES] = 0; + ci->botflags.SetFlag(BS_KICK_UNDERLINES); + if (ci->ttb[TTB_UNDERLINES]) + notice_lang(Config.s_BotServ, u, BOT_KICK_UNDERLINES_ON_BAN, ci->ttb[TTB_UNDERLINES]); + else + notice_lang(Config.s_BotServ, u, BOT_KICK_UNDERLINES_ON); + } + else + { + ci->botflags.UnsetFlag(BS_KICK_UNDERLINES); + notice_lang(Config.s_BotServ, u, BOT_KICK_UNDERLINES_OFF); + } + } + else + notice_help(Config.s_BotServ, u, BOT_KICK_UNKNOWN, option.c_str()); + } + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + if (subcommand.empty()) + notice_help(Config.s_BotServ, u, BOT_HELP_KICK); + else if (subcommand == "BADWORDS") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_BADWORDS); + else if (subcommand == "BOLDS") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_BOLDS); + else if (subcommand == "CAPS") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_CAPS); + else if (subcommand == "COLORS") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_COLORS); + else if (subcommand == "FLOOD") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_FLOOD); + else if (subcommand == "REPEAT") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_REPEAT); + else if (subcommand == "REVERSES") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_REVERSES); + else if (subcommand == "UNDERLINES") + notice_help(Config.s_BotServ, u, BOT_HELP_KICK_UNDERLINES); + else + return false; + + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_BotServ, u, "KICK", BOT_KICK_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_KICK); + } +}; + +class BSKick : public Module +{ + public: + BSKick(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSKick()); + } +}; + +MODULE_INIT(BSKick) diff --git a/modules/core/bs_say.cpp b/modules/core/bs_say.cpp new file mode 100644 index 000000000..88b298544 --- /dev/null +++ b/modules/core/bs_say.cpp @@ -0,0 +1,91 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandBSSay : public Command +{ + public: + CommandBSSay() : Command("SAY", 2, 2) + { + } + + CommandReturn Execute(User *u, const std::vector ¶ms) + { + ChannelInfo *ci; + + const char *chan = params[0].c_str(); + const char *text = params[1].c_str(); + + ci = cs_findchan(chan); + + if (!check_access(u, ci, CA_SAY)) + { + notice_lang(Config.s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (!ci->bi) + { + notice_help(Config.s_BotServ, u, BOT_NOT_ASSIGNED); + return MOD_CONT; + } + + if (!ci->c || !ci->c->FindUser(ci->bi)) + { + notice_lang(Config.s_BotServ, u, BOT_NOT_ON_CHANNEL, ci->name.c_str()); + return MOD_CONT; + } + + if (text[0] == '\001') + { + this->OnSyntaxError(u, ""); + return MOD_CONT; + } + + ircdproto->SendPrivmsg(ci->bi, ci->name.c_str(), "%s", text); + ci->bi->lastmsg = time(NULL); + if (Config.LogBot && Config.LogChannel && LogChan && !debug && findchan(Config.LogChannel)) + ircdproto->SendPrivmsg(ci->bi, Config.LogChannel, "SAY %s %s %s", u->nick.c_str(), ci->name.c_str(), text); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_BotServ, u, BOT_HELP_SAY); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_BotServ, u, "SAY", BOT_SAY_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SAY); + } +}; + +class BSSay : public Module +{ + public: + BSSay(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + this->AddCommand(BotServ, new CommandBSSay()); + } +}; + +MODULE_INIT(BSSay) diff --git a/modules/core/bs_set.cpp b/modules/core/bs_set.cpp new file mode 100644 index 000000000..d6f70352a --- /dev/null +++ b/modules/core/bs_set.cpp @@ -0,0 +1,215 @@ +/* BotServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************