]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/modules.h
Remove two useless methods, chanlog is b0rked at the moment.
[user/henk/code/inspircd.git] / include / modules.h
index 908a3e264042394ea70c2b19cb9318824cb3ca6e..abc783ca9e5e7e1dd6ffd0701e6d0414bb5a95c5 100644 (file)
@@ -2,7 +2,7 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
  * See: http://www.inspircd.org/wiki/index.php/Credits
  *
  * This program is free but copyrighted software; see
 #ifndef __MODULES_H
 #define __MODULES_H
 
+#include "globals.h"
+#include "dynamic.h"
+#include "base.h"
+#include "ctables.h"
+#include "inspsocket.h"
+#include <string>
+#include <deque>
+#include <sstream>
+#include "timer.h"
+#include "mode.h"
+#include "dns.h"
+
 class XLine;
 
 /** Used with OnAccessCheck() method of modules
@@ -65,18 +77,6 @@ enum MessageType {
        MSG_NOTICE = 1
 };
 
-#include "globals.h"
-#include "dynamic.h"
-#include "base.h"
-#include "ctables.h"
-#include "inspsocket.h"
-#include <string>
-#include <deque>
-#include <sstream>
-#include "timer.h"
-#include "mode.h"
-#include "dns.h"
-
 /** 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
@@ -123,20 +123,23 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist;
  * loaded modules in a readable simple way, e.g.:
  * 'FOREACH_MOD(I_OnConnect,OnConnect(user));'
  */
-#define FOREACH_MOD(y,x) if (!ServerInstance->Modules->EventHandlers[y].empty()) \
-{ \
-       for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ++_i) \
+#define FOREACH_MOD(y,x) do { \
+       EventHandlerIter safei; \
+       for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ) \
        { \
+               safei = _i; \
+               ++safei; \
                try \
                { \
                        (*_i)->x ; \
                } \
                catch (CoreException& modexcept) \
                { \
-                       ServerInstance->Log(DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
+                       ServerInstance->Logs->Log("MODULE",DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
                } \
+               _i = safei; \
        } \
-}
+} while (0);
 
 /**
  * This #define allows us to call a method in all
@@ -144,31 +147,37 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist;
  * an instance pointer to the macro. e.g.:
  * 'FOREACH_MOD_I(Instance, OnConnect, OnConnect(user));'
  */
-#define FOREACH_MOD_I(z,y,x) if (!z->Modules->EventHandlers[y].empty()) \
-{ \
-       for (EventHandlerIter _i = z->Modules->EventHandlers[y].begin(); _i != z->Modules->EventHandlers[y].end(); ++_i) \
+#define FOREACH_MOD_I(z,y,x) do { \
+       EventHandlerIter safei; \
+       for (EventHandlerIter _i = z->Modules->EventHandlers[y].begin(); _i != z->Modules->EventHandlers[y].end(); ) \
        { \
+               safei = _i; \
+               ++safei; \
                try \
                { \
                        (*_i)->x ; \
                } \
                catch (CoreException& modexcept) \
                { \
-                       z->Log(DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
+                       z->Logs->Log("MODULE",DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
                } \
+               _i = safei; \
        } \
-}
+} while (0);
 
 /**
  * This define is similar to the one above but returns a result in MOD_RESULT.
  * The first module to return a nonzero result is the value to be accepted,
  * and any modules after are ignored.
  */
-#define FOREACH_RESULT(y,x) if (!ServerInstance->Modules->EventHandlers[y].empty()) \
-{ \
+#define FOREACH_RESULT(y,x) \
+do { \
+       EventHandlerIter safei; \
        MOD_RESULT = 0; \
-       for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ++_i) \
+       for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ) \
        { \
+               safei = _i; \
+               ++safei; \
                try \
                { \
                        int res = (*_i)->x ; \
@@ -179,10 +188,11 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist;
                } \
                catch (CoreException& modexcept) \
                { \
-                       ServerInstance->Log(DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
+                       ServerInstance->Logs->Log("MODULE",DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
                } \
+               _i = safei; \
        } \
-} 
+} while(0);
 
 
 /**
@@ -190,11 +200,14 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist;
  * The first module to return a nonzero result is the value to be accepted,
  * and any modules after are ignored.
  */
-#define FOREACH_RESULT_I(z,y,x) if (!z->Modules->EventHandlers[y].empty()) \
-{ \
+#define FOREACH_RESULT_I(z,y,x) \
+do { \
+       EventHandlerIter safei; \
        MOD_RESULT = 0; \
-       for (EventHandlerIter _i = z->Modules->EventHandlers[y].begin(); _i != z->Modules->EventHandlers[y].end(); ++_i) \
+       for (EventHandlerIter _i = z->Modules->EventHandlers[y].begin(); _i != z->Modules->EventHandlers[y].end(); ) \
        { \
+               safei = _i; \
+               ++safei; \
                try \
                { \
                        int res = (*_i)->x ; \
@@ -205,10 +218,11 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist;
                } \
                catch (CoreException& modexcept) \
                { \
-                       z->Log(DEBUG,"Exception caught: %s",modexcept.GetReason()); \
+                       z->Logs->Log("MODULE",DEBUG,"Exception caught: %s",modexcept.GetReason()); \
                } \
+               _i = safei; \
        } \
-}
+} while (0);
 
 /** Represents a non-local user.
  * (in fact, any FD less than -1 does)
@@ -216,13 +230,9 @@ typedef std::map<std::string, std::pair<int, modulelist> > interfacelist;
 #define FD_MAGIC_NUMBER -42
 
 /* Useful macros */
-#ifdef WINDOWS
+
 /** Is a local user */
 #define IS_LOCAL(x) ((x->GetFd() > -1))
-#else
-/** Is a local user */
-#define IS_LOCAL(x) ((x->GetFd() > -1) && (x->GetFd() <= MAX_DESCRIPTORS))
-#endif
 /** Is a remote user */
 #define IS_REMOTE(x) (x->GetFd() < 0)
 /** Is a module created user */
@@ -321,7 +331,7 @@ class CoreExport Request : public ModuleMessage
         * sent the request to. It is up to your module to know what this data is and
         * how to deal with it.
         */
-       char* Send();
+       const char* Send();
 };
 
 
