/**
* This #define allows us to call a method in all
* loaded modules in a readable simple way, e.g.:
- * 'FOREACH_MOD(I_OnConnect,OnConnect(user));'
+ * 'FOREACH_MOD(OnConnect,(user));'
*/
#define FOREACH_MOD(y,x) do { \
- EventHandlerIter safei; \
- for (EventHandlerIter _i = ServerInstance->Modules->EventHandlers[y].begin(); _i != ServerInstance->Modules->EventHandlers[y].end(); ) \
+ const IntModuleList& _handlers = ServerInstance->Modules->EventHandlers[I_ ## y]; \
+ for (IntModuleList::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
{ \
- safei = _i; \
- ++safei; \
+ _next = _i+1; \
try \
{ \
- (*_i)->x ; \
+ (*_i)->y x ; \
} \
catch (CoreException& modexcept) \
{ \
ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: %s",modexcept.GetReason()); \
} \
- _i = safei; \
} \
} while (0);
*/
#define DO_EACH_HOOK(n,v,args) \
do { \
- EventHandlerIter iter_ ## n = ServerInstance->Modules->EventHandlers[I_ ## n].begin(); \
- while (iter_ ## n != ServerInstance->Modules->EventHandlers[I_ ## n].end()) \
+ const IntModuleList& _handlers = ServerInstance->Modules->EventHandlers[I_ ## n]; \
+ for (IntModuleList::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
{ \
- Module* mod_ ## n = *iter_ ## n; \
- iter_ ## n ++; \
+ _next = _i+1; \
try \
{ \
- v = (mod_ ## n)->n args;
+ v = (*_i)->n args;
#define WHILE_EACH_HOOK(n) \
} \
catch (CoreException& except_ ## n) \
{ \
ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: %s", (except_ ## n).GetReason()); \
- (void) mod_ ## n; /* catch mismatched pairs */ \
} \
} \
} while(0)
: ServiceProvider(Creator, Name, SERVICE_DATA) {}
};
-class CoreExport dynamic_reference_base : public interfacebase
-{
- private:
- std::string name;
- void resolve();
- protected:
- ServiceProvider* value;
- public:
- ModuleRef creator;
- dynamic_reference_base(Module* Creator, const std::string& Name);
- ~dynamic_reference_base();
- inline const std::string& GetProvider() { return name; }
- void SetProvider(const std::string& newname);
- void check();
- operator bool() { return (value != NULL); }
- static void reset_all();
-};
-
-inline void dynamic_reference_base::check()
-{
- if (!value)
- throw ModuleException("Dynamic reference to '" + name + "' failed to resolve");
-}
-
-template<typename T>
-class dynamic_reference : public dynamic_reference_base
-{
- public:
- dynamic_reference(Module* Creator, const std::string& Name)
- : dynamic_reference_base(Creator, Name) {}
-
- inline T* operator->()
- {
- check();
- return static_cast<T*>(value);
- }
-
- T* operator*()
- {
- return operator->();
- }
-};
-
-template<typename T>
-class dynamic_reference_nocheck : public dynamic_reference_base
-{
- public:
- dynamic_reference_nocheck(Module* Creator, const std::string& Name)
- : dynamic_reference_base(Creator, Name) {}
-
- T* operator->()
- {
- return static_cast<T*>(value);
- }
-
- T* operator*()
- {
- return operator->();
- }
-};
-
-class ModeReference : public dynamic_reference_nocheck<ModeHandler>
-{
- public:
- ModeReference(Module* mod, const std::string& modename)
- : dynamic_reference_nocheck<ModeHandler>(mod, "mode/" + modename) {}
-};
-
/** Priority types which can be used by Module::Prioritize()
*/
enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
I_OnUserMessage, I_OnMode, I_OnGetServerDescription, 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_OnRemoteKill, I_OnLoadModule,
+ 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,
*/
class CoreExport Module : public classbase, public usecountbase
{
+ /** Detach an event from this module
+ * @param i Event type to detach
+ */
+ void DetachEvent(Implementation i);
+
public:
/** File that this module was loaded from
*/
virtual void OnText(User* user, void* dest, int target_type, const std::string &text, char status, CUList &exempt_list);
/** Called after every MODE command sent from a user
- * The dest variable contains a User* if target_type is TYPE_USER and a Channel*
- * if target_type is TYPE_CHANNEL. The text variable contains the remainder of the
- * mode string after the target, e.g. "+wsi" or "+ooo nick1 nick2 nick3".
+ * 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"].
* @param user The user sending the MODEs
- * @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 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, void* dest, int target_type, const std::vector<std::string> &text, const std::vector<TranslateType> &translate);
+ 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
/** Called when a 005 numeric is about to be output.
* The module should modify the 005 numeric if needed to indicate its features.
- * @param output The 005 map to be modified if neccessary.
+ * @param tokens The 005 map to be modified if neccessary.
*/
virtual void On005Numeric(std::map<std::string, std::string>& tokens);
*/
virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
- /** Called when an oper wants to disconnect a remote user via KILL
- * @param source The user sending the KILL
- * @param dest The user being killed
- * @param reason The kill reason
- * @param operreason The oper kill reason
- */
- virtual void OnRemoteKill(User* source, User* dest, const std::string &reason, const std::string &operreason);
-
/** Called whenever a module is loaded.
* 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,
FileReader() : totalSize(0) { }
/** Initializes a new file reader and reads the specified file.
- * @param file The file to read into memory.
+ * @param filename The file to read into memory.
*/
FileReader(const std::string& filename);
*/
void DetachAll(Module* mod);
+ /** Attach all events to a module (used on module load)
+ * @param mod Module to attach to all events
+ */
+ void AttachAll(Module* mod);
+
/** Returns text describing the last module error
* @return The last error message to occur
*/