]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/modules.h
MetaData rework
[user/henk/code/inspircd.git] / include / modules.h
index 1761b1b5485f7f12f26f18e691afc4f8b6cc46ff..e67f287c889d973542a671781135cd371089489f 100644 (file)
@@ -76,18 +76,33 @@ enum MessageType {
        MSG_NOTICE = 1
 };
 
-/** If you change the module API, change this value.
- * If you have enabled ipv6, the sizes of structs is
- * different, and modules will be incompatible with
- * ipv4 servers, so this value will be ten times as
- * high on ipv6 servers.
+/** Used to represent an allow/deny module result.
+ * Not constructed as an enum because it reverses the value logic of some functions;
+ * the compiler will inline accesses to have the same efficiency as integer operations.
  */
-#define NATIVE_API_VERSION 12000
-#ifdef IPV6
-#define API_VERSION (NATIVE_API_VERSION * 10)
-#else
-#define API_VERSION (NATIVE_API_VERSION * 1)
-#endif
+struct ModResult {
+       int res;
+       explicit ModResult(int r) : res(r) {}
+       bool operator==(const ModResult& r) const
+       {
+               return res == r.res;
+       }
+       bool operator!=(const ModResult& r) const
+       {
+               return res != r.res;
+       }
+       bool operator!() const
+       {
+               return !res;
+       }
+};
+
+#define MOD_RES_ALLOW (ModResult(1))
+#define MOD_RES_PASSTHRU (ModResult(0))
+#define MOD_RES_DENY (ModResult(-1))
+
+/** If you change the module API, change this value. */
+#define API_VERSION 13000
 
 class ServerConfig;
 
@@ -223,25 +238,42 @@ do { \
        } \
 } while (0);
 