@@ -380,17 +390,19 @@ enum Implementation
        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_OnCleanup, I_OnUserPostNick, I_OnAccessCheck, I_On005Numeric, I_OnKill, I_OnRemoteKill, I_OnLoadModule, I_OnUnloadModule,
-       I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnUserRrgister, I_OnCheckInvite,
+       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_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos, I_OnLocalTopicChange,
-       I_OnPostLocalTopicChange, I_OnEvent, I_OnRequest, I_OnOperCompre, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan, I_OnDelBan,
+       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_OnOperCompare, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnCancelAway, I_OnUserList,
+       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_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookUserIO,
        I_END
 };
 
+class ConfigReader;
+
 /** Base class for all InspIRCd modules
  *  This class is the base class for InspIRCd modules. All modules must inherit from this class,
  *  its methods will be called when irc server events occur. class inherited from module must be
@@ -450,6 +462,12 @@ class CoreExport Module : public Extensible
         */
        virtual void OnUserDisconnect(User* user);
 
+       /** Called whenever a channel is about to be deleted
+        * @param chan The channel being deleted
+        * @return An integer specifying whether or not the channel may be deleted. 0 for yes, 1 for no.
+        */
+       virtual int OnChannelPreDelete(Channel *chan);
+
        /** Called whenever a channel is deleted, either by QUIT, KICK or PART.
         * @param chan The channel being deleted
         */
@@ -462,8 +480,10 @@ class CoreExport Module : public Extensible
         * @param channel The channel being joined
         * @param silent Change this to true if you want to conceal the JOIN command from the other users
         * 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.
         */
-       virtual void OnUserJoin(User* user, Channel* channel, bool &silent);
+       virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent);
 
        /** Called after a user joins a channel
         * Identical to OnUserJoin, but called immediately afterwards, when any linking module has
@@ -566,9 +586,10 @@ class CoreExport Module : public Extensible
         * can be gauranteed to already have processed the oper-up, for example m_spanningtree has sent
         * out the OPERTYPE, etc.
         * @param user The user who is opering up
+        * @param opername The name of the oper that the user is opering up to. Only valid locally. Empty string otherwise.
         * @param opertype The opers type name
         */
-       virtual void OnPostOper(User* user, const std::string &opertype);
+       virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
        
        /** Called whenever a user types /INFO.
         * The User will contain the information of the user who typed the command. Modules may use this
@@ -597,9 +618,10 @@ class CoreExport Module : public Extensible
         * @param source The user who is issuing the INVITE
         * @param dest The user being invited
         * @param channel The channel the user is being invited to
+        * @param timeout The time the invite will expire (0 == never)
         * @return 1 to deny the invite, 0 to allow
         */
