diff options
Diffstat (limited to 'modules')
31 files changed, 1165 insertions, 1150 deletions
diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp index db3843cf4..e0db84c40 100644 --- a/modules/commands/bs_badwords.cpp +++ b/modules/commands/bs_badwords.cpp @@ -13,42 +13,6 @@ #include "module.h" -class BadwordsListCallback : public NumberList -{ - CommandSource &source; - ChannelInfo *ci; - bool SentHeader; - public: - BadwordsListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, false), source(_source), ci(_ci), SentHeader(false) - { - } - - ~BadwordsListCallback() - { - if (!SentHeader) - source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); - } - - void HandleNumber(unsigned Number) - { - if (!Number || Number > ci->GetBadWordCount()) - return; - - if (!SentHeader) - { - SentHeader = true; - source.Reply(_("Bad words list for %s:\n" - " Num Word Type"), ci->name.c_str()); - } - - DoList(source, Number - 1, ci->GetBadWord(Number - 1)); - } - - static void DoList(CommandSource &source, unsigned Number, BadWord *bw) - { - source.Reply(_(" %3d %-30s %s"), 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 { @@ -92,18 +56,44 @@ class CommandBSBadwords : public Command { bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS"); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST"; + ListFormatter list; + + list.addColumn("Number").addColumn("Word").addColumn("Type"); if (!ci->GetBadWordCount()) + { source.Reply(_("%s bad words list is empty."), ci->name.c_str()); + return; + } else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos) { - BadwordsListCallback list(source, ci, word); - list.Process(); + class BadwordsListCallback : public NumberList + { + ListFormatter &list; + ChannelInfo *ci; + public: + BadwordsListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci) + { + } + + void HandleNumber(unsigned Number) + { + if (!Number || Number > ci->GetBadWordCount()) + return; + + BadWord *bw = ci->GetBadWord(Number - 1); + ListFormatter::ListEntry entry; + entry["Number"] = stringify(Number); + entry["Word"] = bw->word; + entry["Type"] = bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : "")); + this->list.addEntry(entry); + } + } + nl_list(list, ci, word); + nl_list.Process(); } else { - bool SentHeader = false; - for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i) { BadWord *bw = ci->GetBadWord(i); @@ -111,22 +101,28 @@ class CommandBSBadwords : public Command if (!word.empty() && !Anope::Match(bw->word, word)) continue; - if (!SentHeader) - { - SentHeader = true; - source.Reply(_("Bad words list for %s:\n" - " Num Word Type"), ci->name.c_str()); + ListFormatter::ListEntry entry; + entry["Number"] = stringify(i + 1); + entry["Word"] = bw->word; + entry["Type"] = bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : "")); + list.addEntry(entry); + } + } - } + if (list.isEmpty()) + source.Reply(_("No matching entries on %s badword list."), ci->name.c_str()); + else + { + std::vector<Anope::string> replies; + list.Process(replies); - BadwordsListCallback::DoList(source, i, bw); - } + source.Reply(_("Badword list for %s:"), ci->name.c_str()); - if (!SentHeader) - source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); - } + for (unsigned i = 0; i < replies.size(); ++i) + source.Reply(replies[i]); - return; + source.Reply(_("End of badword list.")); + } } void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word) diff --git a/modules/commands/bs_botlist.cpp b/modules/commands/bs_botlist.cpp index 03e0c16b8..73905f0a8 100644 --- a/modules/commands/bs_botlist.cpp +++ b/modules/commands/bs_botlist.cpp @@ -26,50 +26,47 @@ class CommandBSBotList : public Command { User *u = source.u; unsigned count = 0; + ListFormatter list; + + list.addColumn("Nick").addColumn("Mask"); for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it) { BotInfo *bi = it->second; - if (!bi->HasFlag(BI_PRIVATE)) + if (u->HasCommand("botserv/botlist") || !bi->HasFlag(BI_PRIVATE)) { - if (!count) - source.Reply(_("Bot list:")); ++count; - source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str()); + ListFormatter::ListEntry entry; + entry["Nick"] = (bi->HasFlag(BI_PRIVATE) ? "* " : "") + bi->nick; + entry["Mask"] = bi->GetIdent() + "@" + bi->host; + list.addEntry(entry); } } - if (u->HasCommand("botserv/botlist") && count < BotListByNick.size()) - { - source.Reply(_("Bots reserved to IRC operators:")); - - for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it) - { - BotInfo *bi = it->second; - - if (bi->HasFlag(BI_PRIVATE)) - { - source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str()); - ++count; - } - } - } + std::vector<Anope::string> replies; + list.Process(replies); if (!count) source.Reply(_("There are no bots available at this time.\n" "Ask a Services Operator to create one!")); else - source.Reply(_("%d bots available."), count); + { + source.Reply(_("Bot list:")); - return; + for (unsigned i = 0; i < replies.size(); ++i) + source.Reply(replies[i]); + + source.Reply(_("%d bots available."), count); + } } bool OnHelp(CommandSource &source, const Anope::string &subcommand) { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Lists all available bots on this network.")); + source.Reply(_("Lists all available bots on this network. Bots prefixed" + "by a * are reserved for IRC operators.")); return true; } }; diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 68a367701..d1d3deb93 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -95,148 +95,6 @@ class AccessAccessProvider : public AccessProvider } }; -class AccessListCallback : public NumberList -{ - protected: - CommandSource &source; - ChannelInfo *ci; - bool SentHeader; - public: - AccessListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false) - { - } - - ~AccessListCallback() - { - if (SentHeader) - source.Reply(_("End of access list.")); - else - source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); - } - - virtual void HandleNumber(unsigned Number) - { - if (!Number || Number > ci->GetAccessCount()) - return; - - if (!SentHeader) - { - SentHeader = true; - source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); - } - - DoList(source, ci, Number - 1, ci->GetAccess(Number - 1)); - } - - static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access) - { - source.Reply(_(" %3d %4d %s"), Number + 1, AccessChanAccess::DetermineLevel(access), access->mask.c_str()); - } -}; - -class AccessViewCallback : public AccessListCallback -{ - public: - AccessViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AccessListCallback(_source, _ci, numlist) - { - } - - void HandleNumber(unsigned Number) - { - if (!Number || Number > ci->GetAccessCount()) - return; - - if (!SentHeader) - { - SentHeader = true; - source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); - } - - DoList(source, ci, Number - 1, ci->GetAccess(Number - 1)); - } - - static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access) - { - Anope::string timebuf; - if (ci->c) - for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) - if (access->Matches((*cit)->user, (*cit)->user->Account())) - timebuf = "Now"; - if (timebuf.empty()) - { - if (access->last_seen == 0) - timebuf = "Never"; - else - timebuf = do_strftime(access->last_seen, NULL, true); - } - - source.Reply(CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, AccessChanAccess::DetermineLevel(access), access->mask.c_str(), access->creator.c_str(), do_strftime(access->created, NULL, true).c_str(), timebuf.c_str()); - } -}; - -class AccessDelCallback : public NumberList -{ - CommandSource &source; - ChannelInfo *ci; - Command *c; - unsigned Deleted; - Anope::string Nicks; - bool Denied; - bool override; - public: - AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), Denied(false) - { - if (!ci->AccessFor(source.u).HasPriv("ACCESS_CHANGE") && source.u->HasPriv("chanserv/access/modify")) - this->override = true; - } - - ~AccessDelCallback() - { - if (Denied && !Deleted) - source.Reply(ACCESS_DENIED); - else if (!Deleted) - source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); - else - { - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks; - - if (Deleted == 1) - source.Reply(_("Deleted 1 entry from %s access list."), ci->name.c_str()); - else - source.Reply(_("Deleted %d entries from %s access list."), Deleted, ci->name.c_str()); - } - } - - void HandleNumber(unsigned Number) - { - if (!Number || Number > ci->GetAccessCount()) - return; - - User *u = source.u; - - ChanAccess *access = ci->GetAccess(Number - 1); - - AccessGroup u_access = ci->AccessFor(u); - ChanAccess *u_highest = u_access.Highest(); - - if (u_highest ? AccessChanAccess::DetermineLevel(u_highest) : 0 <= AccessChanAccess::DetermineLevel(access) && !u->HasPriv("chanserv/access/modify")) - { - Denied = true; - return; - } - - ++Deleted; - if (!Nicks.empty()) - Nicks += ", " + access->mask; - else - Nicks = access->mask; - - FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access)); - - ci->EraseAccess(Number - 1); - } -}; - class CommandCSAccess : public Command { void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) @@ -329,8 +187,70 @@ class CommandCSAccess : public Command source.Reply(_("%s access list is empty."), ci->name.c_str()); else if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos) { - AccessDelCallback list(source, ci, this, mask); - list.Process(); + class AccessDelCallback : public NumberList + { + CommandSource &source; + ChannelInfo *ci; + Command *c; + unsigned Deleted; + Anope::string Nicks; + bool Denied; + bool override; + public: + AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), Denied(false), override(false) + { + if (!ci->AccessFor(source.u).HasPriv("ACCESS_CHANGE") && source.u->HasPriv("chanserv/access/modify")) + this->override = true; + } + + ~AccessDelCallback() + { + if (Denied && !Deleted) + source.Reply(ACCESS_DENIED); + else if (!Deleted) + source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); + else + { + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks; + + if (Deleted == 1) + source.Reply(_("Deleted 1 entry from %s access list."), ci->name.c_str()); + else + source.Reply(_("Deleted %d entries from %s access list."), Deleted, ci->name.c_str()); + } + } + + void HandleNumber(unsigned Number) + { + if (!Number || Number > ci->GetAccessCount()) + return; + + User *user = source.u; + + ChanAccess *access = ci->GetAccess(Number - 1); + + AccessGroup u_access = ci->AccessFor(user); + ChanAccess *u_highest = u_access.Highest(); + + if (u_highest ? AccessChanAccess::DetermineLevel(u_highest) : 0 <= AccessChanAccess::DetermineLevel(access) && !u_access.Founder && !user->HasPriv("chanserv/access/modify")) + { + Denied = true; + return; + } + + ++Deleted; + if (!Nicks.empty()) + Nicks += ", " + access->mask; + else + Nicks = access->mask; + + FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, user, access)); + + ci->EraseAccess(Number - 1); + } + } + delcallback(source, ci, this, mask); + delcallback.Process(); } else { @@ -365,7 +285,7 @@ class CommandCSAccess : public Command return; } - void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms, ListFormatter &list) { const Anope::string &nick = params.size() > 2 ? params[2] : ""; @@ -373,13 +293,50 @@ class CommandCSAccess : public Command source.Reply(_("%s access list is empty."), ci->name.c_str()); else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos) { - AccessListCallback list(source, ci, nick); - list.Process(); + class AccessListCallback : public NumberList + { + ListFormatter &list; + ChannelInfo *ci; + + public: + AccessListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci) + { + } + + void HandleNumber(unsigned number) + { + if (!number || number > ci->GetAccessCount()) + return; + + ChanAccess *access = ci->GetAccess(number - 1); + + Anope::string timebuf; + if (ci->c) + for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) + if (access->Matches((*cit)->user, (*cit)->user->Account())) + timebuf = "Now"; + if (timebuf.empty()) + { + if (access->last_seen == 0) + timebuf = "Never"; + else + timebuf = do_strftime(access->last_seen, NULL, true); + } + + ListFormatter::ListEntry entry; + entry["Number"] = stringify(number); + entry["Level"] = stringify(AccessChanAccess::DetermineLevel(access)); + entry["Mask"] = access->mask; + entry["By"] = access->creator; + entry["Last seen"] = timebuf; + this->list.addEntry(entry); + } + } + nl_list(list, ci, nick); + nl_list.Process(); } else { - bool SentHeader = false; - for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i) { ChanAccess *access = ci->GetAccess(i); @@ -387,62 +344,71 @@ class CommandCSAccess : public Command if (!nick.empty() && !Anope::Match(access->mask, nick)) continue; - if (!SentHeader) + Anope::string timebuf; + if (ci->c) + for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) + if (access->Matches((*cit)->user, (*cit)->user->Account())) + timebuf = "Now"; + if (timebuf.empty()) { - SentHeader = true; - source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); + if (access->last_seen == 0) + timebuf = "Never"; + else + timebuf = do_strftime(access->last_seen, NULL, true); } - AccessListCallback::DoList(source, ci, i, access); + ListFormatter::ListEntry entry; + entry["Number"] = stringify(i + 1); + entry["Level"] = stringify(AccessChanAccess::DetermineLevel(access)); + entry["Mask"] = access->mask; + entry["By"] = access->creator; + entry["Last seen"] = timebuf; + list.addEntry(entry); } + } - if (SentHeader) - source.Reply(_("End of access list.")); - else - source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); + if (list.isEmpty()) + source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); + else + { + std::vector<Anope::string> replies; + list.Process(replies); + + source.Reply(_("Access list for %s:"), ci->name.c_str()); + + for (unsigned i = 0; i < replies.size(); ++i) + source.Reply(replies[i]); + + source.Reply(_("End of access list")); } return; } - void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) { - const Anope::string &nick = params.size() > 2 ? params[2] : ""; - if (!ci->GetAccessCount()) - source.Reply(_("%s access list is empty."), ci->name.c_str()); - else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos) { - AccessViewCallback list(source, ci, nick); - list.Process(); + source.Reply(_("%s access list is empty."), ci->name.c_str()); + return; } - else - { - bool SentHeader = false; - - for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i) - { - ChanAccess *access = ci->GetAccess(i); - - if (!nick.empty() && !Anope::Match(access->mask, nick)) - continue; - - if (!SentHeader) - { - SentHeader = true; - source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); - } - AccessViewCallback::DoList(source, ci, i, access); - } + ListFormatter list; + list.addColumn("Number").addColumn("Level").addColumn("Mask"); + this->ProcessList(source, ci, params, list); + } - if (SentHeader) - source.Reply(_("End of access list.")); - else - source.Reply(_("No matching entries on %s access list."), ci->name.c_str()); + void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + if (!ci->GetAccessCount()) + { + source.Reply(_("%s access list is empty."), ci->name.c_str()); + return; } - return; + ListFormatter list; + list.addColumn("Number").addColumn("Level").addColumn("Mask").addColumn("By").addColumn("Last seen"); + this->ProcessList(source, ci, params, list); } void DoClear(CommandSource &source, ChannelInfo *ci) @@ -600,8 +566,6 @@ class CommandCSAccess : public Command class CommandCSLevels : public Command { - int levelinfo_maxwidth; - void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) { User *u = source.u; @@ -681,29 +645,34 @@ class CommandCSLevels : public Command { source.Reply(_("Access level settings for channel %s:"), ci->name.c_str()); - const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); - if (!levelinfo_maxwidth) - for (unsigned i = 0; i < privs.size(); ++i) - { - const Privilege &p = privs[i]; + ListFormatter list; + list.addColumn("Name").addColumn("Level"); - int len = p.name.length(); - if (len > levelinfo_maxwidth) - levelinfo_maxwidth = len; - } + const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); for (unsigned i = 0; i < privs.size(); ++i) { const Privilege &p = privs[i]; int16_t j = ci->GetLevel(p.name); + ListFormatter::ListEntry entry; + entry["Name"] = p.name; + if (j == ACCESS_INVALID) - source.Reply(_(" %-*s (disabled)"), levelinfo_maxwidth, p.name.c_str()); + entry["Level"] = "(disabled)"; else if (j == ACCESS_FOUNDER) - source.Reply(_(" %-*s (founder only)"), levelinfo_maxwidth, p.name.c_str()); + entry["Level"] = "(founder only)"; else - source.Reply(_(" %-*s %d"), levelinfo_maxwidth, p.name.c_str(), j); + entry["Level"] = stringify(j); + + list.addEntry(entry); } + + std::vector<Anope::string> replies; + list.Process(replies); + + for (unsigned i = 0; i < replies.size(); ++i) + source.Reply(replies[i]); } void DoReset(CommandSource &source, ChannelInfo *ci) @@ -721,7 +690,7 @@ class CommandCSLevels : public Command } public: - CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4), levelinfo_maxwidth(0) + CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4) { this->SetDesc(_("Redefine the meanings of access levels")); this->SetSyntax(_("\037channel\037 SET \037type\037 \037level\037")); @@ -771,21 +740,25 @@ class CommandCSLevels : public Command if (subcommand.equals_ci("DESC")) { source.Reply(_("The following feature/function names are understood.")); - const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); - if (!levelinfo_maxwidth) - for (unsigned i = 0; i < privs.size(); ++i) - { - const Privilege &p = privs[i]; - int len = p.name.length(); - if (len > levelinfo_maxwidth) - levelinfo_maxwidth = len; - } + ListFormatter list; + list.addColumn("Name").addColumn("Description"); + + const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); for (unsigned i = 0; i < privs.size(); ++i) { const Privilege &p = privs[i]; - source.Reply(_(" %-*s %s"), levelinfo_maxwidth, p.name.c_str(), translate(source.u, p.desc.c_str())); + ListFormatter::ListEntry entry; + entry["Name"] = p.name; + entry["Description"] = translate(source.u, p.desc.c_str()); + list.addEntry(entry); } + + std::vector<Anope::string> replies; + list.Process(replies); + + for (unsigned i = 0; i < replies.size(); ++i) + source.Reply(replies[i]); } else { diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp index f4325ea3a..b87e97354 100644 --- a/modules/commands/cs_akick.cpp +++ b/modules/commands/cs_akick.cpp @@ -46,115 +46,6 @@ static void split_usermask(const Anope::string &mask, Anope::string &nick, Anope } } -class AkickListCallback : public NumberList -{ - protected: - CommandSource &source; - ChannelInfo *ci; - bool SentHeader; - public: - AkickListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false) - { - } - - ~AkickListCallback() - { - if (!SentHeader) - source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str()); - } - - virtual void HandleNumber(unsigned Number) - { - if (!Number || Number > ci->GetAkickCount()) - return; - - if (!SentHeader) - { - SentHeader = true; - source.Reply(_("Autokick list for %s:"), ci->name.c_str()); - } - - DoList(source, ci, Number - 1, ci->GetAkick(Number - 1)); - } - - static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick) - { - source.Reply(_(" %3d %s (%s)"), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : NO_REASON); - } -}; - -class AkickViewCallback : public AkickListCallback -{ - public: - AkickViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AkickListCallback(_source, _ci, numlist) - { - } - - void HandleNumber(unsigned Number) - { - if (!Number || Number > ci->GetAkickCount()) - return; - - if (!SentHeader) - { - SentHeader = true; - source.Reply(_("Autokick list for %s:"), ci->name.c_str()); - } - - DoList(source, ci, Number - 1, ci->GetAkick(Number - 1)); - } - - static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick) - { - Anope::string timebuf; - - if (akick->addtime) - timebuf = do_strftime(akick->addtime); - else - timebuf = UNKNOWN; - - source.Reply(CHAN_AKICK_VIEW_FORMAT, index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : UNKNOWN, timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON)); - - if (akick->last_used) - source.Reply(_(" Last used %s"), do_strftime(akick->last_used).c_str()); - } -}; - -class AkickDelCallback : public NumberList -{ - CommandSource &source; - ChannelInfo *ci; - Command *c; - unsigned Deleted; - public: - AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0) - { - } - - ~AkickDelCallback() - { - User *u = source.u; - bool override = !ci->AccessFor(u).HasPriv("AKICK"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL on " << Deleted << " users"; - - if (!Deleted) - source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str()); - else if (Deleted == 1) - source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str()); - else - source.Reply(_("Deleted %d entries from %s autokick list."), Deleted, ci->name.c_str()); - } - - void HandleNumber(unsigned Number) - { - if (!Number || Number > ci->GetAkickCount()) - return; - - ++Deleted; - ci->EraseAkick(Number - 1); - } -}; - class CommandCSAKick : public Command { void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) @@ -287,8 +178,41 @@ class CommandCSAKick : public Command /* Special case: is it a number/list? Only do search if it isn't. */ if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos) { - AkickDelCallback list(source, ci, this, mask); - list.Process(); + class AkickDelCallback : public NumberList + { + CommandSource &source; + ChannelInfo *ci; + Command *c; + unsigned Deleted; + public: + AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0) + { + } + + ~AkickDelCallback() + { + bool override = !ci->AccessFor(source.u).HasPriv("AKICK"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "DEL on " << Deleted << " users"; + + if (!Deleted) + source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str()); + else if (Deleted == 1) + source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str()); + else + source.Reply(_("Deleted %d entries from %s autokick list."), Deleted, ci->name.c_str()); + } |
