]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/modules.h
Added OnLoadModule and OnUnloadModule (OnLoadModule was not triggering)
[user/henk/code/inspircd.git] / include / modules.h
index c9248575f43701d73efcaff65b759af05386961b..91f9604e550f7769f96d37e538b918925a927338 100644 (file)
@@ -76,7 +76,7 @@ typedef std::deque<userrec*> chanuserlist;
 // loaded modules in a readable simple way, e.g.:
 // 'FOREACH_MOD OnConnect(user);'
 
-#define FOREACH_MOD for (int i = 0; i <= MODCOUNT; i++) modules[i]->
+#define FOREACH_MOD for (int _i = 0; _i <= MODCOUNT; _i++) modules[_i]->
 
 // 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,
@@ -85,8 +85,8 @@ typedef std::deque<userrec*> chanuserlist;
 // *********************************************************************************************
 
 #define FOREACH_RESULT(x) { MOD_RESULT = 0; \
-                       for (int i = 0; i <= MODCOUNT; i++) { \
-                       int res = modules[i]->x ; \
+                       for (int _i = 0; _i <= MODCOUNT; _i++) { \
+                       int res = modules[_i]->x ; \
                        if (res != 0) { \
                                MOD_RESULT = res; \
                                break; \
@@ -127,6 +127,108 @@ class Admin : public classbase
         Admin(std::string name, std::string email, std::string nick);
 };
 
+
+// Forward-delacare module for ModuleMessage etc
+class Module;
+
+// Thanks to Rob (from anope) for the idea of this message passing API
+// (its been done before, but this seemed a very neat and tidy way...
+
+/** The ModuleMessage class is the base class of Request and Event
+ * This class is used to represent a basic data structure which is passed
+ * between modules for safe inter-module communications.
+ */
+class ModuleMessage : public classbase
+{
+ public:
+        /** This class is pure virtual and must be inherited.
+         */
+        virtual char* Send() = 0;
+       virtual ~ModuleMessage() {};
+};
+
+/** The Request class is a unicast message directed at a given module.
+ * When this class is properly instantiated it may be sent to a module
+ * using the Send() method, which will call the given module's OnRequest
+ * method with this class as its parameter.
+ */
+class Request : public ModuleMessage
+{
+ protected:
+        /** This member holds a pointer to arbitary data set by the emitter of the message
+         */
+        char* data;
+        /** This is a pointer to the sender of the message, which can be used to
+         * directly trigger events, or to create a reply.
+         */
+        Module* source;
+        /** The single destination of the Request
+         */
+        Module* dest;
+ public:
+        /** Create a new Request
+         */
+        Request(char* anydata, Module* src, Module* dst);
+        /** Fetch the Request data
+         */
+        char* GetData();
+        /** Fetch the request source
+         */
+        Module* GetSource();
+        /** Fetch the request destination (should be 'this' in the receiving module)
+         */
+        Module* GetDest();
+        /** Send the Request.
+         * Upon returning the result will be arbitary data returned by the module you
+         * sent the request to. It is up to your module to know what this data is and
+         * how to deal with it.
+         */
+        char* Send();
+};
+
+
+/** The Event class is a unicast message directed at all modules.
+ * When the class is properly instantiated it may be sent to all modules
+ * using the Send() method, which will trigger the OnEvent method in
+ * all modules passing the object as its parameter.
+ */
+class Event : public ModuleMessage
+{
+ protected:
+        /** This member holds a pointer to arbitary data set by the emitter of the message
+         */
+        char* data;
+        /** This is a pointer to the sender of the message, which can be used to
+         * directly trigger events, or to create a reply.
+         */
+        Module* source;
+        /** The event identifier.
+         * This is arbitary text which should be used to distinguish
+         * one type of event from another.
+         */
+        std::string id;
+ public:
+        /** Create a new Event
+         */
+        Event(char* anydata, Module* src, std::string eventid);
+        /** Get the Event data
+         */
+        char* GetData();
+        /** Get the event Source
+         */
+        Module* GetSource();
+        /** Get the event ID.
+         * Use this to determine the event type for safe casting of the data
+         */
+        std::string GetEventID();
+        /** Send the Event.
+         * The return result of an Event::Send() will always be NULL as
+         * no replies are expected.
+         */
+        char* Send();
+};
+
+
 /** 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
@@ -159,9 +261,18 @@ class Module : public classbase
 
        /** Called when a user quits.
         * The details of the exiting user are available to you in the parameter userrec *user
+        * This event is only called when the user is fully registered when they quit. To catch
+        * raw disconnections, use the OnUserDisconnect method.
         */
        virtual void OnUserQuit(userrec* user);
 
+       /** Called whenever a user's socket is closed.
+        * The details of the exiting user are available to you in the parameter userrec *user
+        * This event is called for all users, registered or not, as a cleanup method for modules
+        * which might assign resources to user, such as dns lookups, objects and sockets.
+        */
+       virtual void OnUserDisconnect(userrec* user);
+
        /** Called when a user joins a channel.
         * The details of the joining user are available to you in the parameter userrec *user,
         * and the details of the channel they have joined is available in the variable chanrec *channel
@@ -380,6 +491,18 @@ class Module : public classbase
         */
        virtual void OnLoadModule(Module* mod,std::string name);
 
+       /** Called whenever a module is unloaded.
+         * mod will contain a pointer to the module, and string will contain its name,
+         * for example m_widgets.so. This function is primary for dependency checking,
+         * your module may decide to enable some extra features if it sees that you have
+         * for example loaded "m_killwidgets.so" with "m_makewidgets.so". It is highly
+         * recommended that modules do *NOT* bail if they cannot satisfy dependencies,
+         * but instead operate under reduced functionality, unless the dependency is
+         * absolutely neccessary (e.g. a module that extends the features of another
+         * module).
+         */
+       virtual void OnUnloadModule(Module* mod,std::string name);
+
        /** Called once every five seconds for background processing.
         * This timer can be used to control timed features. Its period is not accurate
         * enough to be used as a clock, but it is gauranteed to be called at least once in
@@ -432,7 +555,7 @@ class Module : public classbase
         * so that you may perform your own code instead. Note that this method allows you to override
         * modes defined by other modes, but this is NOT RECOMMENDED!
         */
-       virtual int OnRawMode(userrec* user, char mode, std::string param, bool adding, int pcnt);
+       virtual int OnRawMode(userrec* user, chanrec* chan, char mode, std::string param, bool adding, int pcnt);
 
        /** Called whenever a user joins a channel, to determine if invite checks should go ahead or not.
         * This method will always be called for each join, wether or not the channel is actually +i, and
@@ -482,6 +605,97 @@ class Module : public classbase
         * Return 1 to deny the topic change, or 0 to allow it.
         */
        virtual int OnLocalTopicChange(userrec* user, chanrec* chan, std::string topic);
+
+       /** Called whenever an unknown token is received in a server to server link.
+        * The token value is the unknown token -- please check that no other modules are using the token
+        * that you use. Returning 1 supresses the 'unknown token type' error which is usually sent to
+        * all opers with +s. The params list is a list of parameters, and if any parameters start with a
+        * colon (:) it is treated as the whole of the last parameter, identical to how RFC messages are
+        * handled. source is the sender of the message, and reply is what should be replied to for a unicast
+        * message. Note that there are not many messages in the mesh protocol which require unicast
+        * messaging. tcp_host is the server name as a string, ipaddr is its ip address in dotted decimal
+        * notation and port is the port number it is using.
+        */
+       virtual int OnMeshToken(char token,string_list params,serverrec* source,serverrec* reply, std::string tcp_host,std::string ipaddr,int port);
+
+       /** Called whenever an Event class is sent to all module by another module.
+        * Please see the documentation of Event::Send() for further information. The Event sent can
+        * always be assumed to be non-NULL, you should *always* check the value of Event::GetEventID()
+        * before doing anything to the event data, and you should *not* change the event data in any way!
+        */
+       virtual void OnEvent(Event* event);
+
+       /** Called whenever a Request class is sent to your module by another module.
+        * Please see the documentation of Request::Send() for further information. The Request sent
+        * can always be assumed to be non-NULL, you should not change the request object or its data.
+        * Your method may return arbitary data in the char* result which the requesting module
+        * may be able to use for pre-determined purposes (e.g. the results of an SQL query, etc).
+        */
+       virtual char* OnRequest(Request* request);
+
+       /** Called whenever an oper password is to be compared to what a user has input.
+        * 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.
+        */
+       virtual int OnOperCompare(std::string password, std::string input);
+
+       /** 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
+        * such a task must be performed by another server. You can however bounce modes by sending
+        * servermodes out to reverse mode changes.
+        */
+       virtual void OnGlobalOper(userrec* user);
+
+       /**  Called whenever a user connects, anywhere on the network.
+        * This event is informational only. You should not change any user information in this
+        * event. To do so, use the OnUserConnect method to change the state of local users.
+        */
+       virtual void OnGlobalConnect(userrec* user);
+
+       /** Called whenever a ban is added to a channel's list.
+        * Return a non-zero value to 'eat' the mode change and prevent the ban from being added.
+        */
+       virtual int OnAddBan(userrec* source, chanrec* channel,std::string banmask);
+
+       /** Called whenever a ban is removed from a channel's list.
+        * Return a non-zero value to 'eat' the mode change and prevent the ban from being removed.
+        */
+       virtual int OnDelBan(userrec* source, chanrec* channel,std::string banmask);
+
+       /** 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.
+        */
+       virtual void OnRawSocketAccept(int fd, std::string ip, int localport);
+
+       /** 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
+        * for use by modules which may wrap connections within another API such as SSL for example.
+        * return a non-zero result if you have handled the write operation, in which case the core
+        * will not call write().
+        */
+       virtual int OnRawSocketWrite(int fd, char* buffer, int count);
+
+       /** Called immediately before any socket is closed. When this event is called, shutdown()
+        * has not yet been called on the socket.
+        */
+       virtual void OnRawSocketClose(int fd);
+
+       /** Called immediately before any read() operation on a client socket in the core.
+        * This occurs AFTER the select() or poll() so there is always data waiting to be read
+        * when this event occurs.
+        * Your event should return 1 if it has handled the reading itself, which prevents the core
+        * just using read(). You should place any data read into buffer, up to but NOT GREATER THAN
+        * the value of count. The value of readresult must be identical to an actual result that might
+        * be returned from the read() system call, for example, number of bytes read upon success,
+        * 0 upon EOF or closed socket, and -1 for error. If your function returns a nonzero value,
+        * you MUST set readresult.
+        */
+       virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult);
 };
 
 
