]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/modules.h
Merge insp20
[user/henk/code/inspircd.git] / include / modules.h
index d13ff58b0cb8c5e2b9822423e239e080cb7ab9fa..fc2aa6324b9dbdf8d0f6a52ec616548b936dcd8e 100644 (file)
@@ -132,7 +132,7 @@ struct ModResult {
                } \
                catch (CoreException& modexcept) \
                { \
-                       ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: %s",modexcept.GetReason()); \
+                       ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + modexcept.GetReason()); \
                } \
        } \
 } while (0);
@@ -157,7 +157,7 @@ do { \
                } \
                catch (CoreException& except_ ## n) \
                { \
-                       ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: %s", (except_ ## n).GetReason()); \
+                       ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
                } \
        } \
 } while(0)
@@ -206,34 +206,6 @@ class CoreExport Version
        virtual ~Version() {}
 };
 
-/** 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 CoreExport Event : public classbase
-{
- public:
-       /** This is a pointer to the sender of the message, which can be used to
-        * directly trigger events, or to create a reply.
-        */
-       ModuleRef source;
-       /** The event identifier.
-        * This is arbitary text which should be used to distinguish
-        * one type of event from another.
-        */
-       const std::string id;
-
-       /** Create a new Event
-        */
-       Event(Module* src, const std::string &eventid);
-       /** Send the Event.
-        * The return result of an Event::Send() will always be NULL as
-        * no replies are expected.
-        */
-       void Send();
-};
-
 class CoreExport DataProvider : public ServiceProvider
 {
  public:
@@ -249,22 +221,21 @@ enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER }
  */
 enum Implementation
 {
-       I_BEGIN,
-       I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart, I_OnRehash,
+       I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart,
        I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo, I_OnWhois,
        I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNick,
-       I_OnUserMessage, I_OnMode, I_OnGetServerDescription, I_OnSyncUser,
+       I_OnUserMessage, I_OnMode, I_OnSyncUser,
        I_OnSyncChannel, I_OnDecodeMetaData, I_OnAcceptConnection, I_OnUserInit,
        I_OnChangeHost, I_OnChangeName, I_OnAddLine, I_OnDelLine, I_OnExpireLine,
        I_OnUserPostNick, I_OnPreMode, I_On005Numeric, I_OnKill, I_OnLoadModule,
        I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
        I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck,
        I_OnStats, I_OnChangeLocalUserHost, I_OnPreTopicChange,
-       I_OnPostTopicChange, I_OnEvent, I_OnGlobalOper, I_OnPostConnect,
+       I_OnPostTopicChange, I_OnPostConnect,
        I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
        I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin,
        I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
-       I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookIO,
+       I_OnText, I_OnPassCompare, I_OnNamesListItem, I_OnNumeric,
        I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, I_OnSetUserIP,
        I_END
 };
@@ -319,6 +290,13 @@ class CoreExport Module : public classbase, public usecountbase
        {
        }
 
+       /** This method is called when you should reload module specific configuration:
+        * on boot, on a /REHASH and on module load.
+        * @param status The current status, can be inspected for more information;
+        * also used for reporting configuration errors and warnings.
+        */
+       virtual void ReadConfig(ConfigStatus& status);
+
        /** Returns the version number of a Module.
         * The method should return a Version object with its version information assigned via
         * Version::Version
@@ -409,14 +387,6 @@ class CoreExport Module : public classbase, public usecountbase
         */
        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')
@@ -557,19 +527,16 @@ class CoreExport Module : public classbase, public usecountbase
         *
         * Set exceptions[user] = true to include, exceptions[user] = false to exclude
         */
-       virtual void OnBuildNeighborList(User* source, UserChanList &include_c, std::map<User*,bool> &exceptions);
+       virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
 
-       /** 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.
-        * check user->server before taking any action (including returning nonzero from the method).
+       /** Called before local nickname changes. This can be used to implement Q-lines etc.
         * If your method returns nonzero, the nickchange is silently forbidden, and it is down to your
         * module to generate some meaninful output.
         * @param user The username changing their nick
         * @param newnick Their new nickname
         * @return 1 to deny the change, 0 to allow
         */
