2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2013-2016 Attila Molnar <attilamolnar@hush.com>
5 * Copyright (C) 2012-2013, 2017-2020 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>
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.
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
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/>.
30 #include "modechange.h"
33 * Holds the values for different type of modes
34 * that can exist, USER or CHANNEL type.
45 * Holds mode actions - modes can be allowed or denied.
49 MODEACTION_DENY = 0, /* Drop the mode change, AND a parameter if its a parameterized mode */
50 MODEACTION_ALLOW = 1 /* Allow the mode */
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.
75 /** Parameter required on mode setting only */
77 /** Parameter always required */
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 ¶meter 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.
99 class CoreExport ModeHandler : public ServiceProvider
113 /** The opaque id of this mode assigned by the mode parser
118 /** What kind of parameters does the mode take?
120 ParamSpec parameters_taken;
123 * The mode letter you're implementing.
128 * True if the mode requires oper status
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)
146 * The mode type, either MODETYPE_USER or
151 /** The object type of this mode handler
155 /** The prefix rank required to set this mode on channels. */
156 unsigned int ranktoset;
158 /** The prefix rank required to unset this mode on channels. */
159 unsigned int ranktounset;
161 /** If non-empty then the syntax of the parameter for this mode. */
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
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();
180 /** Register this object in the ModeParser
182 void RegisterService() CXX11_OVERRIDE;
185 * Returns true if the mode is a list mode
187 bool IsListMode() const { return list; }
190 * Check whether this mode is a prefix mode
191 * @return non-NULL if this mode is a prefix mode, NULL otherwise
193 PrefixMode* IsPrefixMode();
196 * Check whether this mode is a prefix mode
197 * @return non-NULL if this mode is a prefix mode, NULL otherwise
199 const PrefixMode* IsPrefixMode() const;
202 * Check whether this mode handler inherits from ListModeBase
203 * @return non-NULL if this mode handler inherits from ListModeBase, NULL otherwise
205 ListModeBase* IsListModeBase();
208 * Check whether this mode handler inherits from ListModeBase
209 * @return non-NULL if this mode handler inherits from ListModeBase, NULL otherwise
211 const ListModeBase* IsListModeBase() const;
214 * Check whether this mode handler inherits from ParamModeBase
215 * @return non-NULL if this mode handler inherits from ParamModeBase, NULL otherwise
217 ParamModeBase* IsParameterMode();
220 * Check whether this mode handler inherits from ParamModeBase
221 * @return non-NULL if this mode handler inherits from ParamModeBase, NULL otherwise
223 const ParamModeBase* IsParameterMode() const;
226 * Returns the mode's type
228 inline ModeType GetModeType() const { return m_type; }
230 * Returns true if the mode can only be set/unset by an oper
232 inline bool NeedsOper() const { return oper; }
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
238 bool NeedsParam(bool adding) const;
240 * Returns the mode character this handler handles.
241 * @return The mode character
243 char GetModeChar() const { return mode; }
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.
248 Id GetId() const { return modeid; }
250 /** For user modes, return the current parameter, if any
252 virtual std::string GetUserParameter(const User* user) const;
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
262 virtual ModResult AccessCheck(User* source, Channel* channel, std::string ¶meter, bool adding);
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
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'.
276 virtual ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding); /* Can change the mode parameter as its a ref */
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)
284 virtual void DisplayList(User* user, Channel* channel);
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.
292 virtual void OnParameterMissing(User* user, User* dest, Channel* channel);
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.
300 virtual void OnParameterInvalid(User* user, Channel* targetchannel, User* targetuser, const std::string& parameter);
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)
308 virtual void DisplayEmptyList(User* user, Channel* channel);
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.
320 virtual bool ResolveModeConflict(std::string &their_param, const std::string &our_param, Channel* channel);
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
327 void RemoveMode(User* user);
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
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
339 virtual void RemoveMode(Channel* channel, Modes::ChangeList& changelist);
341 /** Retrieves the level required to modify this mode.
342 * @param adding Whether the mode is being added or removed.
344 inline unsigned int GetLevelRequired(bool adding) const
346 return adding ? ranktoset : ranktounset;
349 /** Retrieves the syntax of the parameter for this mode. */
350 const std::string& GetSyntax() const { return syntax; }
352 friend class ModeParser;
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.
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.
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.
369 class CoreExport PrefixMode : public ModeHandler
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.
377 /** The prefix rank of this mode, used to compare prefix
380 unsigned int prefixrank;
382 /** Whether a client with this prefix can remove it from themself. */
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
394 PrefixMode(Module* Creator, const std::string& Name, char ModeLetter, unsigned int Rank = 0, char PrefixChar = 0);
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
404 ModResult AccessCheck(User* source, Channel* channel, std::string ¶meter, bool adding) CXX11_OVERRIDE;
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
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).
419 ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& param, bool adding) CXX11_OVERRIDE;
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.
428 void Update(unsigned int rank, unsigned int setrank, unsigned int unsetrank, bool selfrm);
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
435 void RemoveMode(Channel* channel, Modes::ChangeList& changelist) CXX11_OVERRIDE;
439 * Determines whether a user with this prefix mode can remove it.
441 bool CanSelfRemove() const { return selfremove; }
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.
448 char GetPrefix() const { return prefix; }
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
457 unsigned int GetPrefixRank() const { return prefixrank; }
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.
465 class CoreExport SimpleUserModeHandler : public ModeHandler
468 SimpleUserModeHandler(Module* Creator, const std::string& Name, char modeletter, bool operonly = false)
469 : ModeHandler(Creator, Name, modeletter, PARAM_NONE, MODETYPE_USER)
474 ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE;
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.
482 class CoreExport SimpleChannelModeHandler : public ModeHandler
485 SimpleChannelModeHandler(Module* Creator, const std::string& Name, char modeletter, bool operonly = false)
486 : ModeHandler(Creator, Name, modeletter, PARAM_NONE, MODETYPE_CHANNEL)
491 ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE;
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.
500 class CoreExport ModeWatcher : public classbase
504 * The mode name this class is watching
506 const std::string mode;
509 * The mode type being watched (user or channel)
516 * The constructor initializes the mode and the mode type
518 ModeWatcher(Module* creator, const std::string& modename, ModeType type);
520 * The default destructor does nothing.
522 virtual ~ModeWatcher();
525 * Get the mode name being watched
526 * @return The mode name being watched
528 const std::string& GetModeName() const { return mode; }
531 * Get the mode type being watched
532 * @return The mode type being watched (user or channel)
534 ModeType GetModeType() const { return m_type; }
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 atered 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.
548 virtual bool BeforeMode(User* source, User* dest, Channel* channel, std::string& parameter, bool adding);
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
558 virtual void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding);
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.
566 class CoreExport ModeParser : public fakederef<ModeParser>
569 /** The maximum number of modes which can be created. */
570 static const ModeHandler::Id MODEID_MAX = 64;
572 /** The maximum length of a mode parameter. */
573 static const size_t MODE_PARAM_MAX = 250;
575 /** Type of the container that maps mode names to ModeHandlers
577 typedef TR1NS::unordered_map<std::string, ModeHandler*, irc::insensitive, irc::StrHashComp> ModeHandlerMap;
580 /** Type of the container that maps mode names to ModeWatchers
582 typedef insp::flat_multimap<std::string, ModeWatcher*> ModeWatcherMap;
584 /** Last item in the ModeType enum
586 static const unsigned int MODETYPE_LAST = 2;
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.
593 ModeHandler* modehandlers[MODETYPE_LAST][128];
595 /** An array of mode handlers indexed by the mode id
597 ModeHandler* modehandlersbyid[MODETYPE_LAST][MODEID_MAX];
599 /** A map of mode handlers keyed by their name
601 ModeHandlerMap modehandlersbyname[MODETYPE_LAST];
603 /** Lists of mode handlers by type
607 /** List of mode handlers that inherit from ListModeBase
609 std::vector<ListModeBase*> list;
611 /** List of mode handlers that inherit from PrefixMode
613 std::vector<PrefixMode*> prefix;
616 /** Mode watcher classes
618 ModeWatcherMap modewatchermap;
620 /** Last processed mode change
622 Modes::ChangeList LastChangeList;
625 * Attempts to apply a mode change to a user or channel
627 ModeAction TryMode(User* user, User* targu, Channel* targc, Modes::Change& mcitem, bool SkipACL);
629 /** Allocates an unused id for the given mode type, throws a ModuleException if out of ids.
630 * @param mt The type of the mode to allocate the id for
633 ModeHandler::Id AllocateModeId(ModeType mt);
636 typedef std::vector<ListModeBase*> ListModeList;
637 typedef std::vector<PrefixMode*> PrefixModeList;
639 typedef unsigned int ModeProcessFlag;
640 enum ModeProcessFlags
642 /** If only this flag is specified, the mode change will be global
643 * and parameter modes will have their parameters explicitly set
644 * (not merged). This is the default.
648 /** If this flag is set then the parameters of non-listmodes will be
649 * merged according to their conflict resolution rules.
650 * Does not affect user modes, channel modes without a parameter and
655 /** If this flag is set then the linking module will ignore the mode change
656 * and not send it to other servers. The mode change will be processed
657 * locally and sent to local user(s) as usual.
661 /** If this flag is set then the mode change will be subject to access checks.
662 * For more information see the documentation of the PrefixMode class,
663 * ModeHandler::ranktoset and ModeHandler::AccessCheck().
664 * Modules may explicitly allow a mode change regardless of this flag by returning
665 * MOD_RES_ALLOW from the OnPreMode hook. Only affects channel mode changes.
673 static bool IsModeChar(char chr);
675 /** Tidy a banmask. This makes a banmask 'acceptable' if fields are left out.
680 * nick!ident -> nick!ident@*
682 * host.name -> *!*\@host.name
684 * ident@host.name -> *!ident\@host.name
686 * This method can be used on both IPV4 and IPV6 user masks.
688 static void CleanMask(std::string &mask);
690 /** Gets the last mode change to be processed. */
691 const Modes::ChangeList& GetLastChangeList() const { return LastChangeList; }
693 /** Add a mode to the mode parser.
694 * Throws a ModuleException if the mode cannot be added.
696 void AddMode(ModeHandler* mh);
698 /** Delete a mode from the mode parser.
699 * When a mode is deleted, the mode handler will be called
700 * for every user (if it is a user mode) or for every channel
701 * (if it is a channel mode) to unset the mode on all objects.
702 * This prevents modes staying in the system which no longer exist.
703 * @param mh The mode handler to remove
704 * @return True if the mode was successfully removed.
706 bool DelMode(ModeHandler* mh);
708 /** Add a mode watcher.
709 * A mode watcher is triggered before and after a mode handler is
710 * triggered. See the documentation of class ModeWatcher for more
712 * @param mw The ModeWatcher you want to add
714 void AddModeWatcher(ModeWatcher* mw);
716 /** Delete a mode watcher.
717 * A mode watcher is triggered before and after a mode handler is
718 * triggered. See the documentation of class ModeWatcher for more
720 * @param mw The ModeWatcher you want to delete
721 * @return True if the ModeWatcher was deleted correctly
723 bool DelModeWatcher(ModeWatcher* mw);
725 /** Process a list of mode changes entirely. If the mode changes do not fit into one MODE line
726 * then multiple MODE lines are generated.
727 * @param user The source of the mode change, can be a server user.
728 * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel.
729 * @param targetuser User to apply the mode change on. NULL if changing modes on a user.
730 * @param changelist Modes to change in form of a Modes::ChangeList.
731 * @param flags Optional flags controlling how the mode change is processed,
732 * defaults to MODE_NONE.
734 void Process(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE);
736 /** Process a single MODE line's worth of mode changes, taking max modes and line length limits
737 * into consideration. Return value indicates how many modes were processed.
738 * @param user The source of the mode change, can be a server user.
739 * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel.
740 * @param targetuser User to apply the mode change on. NULL if changing modes on a user.
741 * @param changelist Modes to change in form of a Modes::ChangeList. May not process
742 * the entire list due to MODE line length and max modes limitations.
743 * @param flags Optional flags controlling how the mode change is processed,
744 * defaults to MODE_NONE.
745 * @param beginindex Index of the first element in changelist to process. Mode changes before
746 * the element with this index are ignored.
747 * @return Number of mode changes processed from changelist.
749 unsigned int ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE, unsigned int beginindex = 0);
751 /** Turn a list of parameters compatible with the format of the MODE command into
752 * Modes::ChangeList form. All modes are processed, regardless of max modes. Unknown modes
754 * @param user The source of the mode change, can be a server user. Error numerics are sent to
756 * @param type MODETYPE_USER if this is a user mode change or MODETYPE_CHANNEL if this
757 * is a channel mode change.
758 * @param parameters List of strings describing the mode change to convert to a ChangeList.
759 * Must be using the same format as the parameters of a MODE command.
760 * @param changelist ChangeList object to populate.
761 * @param beginindex Index of the first element that is part of the MODE list in the parameters
762 * container. Defaults to 1.
763 * @param endindex Index of the first element that is not part of the MODE list. By default,
764 * the entire container is considered part of the MODE list.
766 void ModeParamsToChangeList(User* user, ModeType type, const std::vector<std::string>& parameters, Modes::ChangeList& changelist, unsigned int beginindex = 1, unsigned int endindex = UINT_MAX);
768 /** Find the mode handler for a given mode name and type.
769 * @param modename The mode name to search for.
770 * @param mt Type of mode to search for, user or channel.
771 * @return A pointer to a ModeHandler class, or NULL of there isn't a handler for the given mode name.
773 ModeHandler* FindMode(const std::string& modename, ModeType mt);
775 /** Find the mode handler for a given mode and type.
776 * @param modeletter mode letter to search for
777 * @param mt type of mode to search for, user or channel
778 * @returns a pointer to a ModeHandler class, or NULL of there isn't a handler for the given mode
780 ModeHandler* FindMode(unsigned const char modeletter, ModeType mt);
782 /** Find the mode handler for the given prefix mode
783 * @param modeletter The mode letter to search for
784 * @return A pointer to the PrefixMode or NULL if the mode wasn't found or it isn't a prefix mode
786 PrefixMode* FindPrefixMode(unsigned char modeletter);
788 /** Find a mode handler by its prefix.
789 * If there is no mode handler with the given prefix, NULL will be returned.
790 * @param pfxletter The prefix to find, e.g. '@'
791 * @return The mode handler which handles this prefix, or NULL if there is none.
793 PrefixMode* FindPrefix(unsigned const char pfxletter);
795 /** Generates a list of modes, comma separated by type:
796 * 1; Listmodes EXCEPT those with a prefix
797 * 2; Modes that take a param when adding or removing
798 * 3; Modes that only take a param when adding
799 * 4; Modes that dont take a param
801 std::string GiveModeList(ModeType mt);
803 /** This returns the PREFIX=(ohv)@%+ section of the 005 numeric, or
804 * just the "@%+" part if the parameter false
806 std::string BuildPrefixes(bool lettersAndModes = true);
808 /** Get a list of all mode handlers that inherit from ListModeBase
809 * @return A list containing ListModeBase modes
811 const ListModeList& GetListModes() const { return mhlist.list; }
813 /** Get a list of all prefix modes
814 * @return A list containing all prefix modes
816 const PrefixModeList& GetPrefixModes() const { return mhlist.prefix; }
818 /** Get a mode name -> ModeHandler* map containing all modes of the given type
819 * @param mt Type of modes to return, MODETYPE_USER or MODETYPE_CHANNEL
820 * @return A map of mode handlers of the given type
822 const ModeHandlerMap& GetModes(ModeType mt) const { return modehandlersbyname[mt]; }
824 /** Show the list of a list mode to a user. Modules can deny the listing.
825 * @param user User to show the list to.
826 * @param chan Channel to show the list of.
827 * @param mh List mode to show the list of.
829 void ShowListModeList(User* user, Channel* chan, ModeHandler* mh);
832 inline PrefixMode* ModeHandler::IsPrefixMode()
834 return (this->type_id == MC_PREFIX ? static_cast<PrefixMode*>(this) : NULL);
837 inline const PrefixMode* ModeHandler::IsPrefixMode() const
839 return (this->type_id == MC_PREFIX ? static_cast<const PrefixMode*>(this) : NULL);
842 inline ListModeBase* ModeHandler::IsListModeBase()
844 return (this->type_id == MC_LIST ? reinterpret_cast<ListModeBase*>(this) : NULL);
847 inline const ListModeBase* ModeHandler::IsListModeBase() const
849 return (this->type_id == MC_LIST ? reinterpret_cast<const ListModeBase*>(this) : NULL);
852 inline ParamModeBase* ModeHandler::IsParameterMode()
854 return (this->type_id == MC_PARAM ? reinterpret_cast<ParamModeBase*>(this) : NULL);
857 inline const ParamModeBase* ModeHandler::IsParameterMode() const
859 return (this->type_id == MC_PARAM ? reinterpret_cast<const ParamModeBase*>(this) : NULL);