From 0fa15e165f9e5d0ad920d329a62af3d2abadee84 Mon Sep 17 00:00:00 2001 From: attilamolnar Date: Thu, 1 Nov 2012 23:34:28 +0100 Subject: cmd_lusers Be smart and know how many invisible users are there without iterating the userlist --- src/commands/cmd_lusers.cpp | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/commands/cmd_lusers.cpp b/src/commands/cmd_lusers.cpp index 6866619c5..ecb289334 100644 --- a/src/commands/cmd_lusers.cpp +++ b/src/commands/cmd_lusers.cpp @@ -24,10 +24,12 @@ struct LusersCounters { unsigned int max_local; unsigned int max_global; + unsigned int invisible; LusersCounters() : max_local(ServerInstance->Users->LocalUserCount() - ServerInstance->Users->UnregisteredUserCount()) , max_global(ServerInstance->Users->RegisteredUserCount()) + , invisible(ServerInstance->Users->ModeCount('i')) { } @@ -71,7 +73,6 @@ class CommandLusers : public Command CmdResult CommandLusers::Handle (const std::vector&, User *user) { unsigned int n_users = ServerInstance->Users->UserCount(); - unsigned int n_invis = ServerInstance->Users->ModeCount('i'); ProtoServerList serverlist; ServerInstance->PI->GetServerList(serverlist); unsigned int n_serv = serverlist.size(); @@ -88,7 +89,7 @@ CmdResult CommandLusers::Handle (const std::vector&, User *user) counters.UpdateMaxUsers(); user->WriteNumeric(251, "%s :There are %d users and %d invisible on %d servers",user->nick.c_str(), - n_users-n_invis, n_invis, n_serv); + n_users - counters.invisible, counters.invisible, n_serv); if (ServerInstance->Users->OperCount()) user->WriteNumeric(252, "%s %d :operator(s) online",user->nick.c_str(),ServerInstance->Users->OperCount()); @@ -104,27 +105,63 @@ CmdResult CommandLusers::Handle (const std::vector&, User *user) return CMD_SUCCESS; } +class InvisibleWatcher : public ModeWatcher +{ + unsigned int& invisible; +public: + InvisibleWatcher(Module* mod, unsigned int& Invisible) + : ModeWatcher(mod, 'i', MODETYPE_USER), invisible(Invisible) + { + } + + void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding, ModeType type) + { + if (dest->registered != REG_ALL) + return; + + if (adding) + invisible++; + else + invisible--; + } +}; + class ModuleLusers : public Module { LusersCounters counters; CommandLusers cmd; + InvisibleWatcher mw; public: ModuleLusers() - : cmd(this, counters) + : cmd(this, counters), mw(this, counters.invisible) { } void init() { ServerInstance->Modules->AddService(cmd); - Implementation events[] = { I_OnPostConnect }; + Implementation events[] = { I_OnPostConnect, I_OnUserQuit }; ServerInstance->Modules->Attach(events, this, sizeof(events)/sizeof(Implementation)); + ServerInstance->Modes->AddModeWatcher(&mw); } void OnPostConnect(User* user) { counters.UpdateMaxUsers(); + if (user->IsModeSet('i')) + counters.invisible++; + } + + void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) + { + if (user->IsModeSet('i')) + counters.invisible--; + } + + ~ModuleLusers() + { + ServerInstance->Modes->DelModeWatcher(&mw); } Version GetVersion() -- cgit v1.2.3