-       virtual ModResult OnUserPreNick(User* user, const std::string &newnick);
+       virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
 
        /** Called after any PRIVMSG sent from a user.
         * The dest variable contains a User* if target_type is TYPE_USER and a Channel*
@@ -602,65 +569,45 @@ class CoreExport Module : public classbase, public usecountbase
        /** Called after every MODE command sent from a user
         * Either the usertarget or the chantarget variable contains the target of the modes,
         * the actual target will have a non-NULL pointer.
-        * The modes vector contains the remainder of the mode string after the target,
-        * e.g.: "+wsi" or ["+ooo", "nick1", "nick2", "nick3"].
+        * All changed modes are available in the changelist object.
         * @param user The user sending the MODEs
         * @param usertarget The target user of the modes, NULL if the target is a channel
         * @param chantarget The target channel of the modes, NULL if the target is a user
-        * @param modes The actual modes and their parameters if any
-        * @param translate The translation types of the mode parameters
-        */
-       virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const std::vector<std::string>& modes, 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
-        * WHOIS, this function is called in all modules. You may change or define the
-        * description given in std::string &description. If you do, this description
-        * will be shown in the WHOIS fields.
-        * @param servername The servername being searched for
-        * @param description Alterable server description for this server
+        * @param changelist The changed modes.
+        * @param processflags Flags passed to ModeParser::Process(), see ModeParser::ModeProcessFlags
+        * for the possible flags.
+        * @param output_mode Changed modes, including '+' and '-' characters, not including any parameters
         */
-       virtual void OnGetServerDescription(const std::string &servername,std::string &description);
+       virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags, const std::string& output_mode);
 
        /** Allows modules to synchronize data which relates to users during a netburst.
         * When this function is called, it will be called from the module which implements
-        * the linking protocol. This currently is m_spanningtree.so. A pointer to this module
-        * is given in Module* proto, so that you may call its methods such as ProtoSendMode
-        * (see below). This function will be called for every user visible on your side
-        * of the burst, allowing you to for example set modes, etc. Do not use this call to
-        * synchronize data which you have stored using class Extensible -- There is a specialist
-        * function OnSyncUserMetaData and OnSyncChannelMetaData for this!
+        * the linking protocol. This currently is m_spanningtree.so.
+        * This function will be called for every user visible on your side
+        * of the burst, allowing you to for example set modes, etc.
         * @param user The user being syncronized
-        * @param proto A pointer to the module handling network protocol
-        * @param opaque An opaque pointer set by the protocol module, should not be modified!
+        * @param server The target of the burst
         */
-       virtual void OnSyncUser(User* user, Module* proto, void* opaque);
+       virtual void OnSyncUser(User* user, ProtocolServer& server);
 
        /** Allows modules to synchronize data which relates to channels during a netburst.
         * When this function is called, it will be called from the module which implements
-        * the linking protocol. This currently is m_spanningtree.so. A pointer to this module
-        * is given in Module* proto, so that you may call its methods such as ProtoSendMode
-        * (see below). This function will be called for every user visible on your side
-        * of the burst, allowing you to for example set modes, etc.
+        * the linking protocol. This currently is m_spanningtree.so.
+        * This function will be called for every channel visible on your side of the burst,
+        * allowing you to for example set modes, etc.
         *
         * @param chan The channel being syncronized
-        * @param proto A pointer to the module handling network protocol
-        * @param opaque An opaque pointer set by the protocol module, should not be modified!
+        * @param server The target of the burst
         */
-       virtual void OnSyncChannel(Channel* chan, Module* proto, void* opaque);
+       virtual void OnSyncChannel(Channel* chan, ProtocolServer& server);
 
-       /* Allows modules to syncronize metadata not related to users or channels, over the network during a netburst.
-        * Whenever the linking module wants to send out data, but doesnt know what the data
-        * represents (e.g. it is Extensible metadata, added to a User or Channel by a module) then
-        * this method is called. You should use the ProtoSendMetaData function after you've
-        * correctly decided how the data should be represented, to send the metadata on its way if
-        * if it belongs to your module.
-        * @param proto A pointer to the module handling network protocol
-        * @param opaque An opaque pointer set by the protocol module, should not be modified!
-        * @param displayable If this value is true, the data is going to be displayed to a user,
-        * and not sent across the network. Use this to determine wether or not to show sensitive data.
+       /** Allows modules to syncronize metadata not related to users or channels, over the network during a netburst.
+        * When the linking module has finished sending all data it wanted to send during a netburst, then
+        * this method is called. You should use the SendMetaData() function after you've
+        * correctly decided how the data should be represented, to send the data.
+        * @param server The target of the burst
         */
