1 /* Mode support
2  *
3  * (C) 2008-2011 Adam <Adam@anope.org>
4  * (C) 2008-2020 Anope Team <team@anope.org>
5  *
6  * Please read COPYING and README for further details.
7  */
8 
9 #ifndef MODES_H
10 #define MODES_H
11 
12 #include "anope.h"
13 #include "base.h"
14 
15 /** The different types of modes
16 */
17 enum ModeType
18 {
19 	/* Regular mode */
20 	MODE_REGULAR,
21 	/* b/e/I */
22 	MODE_LIST,
23 	/* k/l etc */
24 	MODE_PARAM,
25 	/* v/h/o/a/q */
26 	MODE_STATUS
27 };
28 
29 /* Classes of modes, Channel modes and User modes
30  */
31 enum ModeClass
32 {
33 	MC_CHANNEL,
34 	MC_USER
35 };
36 
37 /** This class is the basis of all modes in Anope
38  */
39 class CoreExport Mode : public Base
40 {
41  public:
42 	/* Mode name */
43 	Anope::string name;
44 	/* Class of mode this is (user/channel) */
45 	ModeClass mclass;
46 	/* Mode char for this, eg 'b' */
47 	char mchar;
48 	/* Type of mode this is, eg MODE_LIST */
49 	ModeType type;
50 
51 	/** constructor
52 	 * @param mname The mode name
53 	 * @param mclass The type of mode this is
54 	 * @param mc The mode char
55 	 * @param type The mode type
56 	 */
57 	Mode(const Anope::string &mname, ModeClass mclass, char mc, ModeType type);
58 	virtual ~Mode();
59 
60 	/** Can a user set this mode, used for mlock
61 	 * @param u The user
62 	 */
63 	virtual bool CanSet(User *u) const;
64 };
65 
66 /** This class is a user mode, all user modes use this/inherit from this
67  */
68 class CoreExport UserMode : public Mode
69 {
70  public:
71 	/** constructor
72 	 * @param name The mode name
73 	 * @param mc The mode char
74 	 */
75 	UserMode(const Anope::string &name, char mc);
76 };
77 
78 class CoreExport UserModeParam : public UserMode
79 {
80  public:
81 	/** constructor
82 	 * @param name The mode name
83 	 * @param mc The mode char
84 	 */
85 	UserModeParam(const Anope::string &name, char mc);
86 
87 	/** Check if the param is valid
88 	 * @param value The param
89 	 * @return true or false
90 	 */
IsValid(Anope::string & value)91 	virtual bool IsValid(Anope::string &value) const { return true; }
92 };
93 
94 /** This class is a channel mode, all channel modes use this/inherit from this
95  */
96 class CoreExport ChannelMode : public Mode
97 {
98  public:
99 	/* channel modes that can posssibly unwrap this mode */
100 	std::vector<ChannelMode *> listeners;
101 
102 	/** constructor
103 	 * @param name The mode name
104 	 * @param mc The mode char
105 	 */
106 	ChannelMode(const Anope::string &name, char mc);
107 
108 	bool CanSet(User *u) const anope_override;
109 
Check()110 	virtual void Check() { }
111 
112 	/** 'wrap' this channel mode and param to the underlying mode and param
113 	 */
114 	virtual ChannelMode *Wrap(Anope::string &param);
115 
116 	/** 'unwrap' this mode to our internal representation
117 	 */
118 	ChannelMode *Unwrap(Anope::string &param);
119 
120 	/** called when a mode is being unwrapped, and is asking us if we can unwrap it
121 	 */
122 	virtual ChannelMode *Unwrap(ChannelMode *, Anope::string &param);
123 };
124 
125 /** This is a mode for lists, eg b/e/I. These modes should inherit from this
126  */
127 class CoreExport ChannelModeList : public ChannelMode
128 {
129  public:
130 	/** constructor
131 	 * @param name The mode name
132 	 * @param mc The mode char
133 	 */
134 	ChannelModeList(const Anope::string &name, char mc);
135 
136 	/** Is the mask valid
137 	 * @param mask The mask
138 	 * @return true for yes, false for no
139 	 */
140 	virtual bool IsValid(Anope::string &mask) const;
141 
142 	/** Checks if mask affects user
143 	 * Should only be used for extbans or other weird ircd-specific things.
144 	 * @param u The user
145 	 * @param e The entry to match against
146 	 * @return true on match
147 	 */
Matches(User * u,const Entry * e)148 	virtual bool Matches(User *u, const Entry *e) { return false; }
149 
150 	/** Called when a mask is added to a channel
151 	 * @param chan The channel
152 	 * @param mask The mask
153 	 */
OnAdd(Channel * chan,const Anope::string & mask)154 	virtual void OnAdd(Channel *chan, const Anope::string &mask) { }
155 
156 	/** Called when a mask is removed from a channel
157 	 * @param chan The channel
158 	 * @param mask The mask
159 	 */
OnDel(Channel * chan,const Anope::string & mask)160 	virtual void OnDel(Channel *chan, const Anope::string &mask) { }
161 };
162 
163 /** This is a mode with a paramater, eg +k/l. These modes should use/inherit from this
164 */
165 class CoreExport ChannelModeParam : public ChannelMode
166 {
167  public:
168 	/** constructor
169 	 * @param name The mode name
170 	 * @param mc The mode char
171 	 * @param minus_no_arg true if this mode sends no arg when unsetting
172 	 */
173 	ChannelModeParam(const Anope::string &name, char mc, bool minus_no_arg = false);
174 
175 	/* Should we send an arg when unsetting this mode? */
176 	bool minus_no_arg;
177 
178 	/** Is the param valid
179 	 * @param value The param
180 	 * @return true for yes, false for no
181 	 */
IsValid(Anope::string & value)182 	virtual bool IsValid(Anope::string &value) const { return true; }
183 };
184 
185 /** This is a mode that is a channel status, eg +v/h/o/a/q.
186 */
187 class CoreExport ChannelModeStatus : public ChannelMode
188 {
189  public:
190 	/* The symbol, eg @ % + */
191 	char symbol;
192 	/* The "level" of the mode, used to compare with other modes.
193 	 * Used so we know op > halfop > voice etc.
194 	 */
195 	unsigned level;
196 
197 	/** constructor
198 	 * @param name The mode name
199 	 * @param mc The mode char
200 	 * @param msymbol The symbol for the mode, eg @ %
201 	 * @param mlevel A level for the mode, which is usually determined by the PREFIX capab
202 	 */
203 	ChannelModeStatus(const Anope::string &name, char mc, char msymbol, unsigned mlevel);
204 };
205 
206 /** A virtual mode. This mode doesn't natively exist on the IRCd (like extbans),
207  * but we still have a representation for it.
208  */
209 template<typename T>
210 class CoreExport ChannelModeVirtual : public T
211 {
212 	Anope::string base;
213 	ChannelMode *basech;
214 
215  public:
216 	ChannelModeVirtual(const Anope::string &mname, const Anope::string &basename);
217 
218 	~ChannelModeVirtual();
219 
220 	void Check() anope_override;
221 
222 	ChannelMode *Wrap(Anope::string &param) anope_override;
223 
224 	ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) = 0;
225 };
226 
227 /* The status a user has on a channel (+v, +h, +o) etc */
228 class CoreExport ChannelStatus
229 {
230 	Anope::string modes;
231  public:
232 	ChannelStatus();
233 	ChannelStatus(const Anope::string &modes);
234 	void AddMode(char c);
235 	void DelMode(char c);
236 	bool HasMode(char c) const;
237 	bool Empty() const;
238 	void Clear();
239 	const Anope::string &Modes() const;
240 	Anope::string BuildModePrefixList() const;
241 };
242 
243 class CoreExport UserModeOperOnly : public UserMode
244 {
245  public:
UserModeOperOnly(const Anope::string & mname,char um)246 	UserModeOperOnly(const Anope::string &mname, char um) : UserMode(mname, um) { }
247 
248 	bool CanSet(User *u) const anope_override;
249 };
250 
251 class CoreExport UserModeNoone : public UserMode
252 {
253  public:
UserModeNoone(const Anope::string & mname,char um)254 	UserModeNoone(const Anope::string &mname, char um) : UserMode(mname, um) { }
255 
256 	bool CanSet(User *u) const anope_override;
257 };
258 
259 /** Channel mode +k (key)
260  */
261 class CoreExport ChannelModeKey : public ChannelModeParam
262 {
263  public:
ChannelModeKey(char mc)264 	ChannelModeKey(char mc) : ChannelModeParam("KEY", mc) { }
265 
266 	bool IsValid(Anope::string &value) const anope_override;
267 };
268 
269 /** This class is used for oper only channel modes
270  */
271 class CoreExport ChannelModeOperOnly : public ChannelMode
272 {
273  public:
ChannelModeOperOnly(const Anope::string & mname,char mc)274 	ChannelModeOperOnly(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { }
275 
276 	/* Opers only */
277 	bool CanSet(User *u) const anope_override;
278 };
279 
280 /** This class is used for channel modes only servers may set
281  */
282 class CoreExport ChannelModeNoone : public ChannelMode
283 {
284  public:
ChannelModeNoone(const Anope::string & mname,char mc)285 	ChannelModeNoone(const Anope::string &mname, char mc) : ChannelMode(mname, mc) { }
286 
287 	bool CanSet(User *u) const anope_override;
288 };
289 
290 /** This is the mode manager
291  * It contains functions for adding modes to Anope so Anope can track them
292  * and do things such as MLOCK.
293  * This also contains a mode stacker that will combine multiple modes and set
294  * them on a channel or user at once
295  */
296 class CoreExport ModeManager
297 {
298  public:
299 
300 	/* Number of generic channel and user modes we are tracking */
301 	static unsigned GenericChannelModes;
302 	static unsigned GenericUserModes;
303 
304 	/** Add a user mode to Anope
305 	 * @param um A UserMode or UserMode derived class
306 	 * @return true on success, false on error
307 	 */
308 	static bool AddUserMode(UserMode *um);
309 
310 	/** Add a channel mode to Anope
311 	 * @param cm A ChannelMode or ChannelMode derived class
312 	 * @return true on success, false on error
313 	 */
314 	static bool AddChannelMode(ChannelMode *cm);
315 
316 	/** Remove a user mode from Anope
317 	 * @param um A UserMode to remove
318 	 */
319 	static void RemoveUserMode(UserMode *um);
320 
321 	/** Remove a channel mode from Anope
322 	 * @param um A ChanneMode to remove
323 	 */
324 	static void RemoveChannelMode(ChannelMode *cm);
325 
326 	/** Find a channel mode
327 	 * @param mode The mode
328 	 * @return The mode class
329 	 */
330 	static ChannelMode *FindChannelModeByChar(char mode);
331 
332 	/** Find a user mode
333 	 * @param mode The mode
334 	 * @return The mode class
335 	 */
336 	static UserMode *FindUserModeByChar(char mode);
337 
338 	/** Find a channel mode
339 	 * @param name The modename
340 	 * @return The mode class
341 	 */
342 	static ChannelMode *FindChannelModeByName(const Anope::string &name);
343 
344 	/** Find a user mode
345 	 * @param name The modename
346 	 * @return The mode class
347 	 */
348 	static UserMode *FindUserModeByName(const Anope::string &name);
349 
350 	/** Gets the channel mode char for a symbol (eg + returns v)
351 	 * @param symbol The symbol
352 	 * @return The char
353 	 */
354 	static char GetStatusChar(char symbol);
355 
356 	static const std::vector<ChannelMode *> &GetChannelModes();
357 	static const std::vector<UserMode *> &GetUserModes();
358 	static const std::vector<ChannelModeStatus *> &GetStatusChannelModesByRank();
359 	static void RebuildStatusModes();
360 
361 	/** Add a mode to the stacker to be set on a channel
362 	 * @param bi The client to set the modes from
363 	 * @param c The channel
364 	 * @param cm The channel mode
365 	 * @param set true for setting, false for removing
366 	 * @param param The param, if there is one
367 	 */
368 	static void StackerAdd(BotInfo *bi, Channel *c, ChannelMode *cm, bool set, const Anope::string &param = "");
369 
370 	/** Add a mode to the stacker to be set on a user
371 	 * @param bi The client to set the modes from
372 	 * @param u The user
373 	 * @param um The user mode
374 	 * @param set true for setting, false for removing
375 	 * @param param The param, if there is one
376 	 */
377 	static void StackerAdd(BotInfo *bi, User *u, UserMode *um, bool set, const Anope::string &param = "");
378 
379 	/** Process all of the modes in the stacker and send them to the IRCd to be set on channels/users
380 	 */
381 	static void ProcessModes();
382 
383 	/** Delete a user, channel, or mode from the stacker
384 	 */
385 	static void StackerDel(User *u);
386 	static void StackerDel(Channel *c);
387 	static void StackerDel(Mode *m);
388 };
389 
390 /** Represents a mask set on a channel (b/e/I)
391  */
392 class CoreExport Entry
393 {
394 	Anope::string name;
395 	Anope::string mask;
396  public:
397 	unsigned short cidr_len;
398 	int family;
399 	Anope::string nick, user, host, real;
400 
401 	/** Constructor
402 	 * @param mode What mode this host is for, can be empty for unknown/no mode
403 	 * @param host A full or poartial nick!ident@host/cidr#real name mask
404 	 */
405 	Entry(const Anope::string &mode, const Anope::string &host);
406 
407 	/** Get the banned mask for this entry
408 	 * @return The mask
409 	 */
410 	const Anope::string GetMask() const;
411 
412 	const Anope::string GetNUHMask() const;
413 
414 	/** Check if this entry matches a user
415 	 * @param u The user
416 	 * @param full True to match against a users real host and IP
417 	 * @return true on match
418 	 */
419 	bool Matches(User *u, bool full = false) const;
420 };
421 
422 #endif // MODES_H
423