]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/modules.h
Replace std::deque with std::vector in spanningtree and related modules
[user/henk/code/inspircd.git] / include / modules.h
index 693fd41fb38a9b5fa2c00d849635e76575246f9a..21e4760897f234045690980735f169f3c88b6287 100644 (file)
@@ -2,8 +2,8 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ * See: http://wiki.inspircd.org/Credits
  *
  * This program is free but copyrighted software; see
  *         the file COPYING for details.
@@ -14,7 +14,6 @@
 #ifndef __MODULES_H
 #define __MODULES_H
 
-#include "globals.h"
 #include "dynamic.h"
 #include "base.h"
 #include "ctables.h"
@@ -77,18 +76,8 @@ 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.
- */
-#define NATIVE_API_VERSION 12000
-#ifdef IPV6
-#define API_VERSION (NATIVE_API_VERSION * 10)
-#else
-#define API_VERSION (NATIVE_API_VERSION * 1)
-#endif
+/** If you change the module API, change this value. */
+#define API_VERSION 13000
 
 class ServerConfig;
 
@@ -224,27 +213,48 @@ do { \
        } \
 } while (0);
 
+#define FOREACH_RESULT_MAP(y,x,f) \
+do { \
+       EventHandlerIter safei; \
+       for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ) \
+       { \
+               safei = _i; \
+               ++safei; \
+               try \
+               { \
+                       int MOD_RESULT = (*_i)->x ; \
+                       f; \
+               } \
+               catch (CoreException& modexcept) \
+               { \
+                       ServerInstance->Logs->Log("MODULE",DEFAULT,"Exception caught: %s",modexcept.GetReason()); \
+               } \
+               _i = safei; \
+       } \
+} while(0);
+
 /** Represents a non-local user.
  * (in fact, any FD less than -1 does)
  */
 #define FD_MAGIC_NUMBER -42
+/** Represents a fake user (i.e. a server)
+ */
+#define FD_FAKEUSER_NUMBER -7
 
 /* 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
+#define IS_LOCAL(x) (x->GetFd() > -1)
 /** Is a remote user */
 #define IS_REMOTE(x) (x->GetFd() < 0)
+/** Is a fake user */
+#define IS_FAKE(x) (x->GetFd() == FD_FAKEUSER_NUMBER)
 /** Is a module created user */
 #define IS_MODULE_CREATED(x) (x->GetFd() == FD_MAGIC_NUMBER)
 /** Is an oper */
-#define IS_OPER(x) (*x->oper)
+#define IS_OPER(x) (!x->oper.empty())
 /** Is away */
-#define IS_AWAY(x) (*x->awaymsg)
+#define IS_AWAY(x) (!x->awaymsg.empty())
 
 /** Holds a module's Version information.
  *  The four members (set by the constructor only) indicate details as to the version number
@@ -256,13 +266,17 @@ do { \
 class CoreExport Version : public classbase
 {
  public:
-        /** Version numbers, build number, flags and API version
-         */
-        const int Major, Minor, Revision, Build, Flags, API;
+       /** Version information.
+        */
+       std::string version;
+
+       /** Flags and API version
+        */
+       const int Flags, API;
 
-        /** Initialize version class
-         */
-        Version(int major, int minor, int revision, int build, int flags, int api_ver);
+       /** Initialize version class
+        */
+       Version(const std::string &sversion, int flags, int api_ver);
 };
 
 /** The ModuleMessage class is the base class of Request and Event
@@ -288,11 +302,11 @@ class CoreExport Request : public ModuleMessage
        /** This member holds a pointer to arbitary data set by the emitter of the message
         */
        char* data;
-       /** This should be a null-terminated string identifying the type of request,
-        * all modules should define this and use it to determine the nature of the
-        * request before they attempt to cast the Request in any way.
-        */
-       const char* id;
+       /** This should be a null-terminated string identifying the type of request,
+        * all modules should define this and use it to determine the nature of the
+        * request before they attempt to cast the Request in any way.
+        */
+       const char* id;
        /** This is a pointer to the sender of the message, which can be used to
         * directly trigger events, or to create a reply.
         */