-       virtual void OnSyncNetwork(Module* proto, void* opaque);
+       virtual void OnSyncNetwork(ProtocolServer& server);
 
        /** Allows module data, sent via ProtoSendMetaData, to be decoded again by a receiving module.
         * Please see src/modules/m_swhois.cpp for a working example of how to use this method call.
@@ -670,34 +617,6 @@ class CoreExport Module : public classbase, public usecountbase
         */
        virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
 
-       /** Implemented by modules which provide the ability to link servers.
-        * These modules will implement this method, which allows transparent sending of servermodes
-        * down the network link as a broadcast, without a module calling it having to know the format
-        * of the MODE command before the actual mode string.
-        *
-        * @param opaque An opaque pointer set by the protocol module, should not be modified!
-        * @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, 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
-        * user and channel records using class Extensible, Extensible::Extend, etc) to be sent
-        * to other servers on a netburst and decoded at the other end by the same module on a
-        * different server.
-        *
-        * More documentation to follow soon. Please see src/modules/m_swhois.cpp for example of
-        * how to use this function.
-        * @param opaque An opaque pointer set by the protocol module, should not be modified!
-        * @param target The Channel* or User* that metadata should be sent for
-        * @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, Extensible* target, const std::string &extname, const std::string &extdata);
-
        /** Called whenever a user's hostname is changed.
         * This event triggers after the host has been set.
         * @param user The user whos host is being changed
@@ -761,7 +680,7 @@ class CoreExport Module : public classbase, public usecountbase
         */
        virtual void OnUserPostNick(User* user, const std::string &oldnick);
 
-       /** Called before any mode change, to allow a single access check for
+       /** Called before a mode change via the MODE command, to allow a single access check for
         * a full mode change (use OnRawMode to check individual modes)
         *
         * Returning MOD_RES_ALLOW will skip prefix level checks, but can be overridden by
@@ -770,9 +689,9 @@ class CoreExport Module : public classbase, public usecountbase
         * @param source the user making the mode change
         * @param dest the user destination of the umode change (NULL if a channel mode)
         * @param channel the channel destination of the mode change
-        * @param parameters raw mode parameters; parameters[0] is the user/channel being changed
+        * @param modes Modes being changed, can be edited
         */
-       virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters);
+       virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
 
        /** Called when a 005 numeric is about to be output.
         * The module should modify the 005 numeric if needed to indicate its features.
@@ -903,15 +822,14 @@ class CoreExport Module : public classbase, public usecountbase
         * 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 mh The mode handler for the mode being changed
         * @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 ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string &param, bool adding, int pcnt);
+       virtual ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding);
 
        /** 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
@@ -1005,12 +923,6 @@ class CoreExport Module : public classbase, public usecountbase
         */
        virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
 
-       /** Called whenever an Event class is sent to all modules by another module.
-        * You should *always* check the value of Event::id to determine the event type.
-        * @param event The Event class being received
-        */
-       virtual void OnEvent(Event& event);
-
        /** 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 passwords (oper, connect:allow, die/restart, etc).
@@ -1023,14 +935,6 @@ class CoreExport Module : public classbase, public usecountbase
         */
        virtual ModResult 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
-        * such a task must be performed by another server. You can however bounce modes by sending
-        * servermodes out to reverse mode changes.
-        * @param user The user who is opering
-        */
-       virtual void OnGlobalOper(User* user);
-
        /** Called after a user has fully connected and all modules have executed OnUserConnect
         * 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.
@@ -1039,12 +943,6 @@ class CoreExport Module : public classbase, public usecountbase
         */
        virtual void OnPostConnect(User* user);
 
