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