@@ -302,26 +316,26 @@ class CoreExport Request : public ModuleMessage
        Module* dest;
  public:
        /** Create a new Request
-        * This is for the 'old' way of casting whatever the data is
-        * to char* and hoping you get the right thing at the other end.
-        * This is slowly being depreciated in favor of the 'new' way.
+        * This is for the 'old' way of casting whatever the data is
+        * to char* and hoping you get the right thing at the other end.
+        * This is slowly being depreciated in favor of the 'new' way.
         */
        Request(char* anydata, Module* src, Module* dst);
-       /** Create a new Request
-        * This is for the 'new' way of defining a subclass
-        * of Request and defining it in a common header,
+       /** Create a new Request
+        * This is for the 'new' way of defining a subclass
+        * of Request and defining it in a common header,
         * passing an object of your Request subclass through
-        * as a Request* and using the ID string to determine
-        * what to cast it back to and the other end. This is
-        * much safer as there are no casts not confirmed by
-        * the ID string, and all casts are child->parent and
-        * can be checked at runtime with dynamic_cast<>()
-        */
-       Request(Module* src, Module* dst, const char* idstr);
+        * as a Request* and using the ID string to determine
+        * what to cast it back to and the other end. This is
+        * much safer as there are no casts not confirmed by
+        * the ID string, and all casts are child->parent and
+        * can be checked at runtime with dynamic_cast<>()
+        */
+       Request(Module* src, Module* dst, const char* idstr);
        /** Fetch the Request data
         */
        char* GetData();
-       /** Fetch the ID string
+       /** Fetch the ID string
         */
        const char* GetId();
        /** Fetch the request source
@@ -389,19 +403,20 @@ 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_OnServerRaw, 
+       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_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos, I_OnLocalTopicChange,
-       I_OnPostLocalTopicChange, I_OnEvent, I_OnRequest, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan, I_OnDelBan,
+       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_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_OnReadConfig, I_OnDownloadFile, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric,
+       I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookUserIO, I_OnHostCycle,
+       I_OnPreRehash, I_OnModuleRehash,
        I_END
 };
 
@@ -436,10 +451,6 @@ class CoreExport Module : public Extensible
        {
        }
 
-       virtual void OnReadConfig(ServerConfig* config, ConfigReader* coreconf);
-
-       virtual int OnDownloadFile(const std::string &filename, std::istream* &filedata);
-
        /** Returns the version number of a Module.
         * The method should return a Version object with its version information assigned via
         * Version::Version
@@ -506,35 +517,50 @@ class CoreExport Module : public Extensible
         * and the details of the channel they have left is available in the variable Channel *channel
         * @param user The user who is parting
         * @param channel The channel being parted
-        * @param partmessage The part message, or an empty string
+        * @param partmessage The part message, or an empty string (may be modified)
         * @param silent Change this to true if you want to conceal the PART command from the other users
         * of the channel (useful for modules such as auditorium)
         */