-       virtual int OnUserPreInvite(User* source,User* dest,Channel* channel);
+       virtual int OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
        
        /** Called after a user has been successfully invited to a channel.
         * You cannot prevent the invite from occuring using this function, to do that,
@@ -607,8 +629,9 @@ class CoreExport Module : public Extensible
         * @param source The user who is issuing the INVITE
         * @param dest The user being invited
         * @param channel The channel the user is being invited to
+        * @param timeout The time the invite will expire (0 == never)
         */
-       virtual void OnUserInvite(User* source,User* dest,Channel* channel);
+       virtual void OnUserInvite(User* source,User* dest,Channel* channel, time_t timeout);
        
        /** Called whenever a user is about to PRIVMSG A user or a channel, before any processing is done.
         * Returning any nonzero value from this function stops the process immediately, causing no
@@ -870,18 +893,18 @@ class CoreExport Module : public Extensible
         */
        virtual void OnAddLine(User* source, XLine* line);
 
-       /** Called whenever an xline is deleted.
+       /** Called whenever an xline is deleted MANUALLY. See OnExpireLine for expiry.
         * This method is triggered after the line is deleted.
         * @param source The user removing the line or NULL for local server
         * @param line the line being deleted
         */
        virtual void OnDelLine(User* source, XLine* line);
 
-       /** Called whenever a zline is deleted.
+       /** Called whenever an xline expires.
         * This method is triggered after the line is deleted.
-        * @param source The user removing the line
-        * @param hostmask The hostmask to delete
+        * @param line The line being deleted.
         */
+       virtual void OnExpireLine(XLine *line);
 
        /** Called before your module is unloaded to clean up Extensibles.
         * This method is called once for every user and channel on the network,
@@ -1013,7 +1036,7 @@ class CoreExport Module : public Extensible
         * @param original_line The entire original line as passed to the parser from the user
         * @return 1 to block the command, 0 to allow
         */
-       virtual int OnPreCommand(const std::string &command, const char** parameters, int pcnt, User *user, bool validated, const std::string &original_line);
+       virtual int OnPreCommand(const std::string &command, const char* const* parameters, int pcnt, User *user, bool validated, const std::string &original_line);
 
        /** Called after any command has been executed.
         * This event occurs for all registered commands, wether they are registered in the core,
@@ -1027,7 +1050,7 @@ class CoreExport Module : public Extensible
         * @param result The return code given by the command handler, one of CMD_SUCCESS or CMD_FAILURE
         * @param original_line The entire original line as passed to the parser from the user
         */
-       virtual void OnPostCommand(const std::string &command, const char** parameters, int pcnt, User *user, CmdResult result, const std::string &original_line);
+       virtual void OnPostCommand(const std::string &command, const char* const* parameters, int pcnt, User *user, CmdResult result, const std::string &original_line);
 
        /** Called to check if a user who is connecting can now be allowed to register
         * If any modules return false for this function, the user is held in the waiting
@@ -1062,6 +1085,20 @@ class CoreExport Module : public Extensible
         */
        virtual int OnCheckInvite(User* user, Channel* chan);
 
+       /** Called whenever a mode character is processed.
+        * Return 1 from this function to block the mode character from being processed entirely.
+        * @param user The user who is sending the mode
+        * @param chan The channel the mode is being sent to (or NULL if a usermode)
+        * @param mode The mode character being set
+        * @param param The parameter for the mode or an empty string
+        * @param adding true of the mode is being added, false if it is being removed
+        * @param pcnt The parameter count for the mode (0 or 1)
+        * @return ACR_DENY to deny the mode, ACR_DEFAULT to do standard mode checking, and ACR_ALLOW
+        * to skip all permission checking. Please note that for remote mode changes, your return value
+        * will be ignored!
+        */
+       virtual int OnRawMode(User* user, Channel* chan, const char mode, const std::string &param, bool adding, int pcnt, bool servermode = true);
+
        /** Called whenever a user joins a channel, to determine if key checks should go ahead or not.
         * This method will always be called for each join, wether or not the channel is actually +k, and
         * determines the outcome of an if statement around the whole section of key checking code.
@@ -1152,19 +1189,19 @@ class CoreExport Module : public Extensible
         * may be able to use for pre-determined purposes (e.g. the results of an SQL query, etc).
         * @param request The Request class being received
         */
-       virtual char* OnRequest(Request* request);
+       virtual const char* OnRequest(Request* request);
 
