summaryrefslogtreecommitdiff
path: root/include/mode.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/mode.h')
-rw-r--r--include/mode.h161
1 files changed, 100 insertions, 61 deletions
diff --git a/include/mode.h b/include/mode.h
index 1dab442d4..9b8d07877 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -20,8 +20,7 @@
*/
-#ifndef MODE_H
-#define MODE_H
+#pragma once
#include "ctables.h"
@@ -101,6 +100,13 @@ enum ParamSpec
*/
class CoreExport ModeHandler : public ServiceProvider
{
+ /**
+ * Removes this prefix mode from all users on the given channel
+ * @param channel The channel which the server wants to remove your mode from
+ * @param stack The mode stack to add the mode change to
+ */
+ void RemovePrefixMode(Channel* chan, irc::modestacker& stack);
+
protected:
/**
* The mode parameter translation type
@@ -149,6 +155,11 @@ class CoreExport ModeHandler : public ServiceProvider
*/
int levelrequired;
+ /** The prefix rank of this mode, used to compare prefix
+ * modes
+ */
+ unsigned int prefixrank;
+
public:
/**
* The constructor for ModeHandler initalizes the mode handler.
@@ -166,7 +177,7 @@ class CoreExport ModeHandler : public ServiceProvider
/**
* Returns true if the mode is a list mode
*/
- bool IsListMode();
+ bool IsListMode() const { return list; }
/**
* Mode prefix or 0. If this is defined, you should
* also implement GetPrefixRank() to return an integer
@@ -180,7 +191,7 @@ class CoreExport ModeHandler : public ServiceProvider
* PrefixModeValue enum and Channel::GetPrefixValue() for
* more information.
*/
- virtual unsigned int GetPrefixRank();
+ unsigned int GetPrefixRank() const { return prefixrank; }
/**
* Returns the mode's type
*/
@@ -269,26 +280,23 @@ class CoreExport ModeHandler : public ServiceProvider
virtual bool ResolveModeConflict(std::string &their_param, const std::string &our_param, Channel* channel);
/**
- * When a MODETYPE_USER mode handler is being removed, the server will call this method for every user on the server.
- * Your mode handler should remove its user mode from the user by sending the appropriate server modes using
- * InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters,
- * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove
- * your mode properly from each user.
+ * When a MODETYPE_USER mode handler is being removed, the core will call this method for every user on the server.
+ * The usermode will be removed using the appropiate server mode using InspIRCd::SendMode().
* @param user The user which the server wants to remove your mode from
- * @param stack The mode stack to add the mode change to
*/
- virtual void RemoveMode(User* user, irc::modestacker* stack = NULL);
+ void RemoveMode(User* user);
/**
* When a MODETYPE_CHANNEL mode handler is being removed, the server will call this method for every channel on the server.
- * Your mode handler should remove its user mode from the channel by sending the appropriate server modes using
- * InspIRCd::SendMode(). The default implementation of this method can remove simple modes which have no parameters,
- * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove
- * your mode properly from each channel. Note that in the case of listmodes, you should remove the entire list of items.
+ * The mode handler has to populate the given modestacker with mode changes that remove the mode from the channel.
+ * The default implementation of this method can remove all kinds of channel modes except listmodes.
+ * In the case of listmodes, the entire list of items must be added to the modestacker (which is handled by ListModeBase,
+ * so if you inherit from it or your mode can be removed by the default implementation then you do not have to implement
+ * this function).
* @param channel The channel which the server wants to remove your mode from
* @param stack The mode stack to add the mode change to
*/
- virtual void RemoveMode(Channel* channel, irc::modestacker* stack = NULL);
+ virtual void RemoveMode(Channel* channel, irc::modestacker& stack);
inline unsigned int GetLevelRequired() const { return levelrequired; }
};
@@ -339,11 +347,12 @@ class CoreExport ParamChannelModeHandler : public ModeHandler
*/
class CoreExport ModeWatcher : public classbase
{
- protected:
+ private:
/**
- * The mode letter this class is watching
+ * The mode name this class is watching
*/
- char mode;
+ const std::string mode;
+
/**
* The mode type being watched (user or channel)
*/
@@ -354,17 +363,18 @@ class CoreExport ModeWatcher : public classbase
/**
* The constructor initializes the mode and the mode type
*/
- ModeWatcher(Module* creator, char modeletter, ModeType type);
+ ModeWatcher(Module* creator, const std::string& modename, ModeType type);
/**
* The default destructor does nothing.
*/
virtual ~ModeWatcher();
/**
- * Get the mode character being watched
- * @return The mode character being watched
+ * Get the mode name being watched
+ * @return The mode name being watched
*/
- char GetModeChar();
+ const std::string& GetModeName() const { return mode; }
+
/**
* Get the mode type being watched
* @return The mode type being watched (user or channel)
@@ -380,11 +390,10 @@ class CoreExport ModeWatcher : public classbase
* If you alter the parameter you are given, the mode handler will see your atered version
* when it handles the mode.
* @param adding True if the mode is being added and false if it is being removed
- * @param type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL
* @return True to allow the mode change to go ahead, false to abort it. If you abort the
* change, the mode handler (and ModeWatcher::AfterMode()) will never see the mode change.
*/
- virtual bool BeforeMode(User* source, User* dest, Channel* channel, std::string &parameter, bool adding, ModeType type);
+ virtual bool BeforeMode(User* source, User* dest, Channel* channel, std::string& parameter, bool adding);
/**
* After the mode character has been processed by the ModeHandler, this method will be called.
* @param source The sender of the mode
@@ -393,12 +402,11 @@ class CoreExport ModeWatcher : public classbase
* @param parameter The parameter of the mode, if the mode is supposed to have a parameter.
* You cannot alter the parameter here, as the mode handler has already processed it.
* @param adding True if the mode is being added and false if it is being removed
- * @param type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL
*/
- virtual void AfterMode(User* source, User* dest, Channel* channel, const std::string &parameter, bool adding, ModeType type);
+ virtual void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding);
};
-typedef std::vector<ModeWatcher*>::iterator ModeWatchIter;
+typedef std::multimap<std::string, ModeWatcher*>::iterator ModeWatchIter;
/** The mode parser handles routing of modes and handling of mode strings.
* It marshalls, controls and maintains both ModeWatcher and ModeHandler classes,
@@ -414,11 +422,11 @@ class CoreExport ModeParser
* or a channel mode, so we have 256 of them not 64.
*/
ModeHandler* modehandlers[256];
- /** Mode watcher classes arranged in the same way as the
- * mode handlers, except for instead of having 256 of them
- * we have 256 lists of them.
+
+ /** Mode watcher classes
*/
- std::vector<ModeWatcher*> modewatchers[256];
+ std::multimap<std::string, ModeWatcher*> modewatchermap;
+
/** Displays the current modes of a channel or user.
* Used by ModeParser::Process.
*/
@@ -433,6 +441,20 @@ class CoreExport ModeParser
*/
ModeAction TryMode(User* user, User* targu, Channel* targc, bool adding, unsigned char mode, std::string &param, bool SkipACL);
+ /** Returns a list of user or channel mode characters.
+ * Used for constructing the parts of the mode list in the 004 numeric.
+ * @param mt Controls whether to list user modes or channel modes
+ * @param needparam Return modes only if they require a parameter to be set
+ * @return The available mode letters that satisfy the given conditions
+ */
+ std::string CreateModeList(ModeType mt, bool needparam = false);
+
+ /** Recreate the cached mode list that is displayed in the 004 numeric
+ * in Cached004ModeList.
+ * Called when a mode handler is added or removed.
+ */
+ void RecreateModeListFor004Numeric();
+
/** The string representing the last set of modes to be parsed.
* Use GetLastParse() to get this value, to be used for display purposes.
*/
@@ -444,17 +466,41 @@ class CoreExport ModeParser
unsigned int seq;
+ /** Cached mode list for use in 004 numeric
+ */
+ std::string Cached004ModeList;
+
public:
+ typedef unsigned int ModeProcessFlag;
+ enum ModeProcessFlags
+ {
+ /** If only this flag is specified, the mode change will be global
+ * and parameter modes will have their parameters explicitly set
+ * (not merged). This is the default.
+ */
+ MODE_NONE = 0,
+
+ /** If this flag is set then the parameters of non-listmodes will be
+ * merged according to their conflict resolution rules.
+ * Does not affect user modes, channel modes without a parameter and
+ * listmodes.
+ */
+ MODE_MERGE = 1,
+
+ /** If this flag is set then the mode change won't be handed over to
+ * the linking module to be sent to other servers, but will be processed
+ * locally and sent to local user(s) as usual.
+ */
+ MODE_LOCALONLY = 2
+ };
- /** The constructor initializes all the RFC basic modes by using ModeParserAddMode().
- */
ModeParser();
~ModeParser();
- /** Used to check if user 'd' should be allowed to do operation 'MASK' on channel 'chan'.
- * for example, should 'user A' be able to 'op' on 'channel B'.
+ /** Initialize all built-in modes
*/
- User* SanityChecks(User *user,const char *dest,Channel *chan,int status);
+ static void InitBuiltinModes();
+
/** Tidy a banmask. This makes a banmask 'acceptable' if fields are left out.
* E.g.
*
@@ -474,7 +520,7 @@ class CoreExport ModeParser
* may be different to what you sent after it has been 'cleaned up' by the parser.
* @return Last parsed string, as seen by users.
*/
- const std::string& GetLastParse();
+ const std::string& GetLastParse() const { return LastParse; }
const std::vector<std::string>& GetLastParseParams() { return LastParseParams; }
const std::vector<TranslateType>& GetLastParseTranslate() { return LastParseTranslate; }
/** Add a mode to the mode parser.
@@ -496,9 +542,9 @@ class CoreExport ModeParser
* triggered. See the documentation of class ModeWatcher for more
* information.
* @param mw The ModeWatcher you want to add
- * @return True if the ModeWatcher was added correctly
*/
- bool AddModeWatcher(ModeWatcher* mw);
+ void AddModeWatcher(ModeWatcher* mw);
+
/** Delete a mode watcher.
* A mode watcher is triggered before and after a mode handler is
* triggered. See the documentation of class ModeWatcher for more
@@ -510,12 +556,11 @@ class CoreExport ModeParser
/** Process a set of mode changes from a server or user.
* @param parameters The parameters of the mode change, in the format
* they would be from a MODE command.
- * @param user The user setting or removing the modes. When the modes are set
- * by a server, an 'uninitialized' User is used, where *user\::nick == NULL
- * and *user->server == NULL.
- * @param merge Should the mode parameters be merged?
+ * @param user The source of the mode change, can be a server user.
+ * @param flags Optional flags controlling how the mode change is processed,
+ * defaults to MODE_NONE.
*/
- void Process(const std::vector<std::string>& parameters, User *user, bool merge = false);
+ void Process(const std::vector<std::string>& parameters, User* user, ModeProcessFlag flags = MODE_NONE);
/** Find the mode handler for a given mode and type.
* @param modeletter mode letter to search for
@@ -531,20 +576,13 @@ class CoreExport ModeParser
*/
ModeHandler* FindPrefix(unsigned const char pfxletter);
- /** Returns a list of mode characters which are usermodes.
- * This is used in the 004 numeric when users connect.
- */
- std::string UserModeList();
-
- /** Returns a list of channel mode characters which are listmodes.
- * This is used in the 004 numeric when users connect.
+ /** Returns a list of modes, space seperated by type:
+ * 1. User modes
+ * 2. Channel modes
+ * 3. Channel modes that require a parameter when set
+ * This is sent to users as the last part of the 004 numeric
*/
- std::string ChannelModeList();
-
- /** Returns a list of channel mode characters which take parameters.
- * This is used in the 004 numeric when users connect.
- */
- std::string ParaModeList();
+ const std::string& GetModeListFor004Numeric();
/** Generates a list of modes, comma seperated by type:
* 1; Listmodes EXCEPT those with a prefix
@@ -554,12 +592,13 @@ class CoreExport ModeParser
*/
std::string GiveModeList(ModeMasks m);
- static bool PrefixComparison(ModeHandler* one, ModeHandler* two);
-
/** This returns the PREFIX=(ohv)@%+ section of the 005 numeric, or
* just the "@%+" part if the parameter false
*/
std::string BuildPrefixes(bool lettersAndModes = true);
};
-#endif
+inline const std::string& ModeParser::GetModeListFor004Numeric()
+{
+ return Cached004ModeList;
+}