-       virtual void OnUserPart(User* user, Channel* channel, const std::string &partmessage, bool &silent);
+       virtual void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent);
 
        /** Called on rehash.
         * This method is called prior to a /REHASH or when a SIGHUP is received from the operating
-        * system. You should use it to reload any files so that your module keeps in step with the
-        * rest of the application. If a parameter is given, the core has done nothing. The module
-        * receiving the event can decide if this parameter has any relevence to it.
-        * @param user The user performing the rehash, if any -- if this is server initiated, the
-        * value of this variable will be NULL.
-        * @param parameter The (optional) parameter given to REHASH from the user.
-        */
-       virtual void OnRehash(User* user, const std::string &parameter);
-
-       /** Called when a raw command is transmitted or received.
-        * This method is the lowest level of handler available to a module. It will be called with raw
-        * data which is passing through a connected socket. If you wish, you may munge this data by changing
-        * the string parameter "raw". If you do this, after your function exits it will immediately be
-        * cut down to 510 characters plus a carriage return and linefeed. For INBOUND messages only (where
-        * inbound is set to true) the value of user will be the User of the connection sending the
-        * data. This is not possible for outbound data because the data may be being routed to multiple targets.
-        * @param raw The raw string in RFC1459 format
-        * @param inbound A flag to indicate wether the data is coming into the daemon or going out to the user
-        * @param user The user record sending the text, when inbound == true.
-        */
-       virtual void OnServerRaw(std::string &raw, bool inbound, User* user);
+        * system. This is called in all cases -- including when this server will not execute the
+        * rehash because it is directed at a remote server.
+        *
+        * @param user The user performing the rehash, if any. If this is server initiated, the value of
+        * this variable will be NULL.
+        * @param parameter The (optional) parameter given to REHASH from the user. Empty when server
+        * initiated.
+        */
+       virtual void OnPreRehash(User* user, const std::string &parameter);
+
+       /** Called on rehash.
+        * This method is called when a user initiates a module-specific rehash. This can be used to do
+        * expensive operations (such as reloading SSL certificates) that are not executed on a normal
+        * rehash for efficiency. A rehash of this type does not reload the core configuration.
+        *
+        * @param user The user performing the rehash.
+        * @param parameter The parameter given to REHASH
+        */
+       virtual void OnModuleRehash(User* user, const std::string &parameter);
+
+       /** Called on rehash.
+        * This method is called after a rehash has completed. You should use it to reload any module
+        * configuration from the main configuration file.
+        * @param user The user that performed the rehash, if it was initiated by a user and that user
+        * is still connected.
+        */
+       virtual void OnRehash(User* user);
+
+       /** Called whenever a snotice is about to be sent to a snomask.
+        * snomask and type may both be modified; the message may not.
+        * @param snomask The snomask the message is going to (e.g. 'A')
+        * @param type The textual description the snomask will go to (e.g. 'OPER')
+        * @param message The text message to be sent via snotice
+        * @return 1 to block the snotice from being sent entirely, 0 else.
+        */
+       virtual int OnSendSnotice(char &snomask, std::string &type, const std::string &message);
 
        /** Called whenever a user is about to join a channel, before any processing is done.
         * Returning a value of 1 from this function stops the process immediately, causing no
@@ -553,10 +579,11 @@ class CoreExport Module : public Extensible
         * @param cname The channel name being joined. For new channels this is valid where chan is not.
         * @param privs A string containing the users privilages when joining the channel. For new channels this will contain "@".
         * You may alter this string to alter the user's modes on the channel.
+        * @param keygiven The key given to join the channel, or an empty string if none was provided
         * @return 1 To prevent the join, 0 to allow it.
         */