-       /** Called to install an I/O hook on an event handler
-        * @param user The socket to possibly install the I/O hook on
-        * @param via The port that the user connected on
-        */
-       virtual void OnHookIO(StreamSocket* user, ListenSocket* via);
-
        /** Called when a port accepts a connection
         * Return MOD_RES_ACCEPT if you have used the file descriptor.
         * @param fd The file descriptor returned from accept()
@@ -1090,16 +988,24 @@ class CoreExport Module : public classbase, public usecountbase
         */
        virtual ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass);
 
+#ifdef INSPIRCD_ENABLE_TESTSUITE
        /** Add test suite hooks here. These are used for testing functionality of a module
         * via the --testsuite debugging parameter.
         */
        virtual void OnRunTestSuite();
+#endif
 
        /** 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.
+        * For example NAMESX, channel mode +u and +I, and UHNAMES.
+        * @param issuer The user who is going to receive the NAMES list being built
+        * @param item The channel member being considered for inclusion
+        * @param prefixes The prefix character(s) to display, initially set to the prefix char of the most powerful
+        * prefix mode the member has, can be changed
+        * @param nick The nick to display, initially set to the member's nick, can be changed
+        * @return Return MOD_RES_PASSTHRU to allow the member to be displayed, MOD_RES_DENY to cause them to be
+        * excluded from this NAMES list
         */
-       virtual void OnNamesListItem(User* issuer, Membership* item, std::string &prefixes, std::string &nick);
+       virtual ModResult OnNamesListItem(User* issuer, Membership* item, std::string& prefixes, std::string& nick);
 
        virtual ModResult OnNumeric(User* user, unsigned int numeric, const std::string &text);
 
@@ -1107,9 +1013,10 @@ class CoreExport Module : public classbase, public usecountbase
         * @param source The user running the /WHO query
         * @param params The parameters to the /WHO query
         * @param user The user that this line of the query is about
+        * @param memb The member shown in this line, NULL if no channel is in this line
         * @param line The raw line to send; modifiable, if empty no line will be returned.
         */
-       virtual void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, std::string& line);
+       virtual void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, Membership* memb, std::string& line);
 
        /** Called whenever a local user's IP is set for the first time, or when a local user's IP changes due to
         * a module like m_cgiirc changing it.
@@ -1118,44 +1025,6 @@ class CoreExport Module : public classbase, public usecountbase
        virtual void OnSetUserIP(LocalUser* user);
 };
 
-/** Provides an easy method of reading a text file into memory. */
-class CoreExport FileReader : public classbase
-{
-       /** The lines of text in the file.
-        */
-       std::vector<std::string> lines;
-
-       /** Content size in bytes
-        */
-       unsigned long totalSize;
-
- public:
-       /** Initializes a new file reader.
-        */
-       FileReader() : totalSize(0) { }
-
-       /** Initializes a new file reader and reads the specified file.
-        * @param filename The file to read into memory.
-        */
-       FileReader(const std::string& filename);
-
-       /** Loads a text file from disk.
-        * @param filename The file to read into memory.
-        * @throw CoreException The file can not be loaded.
-        */
-       void Load(const std::string& filename);
-
-       /** Retrieves the entire contents of the file cache as a single string.
-        */
-       std::string GetString();
-
-       /** Retrieves the entire contents of the file cache as a vector of strings.
-        */
-       const std::vector<std::string>& GetVector() { return lines; }
-
-       unsigned long TotalSize() { return totalSize; }
-};
-
 /** A list of modules
  */
 typedef std::vector<Module*> IntModuleList;
@@ -1167,17 +1036,16 @@ typedef IntModuleList::iterator EventHandlerIter;
 /** ModuleManager takes care of all things module-related
  * in the core.
  */
