X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=include%2Fmodules.h;h=1e0fcf9365063aba037cb7160ef15b425cd301ee;hb=1b24d217bb55a57c761cc52ee8c6caae40f19a79;hp=a7a42991e6123acd71856ee4e8b32533b61bd47f;hpb=3555423633e1accae18bd804b4c4f9cd69ad33e9;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/include/modules.h b/include/modules.h index a7a42991e..1e0fcf936 100644 --- a/include/modules.h +++ b/include/modules.h @@ -127,6 +127,107 @@ 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; +}; + +/** 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 +260,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 @@ -232,7 +342,19 @@ class Module : public classbase */ virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname); - + /** 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, + * notices etc. + */ + virtual int OnUserPreKick(userrec* source, userrec* user, chanrec* chan, std::string reason); + + /** Called whenever a user is kicked. + * If this method is called, the kick is already underway and cannot be prevented, so + * to prevent a kick, please use Module::OnUserPreKick instead of this method. + */ + virtual void OnUserKick(userrec* source, userrec* user, chanrec* chan, std::string reason); + /** Called whenever a user opers locally. * The userrec will contain the oper mode 'o' as this function is called after any modifications * are made to the user's structure by the core. @@ -384,6 +506,119 @@ class Module : public classbase */ virtual void OnSendList(userrec* user, chanrec* channel, char mode); + /** Called whenever any command is about to be executed. + * This event occurs for all registered commands, wether they are registered in the core, + * or another module, but it will not occur for invalid commands (e.g. ones which do not + * exist within the command table). By returning 1 from this method you may prevent the + * command being executed. If you do this, no output is created by the core, and it is + * down to your module to produce any output neccessary. + * Note that unless you return 1, you should not destroy any structures (e.g. by using + * Server::QuitUser) otherwise when the command's handler function executes after your + * method returns, it will be passed an invalid pointer to the user object and crash!) + */ + virtual int OnPreCommand(std::string command, char **parameters, int pcnt, userrec *user); + + /** 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 + * state until all modules return true. For example a module which implements ident + * lookups will continue to return false for a user until their ident lookup is completed. + * Note that the registration timeout for a user overrides these checks, if the registration + * timeout is reached, the user is disconnected even if modules report that the user is + * not ready to connect. + */ + virtual bool OnCheckReady(userrec* user); + + /** Called whenever a user is about to register their connection (e.g. before the user + * is sent the MOTD etc). Modules can use this method if they are performing a function + * which must be done before the actual connection is completed (e.g. ident lookups, + * dnsbl lookups, etc). + * Note that you should NOT delete the user record here by causing a disconnection! + * Use OnUserConnect for that instead. + */ + virtual void OnUserRegister(userrec* user); + + /** Called whenever a mode character is processed. + * Return 1 from this function to block the mode character from being processed entirely, + * 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, 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 + * determines the outcome of an if statement around the whole section of invite checking code. + * return 1 to explicitly allow the join to go ahead or 0 to ignore the event. + */ + virtual int OnCheckInvite(userrec* user, chanrec* chan); + + /** 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. + * if the user specified no key, the keygiven string will be a valid but empty value. + * return 1 to explicitly allow the join to go ahead or 0 to ignore the event. + */ + virtual int OnCheckKey(userrec* user, chanrec* chan, std::string keygiven); + + /** Called whenever a user joins a channel, to determine if channel limit checks should go ahead or not. + * This method will always be called for each join, wether or not the channel is actually +l, and + * determines the outcome of an if statement around the whole section of channel limit checking code. + * return 1 to explicitly allow the join to go ahead or 0 to ignore the event. + */ + virtual int OnCheckLimit(userrec* user, chanrec* chan); + + /** Called whenever a user joins a channel, to determine if banlist checks should go ahead or not. + * This method will always be called for each join, wether or not the user actually matches a channel ban, and + * determines the outcome of an if statement around the whole section of ban checking code. + * return 1 to explicitly allow the join to go ahead or 0 to ignore the event. + */ + virtual int OnCheckBan(userrec* user, chanrec* chan); + + /** Called on all /STATS commands + * This method is triggered for all /STATS use, including stats symbols handled by the core. + */ + virtual void OnStats(char symbol); + + /** Called whenever a change of a local users displayed host is attempted. + * Return 1 to deny the host change, or 0 to allow it. + */ + virtual int OnChangeLocalUserHost(userrec* user, std::string newhost); + + /** Called whenever a change of a local users GECOS (fullname field) is attempted. + * return 1 to deny the name change, or 0 to allow it. + */ + virtual int OnChangeLocalUserGECOS(userrec* user, 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. + */ + 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); }; @@ -777,13 +1012,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.