-#define FOREACH_RESULT_MAP(y,x,f) \
+/**
+ * Custom module result handling loop. This is a paired macro, and should only
+ * be used with while_each_hook.
+ *
+ * See src/channels.cpp for an example of use.
+ */
+#define DO_EACH_HOOK(z,n,v,args) \
 do { \
-       EventHandlerIter safei; \
-       for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ) \
+       EventHandlerIter iter_ ## n = z->Modules->EventHandlers[I_ ## n].begin(); \
+       while (iter_ ## n != z->Modules->EventHandlers[I_ ## n].end()) \
        { \
-               safei = _i; \
-               ++safei; \
+               Module* mod_ ## n = *iter_ ## n; \
+               iter_ ## n ++; \
                try \
                { \
-                       int MOD_RESULT = (*_i)->x ; \
-                       f; \
+                       v = (mod_ ## n)->n args;
+
+#define WHILE_EACH_HOOK(z,n) \
                } \
-               catch (CoreException& modexcept) \
+               catch (CoreException& except_ ## n) \
                { \
-                       ServerInstance->Logs->Log("MODULE",DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
+                       z->Logs->Log("MODULE",DEFAULT,"Exception caught: %s", (except_ ## n).GetReason()); \
+                       (void) mod_ ## n; /* catch mismatched pairs */ \
                } \
-               _i = safei; \
        } \
-} while(0);
+} while(0)
+
+#define FIRST_MOD_RESULT(z,n,v,args) do { \
+       v = MOD_RES_PASSTHRU; \
+       DO_EACH_HOOK(z,n,v,args) \
+       { \
+               if (v != MOD_RES_PASSTHRU) \
+                       break; \
+       } \
+       WHILE_EACH_HOOK(z,n); \
+} while (0)
 
 /** Represents a non-local user.
  * (in fact, any FD less than -1 does)
@@ -413,20 +445,23 @@ enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFOR
 enum Implementation
 {
        I_BEGIN,
-       I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash, I_OnSendSnotice,
-       I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo, I_OnWhois, I_OnUserPreInvite,
-       I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserPreNick, I_OnUserMessage, I_OnUserNotice, I_OnMode,
-       I_OnGetServerDescription, I_OnSyncUser, I_OnSyncChannel, I_OnSyncChannelMetaData, I_OnSyncUserMetaData,
-       I_OnDecodeMetaData, I_ProtoSendMode, I_ProtoSendMetaData, I_OnWallops, I_OnChangeHost, I_OnChangeName, I_OnAddLine,
-       I_OnDelLine, I_OnExpireLine, I_OnCleanup, I_OnUserPostNick, I_OnAccessCheck, I_On005Numeric, I_OnKill, I_OnRemoteKill,
-       I_OnLoadModule, I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite, I_OnRawMode,
-       I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckExtBan, I_OnCheckStringExtBan, I_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos,
-       I_OnLocalTopicChange, I_OnPostLocalTopicChange, I_OnEvent, I_OnRequest, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan, I_OnDelBan,
-       I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead, I_OnChangeLocalUserGECOS, I_OnUserRegister,
-       I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnUserList,
-       I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed,
-       I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookUserIO, I_OnHostCycle,
-       I_OnPreRehash, I_OnModuleRehash,
+       I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash,
+       I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo, I_OnWhois,
+       I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserPreNick,
+       I_OnUserMessage, I_OnUserNotice, I_OnMode, I_OnGetServerDescription, I_OnSyncUser,
+       I_OnSyncChannel, I_OnDecodeMetaData, I_OnWallops,
+       I_OnChangeHost, I_OnChangeName, I_OnAddLine, I_OnDelLine, I_OnExpireLine, I_OnCleanup,
+       I_OnUserPostNick, I_OnAccessCheck, I_On005Numeric, I_OnKill, I_OnRemoteKill, I_OnLoadModule,
+       I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
+       I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckExtBan, I_OnCheckStringExtBan,
+       I_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos, I_OnLocalTopicChange,
+       I_OnPostLocalTopicChange, I_OnEvent, I_OnRequest, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan,
+       I_OnDelBan, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead,
+       I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
+       I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnUserList, I_OnPostCommand, I_OnPostJoin,
+       I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed,
+       I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookUserIO,
+       I_OnHostCycle, I_OnPreRehash, I_OnModuleRehash,
        I_END
 };
 
@@ -511,8 +546,9 @@ class CoreExport Module : public Extensible
         * of the channel (useful for modules such as auditorium)
         * @param sync This is set to true if the JOIN is the result of a network sync and the remote user is being introduced
         * to a channel due to the network sync.
+        * @param created This is true if the join created the channel
         */
-       virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent);
+       virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created);
 
        /** Called after a user joins a channel
         * Identical to OnUserJoin, but called immediately afterwards, when any linking module has
@@ -786,7 +822,7 @@ class CoreExport Module : public Extensible
         * @param text The actual modes and their parameters if any
         * @param translate The translation types of the mode parameters
         */
-       virtual void OnMode(User* user, void* dest, int target_type, const std::deque<std::string> &text, const std::deque<TranslateType> &translate);
+       virtual void OnMode(User* user, void* dest, int target_type, const std::vector<std::string> &text, const std::vector<TranslateType> &translate);
 
        /** Allows modules to alter or create server descriptions
         * Whenever a module requires a server description, for example for display in
@@ -817,9 +853,7 @@ class CoreExport Module : public Extensible
         * the linking protocol. This currently is m_spanningtree.so. A pointer to this module
         * is given in Module* proto, so that you may call its methods such as ProtoSendMode
         * (see below). This function will be called for every user visible on your side
-        * of the burst, allowing you to for example set modes, etc. Do not use this call to
-        * synchronize data which you have stored using class Extensible -- There is a specialist
-        * function OnSyncUserMetaData and OnSyncChannelMetaData for this!
+        * of the burst, allowing you to for example set modes, etc.
         *
         * For a good example of how to use this function, please see src/modules/m_chanprotect.cpp
         *
@@ -829,36 +863,6 @@ class CoreExport Module : public Extensible
         */
        virtual void OnSyncChannel(Channel* chan, Module* proto, void* opaque);
 
-       /* Allows modules to syncronize metadata related to channels over the network during a netburst.
-        * Whenever the linking module wants to send out data, but doesnt know what the data
-        * represents (e.g. it is Extensible metadata, added to a User or Channel by a module) then
-        * this method is called.You should use the ProtoSendMetaData function after you've
-        * correctly decided how the data should be represented, to send the metadata on its way if it belongs
-        * to your module. For a good example of how to use this method, see src/modules/m_swhois.cpp.
-        * @param chan The channel whos metadata is being syncronized
-        * @param proto A pointer to the module handling network protocol
-        * @param opaque An opaque pointer set by the protocol module, should not be modified!
-        * @param extname The extensions name which is being searched for
-        * @param displayable If this value is true, the data is going to be displayed to a user,
-        * and not sent across the network. Use this to determine wether or not to show sensitive data.
-        */
-       virtual void OnSyncChannelMetaData(Channel* chan, Module* proto,void* opaque, const std::string &extname, bool displayable = false);
-
-       /* Allows modules to syncronize metadata related to users over the network during a netburst.
-        * Whenever the linking module wants to send out data, but doesnt know what the data
-        * represents (e.g. it is Extensible metadata, added to a User or Channel by a module) then
-        * this method is called. You should use the ProtoSendMetaData function after you've
-        * correctly decided how the data should be represented, to send the metadata on its way if
-        * if it belongs to your module.
-        * @param user The user whos metadata is being syncronized
-        * @param proto A pointer to the module handling network protocol
-        * @param opaque An opaque pointer set by the protocol module, should not be modified!
-        * @param extname The extensions name which is being searched for
-        * @param displayable If this value is true, the data is going to be displayed to a user,
-        * and not sent across the network. Use this to determine wether or not to show sensitive data.
-        */
-       virtual void OnSyncUserMetaData(User* user, Module* proto,void* opaque, const std::string &extname, bool displayable = false);
-
        /* Allows modules to syncronize metadata not related to users or channels, over the network during a netburst.
         * Whenever the linking module wants to send out data, but doesnt know what the data
         * represents (e.g. it is Extensible metadata, added to a User or Channel by a module) then
@@ -870,7 +874,7 @@ class CoreExport Module : public Extensible
         * @param displayable If this value is true, the data is going to be displayed to a user,
         * and not sent across the network. Use this to determine wether or not to show sensitive data.
         */
-       virtual void OnSyncOtherMetaData(Module* proto, void* opaque, bool displayable = false);
+       virtual void OnSyncNetwork(Module* proto, void* opaque);
 
        /** Allows module data, sent via ProtoSendMetaData, to be decoded again by a receiving module.
         * Please see src/modules/m_swhois.cpp for a working example of how to use this method call.
@@ -879,7 +883,7 @@ class CoreExport Module : public Extensible
         * @param extname The extension name which is being sent
         * @param extdata The extension data, encoded at the other end by an identical module through OnSyncChannelMetaData or OnSyncUserMetaData
         */
-       virtual void OnDecodeMetaData(int target_type, void* target, const std::string &extname, const std::string &extdata);
+       virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
 
        /** Implemented by modules which provide the ability to link servers.
         * These modules will implement this method, which allows transparent sending of servermodes
@@ -895,7 +899,7 @@ class CoreExport Module : public Extensible
         * @param modeline The modes and parameters to be sent
         * @param translate The translation types of the mode parameters
         */
-       virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::deque<std::string> &modeline, const std::deque<TranslateType> &translate);
+       virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::vector<std::string> &modeline, const std::vector<TranslateType> &translate);
 
        /** Implemented by modules which provide the ability to link servers.
         * These modules will implement this method, which allows metadata (extra data added to
@@ -911,7 +915,14 @@ class CoreExport Module : public Extensible
         * @param extname The extension name to send metadata for
         * @param extdata Encoded data for this extension name, which will be encoded at the oppsite end by an identical module using OnDecodeMetaData
         */
