]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/coremods/core_lusers.cpp
a995e59e7fa6cffabf3c84e2a4f9aa83764a6e6f
[user/henk/code/inspircd.git] / src / coremods / core_lusers.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #include "inspircd.h"
22
23 struct LusersCounters
24 {
25         unsigned int max_local;
26         unsigned int max_global;
27         unsigned int invisible;
28
29         LusersCounters(unsigned int inv)
30                 : max_local(ServerInstance->Users->LocalUserCount())
31                 , max_global(ServerInstance->Users->RegisteredUserCount())
32                 , invisible(inv)
33         {
34         }
35
36         inline void UpdateMaxUsers()
37         {
38                 unsigned int current = ServerInstance->Users->LocalUserCount();
39                 if (current > max_local)
40                         max_local = current;
41
42                 current = ServerInstance->Users->RegisteredUserCount();
43                 if (current > max_global)
44                         max_global = current;
45         }
46 };
47
48 /** Handle /LUSERS.
49  */
50 class CommandLusers : public Command
51 {
52         LusersCounters& counters;
53  public:
54         /** Constructor for lusers.
55          */
56         CommandLusers(Module* parent, LusersCounters& Counters)
57                 : Command(parent,"LUSERS",0,0), counters(Counters)
58         { }
59         /** Handle command.
60          * @param parameters The parameters to the command
61          * @param user The user issuing the command
62          * @return A value from CmdResult to indicate command success or failure.
63          */
64         CmdResult Handle(const std::vector<std::string>& parameters, User* user) CXX11_OVERRIDE;
65 };
66
67 /** Handle /LUSERS
68  */
69 CmdResult CommandLusers::Handle (const std::vector<std::string>&, User *user)
70 {
71         unsigned int n_users = ServerInstance->Users->RegisteredUserCount();
72         ProtocolInterface::ServerList serverlist;
73         ServerInstance->PI->GetServerList(serverlist);
74         unsigned int n_serv = serverlist.size();
75         unsigned int n_local_servs = 0;
76         for (ProtocolInterface::ServerList::const_iterator i = serverlist.begin(); i != serverlist.end(); ++i)
77         {
78                 if (i->parentname == ServerInstance->Config->ServerName)
79                         n_local_servs++;
80         }
81         // fix for default GetServerList not returning us
82         if (!n_serv)
83                 n_serv = 1;
84
85         counters.UpdateMaxUsers();
86
87         user->WriteNumeric(RPL_LUSERCLIENT, InspIRCd::Format("There are %d users and %d invisible on %d servers",
88                         n_users - counters.invisible, counters.invisible, n_serv));
89
90         if (ServerInstance->Users->OperCount())
91                 user->WriteNumeric(RPL_LUSEROP, ServerInstance->Users.OperCount(), "operator(s) online");
92
93         if (ServerInstance->Users->UnregisteredUserCount())
94                 user->WriteNumeric(RPL_LUSERUNKNOWN, ServerInstance->Users.UnregisteredUserCount(), "unknown connections");
95
96         user->WriteNumeric(RPL_LUSERCHANNELS, ServerInstance->GetChans().size(), "channels formed");
97         user->WriteNumeric(RPL_LUSERME, InspIRCd::Format("I have %d clients and %d servers", ServerInstance->Users.LocalUserCount(), n_local_servs));
98         user->WriteNumeric(RPL_LOCALUSERS, InspIRCd::Format("Current local users: %d  Max: %d", ServerInstance->Users.LocalUserCount(), counters.max_local));
99         user->WriteNumeric(RPL_GLOBALUSERS, InspIRCd::Format("Current global users: %d  Max: %d", n_users, counters.max_global));
100
101         return CMD_SUCCESS;
102 }
103
104 class InvisibleWatcher : public ModeWatcher
105 {
106         unsigned int& invisible;
107 public:
108         InvisibleWatcher(Module* mod, unsigned int& Invisible)
109                 : ModeWatcher(mod, "invisible", MODETYPE_USER), invisible(Invisible)
110         {
111         }
112
113         void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding) CXX11_OVERRIDE
114         {
115                 if (dest->registered != REG_ALL)
116                         return;
117
118                 if (adding)
119                         invisible++;
120                 else
121                         invisible--;
122         }
123 };
124
125 class ModuleLusers : public Module
126 {
127         UserModeReference invisiblemode;
128         LusersCounters counters;
129         CommandLusers cmd;
130         InvisibleWatcher mw;
131
132         unsigned int CountInvisible()
133         {
134                 unsigned int c = 0;
135                 const user_hash& users = ServerInstance->Users->GetUsers();
136                 for (user_hash::const_iterator i = users.begin(); i != users.end(); ++i)
137                 {
138                         User* u = i->second;
139                         if (u->IsModeSet(invisiblemode))
140                                 c++;
141                 }
142                 return c;
143         }
144
145  public:
146         ModuleLusers()
147                 : invisiblemode(this, "invisible")
148                 , counters(CountInvisible())
149                 , cmd(this, counters)
150                 , mw(this, counters.invisible)
151         {
152         }
153
154         void OnPostConnect(User* user) CXX11_OVERRIDE
155         {
156                 counters.UpdateMaxUsers();
157                 if (user->IsModeSet(invisiblemode))
158                         counters.invisible++;
159         }
160
161         void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) CXX11_OVERRIDE
162         {
163                 if (user->IsModeSet(invisiblemode))
164                         counters.invisible--;
165         }
166
167         Version GetVersion() CXX11_OVERRIDE
168         {
169                 return Version("LUSERS", VF_VENDOR | VF_CORE);
170         }
171 };
172
173 MODULE_INIT(ModuleLusers)