@@ -521,6 +735,10 @@ class Server : public classbase
         * as used by numerics (see RFC 1459)
         */
        virtual void SendServ(int Socket, std::string s);
+       /** Writes text to a channel, but from a server, including all.
+        * This can be used to send server notices to a group of users.
+        */
+       virtual void SendChannelServerNotice(std::string ServName, chanrec* Channel, std::string text);
        /** Sends text from a user to a socket.
         * This method writes a line of text to an established socket, with the given user's nick/ident
         * /host combination prepended, as used in PRIVSG etc commands (see RFC 1459)
@@ -579,6 +797,10 @@ class Server : public classbase
         * This function will return NULL if the nick does not exist.
         */
        virtual userrec* FindNick(std::string nick);
+       /** Attempts to look up a nick using the file descriptor associated with that nick.
+        * This function will return NULL if the file descriptor is not associated with a valid user.
+        */
+       virtual userrec* FindDescriptor(int socket);
        /** Attempts to look up a channel and return a pointer to it.
         * This function will return NULL if the channel does not exist.
         */
@@ -598,6 +820,9 @@ class Server : public classbase
        /** Returns the network name, global to all linked servers.
         */
        virtual std::string GetNetworkName();
+       /** Returns the server description string of the local server
+        */
+       virtual std::string GetServerDescription();
        /** Returns the information of the server as returned by the /ADMIN command.
         * See the Admin class for further information of the return value. The members
         * Admin::Nick, Admin::Email and Admin::Name contain the information for the
@@ -875,13 +1100,60 @@ class Server : public classbase
        /** Returns true if a nick!ident@host string is correctly formatted, false if otherwise.
         */
        virtual bool IsValidMask(std::string mask);