-       virtual int OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs);
-       
+       virtual int OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven);
+
        /** Called whenever a user is about to be kicked.
         * Returning a value of 1 from this function stops the process immediately, causing no
         * output to be sent to the user by the core. If you do this you must produce your own numerics,
@@ -598,7 +625,7 @@ class CoreExport Module : public Extensible
         * @param opertype The opers type name
         */
        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
         * method to output their own credits in /INFO (which is the ircd's version of an about box).
@@ -610,7 +637,7 @@ class CoreExport Module : public Extensible
         * @param user The user issuing /INFO
         */
        virtual void OnInfo(User* user);
-       
+
        /** Called whenever a /WHOIS is performed on a local user.
         * The source parameter contains the details of the user who issued the WHOIS command, and
         * the dest parameter contains the information of the user they are whoising.
@@ -618,7 +645,7 @@ class CoreExport Module : public Extensible
         * @param dest The user who is being WHOISed
         */
        virtual void OnWhois(User* source, User* dest);
-       
+
        /** Called whenever a user is about to invite another user into a channel, before any processing is done.
         * Returning 1 from this function stops the process immediately, causing no
         * output to be sent to the user by the core. If you do this you must produce your own numerics,
@@ -627,10 +654,10 @@ class CoreExport Module : public Extensible
         * @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
+        * @return 1 to deny the invite, 0 to check whether or not the user has permission to invite, -1 to explicitly allow the invite
         */
        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,
         * use OnUserPreInvite instead.
@@ -640,7 +667,7 @@ class CoreExport Module : public Extensible
         * @param timeout The time the invite will expire (0 == never)
         */
        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
         * output to be sent to the user by the core. If you do this you must produce your own numerics,
@@ -655,7 +682,7 @@ class CoreExport Module : public Extensible
         * @param status The status being used, e.g. PRIVMSG @#chan has status== '@', 0 to send to everyone.
         * @param exempt_list A list of users not to send to. For channel messages, this will usually contain just the sender.
         * It will be ignored for private messages.
-        * @return 1 to deny the NOTICE, 0 to allow it
+        * @return 1 to deny the message, 0 to allow it
         */
        virtual int OnUserPreMessage(User* user,void* dest,int target_type, std::string &text,char status, CUList &exempt_list);
 
@@ -690,7 +717,7 @@ class CoreExport Module : public Extensible
         * @param text The original message text causing the exempt list to be built
         */
        virtual void OnBuildExemptList(MessageType message_type, Channel* chan, User* sender, char status, CUList &exempt_list, const std::string &text);
-       
+
        /** Called before any nickchange, local or remote. This can be used to implement Q-lines etc.
         * Please note that although you can see remote nickchanges through this function, you should
         * NOT make any changes to the User if the user is a remote user as this may cause a desnyc.
@@ -747,8 +774,9 @@ class CoreExport Module : public Extensible
         * @param dest The target of the modes (User* or Channel*)
         * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL)
         * @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::string &text);
+       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
@@ -855,8 +883,9 @@ class CoreExport Module : public Extensible
         * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL
         * @param target The Channel* or User* that modes should be sent for
         * @param modeline The modes and parameters to be sent
+        * @param translate The translation types of the mode parameters
         */
-       virtual void ProtoSendMode(void* opaque, int target_type, void* target, const std::string &modeline);
+       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
@@ -872,8 +901,8 @@ 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, int target_type, void* target, const std::string &extname, const std::string &extdata);
-       
+       virtual void ProtoSendMetaData(void* opaque, TargetTypeFlags target_type, void* target, const std::string &extname, const std::string &extdata);
+
        /** Called after every WALLOPS command.
         * @param user The user sending the WALLOPS
         * @param text The content of the WALLOPS message
@@ -941,15 +970,15 @@ class CoreExport Module : public Extensible
         * before opping a user, deopping a user, kicking a user, etc.
         * There are several values for access_type which indicate for what reason access is being checked.
         * These are:<br><br>
-        * AC_KICK (0) - A user is being kicked<br>
-        * AC_DEOP (1) - a user is being deopped<br>
-        * AC_OP (2) - a user is being opped<br>
-        * AC_VOICE (3) - a user is being voiced<br>
-        * AC_DEVOICE (4) - a user is being devoiced<br>
-        * AC_HALFOP (5) - a user is being halfopped<br>
-        * AC_DEHALFOP (6) - a user is being dehalfopped<br>
-        * AC_INVITE () - a user is being invited<br>
-        * AC_GENERAL_MODE (8) - a user channel mode is being changed<br><br>
+        * AC_KICK - A user is being kicked<br>
+        * AC_DEOP - a user is being deopped<br>
+        * AC_OP - a user is being opped<br>
+        * AC_VOICE - a user is being voiced<br>
+        * AC_DEVOICE - a user is being devoiced<br>
+        * AC_HALFOP - a user is being halfopped<br>
+        * AC_DEHALFOP - a user is being dehalfopped<br>
+        * AC_INVITE - a user is being invited<br>
+        * AC_GENERAL_MODE - a user channel mode is being changed<br><br>
         * Upon returning from your function you must return either ACR_DEFAULT, to indicate the module wishes
         * to do nothing, or ACR_DENY where approprate to deny the action, and ACR_ALLOW where appropriate to allow
         * the action. Please note that in the case of some access checks (such as AC_GENERAL_MODE) access may be
@@ -1041,10 +1070,11 @@ class CoreExport Module : public Extensible
         * @param pcnt The nuimber of parameters passed to the command
         * @param user the user issuing the command
         * @param validated True if the command has passed all checks, e.g. it is recognised, has enough parameters, the user has permission to execute it, etc.
+        * You should only change the parameter list and command string if validated == false (e.g. before the command lookup occurs).
         * @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* const* parameters, int pcnt, User *user, bool validated, const std::string &original_line);
+       virtual int OnPreCommand(std::string &command, std::vector<std::string>& parameters, 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,
@@ -1058,7 +1088,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* const* parameters, int pcnt, User *user, CmdResult result, const std::string &original_line);
+       virtual void OnPostCommand(const std::string &command, const std::vector<std::string>& parameters, 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
@@ -1134,10 +1164,26 @@ class CoreExport Module : public Extensible
         * return 1 to explicitly allow the join to go ahead or 0 to ignore the event.
         * @param user The user joining the channel
         * @param chan The channel being joined
-        * @return 1 to explicitly allow the join, 0 to proceed as normal
+        * @return 1 to explicitly allow the join, 0 to proceed as normal. Return -1 to explicitly deny the
+        * join to the channel.
         */
        virtual int OnCheckBan(User* user, Channel* chan);
 
