/* BotServ core functions * * (C) 2003-2025 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 final : public Command { public: CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 1) { this->SetDesc(_("Lists available bots")); this->SetSyntax("[OPERONLY] [UNUSED] [VANITY]"); } void Execute(CommandSource &source, const std::vector ¶ms) override { const bool is_admin = source.HasCommand("botserv/administration"); auto operonly = false; auto unused = false; auto vanity = false; if (is_admin && !params.empty()) { spacesepstream keywords(params[0]); for (Anope::string keyword; keywords.GetToken(keyword); ) { if (keyword.equals_ci("OPERONLY")) operonly = true; if (keyword.equals_ci("UNUSED")) unused = true; if (keyword.equals_ci("VANITY")) vanity = true; } } unsigned count = 0; ListFormatter list(source.GetAccount()); list.AddColumn(_("Nick")).AddColumn(_("Mask")).AddColumn(_("Real name")); for (const auto &[_, bi] : *BotListByNick) { if (is_admin || !bi->oper_only) { if (operonly && !bi->oper_only) continue; if (unused && bi->GetChannelCount()) continue; if (vanity && bi->conf) continue; ++count; ListFormatter::ListEntry entry; entry["Nick"] = bi->nick; entry["Mask"] = bi->GetIdent() + "@" + bi->host; entry["Real name"] = bi->realname; list.AddEntry(entry); } } std::vector 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(_("Bot list:")); for (const auto &reply : replies) source.Reply(reply); source.Reply(_("%d bots available."), count); } } bool OnHelp(CommandSource &source, const Anope::string &subcommand) override { this->SendSyntax(source); source.Reply(" "); source.Reply(_("Lists all available bots on this network.\n" "\n" "If the OPERONLY, UNUSED or VANITY options are given only\n" "bots which, respectively, are oper-only, unused or were\n" "added at runtime will be displayed. If multiple options are\n" "given, all nicks matching at least one option will be\n" "displayed.\n" "\n" "Note that these options are limited to \037Services Operators\037.")); return true; } }; class BSBotList final : public Module { CommandBSBotList commandbsbotlist; public: BSBotList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandbsbotlist(this) { } }; MODULE_INIT(BSBotList)