-       virtual void ProtoSendMetaData(void* opaque, TargetTypeFlags target_type, void* target, const std::string &extname, const std::string &extdata);
+       virtual void ProtoSendMetaData(void* opaque, Extensible* target, const std::string &extname, const std::string &extdata);
+
+       /**
+        * Implemented by all modules that implement ProtoSendMetaData.
+        * Translates the item into a string format suitable for sending to other servers.
+        * Currently, this just translates nicks to their UID and channels to their name
+        */
+       virtual std::string ProtoTranslate(Extensible* item);
 
        /** Called after every WALLOPS command.
         * @param user The user sending the WALLOPS
@@ -1301,7 +1312,7 @@ class CoreExport Module : public Extensible
         */
        virtual int OnDelBan(User* source, Channel* channel,const std::string &banmask);
 
-       virtual void OnHookUserIO(User* user, const std::string &targetip);
+       virtual void OnHookUserIO(User* user);
 
        /** Called immediately after any  connection is accepted. This is intended for raw socket
         * processing (e.g. modules which wrap the tcp connection within another library) and provides
@@ -1309,10 +1320,11 @@ class CoreExport Module : public Extensible
         * There are no return values from this call as all modules get an opportunity if required to
         * process the connection.
         * @param fd The file descriptor returned from accept()
-        * @param ip The IP address of the connecting user
+        * @param client The client IP address and port
+        * @param server The server IP address and port
         * @param localport The local port number the user connected to
         */