+       /* Called whenever checking whether or not a user is matched by an applicable extended bantype.
+        * NOTE: may also trigger extra OnCheckStringExtBan events!
+        * @param u The user to check
+        * @param c The channel the user is on
+        * @param type The type of extended ban to check for.
+        * @returns 1 = exempt, 0 = no match, -1 = banned
+        */
+       virtual int OnCheckExtBan(User *u, Channel *c, char type);
+
+       /** Called whenever checking whether or not a string is extbanned. NOTE: one OnCheckExtBan will also trigger a number of
+        * OnCheckStringExtBan events for seperate host/IP comnbinations.
+        * @returns 1 = exempt, 0 = no match, -1 = banned
+        */
+       virtual int OnCheckStringExtBan(const std::string &s, Channel *c, char type);
+
        /** Called on all /STATS commands
         * This method is triggered for all /STATS use, including stats symbols handled by the core.
         * @param symbol the symbol provided to /STATS
@@ -1163,10 +1209,10 @@ class CoreExport Module : public Extensible
         * @param newhost The new GECOS
         * @return 1 to deny the GECOS change, 0 to allow
         */
-       virtual int OnChangeLocalUserGECOS(User* user, const std::string &newhost); 
+       virtual int OnChangeLocalUserGECOS(User* user, const std::string &newhost);
 
        /** Called whenever a topic is changed by a local user.
-        * Return 1 to deny the topic change, or 0 to allow it.
+        * Return 1 to deny the topic change, 0 to check details on the change, -1 to let it through with no checks
         * @param user The user changing the topic
         * @param chan The channels who's topic is being changed
         * @param topic The actual topic text
@@ -1245,16 +1291,19 @@ class CoreExport Module : public Extensible
         */
        virtual int OnDelBan(User* source, Channel* channel,const std::string &banmask);
 
+       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
         * no information relating to a user record as the connection has not been assigned yet.
         * 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
@@ -1297,17 +1346,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,
@@ -1365,6 +1412,12 @@ class CoreExport Module : public Extensible
        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);
+
+       /** Called for every time the user's host or ident changes, to indicate wether or not the 'Changing host'
+        * message should be sent, if enabled. Certain modules such as auditorium may opt to hide this message
+        * even if it is enabled.
+        */
+       virtual bool OnHostCycle(User* user);
 };
 
 
