diff options
| author | Adam <Adam@anope.org> | 2011-12-19 15:37:15 -0500 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2011-12-19 15:37:15 -0500 |
| commit | 45fc3ce1c41b06af6e03712988870ead95b72435 (patch) | |
| tree | 7b574d077f77707edb3916fb43dfa30dec8b0f54 | |
| parent | d320c73f23ff7a9b848b86b59c6bf91c1254e410 (diff) | |
Fixed formatting of many lists and INFO outputs
35 files changed, 1309 insertions, 1165 deletions
diff --git a/include/language.h b/include/language.h index 91bc462cb..9af139ed9 100644 --- a/include/language.h +++ b/include/language.h @@ -30,7 +30,6 @@ #define NO_REASON _("No reason") #define UNKNOWN _("<unknown>") #define NO_EXPIRE _("does not expire") -#define END_OF_ANY_LIST _("End of \002%s\002 list.") #define LIST_INCORRECT_RANGE _("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002.") #define UNKNOWN_OPTION _("Unknown option \002%s\002.\n" \ "Type %s%s HELP %s for more information.") @@ -47,7 +46,6 @@ #define NICK_SET_UNKNOWN_OPTION _("Unknown SET option \002%s%s\002.") #define NICK_SET_DISPLAY_CHANGED _("The new display is now \002%s\002.") #define NICK_LIST_SYNTAX _("LIST \037pattern\037") -#define LIST_HEADER _("List of entries matching \002%s\002:") #define NICK_RECOVERED _("User claiming your nick has been killed.\n" \ "\002%s%s RELEASE %s\002 to get it back before %s timeout.") #define NICK_REQUESTED _("This nick has already been requested, please check your e-mail address for the pass code") @@ -62,16 +60,8 @@ #define CHAN_SETTING_UNSET _("%s for %s unset.") #define CHAN_SET_MLOCK_DEPRECATED _("MLOCK is deprecated. Use \002%s%s HELP MODE\002 instead.") #define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.") -#define CHAN_ACCESS_LIST_HEADER _("Access list for %s:\n" \ - " Num Lev Mask") -#define CHAN_ACCESS_VIEW_AXS_FORMAT _(" %3d %4d %s\n" \ - " by %s on %s, last seen %s") -#define CHAN_AKICK_VIEW_FORMAT _("%3d %s (by %s on %s)\n" \ - " %s") #define CHAN_INFO_HEADER _("Information for channel \002%s\002:") #define CHAN_EXCEPTED _("\002%s\002 matches an except on %s and cannot be banned until the except have been removed.") -#define CHAN_LIST_ENTRY _("%3d %s\n" \ - " Added by %s on %s") #define MEMO_NEW_X_MEMO_ARRIVED _("There is a new memo on channel %s.\n" \ "Type \002%s%s READ %s %d\002 to read it.") #define MEMO_NEW_MEMO_ARRIVED _("You have a new memo from %s.\n" \ @@ -88,9 +78,6 @@ #define BOT_ASSIGN_READONLY _("Sorry, bot assignment is temporarily disabled.") #define ENABLED _("Enabled") #define DISABLED _("Disabled") -#define OPER_LIST_FORMAT _(" %3d %-32s %s") -#define OPER_VIEW_FORMAT _("%3d %s (by %s on %s; %s)\n" \ - " %s") #define HOST_SET_ERROR _("A vhost must be in the format of a valid hostmask.") #define HOST_SET_IDENT_ERROR _("A vhost ident must be in the format of a valid ident") #define HOST_SET_TOOLONG _("Error! The vhost is too long, please use a host shorter than %d characters.") diff --git a/include/modules.h b/include/modules.h index d3a43cd8a..ca0656e06 100644 --- a/include/modules.h +++ b/include/modules.h @@ -640,9 +640,10 @@ class CoreExport Module : public Extensible /** Called when a user requests info for a channel * @param source The user requesting info * @param ci The channel the user is requesting info for + * @param info Data to show the user requesting information * @param ShowHidden true if we should show the user everything */ - virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, bool ShowHidden) { } + virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool ShowHidden) { } /** Called on cs_findchan() * @param chname The name being looked up @@ -758,9 +759,10 @@ class CoreExport Module : public Extensible /** Called when a user requests info for a nick * @param source The user requesting info * @param na The nick the user is requesting info from + * @param info Data to show the user requesting information * @param ShowHidden true if we should show the user everything */ - virtual void OnNickInfo(CommandSource &source, NickAlias *na, bool ShowHidden) { } + virtual void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool ShowHidden) { } /** Called in findnick() * Useful to modify the na returned by findnick() diff --git a/include/services.h b/include/services.h index 1da51e296..3bf8d4494 100644 --- a/include/services.h +++ b/include/services.h @@ -915,4 +915,29 @@ class CoreExport NumberList virtual bool InvalidRange(const Anope::string &list); }; +class CoreExport ListFormatter +{ + public: + typedef std::map<Anope::string, Anope::string> ListEntry; + private: + std::vector<Anope::string> columns; + std::vector<ListEntry> entries; + public: + ListFormatter &addColumn(const Anope::string &name); + void addEntry(const ListEntry &entry); + bool isEmpty() const; + void Process(std::vector<Anope::string> &); +}; + +class CoreExport InfoFormatter +{ + User *user; + std::vector<std::pair<Anope::string, Anope::string> > replies; + unsigned longest; + public: + InfoFormatter(User *u); + void Process(std::vector<Anope::string> &); + Anope::string &operator[](const Anope::string &key); +}; + #endif /* SERVICES_H */ 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 \037leve |
