anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
os_list.cpp (8305B)
1 /* OperServ core functions 2 * 3 * (C) 2003-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 * 8 * Based on the original code of Epona by Lara. 9 * Based on the original code of Services by Andy Church. 10 */ 11 12 #include "module.h" 13 14 class CommandOSChanList : public Command 15 { 16 public: 17 CommandOSChanList(Module *creator) : Command(creator, "operserv/chanlist", 0, 2) 18 { 19 this->SetDesc(_("Lists all channel records")); 20 this->SetSyntax(_("[{\037pattern\037 | \037nick\037} [\037SECRET\037]]")); 21 } 22 23 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override 24 { 25 const Anope::string &pattern = !params.empty() ? params[0] : ""; 26 const Anope::string &opt = params.size() > 1 ? params[1] : ""; 27 std::set<Anope::string> modes; 28 User *u2; 29 unsigned int count = 0; 30 31 if (!pattern.empty()) 32 Log(LOG_ADMIN, source, this) << "for " << pattern; 33 else 34 Log(LOG_ADMIN, source, this); 35 36 if (!opt.empty() && opt.equals_ci("SECRET")) 37 { 38 modes.insert("SECRET"); 39 modes.insert("PRIVATE"); 40 } 41 42 ListFormatter list(source.GetAccount()); 43 list.AddColumn(_("Name")).AddColumn(_("Users")).AddColumn(_("Modes")).AddColumn(_("Topic")); 44 45 if (!pattern.empty() && (u2 = User::Find(pattern, true))) 46 { 47 source.Reply(_("\002%s\002 channel list:"), u2->nick.c_str()); 48 49 for (User::ChanUserList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit) 50 { 51 ChanUserContainer *cc = uit->second; 52 53 if (!modes.empty()) 54 for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) 55 if (!cc->chan->HasMode(*it)) 56 continue; 57 58 ListFormatter::ListEntry entry; 59 entry["Name"] = cc->chan->name; 60 entry["Users"] = stringify(cc->chan->users.size()); 61 entry["Modes"] = cc->chan->GetModes(true, true); 62 entry["Topic"] = cc->chan->topic; 63 list.AddEntry(entry); 64 65 ++count; 66 } 67 } 68 else 69 { 70 source.Reply(_("Channel list:")); 71 72 for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit) 73 { 74 Channel *c = cit->second; 75 76 if (!pattern.empty() && !Anope::Match(c->name, pattern, false, true)) 77 continue; 78 if (!modes.empty()) 79 for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) 80 if (!c->HasMode(*it)) 81 continue; 82 83 ListFormatter::ListEntry entry; 84 entry["Name"] = c->name; 85 entry["Users"] = stringify(c->users.size()); 86 entry["Modes"] = c->GetModes(true, true); 87 entry["Topic"] = c->topic; 88 list.AddEntry(entry); 89 90 ++count; 91 } 92 } 93 94 std::vector<Anope::string> replies; 95 list.Process(replies); 96 97 for (unsigned i = 0; i < replies.size(); ++i) 98 source.Reply(replies[i]); 99 100 source.Reply(_("End of channel list. \002%u\002 channels shown."), count); 101 } 102 103 bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override 104 { 105 this->SendSyntax(source); 106 source.Reply(" "); 107 source.Reply(_("Lists all channels currently in use on the IRC network, whether they\n" 108 "are registered or not.\n" 109 " \n" 110 "If \002pattern\002 is given, lists only channels that match it. If a nickname\n" 111 "is given, lists only the channels the user using it is on. If SECRET is\n" 112 "specified, lists only channels matching \002pattern\002 that have the +s or\n" 113 "+p mode.")); 114 115 const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); 116 if (!regexengine.empty()) 117 { 118 source.Reply(" "); 119 source.Reply(_("Regex matches are also supported using the %s engine.\n" 120 "Enclose your pattern in // if this is desired."), regexengine.c_str()); 121 } 122 123 return true; 124 } 125 }; 126 127 class CommandOSUserList : public Command 128 { 129 public: 130 CommandOSUserList(Module *creator) : Command(creator, "operserv/userlist", 0, 2) 131 { 132 this->SetDesc(_("Lists all user records")); 133 this->SetSyntax(_("[{\037pattern\037 | \037channel\037} [\037INVISIBLE\037]]")); 134 } 135 136 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override 137 { 138 const Anope::string &pattern = !params.empty() ? params[0] : ""; 139 const Anope::string &opt = params.size() > 1 ? params[1] : ""; 140 Channel *c; 141 std::set<Anope::string> modes; 142 unsigned int count = 0; 143 144 if (!pattern.empty()) 145 Log(LOG_ADMIN, source, this) << "for " << pattern; 146 else 147 Log(LOG_ADMIN, source, this); 148 149 if (!opt.empty() && opt.equals_ci("INVISIBLE")) 150 modes.insert("INVIS"); 151 152 ListFormatter list(source.GetAccount()); 153 list.AddColumn(_("Name")).AddColumn(_("Mask")).AddColumn(_("Realname")); 154 155 if (!pattern.empty() && (c = Channel::Find(pattern))) 156 { 157 source.Reply(_("\002%s\002 users list:"), pattern.c_str()); 158 159 for (Channel::ChanUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit) 160 { 161 ChanUserContainer *uc = cuit->second; 162 163 if (!modes.empty()) 164 for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) 165 if (!uc->user->HasMode(*it)) 166 continue; 167 168 ListFormatter::ListEntry entry; 169 entry["Name"] = uc->user->nick; 170 entry["Mask"] = uc->user->GetIdent() + "@" + uc->user->GetDisplayedHost(); 171 entry["Realname"] = uc->user->realname; 172 list.AddEntry(entry); 173 174 ++count; 175 } 176 } 177 else 178 { 179 /* Historically this has been ordered, so... */ 180 Anope::map<User *> ordered_map; 181 for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) 182 ordered_map[it->first] = it->second; 183 184 source.Reply(_("Users list:")); 185 186 for (Anope::map<User *>::const_iterator it = ordered_map.begin(); it != ordered_map.end(); ++it) 187 { 188 User *u2 = it->second; 189 190 if (!pattern.empty()) 191 { 192 /* check displayed host, host, and ip */ 193 Anope::string masks[] = { 194 u2->nick + "!" + u2->GetIdent() + "@" + u2->GetDisplayedHost(), 195 u2->nick + "!" + u2->GetIdent() + "@" + u2->host, 196 u2->nick + "!" + u2->GetIdent() + "@" + u2->ip.addr() 197 }; 198 199 bool match = false; 200 for (unsigned int i = 0; i < sizeof(masks) / sizeof(*masks); ++i) 201 { 202 /* Check mask with realname included, too */ 203 if (Anope::Match(masks[i], pattern, false, true) || Anope::Match(masks[i] + "#" + u2->realname, pattern, false, true)) 204 { 205 match = true; 206 break; 207 } 208 } 209 210 if (!match) 211 continue; 212 213 if (!modes.empty()) 214 for (std::set<Anope::string>::iterator mit = modes.begin(), mit_end = modes.end(); mit != mit_end; ++mit) 215 if (!u2->HasMode(*mit)) 216 continue; 217 } 218 219 ListFormatter::ListEntry entry; 220 entry["Name"] = u2->nick; 221 entry["Mask"] = u2->GetIdent() + "@" + u2->GetDisplayedHost(); 222 entry["Realname"] = u2->realname; 223 list.AddEntry(entry); 224 225 ++count; 226 } 227 } 228 229 std::vector<Anope::string> replies; 230 list.Process(replies); 231 232 for (unsigned i = 0; i < replies.size(); ++i) 233 source.Reply(replies[i]); 234 235 source.Reply(_("End of users list. \002%u\002 users shown."), count); 236 return; 237 } 238 239 bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override 240 { 241 this->SendSyntax(source); 242 source.Reply(" "); 243 source.Reply(_("Lists all users currently online on the IRC network, whether their\n" 244 "nick is registered or not.\n" 245 " \n" 246 "If \002pattern\002 is given, lists only users that match it (it must be in\n" 247 "the format nick!user@host[#realname]). If \002channel\002 is given, lists\n" 248 "only users that are on the given channel. If INVISIBLE is specified, only users\n" 249 "with the +i flag will be listed.")); 250 251 const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); 252 if (!regexengine.empty()) 253 { 254 source.Reply(" "); 255 source.Reply(_("Regex matches are also supported using the %s engine.\n" 256 "Enclose your pattern in // if this is desired."), regexengine.c_str()); 257 } 258 259 return true; 260 } 261 }; 262 263 class OSList : public Module 264 { 265 CommandOSChanList commandoschanlist; 266 CommandOSUserList commandosuserlist; 267 268 public: 269 OSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), 270 commandoschanlist(this), commandosuserlist(this) 271 { 272 273 } 274 }; 275 276 MODULE_INIT(OSList)