-class CoreExport ModuleManager
+class CoreExport ModuleManager : public fakederef<ModuleManager>
 {
+ public:
+       typedef std::vector<ServiceProvider*> ServiceList;
+
  private:
        /** Holds a string describing the last module error to occur
         */
        std::string LastModuleError;
 
-       /** Total number of modules loaded into the ircd
-        */
-       int ModCount;
-
        /** List of loaded modules and shared object/dll handles
         * keyed by module name
         */
@@ -1191,7 +1059,18 @@ class CoreExport ModuleManager
 
        /** Internal unload module hook */
        bool CanUnload(Module*);
+
+       /** Loads all core modules (cmd_*)
+        */
+       void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
+
+       /** Calls the Prioritize() method in all loaded modules
+        * @return True if all went well, false if a dependency loop was detected
+        */
+       bool PrioritizeHooks();
+
  public:
+       typedef std::map<std::string, Module*> ModuleMap;
 
        /** Event handler hooks.
         * This needs to be public to be used by FOREACH_MOD and friends.
@@ -1201,6 +1080,16 @@ class CoreExport ModuleManager
        /** List of data services keyed by name */
        std::multimap<std::string, ServiceProvider*> DataProviders;
 
+       /** A list of ServiceProviders waiting to be registered.
+        * Non-NULL when constructing a Module, NULL otherwise.
+        * When non-NULL ServiceProviders add themselves to this list on creation and the core
+        * automatically registers them (that is, call AddService()) after the Module is constructed,
+        * and before Module::init() is called.
+        * If a service is created after the construction of the Module (for example in init()) it
+        * has to be registered manually.
+        */
+       ServiceList* NewServices;
+
        /** Simple, bog-standard, boring constructor.
         */
        ModuleManager();
@@ -1227,12 +1116,6 @@ class CoreExport ModuleManager
         */
        bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
 
-       /** Backwards compat interface */
-       inline bool SetPriority(Module* mod, Implementation i, Priority s, Module** dptr)
-       {
-               return SetPriority(mod, i, s, *dptr);
-       }
-
        /** 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.
@@ -1241,7 +1124,7 @@ class CoreExport ModuleManager
         * SetPriority method for this, where you may specify other modules to
         * be prioritized against.
         */
-       bool SetPriority(Module* mod, Priority s);
+       void SetPriority(Module* mod, Priority s);
 
        /** Attach an event to a module.
         * You may later detatch the event with ModuleManager::Detach().
@@ -1309,14 +1192,6 @@ class CoreExport ModuleManager
        void UnloadAll();
        void DoSafeUnload(Module*);
 
-       /** Get the total number of currently loaded modules
-        * @return The number of loaded modules
-        */
-       int GetCount()
-       {
-               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
@@ -1330,6 +1205,11 @@ class CoreExport ModuleManager
        /** Unregister a service provided by a module */
        void DelService(ServiceProvider&);
 
+       /** Register all services in a given ServiceList
+        * @param list The list containing the services to register
+        */
+       void AddServices(const ServiceList& list);
+
        inline void AddServices(ServiceProvider** list, int count)
        {
                for(int i=0; i < count; i++)
@@ -1346,13 +1226,10 @@ class CoreExport ModuleManager
                return static_cast<T*>(FindService(SERVICE_DATA, name));
        }
 
-       /** 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
+       /** Get a map of all loaded modules keyed by their name
+        * @return A ModuleMap containing all loaded modules
         */
-       const std::vector<std::string> GetAllModuleNames(int filter);
+       const ModuleMap& GetModules() const { return Modules; }
 };
 
 /** Do not mess with these functions unless you know the C preprocessor
@@ -1382,11 +1259,7 @@ struct AllModuleList {
 };
 
 #define MODULE_INIT(x) static Module* MK_ ## x() { return new x; } \
-       static const AllModuleList PREP_ ## x(&MK_ ## x, MODNAMESTR);
-
-#define MODNAMESTR MODNAMESTR_FN_2(MODNAME)
-#define MODNAMESTR_FN_2(x) MODNAMESTR_FN_1(x)
-#define MODNAMESTR_FN_1(x) #x
+       static const AllModuleList PREP_ ## x(&MK_ ## x, MODNAME ".so");
 
 #else
 
@@ -1410,7 +1283,8 @@ struct AllModuleList {
                                break; \
                } \
                return TRUE; \
-       }
+       } \
+       extern "C" DllExport const char inspircd_src_version[] = INSPIRCD_VERSION " " INSPIRCD_REVISION;
 
 #else
 
@@ -1419,7 +1293,7 @@ struct AllModuleList {
        { \
                return new y; \
        } \
-       extern "C" const char inspircd_src_version[] = VERSION " " REVISION;
+       extern "C" DllExport const char inspircd_src_version[] = INSPIRCD_VERSION " " INSPIRCD_REVISION;
 #endif
 
 #define COMMAND_INIT(c) MODULE_INIT(CommandModule<c>)