X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=include%2Fmode.h;h=2833d75a2cd8504c19661ea8c5f02bb9f1e81f6f;hb=3d958279c6c4d352132ea50836a2b7b1d3be5434;hp=3193af65f1d8832c913aaf291b65debb03d2d758;hpb=0556720b559d7ec5d8badacf0ac9b11e9c864847;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/mode.h b/include/mode.h index 3193af65f..2833d75a2 100644 --- a/include/mode.h +++ b/include/mode.h @@ -23,6 +23,7 @@ #pragma once #include "ctables.h" +#include "modechange.h" /** * Holds the values for different type of modes @@ -45,17 +46,6 @@ enum ModeAction MODEACTION_ALLOW = 1 /* Allow the mode */ }; -/** - * Used to mask off the mode types in the mode handler - * array. Used in a simple two instruction hashing function - * "(modeletter - 65) OR mask" - */ -enum ModeMasks -{ - MASK_USER = 128, /* A user mode */ - MASK_CHANNEL = 0 /* A channel mode */ -}; - /** * These fixed values can be used to proportionally compare module-defined prefixes to known values. * For example, if your module queries a Channel, and is told that user 'joebloggs' has the prefix @@ -105,6 +95,8 @@ class ParamModeBase; class CoreExport ModeHandler : public ServiceProvider { public: + typedef size_t Id; + enum Class { MC_PREFIX, @@ -113,12 +105,12 @@ class CoreExport ModeHandler : public ServiceProvider MC_OTHER }; - protected: - /** - * The mode parameter translation type + private: + /** The opaque id of this mode assigned by the mode parser */ - TranslateType m_paramtype; + Id modeid; + protected: /** What kind of parameters does the mode take? */ ParamSpec parameters_taken; @@ -203,10 +195,6 @@ class CoreExport ModeHandler : public ServiceProvider * Returns the mode's type */ inline ModeType GetModeType() const { return m_type; } - /** - * Returns the mode's parameter translation type - */ - inline TranslateType GetTranslateType() const { return m_paramtype; } /** * Returns true if the mode can only be set/unset by an oper */ @@ -224,6 +212,11 @@ class CoreExport ModeHandler : public ServiceProvider */ inline char GetModeChar() { return mode; } + /** Return the id of this mode which is used in User::modes and + * Channel::modes as the index to determine whether a mode is set. + */ + Id GetId() const { return modeid; } + /** For user modes, return the current parameter, if any */ virtual std::string GetUserParameter(User* useor); @@ -306,6 +299,8 @@ class CoreExport ModeHandler : public ServiceProvider virtual void RemoveMode(Channel* channel, irc::modestacker& stack); inline unsigned int GetLevelRequired() const { return levelrequired; } + + friend class ModeParser; }; /** @@ -341,8 +336,10 @@ class CoreExport PrefixMode : public ModeHandler * @param Creator The module creating this mode * @param Name The user-friendly one word name of the prefix mode, e.g.: "op", "voice" * @param ModeLetter The mode letter of this mode + * @param Rank Rank given by this prefix mode, see explanation above + * @param PrefixChar Prefix character, or 0 if the mode has no prefix character */ - PrefixMode(Module* Creator, const std::string& Name, char ModeLetter); + PrefixMode(Module* Creator, const std::string& Name, char ModeLetter, unsigned int Rank = 0, char PrefixChar = 0); /** * Handles setting and unsetting the prefix mode. @@ -483,15 +480,34 @@ typedef std::multimap::iterator ModeWatchIter; * parses client to server MODE strings for user and channel modes, and performs * processing for the 004 mode list numeric, amongst other things. */ -class CoreExport ModeParser +class CoreExport ModeParser : public fakederef { + public: + static const ModeHandler::Id MODEID_MAX = 64; + + /** Type of the container that maps mode names to ModeHandlers + */ + typedef TR1NS::unordered_map ModeHandlerMap; + private: + /** Last item in the ModeType enum + */ + static const unsigned int MODETYPE_LAST = 2; + /** Mode handlers for each mode, to access a handler subtract * 65 from the ascii value of the mode letter. * The upper bit of the value indicates if its a usermode * or a channel mode, so we have 256 of them not 64. */ - ModeHandler* modehandlers[256]; + ModeHandler* modehandlers[MODETYPE_LAST][128]; + + /** An array of mode handlers indexed by the mode id + */ + ModeHandler* modehandlersbyid[MODETYPE_LAST][MODEID_MAX]; + + /** A map of mode handlers keyed by their name + */ + ModeHandlerMap modehandlersbyname[MODETYPE_LAST]; /** Lists of mode handlers by type */ @@ -510,6 +526,10 @@ class CoreExport ModeParser */ std::multimap modewatchermap; + /** Last processed mode change + */ + Modes::ChangeList LastChangeList; + /** Displays the current modes of a channel or user. * Used by ModeParser::Process. */ @@ -517,12 +537,12 @@ class CoreExport ModeParser /** Displays the value of a list mode * Used by ModeParser::Process. */ - void DisplayListModes(User* user, Channel* chan, std::string &mode_sequence); + void DisplayListModes(User* user, Channel* chan, const std::string& mode_sequence); /** * Attempts to apply a mode change to a user or channel */ - ModeAction TryMode(User* user, User* targu, Channel* targc, bool adding, unsigned char mode, std::string ¶m, bool SkipACL); + ModeAction TryMode(User* user, User* targu, Channel* targc, Modes::Change& mcitem, bool SkipACL); /** Returns a list of user or channel mode characters. * Used for constructing the parts of the mode list in the 004 numeric. @@ -538,12 +558,16 @@ class CoreExport ModeParser */ void RecreateModeListFor004Numeric(); + /** Allocates an unused id for the given mode type, throws a ModuleException if out of ids. + * @param mt The type of the mode to allocate the id for + * @return The id + */ + ModeHandler::Id AllocateModeId(ModeType mt); + /** The string representing the last set of modes to be parsed. * Use GetLastParse() to get this value, to be used for display purposes. */ std::string LastParse; - std::vector LastParseParams; - std::vector LastParseTranslate; unsigned int sent[256]; @@ -573,11 +597,19 @@ class CoreExport ModeParser */ 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 + /** If this flag is set then the linking module will ignore the mode change + * and not send it to other servers. The mode change will be processed * locally and sent to local user(s) as usual. */ - MODE_LOCALONLY = 2 + MODE_LOCALONLY = 2, + + /** If this flag is set then the mode change will be subject to access checks. + * For more information see the documentation of the PrefixMode class, + * ModeHandler::levelrequired and ModeHandler::AccessCheck(). + * Modules may explicitly allow a mode change regardless of this flag by returning + * MOD_RES_ALLOW from the OnPreMode hook. Only affects channel mode changes. + */ + MODE_CHECKACCESS = 4 }; ModeParser(); @@ -607,12 +639,12 @@ class CoreExport ModeParser * @return Last parsed string, as seen by users. */ const std::string& GetLastParse() const { return LastParse; } - const std::vector& GetLastParseParams() { return LastParseParams; } - const std::vector& GetLastParseTranslate() { return LastParseTranslate; } + /** Add a mode to the mode parser. - * @return True if the mode was successfully added. + * Throws a ModuleException if the mode cannot be added. */ - bool AddMode(ModeHandler* mh); + void AddMode(ModeHandler* mh); + /** Delete a mode from the mode parser. * When a mode is deleted, the mode handler will be called * for every user (if it is a user mode) or for every channel @@ -648,6 +680,25 @@ class CoreExport ModeParser */ void Process(const std::vector& parameters, User* user, ModeProcessFlag flags = MODE_NONE); + /** Process a single MODE line's worth of mode changes, taking max modes and line length limits + * into consideration. + * @param user The source of the mode change, can be a server user. + * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel. + * @param targetuser User to apply the mode change on. NULL if changing modes on a user. + * @param changelist Modes to change in form of a Modes::ChangeList. May not process + * the entire list due to MODE line length and max modes limitations. + * @param flags Optional flags controlling how the mode change is processed, + * defaults to MODE_NONE. + */ + void ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE); + + /** Find the mode handler for a given mode name and type. + * @param modename The mode name to search for. + * @param mt Type of mode to search for, user or channel. + * @return A pointer to a ModeHandler class, or NULL of there isn't a handler for the given mode name. + */ + ModeHandler* FindMode(const std::string& modename, ModeType mt); + /** Find the mode handler for a given mode and type. * @param modeletter mode letter to search for * @param mt type of mode to search for, user or channel @@ -682,7 +733,7 @@ class CoreExport ModeParser * 3; Modes that only take a param when adding * 4; Modes that dont take a param */ - std::string GiveModeList(ModeMasks m); + std::string GiveModeList(ModeType mt); /** This returns the PREFIX=(ohv)@%+ section of the 005 numeric, or * just the "@%+" part if the parameter false @@ -698,6 +749,12 @@ class CoreExport ModeParser * @return A list containing all prefix modes */ const PrefixModeList& GetPrefixModes() const { return mhlist.prefix; } + + /** Get a mode name -> ModeHandler* map containing all modes of the given type + * @param mt Type of modes to return, MODETYPE_USER or MODETYPE_CHANNEL + * @return A map of mode handlers of the given type + */ + const ModeHandlerMap& GetModes(ModeType mt) const { return modehandlersbyname[mt]; } }; inline const std::string& ModeParser::GetModeListFor004Numeric()