1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013-2016 Attila Molnar <attilamolnar@hush.com>
5  *   Copyright (C) 2012-2013, 2017-2021 Sadie Powell <sadie@witchery.services>
6  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
7  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
8  *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
9  *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
10  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
11  *   Copyright (C) 2006-2008, 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 #pragma once
28 
29 #include "ctables.h"
30 #include "modechange.h"
31 
32 /**
33  * Holds the values for different type of modes
34  * that can exist, USER or CHANNEL type.
35  */
36 enum ModeType
37 {
38 	/** User mode */
39 	MODETYPE_USER = 0,
40 	/** Channel mode */
41 	MODETYPE_CHANNEL = 1
42 };
43 
44 /**
45  * Holds mode actions - modes can be allowed or denied.
46  */
47 enum ModeAction
48 {
49 	MODEACTION_DENY = 0, /* Drop the mode change, AND a parameter if its a parameterized mode */
50 	MODEACTION_ALLOW = 1 /* Allow the mode */
51 };
52 
53 /**
54  * These fixed values can be used to proportionally compare module-defined prefixes to known values.
55  * For example, if your module queries a Channel, and is told that user 'joebloggs' has the prefix
56  * '$', and you dont know what $ means, then you can compare it to these three values to determine
57  * its worth against them. For example if '$' had a value of 15000, you would know it is of higher
58  * status than voice, but lower status than halfop.
59  * No two modes should have equal prefix values.
60  */
61 enum PrefixModeValue
62 {
63 	/* +v */
64 	VOICE_VALUE	=	10000,
65 	/* +h */
66 	HALFOP_VALUE	=	20000,
67 	/* +o */
68 	OP_VALUE	=	30000
69 };
70 
71 enum ParamSpec
72 {
73 	/** No parameters */
74 	PARAM_NONE,
75 	/** Parameter required on mode setting only */
76 	PARAM_SETONLY,
77 	/** Parameter always required */
78 	PARAM_ALWAYS
79 };
80 
81 class PrefixMode;
82 class ListModeBase;
83 class ParamModeBase;
84 
85 /** Each mode is implemented by ONE ModeHandler class.
86  * You must derive ModeHandler and add the child class to
87  * the list of modes handled by the ircd, using
88  * ModeParser::AddMode. When the mode you implement is
89  * set by a user, the virtual function OnModeChange is
90  * called. If you specify a value greater than 0 for
91  * parameters_on or parameters_off, then when the mode is
92  * set or unset respectively, std::string &parameter will
93  * contain the parameter given by the user, else it will
94  * contain an empty string. You may alter this parameter
95  * string, and if you alter it to an empty string, and your
96  * mode is expected to have a parameter, then this is
97  * equivalent to returning MODEACTION_DENY.
98  */
99 class CoreExport ModeHandler : public ServiceProvider
100 {
101  public:
102 	typedef size_t Id;
103 
104 	enum Class
105 	{
106 		MC_PREFIX,
107 		MC_LIST,
108 		MC_PARAM,
109 		MC_OTHER
110 	};
111 
112  private:
113 	/** The opaque id of this mode assigned by the mode parser
114 	 */
115 	Id modeid;
116 
117  protected:
118 	/** What kind of parameters does the mode take?
119 	 */
120 	ParamSpec parameters_taken;
121 
122 	/**
123 	 * The mode letter you're implementing.
124 	 */
125 	char mode;
126 
127 	/**
128 	 * True if the mode requires oper status
129 	 * to set.
130 	 */
131 	bool oper;
132 
133 	/**
134 	 * Mode is a 'list' mode. The behaviour
135 	 * of your mode is now set entirely within
136 	 * the class as of the 1.1 api, rather than
137 	 * inside the mode parser as in the 1.0 api,
138 	 * so the only use of this value (along with
139 	 * IsListMode()) is for the core to determine
140 	 * whether your module can produce 'lists' or not
141 	 * (e.g. banlists, etc)
142 	 */
143 	bool list;
144 
145 	/**
146 	 * The mode type, either MODETYPE_USER or
147 	 * MODETYPE_CHANNEL.
148 	 */
149 	ModeType m_type;
150 
151 	/** The object type of this mode handler
152 	 */
153 	const Class type_id;
154 
155 	/** The prefix rank required to set this mode on channels. */
156 	unsigned int ranktoset;
157 
158 	/** The prefix rank required to unset this mode on channels. */
159 	unsigned int ranktounset;
160 
161 	/** If non-empty then the syntax of the parameter for this mode. */
162 	std::string syntax;
163 
164  public:
165 	/**
166 	 * The constructor for ModeHandler initializes the mode handler.
167 	 * The constructor of any class you derive from ModeHandler should
168 	 * probably call this constructor with the parameters set correctly.
169 	 * @param me The module which created this mode
170 	 * @param name A one-word name for the mode
171 	 * @param modeletter The mode letter you wish to handle
172 	 * @param params Parameters taken by the mode
173 	 * @param type Type of the mode (MODETYPE_USER or MODETYPE_CHANNEL)
174 	 * @param mclass The object type of this mode handler, one of ModeHandler::Class
175 	 */
176 	ModeHandler(Module* me, const std::string& name, char modeletter, ParamSpec params, ModeType type, Class mclass = MC_OTHER);
177 	CullResult cull() CXX11_OVERRIDE;
178 	virtual ~ModeHandler();
179 
180 	/** Register this object in the ModeParser
181 	 */
182 	void RegisterService() CXX11_OVERRIDE;
183 
184 	/**
185 	 * Returns true if the mode is a list mode
186 	 */
IsListMode()187 	bool IsListMode() const { return list; }
188 
189 	/**
190 	 * Check whether this mode is a prefix mode
191 	 * @return non-NULL if this mode is a prefix mode, NULL otherwise
192 	 */
193 	PrefixMode* IsPrefixMode();
194 
195 	/**
196 	 * Check whether this mode is a prefix mode
197 	 * @return non-NULL if this mode is a prefix mode, NULL otherwise
198 	 */
199 	const PrefixMode* IsPrefixMode() const;
200 
201 	/**
202 	 * Check whether this mode handler inherits from ListModeBase
203 	 * @return non-NULL if this mode handler inherits from ListModeBase, NULL otherwise
204 	 */
205 	ListModeBase* IsListModeBase();
206 
207 	/**
208 	 * Check whether this mode handler inherits from ListModeBase
209 	 * @return non-NULL if this mode handler inherits from ListModeBase, NULL otherwise
210 	 */
211 	const ListModeBase* IsListModeBase() const;
212 
213 	/**
214 	 * Check whether this mode handler inherits from ParamModeBase
215 	 * @return non-NULL if this mode handler inherits from ParamModeBase, NULL otherwise
216 	 */
217 	ParamModeBase* IsParameterMode();
218 
219 	/**
220 	 * Check whether this mode handler inherits from ParamModeBase
221 	 * @return non-NULL if this mode handler inherits from ParamModeBase, NULL otherwise
222 	 */
223 	const ParamModeBase* IsParameterMode() const;
224 
225 	/**
226 	 * Returns the mode's type
227 	 */
GetModeType()228 	inline ModeType GetModeType() const { return m_type; }
229 	/**
230 	 * Returns true if the mode can only be set/unset by an oper
231 	 */
NeedsOper()232 	inline bool NeedsOper() const { return oper; }
233 	/**
234 	 * Check if the mode needs a parameter for adding or removing
235 	 * @param adding True to check if the mode needs a parameter when setting, false to check if the mode needs a parameter when unsetting
236 	 * @return True if the mode needs a parameter for the specified action, false if it doesn't
237 	 */
238 	bool NeedsParam(bool adding) const;
239 	/**
240 	 * Returns the mode character this handler handles.
241 	 * @return The mode character
242 	 */
GetModeChar()243 	char GetModeChar() const { return mode; }
244 
245 	/** Return the id of this mode which is used in User::modes and
246 	 * Channel::modes as the index to determine whether a mode is set.
247 	 */
GetId()248 	Id GetId() const { return modeid; }
249 
250 	/** For user modes, return the current parameter, if any
251 	 */
252 	virtual std::string GetUserParameter(const User* user) const;
253 
254 	/**
255 	 * Called when a channel mode change access check for your mode occurs.
256 	 * @param source Contains the user setting the mode.
257 	 * @param channel contains the destination channel the modes are being set on.
258 	 * @param parameter The parameter for your mode. This is modifiable.
259 	 * @param adding This value is true when the mode is being set, or false when it is being unset.
260 	 * @return allow, deny, or passthru to check against the required level
261 	 */
262 	virtual ModResult AccessCheck(User* source, Channel* channel, std::string &parameter, bool adding);
263 
264 	/**
265 	 * Called when a mode change for your mode occurs.
266 	 * @param source Contains the user setting the mode.
267 	 * @param dest For usermodes, contains the destination user the mode is being set on. For channelmodes, this is an undefined value.
268 	 * @param channel For channel modes, contains the destination channel the modes are being set on. For usermodes, this is an undefined value.
269 	 * @param parameter The parameter for your mode, if you indicated that your mode requires a parameter when being set or unset. Note that
270 	 * if you alter this value, the new value becomes the one displayed and send out to the network, also, if you set this to an empty string
271 	 * but you specified your mode REQUIRES a parameter, this is equivalent to returning MODEACTION_DENY and will prevent the mode from being
272 	 * displayed.
273 	 * @param adding This value is true when the mode is being set, or false when it is being unset.
274 	 * @return MODEACTION_ALLOW to allow the mode, or MODEACTION_DENY to prevent the mode, also see the description of 'parameter'.
275 	 */
276 	virtual ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding); /* Can change the mode parameter as its a ref */
277 
278 	/**
279 	 * If your mode is a listmode, then this method will be called for displaying an item list, e.g. on MODE \#channel +modechar
280 	 * without any parameter or other modes in the command.
281 	 * @param user The user issuing the command
282 	 * @param channel The channel they're requesting an item list of (e.g. a banlist, or an exception list etc)
283 	 */
284 	virtual void DisplayList(User* user, Channel* channel);
285 
286 	/** In the event that the mode should be given a parameter, and no parameter was provided, this method is called.
287 	 * This allows you to give special information to the user, or handle this any way you like.
288 	 * @param user The user issuing the mode change
289 	 * @param dest For user mode changes, the target of the mode. For channel mode changes, NULL.
290 	 * @param channel For channel mode changes, the target of the mode. For user mode changes, NULL.
291 	 */
292 	virtual void OnParameterMissing(User* user, User* dest, Channel* channel);
293 
294 	/** Called when a user attempts to set a mode and the parameter is invalid.
295 	 * @param user The user issuing the mode change
296 	 * @param targetchannel Either the channel target or NULL if changing a user mode.
297 	 * @param targetuser Either the user target or NULL if changing a channel mode.
298 	 * @param parameter The invalid parameter.
299 	 */
300 	virtual void OnParameterInvalid(User* user, Channel* targetchannel, User* targetuser, const std::string& parameter);
301 
302 
303 	/**
304 	 * If your mode is a listmode, this method will be called to display an empty list (just the end of list numeric)
305 	 * @param user The user issuing the command
306 	 * @param channel The channel they're requesting an item list of (e.g. a banlist, or an exception list etc)
307 	 */
308 	virtual void DisplayEmptyList(User* user, Channel* channel);
309 
310 	/**
311 	 * If your mode needs special action during a server sync to determine which side wins when comparing timestamps,
312 	 * override this function and use it to return true or false. The default implementation just returns true if
313 	 * theirs < ours. This will only be called for non-listmodes with parameters, when adding the mode and where
314 	 * theirs == ours (therefore the default implementation will always return false).
315 	 * @param their_param Their parameter if the mode has a parameter
316 	 * @param our_param Our parameter if the mode has a parameter
317 	 * @param channel The channel we are checking against
318 	 * @return True if the other side wins the merge, false if we win the merge for this mode.
319 	 */
320 	virtual bool ResolveModeConflict(std::string &their_param, const std::string &our_param, Channel* channel);
321 
322 	/**
323 	 * When a MODETYPE_USER mode handler is being removed, the core will call this method for every user on the server.
324 	 * The usermode will be removed using the appropriate server mode using InspIRCd::SendMode().
325 	 * @param user The user which the server wants to remove your mode from
326 	 */
327 	void RemoveMode(User* user);
328 
329 	/**
330 	 * When a MODETYPE_CHANNEL mode handler is being removed, the server will call this method for every channel on the server.
331 	 * The mode handler has to populate the given modestacker with mode changes that remove the mode from the channel.
332 	 * The default implementation of this method can remove all kinds of channel modes except listmodes.
333 	 * In the case of listmodes, the entire list of items must be added to the modestacker (which is handled by ListModeBase,
334 	 * so if you inherit from it or your mode can be removed by the default implementation then you do not have to implement
335 	 * this function).
336 	 * @param channel The channel which the server wants to remove your mode from
337 	 * @param changelist Mode change list to populate with the removal of this mode
338 	 */
339 	virtual void RemoveMode(Channel* channel, Modes::ChangeList& changelist);
340 
341 	/** Retrieves the level required to modify this mode.
342 	 * @param adding Whether the mode is being added or removed.
343 	 */
GetLevelRequired(bool adding)344 	inline unsigned int GetLevelRequired(bool adding) const
345 	{
346 		return adding ? ranktoset : ranktounset;
347 	}
348 
349 	/** Retrieves the syntax of the parameter for this mode. */
GetSyntax()350 	const std::string& GetSyntax() const { return syntax; }
351 
352 	friend class ModeParser;
353 };
354 
355 /**
356  * Prefix modes are channel modes that grant a specific rank to members having prefix mode set.
357  * They require a parameter when setting and unsetting; the parameter is always a member of the channel.
358  * A prefix mode may be set on any number of members on a channel, but for a given member a given prefix
359  * mode is either set or not set, in other words members cannot have the same prefix mode set more than once.
360  *
361  * A rank of a member is defined as the rank given by the 'strongest' prefix mode that member has.
362  * Other parts of the IRCd use this rank to determine whether a channel action is allowable for a user or not.
363  * The rank of a prefix mode is constant, i.e. the same rank value is given to all users having that prefix mode set.
364  *
365  * Note that it is possible that the same action requires a different rank on a different channel;
366  * for example changing the topic on a channel having +t set requires a rank that is >= than the rank of a halfop,
367  * but there is no such restriction when +t isn't set.
368  */
369 class CoreExport PrefixMode : public ModeHandler
370 {
371  protected:
372 	/** The prefix character granted by this mode. '@' for op, '+' for voice, etc.
373 	 * If 0, this mode does not have a visible prefix character.
374 	 */
375 	char prefix;
376 
377 	/** The prefix rank of this mode, used to compare prefix
378 	 * modes
379 	 */
380 	unsigned int prefixrank;
381 
382 	/** Whether a client with this prefix can remove it from themself. */
383 	bool selfremove;
384 
385  public:
386 	/**
387 	 * Constructor
388 	 * @param Creator The module creating this mode
389 	 * @param Name The user-friendly one word name of the prefix mode, e.g.: "op", "voice"
390 	 * @param ModeLetter The mode letter of this mode
391 	 * @param Rank Rank given by this prefix mode, see explanation above
392 	 * @param PrefixChar Prefix character, or 0 if the mode has no prefix character
393 	 */
394 	PrefixMode(Module* Creator, const std::string& Name, char ModeLetter, unsigned int Rank = 0, char PrefixChar = 0);
395 
396 	/**
397 	 * Called when a channel mode change access check for your mode occurs.
398 	 * @param source Contains the user setting the mode.
399 	 * @param channel contains the destination channel the modes are being set on.
400 	 * @param parameter The parameter for your mode. This is modifiable.
401 	 * @param adding This value is true when the mode is being set, or false when it is being unset.
402 	 * @return allow, deny, or passthru to check against the required level
403 	 */
404 	ModResult AccessCheck(User* source, Channel* channel, std::string &parameter, bool adding) CXX11_OVERRIDE;
405 
406 	/**
407 	 * Handles setting and unsetting the prefix mode.
408 	 * Finds the given member of the given channel, if it's not found an error message is sent to 'source'
409 	 * and MODEACTION_DENY is returned. Otherwise the mode change is attempted.
410 	 * @param source Source of the mode change, an error message is sent to this user if the target is not found
411 	 * @param dest Unused
412 	 * @param channel The channel the mode change is happening on
413 	 * @param param The nickname or uuid of the target user
414 	 * @param adding True when the mode is being set, false when it is being unset
415 	 * @return MODEACTION_ALLOW if the change happened, MODEACTION_DENY if no change happened
416 	 * The latter occurs either when the member cannot be found or when the member already has this prefix set
417 	 * (when setting) or doesn't have this prefix set (when unsetting).
418 	 */
419 	ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& param, bool adding) CXX11_OVERRIDE;
420 
421 	/**
422 	 * Updates the configuration of this prefix.
423 	 * @param rank The prefix rank of this mode.
424 	 * @param setrank The prefix rank required to set this mode on channels.
425 	 * @param unsetrank The prefix rank required to set this unmode on channels.
426 	 * @param selfrm Whether a client with this prefix can remove it from themself.
427 	 */
428 	void Update(unsigned int rank, unsigned int setrank, unsigned int unsetrank, bool selfrm);
429 
430 	/**
431 	 * Removes this prefix mode from all users on the given channel
432 	 * @param channel The channel which the server wants to remove your mode from
433 	 * @param changelist Mode change list to populate with the removal of this mode
434 	 */
435 	void RemoveMode(Channel* channel, Modes::ChangeList& changelist) CXX11_OVERRIDE;
436 
437 
438 	/**
439 	* Determines whether a user with this prefix mode can remove it.
440 	*/
CanSelfRemove()441 	bool CanSelfRemove() const { return selfremove; }
442 
443 	/**
444 	 * Mode prefix or 0. If this is defined, you should
445 	 * also implement GetPrefixRank() to return an integer
446 	 * value for this mode prefix.
447 	 */
GetPrefix()448 	char GetPrefix() const { return prefix; }
449 
450 	/**
451 	 * Get the 'value' of this modes prefix.
452 	 * determines which to display when there are multiple.
453 	 * The mode with the highest value is ranked first. See the
454 	 * PrefixModeValue enum and Channel::GetPrefixValue() for
455 	 * more information.
456 	 */
GetPrefixRank()457 	unsigned int GetPrefixRank() const { return prefixrank; }
458 };
459 
460 /** A prebuilt mode handler which handles a simple user mode, e.g. no parameters, usable by any user, with no extra
461  * behaviour to the mode beyond the basic setting and unsetting of the mode, not allowing the mode to be set if it
462  * is already set and not allowing it to be unset if it is already unset.
463  * An example of a simple user mode is user mode +w.
464  */
465 class CoreExport SimpleUserModeHandler : public ModeHandler
466 {
467  public:
468 	SimpleUserModeHandler(Module* Creator, const std::string& Name, char modeletter, bool operonly = false)
ModeHandler(Creator,Name,modeletter,PARAM_NONE,MODETYPE_USER)469 		: ModeHandler(Creator, Name, modeletter, PARAM_NONE, MODETYPE_USER)
470 	{
471 		oper = operonly;
472 	}
473 
474 	ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE;
475 };
476 
477 /** A prebuilt mode handler which handles a simple channel mode, e.g. no parameters, usable by any user, with no extra
478  * behaviour to the mode beyond the basic setting and unsetting of the mode, not allowing the mode to be set if it
479  * is already set and not allowing it to be unset if it is already unset.
480  * An example of a simple channel mode is channel mode +s.
481  */
482 class CoreExport SimpleChannelModeHandler : public ModeHandler
483 {
484  public:
485 	SimpleChannelModeHandler(Module* Creator, const std::string& Name, char modeletter, bool operonly = false)
ModeHandler(Creator,Name,modeletter,PARAM_NONE,MODETYPE_CHANNEL)486 		: ModeHandler(Creator, Name, modeletter, PARAM_NONE, MODETYPE_CHANNEL)
487 	{
488 		oper = operonly;
489 	}
490 
491 	ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE;
492 };
493 
494 /**
495  * The ModeWatcher class can be used to alter the behaviour of a mode implemented
496  * by the core or by another module. To use ModeWatcher, derive a class from it,
497  * and attach it to the mode using Server::AddModeWatcher and Server::DelModeWatcher.
498  * A ModeWatcher will be called both before and after the mode change.
499  */
500 class CoreExport ModeWatcher : public classbase
501 {
502  private:
503 	/**
504 	 * The mode name this class is watching
505 	 */
506 	const std::string mode;
507 
508 	/**
509 	 * The mode type being watched (user or channel)
510 	 */
511 	ModeType m_type;
512 
513  public:
514 	ModuleRef creator;
515 	/**
516 	 * The constructor initializes the mode and the mode type
517 	 */
518 	ModeWatcher(Module* creator, const std::string& modename, ModeType type);
519 	/**
520 	 * The default destructor does nothing.
521 	 */
522 	virtual ~ModeWatcher();
523 
524 	/**
525 	 * Get the mode name being watched
526 	 * @return The mode name being watched
527 	 */
GetModeName()528 	const std::string& GetModeName() const { return mode; }
529 
530 	/**
531 	 * Get the mode type being watched
532 	 * @return The mode type being watched (user or channel)
533 	 */
GetModeType()534 	ModeType GetModeType() const { return m_type; }
535 
536 	/**
537 	 * Before the mode character is processed by its handler, this method will be called.
538 	 * @param source The sender of the mode
539 	 * @param dest The target user for the mode, if you are watching a user mode
540 	 * @param channel The target channel for the mode, if you are watching a channel mode
541 	 * @param parameter The parameter of the mode, if the mode is supposed to have a parameter.
542 	 * If you alter the parameter you are given, the mode handler will see your altered version
543 	 * when it handles the mode.
544 	 * @param adding True if the mode is being added and false if it is being removed
545 	 * @return True to allow the mode change to go ahead, false to abort it. If you abort the
546 	 * change, the mode handler (and ModeWatcher::AfterMode()) will never see the mode change.
547 	 */
548 	virtual bool BeforeMode(User* source, User* dest, Channel* channel, std::string& parameter, bool adding);
549 	/**
550 	 * After the mode character has been processed by the ModeHandler, this method will be called.
551 	 * @param source The sender of the mode
552 	 * @param dest The target user for the mode, if you are watching a user mode
553 	 * @param channel The target channel for the mode, if you are watching a channel mode
554 	 * @param parameter The parameter of the mode, if the mode is supposed to have a parameter.
555 	 * You cannot alter the parameter here, as the mode handler has already processed it.
556 	 * @param adding True if the mode is being added and false if it is being removed
557 	 */
558 	virtual void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding);
559 };
560 
561 /** The mode parser handles routing of modes and handling of mode strings.
562  * It marshalls, controls and maintains both ModeWatcher and ModeHandler classes,
563  * parses client to server MODE strings for user and channel modes, and performs
564  * processing for the 004 mode list numeric, amongst other things.
565  */
566 class CoreExport ModeParser : public fakederef<ModeParser>
567 {
568  public:
569 	/** The maximum number of modes which can be created. */
570 	static const ModeHandler::Id MODEID_MAX = 64;
571 
572 	/** The maximum length of a mode parameter. */
573 	static const size_t MODE_PARAM_MAX = 250;
574 
575 	/** Type of the container that maps mode names to ModeHandlers
576 	 */
577 	typedef TR1NS::unordered_map<std::string, ModeHandler*, irc::insensitive, irc::StrHashComp> ModeHandlerMap;
578 
579  private:
580 	/** Type of the container that maps mode names to ModeWatchers
581 	 */
582 	typedef insp::flat_multimap<std::string, ModeWatcher*> ModeWatcherMap;
583 
584 	/** Last item in the ModeType enum
585 	 */
586 	static const unsigned int MODETYPE_LAST = 2;
587 
588 	/** Mode handlers for each mode, to access a handler subtract
589 	 * 65 from the ascii value of the mode letter.
590 	 * The upper bit of the value indicates if its a usermode
591 	 * or a channel mode, so we have 256 of them not 64.
592 	 */
593 	ModeHandler* modehandlers[MODETYPE_LAST][128];
594 
595 	/** An array of mode handlers indexed by the mode id
596 	 */
597 	ModeHandler* modehandlersbyid[MODETYPE_LAST][MODEID_MAX];
598 
599 	/** A map of mode handlers keyed by their name
600 	 */
601 	ModeHandlerMap modehandlersbyname[MODETYPE_LAST];
602 
603 	/** Lists of mode handlers by type
604 	 */
605 	struct
606 	{
607 		/** List of mode handlers that inherit from ListModeBase
608 		 */
609 		std::vector<ListModeBase*> list;
610 
611 		/** List of mode handlers that inherit from PrefixMode
612 		 */
613 		std::vector<PrefixMode*> prefix;
614 	} mhlist;
615 
616 	/** Mode watcher classes
617 	 */
618 	ModeWatcherMap modewatchermap;
619 
620 	/** Last processed mode change
621 	 */
622 	Modes::ChangeList LastChangeList;
623 
624 	/** Attempts to apply a mode change to a user or channel
625 	 * @param user The user who triggered the mode change.
626 	 * @param usertarget If non-NULL then the user to change the modes of.
627 	 * @param chantarget If non-NULL then the channel to change the modes of.
628 	 * @param mcitem The actual mode change to attempt.
629 	 * @param skipacl Whether to skip access checks for the mode change.
630 	 */
631 	ModeAction TryMode(User* user, User* usertarget, Channel* chantarget, Modes::Change& mcitem, bool skipacl);
632 
633 	/** Allocates an unused id for the given mode type, throws a ModuleException if out of ids.
634 	 * @param mt The type of the mode to allocate the id for
635 	 * @return The id
636 	 */
637 	ModeHandler::Id AllocateModeId(ModeType mt);
638 
639  public:
640 	typedef std::vector<ListModeBase*> ListModeList;
641 	typedef std::vector<PrefixMode*> PrefixModeList;
642 
643 	typedef unsigned int ModeProcessFlag;
644 	enum ModeProcessFlags
645 	{
646 		/** If only this flag is specified, the mode change will be global
647 		 * and parameter modes will have their parameters explicitly set
648 		 * (not merged). This is the default.
649 		 */
650 		MODE_NONE = 0,
651 
652 		/** If this flag is set then the parameters of non-listmodes will be
653 		 * merged according to their conflict resolution rules.
654 		 * Does not affect user modes, channel modes without a parameter and
655 		 * listmodes.
656 		 */
657 		MODE_MERGE = 1,
658 
659 		/** If this flag is set then the linking module will ignore the mode change
660 		 * and not send it to other servers. The mode change will be processed
661 		 * locally and sent to local user(s) as usual.
662 		 */
663 		MODE_LOCALONLY = 2,
664 
665 		/** If this flag is set then the mode change will be subject to access checks.
666 		 * For more information see the documentation of the PrefixMode class,
667 		 * ModeHandler::ranktoset and ModeHandler::AccessCheck().
668 		 * Modules may explicitly allow a mode change regardless of this flag by returning
669 		 * MOD_RES_ALLOW from the OnPreMode hook. Only affects channel mode changes.
670 		 */
671 		MODE_CHECKACCESS = 4
672 	};
673 
674 	ModeParser();
675 	~ModeParser();
676 
677 	static bool IsModeChar(char chr);
678 
679 	/** Tidy a banmask. This makes a banmask 'acceptable' if fields are left out.
680 	 * E.g.
681 	 *
682 	 * nick -> nick!*@*
683 	 *
684 	 * nick!ident -> nick!ident@*
685 	 *
686 	 * host.name -> *!*\@host.name
687 	 *
688 	 * ident\@host.name -> *!ident\@host.name
689 	 *
690 	 * This method can be used on both IPV4 and IPV6 user masks.
691 	 */
692 	static void CleanMask(std::string &mask);
693 
694 	/** Gets the last mode change to be processed. */
GetLastChangeList()695 	const Modes::ChangeList& GetLastChangeList() const { return LastChangeList; }
696 
697 	/** Add a mode to the mode parser.
698 	 * Throws a ModuleException if the mode cannot be added.
699 	 */
700 	void AddMode(ModeHandler* mh);
701 
702 	/** Delete a mode from the mode parser.
703 	 * When a mode is deleted, the mode handler will be called
704 	 * for every user (if it is a user mode) or for every  channel
705 	 * (if it is a channel mode) to unset the mode on all objects.
706 	 * This prevents modes staying in the system which no longer exist.
707 	 * @param mh The mode handler to remove
708 	 * @return True if the mode was successfully removed.
709 	 */
710 	bool DelMode(ModeHandler* mh);
711 
712 	/** Add a mode watcher.
713 	 * A mode watcher is triggered before and after a mode handler is
714 	 * triggered. See the documentation of class ModeWatcher for more
715 	 * information.
716 	 * @param mw The ModeWatcher you want to add
717 	 */
718 	void AddModeWatcher(ModeWatcher* mw);
719 
720 	/** Delete a mode watcher.
721 	 * A mode watcher is triggered before and after a mode handler is
722 	 * triggered. See the documentation of class ModeWatcher for more
723 	 * information.
724 	 * @param mw The ModeWatcher you want to delete
725 	 * @return True if the ModeWatcher was deleted correctly
726 	 */
727 	bool DelModeWatcher(ModeWatcher* mw);
728 
729 	/** Process a list of mode changes entirely. If the mode changes do not fit into one MODE line
730 	 * then multiple MODE lines are generated.
731 	 * @param user The source of the mode change, can be a server user.
732 	 * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel.
733 	 * @param targetuser User to apply the mode change on. NULL if changing modes on a user.
734 	 * @param changelist Modes to change in form of a Modes::ChangeList.
735 	 * @param flags Optional flags controlling how the mode change is processed,
736 	 * defaults to MODE_NONE.
737 	 */
738 	void Process(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE);
739 
740 	/** Process a single MODE line's worth of mode changes, taking max modes and line length limits
741 	 * into consideration. Return value indicates how many modes were processed.
742 	 * @param user The source of the mode change, can be a server user.
743 	 * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel.
744 	 * @param targetuser User to apply the mode change on. NULL if changing modes on a user.
745 	 * @param changelist Modes to change in form of a Modes::ChangeList. May not process
746 	 * the entire list due to MODE line length and max modes limitations.
747 	 * @param flags Optional flags controlling how the mode change is processed,
748 	 * defaults to MODE_NONE.
749 	 * @param beginindex Index of the first element in changelist to process. Mode changes before
750 	 * the element with this index are ignored.
751 	 * @return Number of mode changes processed from changelist.
752 	 */
753 	unsigned int ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE, unsigned int beginindex = 0);
754 
755 	/** Turn a list of parameters compatible with the format of the MODE command into
756 	 * Modes::ChangeList form. All modes are processed, regardless of max modes. Unknown modes
757 	 * are skipped.
758 	 * @param user The source of the mode change, can be a server user. Error numerics are sent to
759 	 * this user.
760 	 * @param type MODETYPE_USER if this is a user mode change or MODETYPE_CHANNEL if this
761 	 * is a channel mode change.
762 	 * @param parameters List of strings describing the mode change to convert to a ChangeList.
763 	 * Must be using the same format as the parameters of a MODE command.
764 	 * @param changelist ChangeList object to populate.
765 	 * @param beginindex Index of the first element that is part of the MODE list in the parameters
766 	 * container. Defaults to 1.
767 	 * @param endindex Index of the first element that is not part of the MODE list. By default,
768 	 * the entire container is considered part of the MODE list.
769 	 */
770 	void ModeParamsToChangeList(User* user, ModeType type, const std::vector<std::string>& parameters, Modes::ChangeList& changelist, unsigned int beginindex = 1, unsigned int endindex = UINT_MAX);
771 
772 	/** Find the mode handler for a given mode name and type.
773 	 * @param modename The mode name to search for.
774 	 * @param mt Type of mode to search for, user or channel.
775 	 * @return A pointer to a ModeHandler class, or NULL of there isn't a handler for the given mode name.
776 	 */
777 	ModeHandler* FindMode(const std::string& modename, ModeType mt);
778 
779 	/** Find the mode handler for a given mode and type.
780 	 * @param modeletter mode letter to search for
781 	 * @param mt type of mode to search for, user or channel
782 	 * @returns a pointer to a ModeHandler class, or NULL of there isn't a handler for the given mode
783 	 */
784 	ModeHandler* FindMode(unsigned const char modeletter, ModeType mt);
785 
786 	/** Find the mode handler for the given prefix mode
787 	 * @param modeletter The mode letter to search for
788 	 * @return A pointer to the PrefixMode or NULL if the mode wasn't found or it isn't a prefix mode
789 	 */
790 	PrefixMode* FindPrefixMode(unsigned char modeletter);
791 
792 	/** Find a mode handler by its prefix.
793 	 * If there is no mode handler with the given prefix, NULL will be returned.
794 	 * @param pfxletter The prefix to find, e.g. '@'
795 	 * @return The mode handler which handles this prefix, or NULL if there is none.
796 	 */
797 	PrefixMode* FindPrefix(unsigned const char pfxletter);
798 
799 	/** Generates a list of modes, comma separated by type:
800 	 *  1; Listmodes EXCEPT those with a prefix
801 	 *  2; Modes that take a param when adding or removing
802 	 *  3; Modes that only take a param when adding
803 	 *  4; Modes that dont take a param
804 	 */
805 	std::string GiveModeList(ModeType mt);
806 
807 	/** This returns the PREFIX=(ohv)@%+ section of the 005 numeric, or
808 	 * just the "@%+" part if the parameter false
809 	 */
810 	std::string BuildPrefixes(bool lettersAndModes = true);
811 
812 	/** Get a list of all mode handlers that inherit from ListModeBase
813 	 * @return A list containing ListModeBase modes
814 	 */
GetListModes()815 	const ListModeList& GetListModes() const { return mhlist.list; }
816 
817 	/** Get a list of all prefix modes
818 	 * @return A list containing all prefix modes
819 	 */
GetPrefixModes()820 	const PrefixModeList& GetPrefixModes() const { return mhlist.prefix; }
821 
822 	/** Get a mode name -> ModeHandler* map containing all modes of the given type
823 	 * @param mt Type of modes to return, MODETYPE_USER or MODETYPE_CHANNEL
824 	 * @return A map of mode handlers of the given type
825 	 */
GetModes(ModeType mt)826 	const ModeHandlerMap& GetModes(ModeType mt) const { return modehandlersbyname[mt]; }
827 
828 	/** Show the list of a list mode to a user. Modules can deny the listing.
829 	 * @param user User to show the list to.
830 	 * @param chan Channel to show the list of.
831 	 * @param mh List mode to show the list of.
832 	 */
833 	void ShowListModeList(User* user, Channel* chan, ModeHandler* mh);
834 };
835 
IsPrefixMode()836 inline PrefixMode* ModeHandler::IsPrefixMode()
837 {
838 	return (this->type_id == MC_PREFIX ? static_cast<PrefixMode*>(this) : NULL);
839 }
840 
IsPrefixMode()841 inline const PrefixMode* ModeHandler::IsPrefixMode() const
842 {
843 	return (this->type_id == MC_PREFIX ? static_cast<const PrefixMode*>(this) : NULL);
844 }
845 
IsListModeBase()846 inline ListModeBase* ModeHandler::IsListModeBase()
847 {
848 	return (this->type_id == MC_LIST ? reinterpret_cast<ListModeBase*>(this) : NULL);
849 }
850 
IsListModeBase()851 inline const ListModeBase* ModeHandler::IsListModeBase() const
852 {
853 	return (this->type_id == MC_LIST ? reinterpret_cast<const ListModeBase*>(this) : NULL);
854 }
855 
IsParameterMode()856 inline ParamModeBase* ModeHandler::IsParameterMode()
857 {
858 	return (this->type_id == MC_PARAM ? reinterpret_cast<ParamModeBase*>(this) : NULL);
859 }
860 
IsParameterMode()861 inline const ParamModeBase* ModeHandler::IsParameterMode() const
862 {
863 	return (this->type_id == MC_PARAM ? reinterpret_cast<const ParamModeBase*>(this) : NULL);
864 }
865