-       /** Called whenever an oper password is to be compared to what a user has input.
+       /** Called whenever a password check is to be made. Replaces the old OldOperCompare API.
         * The password field (from the config file) is in 'password' and is to be compared against
-        * 'input'. This method allows for encryption of oper passwords and much more besides.
-        * You should return a nonzero value if you want to allow the comparison or zero if you wish
-        * to do nothing.
-        * @param password The oper's password
-        * @param input The password entered
-        * @param tagnumber The tag number (from the configuration file) of this oper's tag
-        * @return 1 to match the passwords, 0 to do nothing. -1 to not match, and not continue.
+        * 'input'. This method allows for encryption of passwords (oper, connect:allow, die/restart, etc).
+        * You should return a nonzero value to override the normal comparison, or zero to pass it on.
+        * @param ex The object that's causing the authentication (User* for <oper> <connect:allow> etc, Server* for <link>).
+        * @param password The password from the configuration file (the password="" value).
+        * @param input The password entered by the user or whoever.
+        * @param hashtype The hash value from the config
+        * @return 0 to do nothing (pass on to next module/default), 1 == password is OK, -1 == password is not OK
         */
-       virtual int OnOperCompare(const std::string &password, const std::string &input, int tagnumber);
+       virtual int OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
 
        /** Called whenever a user is given usermode +o, anywhere on the network.
         * You cannot override this and prevent it from happening as it is already happened and
@@ -1200,6 +1237,8 @@ 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);
+
        /** 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
         * no information relating to a user record as the connection has not been assigned yet.
@@ -1252,17 +1291,15 @@ class CoreExport Module : public Extensible
         */
        virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult);
 
-       /** Called whenever a user sets away.
-        * This method has no parameter for the away message, as it is available in the
-        * user record as User::awaymsg.
+       /** Called whenever a user sets away or returns from being away.
+        * The away message is available as a parameter, but should not be modified.
+        * At this stage, it has already been copied into the user record.
+        * If awaymsg is empty, the user is returning from away.
         * @param user The user setting away
+        * @param awaymsg The away message of the user, or empty if returning from away
+        * @return nonzero if the away message should be blocked - should ONLY be nonzero for LOCAL users (IS_LOCAL) (no output is returned by core)
         */
-       virtual void OnSetAway(User* user);
-
-       /** Called when a user cancels their away state.
-        * @param user The user returning from away
-        */
-       virtual void OnCancelAway(User* user);
+       virtual int OnSetAway(User* user, const std::string &awaymsg);
 
        /** Called whenever a NAMES list is requested.
         * You can produce the nameslist yourself, overriding the current list,
@@ -1273,7 +1310,9 @@ class CoreExport Module : public Extensible
         * @param userlist The user list for the channel (you may change this pointer.
         * If you want to change the values, take a copy first, and change the copy, then
         * point the pointer at your copy)
-        * @return 1 to prevent the user list being sent to the client, 0 to allow it
+        * @return 1 to prevent the user list being sent to the client, 0 to allow it.
+        * Returning -1 allows the names list, but bypasses any checks which check for
+        * channel membership before sending the names list.
         */
        virtual int OnUserList(User* user, Channel* Ptr, CUList* &userlist);
 
@@ -1305,6 +1344,19 @@ class CoreExport Module : public Extensible
         * @param user The user who's buffer is now empty.
         */
        virtual void OnBufferFlushed(User* user);
+
+       /** Add test suite hooks here. These are used for testing functionality of a module
+        * via the --testsuite debugging parameter.
+        */
+       virtual void OnRunTestSuite();
+
+       /** Called for every item in a NAMES list, so that modules may reformat portions of it as they see fit.
+        * For example NAMESX, channel mode +u and +I, and UHNAMES. If the nick is set to an empty string by any
+        * module, then this will cause the nickname not to be displayed at all.
+        */
+       virtual void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick);
+
+       virtual int OnNumeric(User* user, unsigned int numeric, const std::string &text);
 };
 
 
@@ -1514,22 +1566,23 @@ class CoreExport FileReader : public classbase
 };
 
 /** A DLLFactory (designed to load shared objects) containing a
- * handle to a module's init_module() function.
+ * handle to a module's init_module() function. Unfortunately,
+ * due to the design of shared object systems we must keep this
+ * hanging around, as if we remove this handle, we remove the
+ * shared object file from memory (!)
  */
 typedef DLLFactory<Module> ircd_module;
 
-/** A list of loaded Modules
+/** A list of modules
  */
-typedef std::vector<Module*> ModuleList;
+typedef std::vector<Module*> IntModuleList;
 