@@ -1385,35 +1438,16 @@ class CoreExport ConfigReader : public classbase
 {
   protected:
        InspIRCd* ServerInstance;
-       /** The contents of the configuration file
-        * This protected member should never be accessed by a module (and cannot be accessed unless the
-        * core is changed). It will contain a pointer to the configuration file data with unneeded data
-        * (such as comments) stripped from it.
-        */
-       ConfigDataHash* data;
-       /** Used to store errors
-        */
-       std::ostringstream* errorlog;
-       /** If we're using our own config data hash or not
-        */
-       bool privatehash;
-       /** True if an error occured reading the config file
-        */
-       bool readerror;
        /** Error code
         */
        long error;
-       
+
   public:
        /** Default constructor.
         * This constructor initialises the ConfigReader class to read the inspircd.conf file
         * as specified when running ./configure.
         */
        ConfigReader(InspIRCd* Instance);
-       /** Overloaded constructor.
-        * This constructor initialises the ConfigReader class to read a user-specified config file
-        */
-       ConfigReader(InspIRCd* Instance, const std::string &filename);
        /** Default destructor.
         * This method destroys the ConfigReader class.
         */
@@ -1477,18 +1511,6 @@ class CoreExport ConfigReader : public classbase
         * multiple instance tag.
         */
        int Enumerate(const std::string &tag);
-       /** Returns true if a config file is valid.
-        * This method is partially implemented and will only return false if the config
-        * file does not exist or could not be opened.
-        */
-       bool Verify();
-       /** Dumps the list of errors in a config file to an output location. If bail is true,
-        * then the program will abort. If bail is false and user points to a valid user
-        * record, the error report will be spooled to the given user by means of NOTICE.
-        * if bool is false AND user is false, the error report will be spooled to all opers
-        * by means of a NOTICE to all opers.
-        */
-       void DumpErrors(bool bail,User* user);
 
        /** Returns the number of items within a tag.
         * For example if the tag was &lt;test tag="blah" data="foo"&gt; then this
@@ -1558,7 +1580,7 @@ class CoreExport FileReader : public classbase
         * This function will return false if the file could not be opened.
         */
        bool Exists();
+
        /** Retrieve one line from the file.
         * This method retrieves one line from the text file. If an empty non-NULL string is returned,
         * the index was out of bounds, or the line had no data on it.
@@ -1589,17 +1611,6 @@ typedef std::vector<Module*> IntModuleList;
  */
 typedef IntModuleList::iterator EventHandlerIter;
 
-/** Module priority states
- */
-enum PriorityState
-{
-       PRIO_DONTCARE,
-       PRIO_FIRST,
-       PRIO_LAST,
-       PRIO_AFTER,
-       PRIO_BEFORE
-};
-
 /** ModuleManager takes care of all things module-related
  * in the core.
  */
@@ -1609,19 +1620,19 @@ class CoreExport ModuleManager : public classbase
        /** Holds a string describing the last module error to occur
         */
        std::string LastModuleError;
-       /** The feature names published by various modules
+
+       /** The feature names published by various modules
         */
        featurelist Features;
 
        /** The interface names published by various modules
         */
        interfacelist Interfaces;
+
        /** Total number of modules loaded into the ircd
         */
-       int ModCount; 
-       
+       int ModCount;
+
        /** Our pointer to the main insp instance
         */
        InspIRCd* Instance;
@@ -1631,6 +1642,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.
@@ -1644,7 +1660,7 @@ class CoreExport ModuleManager : public classbase
 
        /** Destructor
         */
-       ~ModuleManager(); 
+       ~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.
@@ -1656,28 +1672,28 @@ 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',
-        * then this contains a list of one or more modules your module must be 
+        * @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.
         */
-       bool SetPriority(Module* mod, Implementation i, PriorityState s, Module** modules = NULL, size_t sz = 1);
+       bool SetPriority(Module* mod, Implementation i, Priority 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
+        * 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.
         */
-       bool SetPriority(Module* mod, PriorityState s);
+       bool SetPriority(Module* mod, Priority s);
 
        /** Attach an event to a module.
         * You may later detatch the event with ModuleManager::Detach().
@@ -1707,7 +1723,7 @@ class CoreExport ModuleManager : public classbase
         * @param mod Module to detach from
         */
        void DetachAll(Module* mod);
+
        /** Returns text describing the last module error
         * @return The last error message to occur
         */
@@ -1724,11 +1740,11 @@ class CoreExport ModuleManager : public classbase
         * @return True if the module was unloaded
         */
        bool Unload(const char* filename);
-       
+
        /** Called by the InspIRCd constructor to load all modules from the config file.
         */
        void LoadAll();
-       
+
        /** Get the total number of currently loaded modules
         * @return The number of loaded modules
         */
@@ -1736,14 +1752,14 @@ class CoreExport ModuleManager : public classbase
        {
                return this->ModCount;
        }
-       
+
        /** Find a module by name, and return a Module* to it.
         * This is preferred over iterating the module lists yourself.
         * @param name The module name to look up
         * @return A pointer to the module, or NULL if the module cannot be found
         */
        Module* Find(const std::string &name);
+
        /** Publish a 'feature'.
         * There are two ways for a module to find another module it depends on.
         * Either by name, using InspIRCd::FindModule, or by feature, using this
@@ -1868,10 +1884,31 @@ class CoreExport ModuleManager : public classbase
  * and functions needed to make a module loadable by the OS.
  * It defines the class factory and external init_module function.
  */
+#ifdef WINDOWS
+
+#define MODULE_INIT(y) \
+       extern "C" DllExport Module * init_module(InspIRCd* Me) \
+       { \
+               return new y(Me); \
+       } \
+       BOOLEAN WINAPI DllMain(HINSTANCE hDllHandle, DWORD nReason, LPVOID Reserved) \
+       { \
+               switch ( nReason ) \
+               { \
+                       case DLL_PROCESS_ATTACH: \
+                       case DLL_PROCESS_DETACH: \
+                               break; \
+               } \
+               return TRUE; \
+       }
+
+#else
+
 #define MODULE_INIT(y) \
        extern "C" DllExport Module * init_module(InspIRCd* Me) \
        { \
                return new y(Me); \
        }
+#endif
 
 #endif