summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/commands/bs_badwords.cpp100
-rw-r--r--modules/commands/bs_botlist.cpp41
-rw-r--r--modules/commands/cs_access.cpp397
-rw-r--r--modules/commands/cs_akick.cpp295
-rw-r--r--modules/commands/cs_entrymsg.cpp33
-rw-r--r--modules/commands/cs_flags.cpp69
-rw-r--r--modules/commands/cs_info.cpp41
-rw-r--r--modules/commands/cs_list.cpp25
-rw-r--r--modules/commands/cs_log.cpp22
-rw-r--r--modules/commands/cs_mode.cpp22
-rw-r--r--modules/commands/cs_set_misc.cpp4
-rw-r--r--modules/commands/cs_xop.cpp97
-rw-r--r--modules/commands/hs_list.cpp40
-rw-r--r--modules/commands/hs_request.cpp33
-rw-r--r--modules/commands/ms_ignore.cpp17
-rw-r--r--modules/commands/ms_list.cpp92
-rw-r--r--modules/commands/ns_ajoin.cpp20
-rw-r--r--modules/commands/ns_alist.cpp62
-rw-r--r--modules/commands/ns_cert.cpp30
-rw-r--r--modules/commands/ns_group.cpp17
-rw-r--r--modules/commands/ns_info.cpp78
-rw-r--r--modules/commands/ns_list.cpp33
-rw-r--r--modules/commands/ns_set_misc.cpp4
-rw-r--r--modules/commands/os_akill.cpp198
-rw-r--r--modules/commands/os_config.cpp16
-rw-r--r--modules/commands/os_forbid.cpp21
-rw-r--r--modules/commands/os_ignore.cpp23
-rw-r--r--modules/commands/os_list.cpp56
-rw-r--r--modules/commands/os_news.cpp24
-rw-r--r--modules/commands/os_session.cpp200
-rw-r--r--modules/commands/os_sxline.cpp205
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> &params)
@@ -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> &params)
+ void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, 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> &params)
+ void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
- 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> &params)
+ {
+ 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> &params)
{
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> &params)
@@ -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());
+ }