-/** A list of loaded module handles (ircd_module)
+/** An event handler iterator
  */
-typedef std::vector<ircd_module*> ModuleHandleList;
-
-typedef std::vector<Module*> IntModuleList;
-typedef std::vector<IntModuleList> EventHandlerList;
 typedef IntModuleList::iterator EventHandlerIter;
 
+/** Module priority states
+ */
 enum PriorityState
 {
        PRIO_DONTCARE,
@@ -1547,7 +1600,7 @@ class CoreExport ModuleManager : public classbase
  private:
        /** Holds a string describing the last module error to occur
         */
-       char MODERR[MAXBUF];
+       std::string LastModuleError;
  
        /** The feature names published by various modules
         */
@@ -1557,7 +1610,7 @@ class CoreExport ModuleManager : public classbase
         */
        interfacelist Interfaces;
  
-       /** Total number of modules loaded into the ircd, minus one
+       /** Total number of modules loaded into the ircd
         */
        int ModCount; 
        
@@ -1565,30 +1618,71 @@ class CoreExport ModuleManager : public classbase
         */
        InspIRCd* Instance;
 
+       /** List of loaded modules and shared object/dll handles
+        * keyed by module name
+        */
        std::map<std::string, std::pair<ircd_module*, Module*> > Modules;
 
  public:
 
-       EventHandlerList EventHandlers;
+       /** Event handler hooks.
+        * This needs to be public to be used by FOREACH_MOD and friends.
+        */
+       IntModuleList EventHandlers[I_END];
 
        /** Simple, bog-standard, boring constructor.
         */
        ModuleManager(InspIRCd* Ins);
 
+       /** Destructor
+        */
        ~ModuleManager(); 
 
+       /** Change the priority of one event in a module.
+        * Each module event has a list of modules which are attached to that event type.
+        * If you wish to be called before or after other specific modules, you may use this
+        * method (usually within void Module::Prioritize()) to set your events priority.
+        * You may use this call in other methods too, however, this is not supported behaviour
+        * for a module.
+        * @param mod The module to change the priority of
+        * @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
+        * 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',
+        * 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.
+        * Defaults to 1, as most of the time you will only want to prioritize your module
+        * to be before or after one other module.
+        */
        bool SetPriority(Module* mod, Implementation i, PriorityState s, Module** modules = NULL, size_t sz = 1);
 
+       /** Change the priority of all events in a module.
+        * @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
+        * SetPriority method for this, where you may specify other modules to
+        * be prioritized against.
+        */
        bool SetPriority(Module* mod, PriorityState s);
 
-       /** Attach an event to a module
+       /** Attach an event to a module.
+        * You may later detatch the event with ModuleManager::Detach().
+        * If your module is unloaded, all events are automatically detatched.
         * @param i Event type to attach
         * @param mod Module to attach event to
         * @return True if the event was attached
         */
        bool Attach(Implementation i, Module* mod);
 
-       /** Detatch an event from a module
+       /** Detatch an event from a module.
+        * This is not required when your module unloads, as the core will
+        * automatically detatch your module from all events it is attached to.
         * @param i Event type to detach
         * @param mod Module to detach event from
         * @param Detach true if the event was detached
@@ -1609,7 +1703,7 @@ class CoreExport ModuleManager : public classbase
        /** Returns text describing the last module error
         * @return The last error message to occur
         */
-       const char* LastError();
+       std::string& LastError();
 
        /** Load a given module file
         * @param filename The file to load
@@ -1739,12 +1833,26 @@ class CoreExport ModuleManager : public classbase
         */
        modulelist* FindInterface(const std::string &InterfaceName);
 
+       /** Determine if a module has published the named interface.
+        * This could be used in, for example, OnLoadModule to pick up other modules that can be used.
+        * @param mod The module to check.
+        * @param InterfaceName the interface you want to check for
+        * @return True if the module provides the interface, false otherwise.
+        */
+       bool ModuleHasInterface(Module* mod, const std::string& InterfaceName);
+
        /** Given a pointer to a Module, return its filename
         * @param m The module pointer to identify
         * @return The module name or an empty string
         */
        const std::string& GetModuleName(Module* m);
 
+       /** Return a list of all modules matching the given filter
+        * @param filter This int is a bitmask of flags set in Module::Flags,
+        * such as VF_VENDOR or VF_STATIC. If you wish to receive a list of
+        * all modules with no filtering, set this to 0.
+        * @return The list of module names
+        */
        const std::vector<std::string> GetAllModuleNames(int filter);
 };