-       virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport);
+       virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
 
        /** Called immediately before any write() operation on a user's socket in the core. Because
         * this event is a low level event no user information is associated with it. It is intended
@@ -1651,6 +1663,11 @@ class CoreExport ModuleManager : public classbase
         */
        std::map<std::string, std::pair<ircd_module*, Module*> > Modules;
 
+       enum {
+               PRIO_STATE_FIRST,
+               PRIO_STATE_AGAIN,
+               PRIO_STATE_LAST
+       } prioritizationState;
  public:
 
        /** Event handler hooks.
@@ -1676,14 +1693,14 @@ class CoreExport ModuleManager : public classbase
         * @param i The event to change the priority of
         * @param s The state you wish to use for this event. Use one of
         * PRIO_FIRST to set the event to be first called, PRIO_LAST to
-        * set it to be the last called, or PRIO_BEFORE and PRIO_AFTER
+        * set it to be the last called, or PRIO_BEFORE and PRIORITY_AFTER
         * to set it to be before or after one or more other modules.
-        * @param modules If PRIO_BEFORE or PRIO_AFTER is set in parameter 's',
+        * @param modules If PRIO_BEFORE or PRIORITY_AFTER is set in parameter 's',
         * then this contains a list of one or more modules your module must be
         * placed before or after. Your module will be placed before the highest
         * priority module in this list for PRIO_BEFORE, or after the lowest
-        * priority module in this list for PRIO_AFTER.
-        * @param sz The number of modules being passed for PRIO_BEFORE and PRIO_AFTER.
+        * priority module in this list for PRIORITY_AFTER.
+        * @param sz The number of modules being passed for PRIO_BEFORE and PRIORITY_AFTER.
         * Defaults to 1, as most of the time you will only want to prioritize your module
         * to be before or after one other module.
         */
@@ -1693,7 +1710,7 @@ class CoreExport ModuleManager : public classbase
         * @param mod The module to set the priority of
         * @param s The priority of all events in the module.
         * Note that with this method, it is not possible to effectively use
-        * PRIO_BEFORE or PRIO_AFTER, you should use the more fine tuned
+        * PRIO_BEFORE or PRIORITY_AFTER, you should use the more fine tuned
         * SetPriority method for this, where you may specify other modules to
         * be prioritized against.
         */