+
+       /** Sends a line of text to all connected servers.
+        * If a server is not directly reachable, the core deals with routing the message, and will also
+        * deal with failures transparently.
+        */
+       virtual void MeshSendAll(std::string text);
+
+       /** This method sends a line of text to all servers who have users which share common channels with the user you provide.
+        * For example, if user A is on server A, and they are on channels #one and #two, and user B is on server B, and also on
+        * channel #one, but user C is on server C and on neither #one or #two, this function will cause the text to only be
+        * sent to server B. However, if server B is only reachable via C, it will route it to C (you do not have to worry about
+        * this routing, it is done transparently, but its good to know how things work!)
+        */
+       virtual void MeshSendCommon(userrec* user, std::string text);
+
+       /** This function is equivalent to Server::MeshSendToAll except it will only route to servers which are directly routable.
+        */
+       virtual void MeshSendAllAlive(std::string text);
+
+       /** This function sends a line of text directly to a server.
+        * If the server is not directly routable at this time, the server attempts to route text through the mesh.
+        */
+       virtual void MeshSendUnicast(std::string destination, std::string text);
+
+       /** This function sends to all servers EXCEPT the one you specify.
+        * You should usually use this function to send messages, specifying the SENDER of your message as 'target'.
+        * This will prevent message loops.
+        */
+       virtual void MeshSendAllExcept(std::string target, std::string text);
+
+       /** This function is used to check if any users on channel c are on server servername.
+        * This is used internally by PRIVMSG etc. You should not need to use it.
+        */
+       virtual bool MeshCheckChan(chanrec *c,std::string servername);
+
+       /** This function is used to check if user u has any channels in common with users on servername.
+        * This is used internally by Server::MeshSendCommon. You should very rarely need to use it.
+        */
+       virtual bool MeshCheckCommon(userrec* u,std::string servername);
+
+       /** This function finds a module by name.
+        * You must provide the filename of the module. If the module cannot be found (is not loaded)
+        * the function will return NULL.
+        */
+       virtual Module* FindModule(std::string name);
 };
 
+
 #define CONF_NOT_A_NUMBER      0x000010
 #define CONF_NOT_UNSIGNED      0x000080
 #define CONF_VALUE_NOT_FOUND   0x000100
 #define CONF_FILE_NOT_FOUND    0x000200
 
+
 /** Allows reading of values from configuration files
  * This class allows a module to read from either the main configuration file (inspircd.conf) or from
  * a module-specified configuration file. It may either be instantiated with one parameter or none.