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