]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_auditorium.cpp
Merge pull request #1361 from genius3000/master+rline_IP
[user/henk/code/inspircd.git] / src / modules / m_auditorium.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
6  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
7  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
8  *
9  * This file is part of InspIRCd.  InspIRCd is free software: you can
10  * redistribute it and/or modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation, version 2.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #include "inspircd.h"
24 #include "modules/exemption.h"
25
26 class AuditoriumMode : public SimpleChannelModeHandler
27 {
28  public:
29         AuditoriumMode(Module* Creator) : SimpleChannelModeHandler(Creator, "auditorium", 'u')
30         {
31                 levelrequired = OP_VALUE;
32         }
33 };
34
35 class ModuleAuditorium : public Module
36 {
37         CheckExemption::EventProvider exemptionprov;
38         AuditoriumMode aum;
39         bool OpsVisible;
40         bool OpsCanSee;
41         bool OperCanSee;
42
43  public:
44         ModuleAuditorium()
45                 : exemptionprov(this)
46                 , aum(this)
47         {
48         }
49
50         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
51         {
52                 ConfigTag* tag = ServerInstance->Config->ConfValue("auditorium");
53                 OpsVisible = tag->getBool("opvisible");
54                 OpsCanSee = tag->getBool("opcansee");
55                 OperCanSee = tag->getBool("opercansee", true);
56         }
57
58         Version GetVersion() CXX11_OVERRIDE
59         {
60                 return Version("Allows for auditorium channels (+u) where nobody can see others joining and parting or the nick list", VF_VENDOR);
61         }
62
63         /* Can they be seen by everyone? */
64         bool IsVisible(Membership* memb)
65         {
66                 if (!memb->chan->IsModeSet(&aum))
67                         return true;
68
69                 ModResult res;
70                 FIRST_MOD_RESULT_CUSTOM(exemptionprov, CheckExemption::EventListener, OnCheckExemption, res, (memb->user, memb->chan, "auditorium-vis"));
71                 return res.check(OpsVisible && memb->getRank() >= OP_VALUE);
72         }
73
74         /* Can they see this specific membership? */
75         bool CanSee(User* issuer, Membership* memb)
76         {
77                 // If user is oper and operoverride is on, don't touch the list
78                 if (OperCanSee && issuer->HasPrivPermission("channels/auspex"))
79                         return true;
80
81                 // You can always see yourself
82                 if (issuer == memb->user)
83                         return true;
84
85                 // Can you see the list by permission?
86                 ModResult res;
87                 FIRST_MOD_RESULT_CUSTOM(exemptionprov, CheckExemption::EventListener, OnCheckExemption, res, (issuer, memb->chan, "auditorium-see"));
88                 if (res.check(OpsCanSee && memb->chan->GetPrefixValue(issuer) >= OP_VALUE))
89                         return true;
90
91                 return false;
92         }
93
94         ModResult OnNamesListItem(User* issuer, Membership* memb, std::string& prefixes, std::string& nick) CXX11_OVERRIDE
95         {
96                 if (IsVisible(memb))
97                         return MOD_RES_PASSTHRU;
98
99                 if (CanSee(issuer, memb))
100                         return MOD_RES_PASSTHRU;
101
102                 // Don't display this user in the NAMES list
103                 return MOD_RES_DENY;
104         }
105
106         /** Build CUList for showing this join/part/kick */
107         void BuildExcept(Membership* memb, CUList& excepts)
108         {
109                 if (IsVisible(memb))
110                         return;
111
112                 const Channel::MemberMap& users = memb->chan->GetUsers();
113                 for (Channel::MemberMap::const_iterator i = users.begin(); i != users.end(); ++i)
114                 {
115                         if (IS_LOCAL(i->first) && !CanSee(i->first, memb))
116                                 excepts.insert(i->first);
117                 }
118         }
119
120         void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts) CXX11_OVERRIDE
121         {
122                 BuildExcept(memb, excepts);
123         }
124
125         void OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts) CXX11_OVERRIDE
126         {
127                 BuildExcept(memb, excepts);
128         }
129
130         void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts) CXX11_OVERRIDE
131         {
132                 BuildExcept(memb, excepts);
133         }
134
135         void OnBuildNeighborList(User* source, IncludeChanList& include, std::map<User*, bool>& exception) CXX11_OVERRIDE
136         {
137                 for (IncludeChanList::iterator i = include.begin(); i != include.end(); )
138                 {
139                         Membership* memb = *i;
140                         if (IsVisible(memb))
141                         {
142                                 ++i;
143                                 continue;
144                         }
145
146                         // this channel should not be considered when listing my neighbors
147                         i = include.erase(i);
148                         // however, that might hide me from ops that can see me...
149                         const Channel::MemberMap& users = memb->chan->GetUsers();
150                         for(Channel::MemberMap::const_iterator j = users.begin(); j != users.end(); ++j)
151                         {
152                                 if (IS_LOCAL(j->first) && CanSee(j->first, memb))
153                                         exception[j->first] = true;
154                         }
155                 }
156         }
157
158         ModResult OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, Membership* memb, Numeric::Numeric& numeric) CXX11_OVERRIDE
159         {
160                 if (!memb)
161                         return MOD_RES_PASSTHRU;
162                 if (IsVisible(memb))
163                         return MOD_RES_PASSTHRU;
164                 if (CanSee(source, memb))
165                         return MOD_RES_PASSTHRU;
166                 return MOD_RES_DENY;
167         }
168 };
169
170 MODULE_INIT(ModuleAuditorium)