2 * Copyright (C) 2004-2011 See the AUTHORS file for details.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published
6 * by the Free Software Foundation.
12 #include "zncconfig.h"
13 #include "WebModules.h"
20 // Forward Declarations
30 // !Forward Declarations
37 #error This module only works when znc is compiled with OpenSSL support
43 typedef void* ModHandle
;
45 template<class M
> void TModInfo(CModInfo
& Info
) {}
47 template<class M
> CModule
* TModLoad(ModHandle p
, CUser
* pUser
,
48 const CString
& sModName
, const CString
& sModPath
) {
49 return new M(p
, pUser
, sModName
, sModPath
);
51 template<class M
> CGlobalModule
* TModLoadGlobal(ModHandle p
,
52 const CString
& sModName
, const CString
& sModPath
) {
53 return new M(p
, sModName
, sModPath
);
57 # define MODULE_EXPORT __attribute__((__visibility__("default")))
59 # define MODULE_EXPORT
62 #define MODCOMMONDEFS(CLASS, DESCRIPTION, GLOBAL, LOADER) \
64 MODULE_EXPORT bool ZNCModInfo(double dCoreVersion, CModInfo& Info); \
65 bool ZNCModInfo(double dCoreVersion, CModInfo& Info) { \
66 if (dCoreVersion != VERSION) \
68 Info.SetDescription(DESCRIPTION); \
69 Info.SetGlobal(GLOBAL); \
71 TModInfo<CLASS>(Info); \
76 /** Instead of writing a constructor, you should call this macro. It accepts all
77 * the necessary arguments and passes them on to CModule's constructor. You
78 * should assume that there are no arguments to the constructor.
82 * class MyModule : public CModule {
83 * MODCONSTRUCTOR(MyModule) {
84 * // Your own constructor's code here
89 * @param CLASS The name of your module's class.
90 * @see For global modules you need GLOBALMODCONSTRUCTOR.
92 #define MODCONSTRUCTOR(CLASS) \
93 CLASS(ModHandle pDLL, CUser* pUser, const CString& sModName, \
94 const CString& sModPath) \
95 : CModule(pDLL, pUser, sModName, sModPath)
97 /** At the end of your source file, you must call this macro in global context.
98 * It defines some static functions which ZNC needs to load this module.
99 * @param CLASS The name of your module's class.
100 * @param DESCRIPTION A short description of your module.
101 * @see For global modules you need GLOBALMODULEDEFS.
103 #define MODULEDEFS(CLASS, DESCRIPTION) \
104 MODCOMMONDEFS(CLASS, DESCRIPTION, false, Info.SetLoader(TModLoad<CLASS>))
105 // !User Module Macros
107 // Global Module Macros
108 /** This works exactly like MODCONSTRUCTOR, but for global modules. */
109 #define GLOBALMODCONSTRUCTOR(CLASS) \
110 CLASS(ModHandle pDLL, const CString& sModName, const CString& sModPath) \
111 : CGlobalModule(pDLL, sModName, sModPath)
113 /** This works exactly like MODULEDEFS, but for global modules. */
114 #define GLOBALMODULEDEFS(CLASS, DESCRIPTION) \
115 MODCOMMONDEFS(CLASS, DESCRIPTION, true, Info.SetGlobalLoader(TModLoadGlobal<CLASS>))
116 // !Global Module Macros
118 // Forward Declarations
126 // !Forward Declarations
128 class CTimer
: public CCron
{
130 CTimer(CModule
* pModule
, unsigned int uInterval
, unsigned int uCycles
, const CString
& sLabel
, const CString
& sDescription
);
135 void SetModule(CModule
* p
);
136 void SetDescription(const CString
& s
);
140 CModule
* GetModule() const;
141 const CString
& GetDescription() const;
146 CString m_sDescription
;
149 typedef void (*FPTimer_t
)(CModule
*, CFPTimer
*);
151 class CFPTimer
: public CTimer
{
153 CFPTimer(CModule
* pModule
, unsigned int uInterval
, unsigned int uCycles
, const CString
& sLabel
, const CString
& sDescription
)
154 : CTimer(pModule
, uInterval
, uCycles
, sLabel
, sDescription
) {
155 m_pFBCallback
= NULL
;
158 virtual ~CFPTimer() {}
160 void SetFPCallback(FPTimer_t p
) { m_pFBCallback
= p
; }
163 virtual void RunJob() {
165 m_pFBCallback(m_pModule
, this);
170 FPTimer_t m_pFBCallback
;
175 typedef CModule
* (*ModLoader
)(ModHandle p
, CUser
* pUser
, const CString
& sModName
, const CString
& sModPath
);
176 typedef CGlobalModule
* (*GlobalModLoader
)(ModHandle p
, const CString
& sModName
, const CString
& sModPath
);
179 m_fGlobalLoader
= NULL
;
182 CModInfo(const CString
& sName
, const CString
& sPath
, bool bGlobal
) {
186 m_fGlobalLoader
= NULL
;
191 bool operator < (const CModInfo
& Info
) const {
192 return (GetName() < Info
.GetName());
196 const CString
& GetName() const { return m_sName
; }
197 const CString
& GetPath() const { return m_sPath
; }
198 const CString
& GetDescription() const { return m_sDescription
; }
199 const CString
& GetWikiPage() const { return m_sWikiPage
; }
200 bool IsGlobal() const { return m_bGlobal
; }
201 ModLoader
GetLoader() const { return m_fLoader
; }
202 GlobalModLoader
GetGlobalLoader() const { return m_fGlobalLoader
; }
206 void SetName(const CString
& s
) { m_sName
= s
; }
207 void SetPath(const CString
& s
) { m_sPath
= s
; }
208 void SetDescription(const CString
& s
) { m_sDescription
= s
; }
209 void SetWikiPage(const CString
& s
) { m_sWikiPage
= s
; }
210 void SetGlobal(bool b
) { m_bGlobal
= b
; }
211 void SetLoader(ModLoader fLoader
) { m_fLoader
= fLoader
; }
212 void SetGlobalLoader(GlobalModLoader fGlobalLoader
) { m_fGlobalLoader
= fGlobalLoader
; }
219 CString m_sDescription
;
222 GlobalModLoader m_fGlobalLoader
;
225 /** A helper class for handling commands in modules. */
228 /// Type for the callback function that handles the actual command.
229 typedef void (CModule::*ModCmdFunc
)(const CString
& sLine
);
231 /// Default constructor, needed so that this can be saved in a std::map.
234 /** Construct a new CModCommand.
235 * @param sCmd The name of the command.
236 * @param func The command's callback function.
237 * @param sArgs Help text describing the arguments to this command.
238 * @param sDesc Help text describing what this command does.
240 CModCommand(const CString
& sCmd
, ModCmdFunc func
, const CString
& sArgs
, const CString
& sDesc
);
242 /** Copy constructor, needed so that this can be saved in a std::map.
243 * @param other Object to copy from.
245 CModCommand(const CModCommand
& other
);
247 /** Assignment operator, needed so that this can be saved in a std::map.
248 * @param other Object to copy from.
250 CModCommand
& operator=(const CModCommand
& other
);
252 /** Initialize a CTable so that it can be used with AddHelp().
253 * @param Table The instance of CTable to initialize.
255 static void InitHelp(CTable
& Table
);
257 /** Add this command to the CTable instance.
258 * @param Table Instance of CTable to which this should be added.
259 * @warning The Table should be initialized via InitHelp().
261 void AddHelp(CTable
& Table
) const;
263 const CString
& GetCommand() const { return m_sCmd
; }
264 ModCmdFunc
GetFunction() const { return m_pFunc
; }
265 const CString
& GetArgs() const { return m_sArgs
; }
266 const CString
& GetDescription() const { return m_sDesc
; }
268 void Call(CModule
*pMod
, const CString
& sLine
) const { (pMod
->*m_pFunc
)(sLine
); }
277 /** The base class for your own ZNC modules.
279 * If you want to write a module for znc, you will have to implement a class
280 * which inherits from this class. You should override some of the "On*"
281 * functions in this class. These function will then be called by ZNC when the
282 * associated event happens.
284 * If such a module hook is called with a non-const reference to e.g. a
285 * CString, then it is free to modify that argument to influence ZNC's
288 * @see MODCONSTRUCTOR and MODULEDEFS
292 CModule(ModHandle pDLL
, CUser
* pUser
, const CString
& sModName
,
293 const CString
& sDataDir
);
294 CModule(ModHandle pDLL
, const CString
& sModName
, const CString
& sDataDir
);
297 /** This enum is just used for return from module hooks. Based on this
298 * return, ZNC then decides what to do with the event which caused the
302 /** ZNC will continue event processing normally. This is what
303 * you should return normally.
306 /** This is the same as both CModule::HALTMODS and
307 * CModule::HALTCORE together.
310 /** Stop sending this even to other modules which were not
311 * called yet. Internally, the event is handled normally.
314 /** Continue calling other modules. When done, ignore the event
315 * in the ZNC core. (For most module hooks this means that a
316 * given event won't be forwarded to the connected users)
322 /** Your module can throw this enum at any given time. When this
323 * is thrown, the module will be unloaded.
328 void SetUser(CUser
* pUser
);
329 void SetClient(CClient
* pClient
);
331 /** This function throws CModule::UNLOAD which causes this module to be unloaded.
333 void Unload() { throw UNLOAD
; }
335 /** This module hook is called when a module is loaded
336 * @param sArgsi The arguments for the modules.
337 * @param sMessage A message that may be displayed to the user after
338 * loading the module. Useful for returning error messages.
339 * @return true if the module loaded successfully, else false.
341 virtual bool OnLoad(const CString
& sArgsi
, CString
& sMessage
);
342 /** This module hook is called during ZNC startup. Only modules loaded
343 * from znc.conf get this call.
344 * @return false to abort ZNC startup.
346 virtual bool OnBoot();
349 /** Modules which can only be used with an active user session have to return true here.
350 * @return false for modules that can do stuff for non-logged in web users as well.
352 virtual bool WebRequiresLogin() { return true; }
353 /** Return true if this module should only be usable for admins on the web.
354 * @return false if normal users can use this module's web pages as well.
356 virtual bool WebRequiresAdmin() { return false; }
357 /** Return the title of the module's section in the web interface's side bar.
360 virtual CString
GetWebMenuTitle() { return ""; }
361 /** For WebMods: Called before the list of registered SubPages will be checked.
362 * Important: If you return true, you need to take care of calling WebSock.Close!
363 * This allows for stuff like returning non-templated data, long-polling and other fun.
364 * @param WebSock The active request.
365 * @param sPageName The name of the page that has been requested.
366 * @return true if you handled the page request or false if the name is to be checked
367 * against the list of registered SubPages and their permission settings.
369 virtual bool OnWebPreRequest(CWebSock
& WebSock
, const CString
& sPageName
);
370 /** If OnWebPreRequest returned false, and the RequiresAdmin/IsAdmin check has been passed,
371 * this method will be called with the page name. It will also be called for pages that
372 * have NOT been specifically registered with AddSubPage.
373 * @param WebSock The active request.
374 * @param sPageName The name of the page that has been requested.
375 * @param Tmpl The active template. You can add variables, loops and stuff to it.
376 * @return You MUST return true if you want the template to be evaluated and sent to the browser.
377 * Return false if you called Redirect() or PrintErrorPage(). If you didn't, a 404 page will be sent.
379 virtual bool OnWebRequest(CWebSock
& WebSock
, const CString
& sPageName
, CTemplate
& Tmpl
);
380 /** Registers a sub page for the sidebar.
381 * @param spSubPage The SubPage instance.
383 virtual void AddSubPage(TWebSubPage spSubPage
) { m_vSubPages
.push_back(spSubPage
); }
384 /** Removes all registered (AddSubPage'd) SubPages.
386 virtual void ClearSubPages() { m_vSubPages
.clear(); }
387 /** Returns a list of all registered SubPages. Don't mess with it too much.
390 virtual VWebSubPages
& GetSubPages() { return m_vSubPages
; }
391 /** Using this hook, module can embed web stuff directly to different places.
392 * This method is called whenever embededded modules I/O happens.
393 * Name of used .tmpl file (if any) is up to caller.
394 * @param WebSock Socket for web connection, don't do bad things with it.
395 * @param sPageName Describes the place where web stuff is embedded to.
396 * @param Tmpl Template. Depending on context, you can do various stuff with it.
397 * @return If you don't need to embed web stuff to the specified place, just return false.
398 * Exact meaning of return value is up to caller, and depends on context.
400 virtual bool OnEmbeddedWebRequest(CWebSock
& WebSock
, const CString
& sPageName
, CTemplate
& Tmpl
);
403 /** Called just before znc.conf is rehashed */
404 virtual void OnPreRehash();
405 /** This module hook is called after a <em>successful</em> rehash. */
406 virtual void OnPostRehash();
407 /** This module hook is called when a user gets disconnected from IRC. */
408 virtual void OnIRCDisconnected();
409 /** This module hook is called after a successful login to IRC. */
410 virtual void OnIRCConnected();
411 /** This module hook is called just before ZNC tries to establish a
412 * connection to an IRC server.
413 * @param pIRCSock The socket that will be used for the connection.
414 * @return See CModule::EModRet.
416 virtual EModRet
OnIRCConnecting(CIRCSock
*pIRCSock
);
417 /** This module hook is called when a CIRCSock fails to connect or
418 * a module returned HALTCORE from OnIRCConnecting.
419 * @param pIRCSock The socket that failed to connect.
421 virtual void OnIRCConnectionError(CIRCSock
*pIRCSock
);
422 /** This module hook is called before loging in to the IRC server. The
423 * low-level connection is established at this point, but SSL
424 * handshakes didn't necessarily finish yet.
425 * @param sPass The server password that will be used.
426 * @param sNick The nick that will be used.
427 * @param sIdent The protocol identity that will be used. This is not
428 * the ident string that is transfered via e.g. oidentd!
429 * @param sRealName The real name that will be used.
430 * @return See CModule::EModRet.
432 virtual EModRet
OnIRCRegistration(CString
& sPass
, CString
& sNick
, CString
& sIdent
, CString
& sRealName
);
433 /** This module hook is called when a message is broadcasted to all users.
434 * @param sMessage The message that is broadcasted.
435 * @return see CModule::EModRet
437 virtual EModRet
OnBroadcast(CString
& sMessage
);
439 /** This module hook is called when a user mode on a channel changes.
440 * @param OpNick The nick who sent the mode change.
441 * @param Nick The nick whose channel mode changes.
442 * @param Channel The channel on which the user mode is changed.
443 * @param uMode The mode character that is changed, e.g. '@' for op.
444 * @param bAdded True if the mode is added, else false.
445 * @param bNoChange true if this mode change doesn't change anything
446 * because the nick already had this permission.
447 * @see CIRCSock::GetModeType() for converting uMode into a mode (e.g.
450 virtual void OnChanPermission(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, unsigned char uMode
, bool bAdded
, bool bNoChange
);
451 /** Called when a nick is opped on a channel */
452 virtual void OnOp(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
453 /** Called when a nick is deopped on a channel */
454 virtual void OnDeop(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
455 /** Called when a nick is voiced on a channel */
456 virtual void OnVoice(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
457 /** Called when a nick is devoiced on a channel */
458 virtual void OnDevoice(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
459 /** Called on an individual channel mode change.
460 * @param OpNick The nick who changes the channel mode.
461 * @param Channel The channel whose mode is changed.
462 * @param uMode The mode character that is changed.
463 * @param sArg The argument to the mode character, if any.
464 * @param bAdded True if this mode is added ("+"), else false.
465 * @param bNoChange True if this mode was already effective before.
467 virtual void OnMode(const CNick
& OpNick
, CChan
& Channel
, char uMode
, const CString
& sArg
, bool bAdded
, bool bNoChange
);
468 /** Called on any channel mode change. This is called before the more
469 * detailed mode hooks like e.g. OnOp() and OnMode().
470 * @param OpNick The nick who changes the channel mode.
471 * @param Channel The channel whose mode is changed.
472 * @param sModes The raw mode change, e.g. "+s-io".
473 * @param sArgs All arguments to the mode change from sModes.
475 virtual void OnRawMode(const CNick
& OpNick
, CChan
& Channel
, const CString
& sModes
, const CString
& sArgs
);
477 /** Called on any raw IRC line received from the <em>IRC server</em>.
478 * @param sLine The line read from the server.
479 * @return See CModule::EModRet.
481 virtual EModRet
OnRaw(CString
& sLine
);
483 /** Called when a command to *status is sent.
484 * @param sCommand The command sent.
485 * @return See CModule::EModRet.
487 virtual EModRet
OnStatusCommand(CString
& sCommand
);
488 /** Called when a command to your module is sent, e.g. query to *modname.
489 * @param sCommand The command that was sent.
491 virtual void OnModCommand(const CString
& sCommand
);
492 /** This is similar to OnModCommand(), but it is only called if
493 * HandleCommand didn't find any that wants to handle this. This is only
494 * called if HandleCommand() is called, which practically means that
495 * this is only called if you don't overload OnModCommand().
496 * @param sCommand The command that was sent.
498 virtual void OnUnknownModCommand(const CString
& sCommand
);
499 /** Called when a your module nick was sent a notice.
500 * @param sMessage The message which was sent.
502 virtual void OnModNotice(const CString
& sMessage
);
503 /** Called when your module nick was sent a CTCP message. OnModCommand()
504 * won't be called for this message.
505 * @param sMessage The message which was sent.
507 virtual void OnModCTCP(const CString
& sMessage
);
509 /** Called when a nick quit from IRC.
510 * @param Nick The nick which quit.
511 * @param sMessage The quit message.
512 * @param vChans List of channels which you and nick share.
514 virtual void OnQuit(const CNick
& Nick
, const CString
& sMessage
, const vector
<CChan
*>& vChans
);
515 /** Called when a nickname change occurs. If we are changing our nick,
516 * sNewNick will equal m_pIRCSock->GetNick().
517 * @param Nick The nick which changed its nickname
518 * @param sNewNick The new nickname.
519 * @param vChans Channels which we and nick share.
521 virtual void OnNick(const CNick
& Nick
, const CString
& sNewNick
, const vector
<CChan
*>& vChans
);
522 /** Called when a nick is kicked from a channel.
523 * @param OpNick The nick which generated the kick.
524 * @param sKickedNick The nick which was kicked.
525 * @param Channel The channel on which this kick occurs.
526 * @param sMessage The kick message.
528 virtual void OnKick(const CNick
& OpNick
, const CString
& sKickedNick
, CChan
& Channel
, const CString
& sMessage
);
529 /** Called when a nick joins a channel.
530 * @param Nick The nick who joined.
531 * @param Channel The channel which was joined.
533 virtual void OnJoin(const CNick
& Nick
, CChan
& Channel
);
534 /** Called when a nick parts a channel.
535 * @param Nick The nick who parted.
536 * @param Channel The channel which was parted.
537 * @param sMessage The part message.
539 virtual void OnPart(const CNick
& Nick
, CChan
& Channel
, const CString
& sMessage
);
541 /** Called before a channel buffer is played back to a client.
542 * @param Chan The channel which will be played back.
543 * @param Client The client the buffer will be played back to.
544 * @return See CModule::EModRet.
546 virtual EModRet
OnChanBufferStarting(CChan
& Chan
, CClient
& Client
);
547 /** Called after a channel buffer was played back to a client.
548 * @param Chan The channel which was played back.
549 * @param Client The client the buffer was played back to.
550 * @return See CModule::EModRet.
552 virtual EModRet
OnChanBufferEnding(CChan
& Chan
, CClient
& Client
);
553 /** Called when for each line during a channel's buffer play back.
554 * @param Chan The channel this playback is from.
555 * @param Client The client the buffer is played back to.
556 * @param sLine The current line of buffer playback. This is a raw IRC
558 * @return See CModule::EModRet.
560 virtual EModRet
OnChanBufferPlayLine(CChan
& Chan
, CClient
& Client
, CString
& sLine
);
561 /** Called when a line from the query buffer is played back.
562 * @param Client The client this line will go to.
563 * @param sLine The raw IRC traffic line from the buffer.
564 * @return See CModule::EModRet.
566 virtual EModRet
OnPrivBufferPlayLine(CClient
& Client
, CString
& sLine
);
568 /** Called when a client successfully logged in to ZNC. */
569 virtual void OnClientLogin();
570 /** Called when a client disconnected from ZNC. */
571 virtual void OnClientDisconnect();
572 /** This module hook is called when a client sends a raw traffic line to ZNC.
573 * @param sLine The raw traffic line sent.
574 * @return See CModule::EModRet.
576 virtual EModRet
OnUserRaw(CString
& sLine
);
577 /** This module hook is called when a client sends a CTCP reply.
578 * @param sTarget The target for the CTCP reply. Could be a channel
579 * name or a nick name.
580 * @param sMessage The CTCP reply message.
581 * @return See CModule::EModRet.
583 virtual EModRet
OnUserCTCPReply(CString
& sTarget
, CString
& sMessage
);
584 /** This module hook is called when a client sends a CTCP request.
585 * @param sTarget The target for the CTCP request. Could be a channel
586 * name or a nick name.
587 * @param sMessage The CTCP request message.
588 * @return See CModule::EModRet.
589 * @note This is not called for CTCP ACTION messages, use
590 * CModule::OnUserAction() instead.
592 virtual EModRet
OnUserCTCP(CString
& sTarget
, CString
& sMessage
);
593 /** Called when a client sends a CTCP ACTION request ("/me").
594 * @param sTarget The target for the CTCP ACTION. Could be a channel
595 * name or a nick name.
596 * @param sMessage The action message.
597 * @return See CModule::EModRet.
598 * @note CModule::OnUserCTCP() will not be called for this message.
600 virtual EModRet
OnUserAction(CString
& sTarget
, CString
& sMessage
);
601 /** This module hook is called when a user sends a normal IRC message.
602 * @param sTarget The target of the message. Could be a channel name or
604 * @param sMessage The message which was sent.
605 * @return See CModule::EModRet.
607 virtual EModRet
OnUserMsg(CString
& sTarget
, CString
& sMessage
);
608 /** This module hook is called when a user sends a notice message.
609 * @param sTarget The target of the message. Could be a channel name or
611 * @param sMessage The message which was sent.
612 * @return See CModule::EModRet.
614 virtual EModRet
OnUserNotice(CString
& sTarget
, CString
& sMessage
);
615 /** This hooks is called when a user sends a JOIN message.
616 * @param sChannel The channel name the join is for.
617 * @param sKey The key for the channel.
618 * @return See CModule::EModRet.
620 virtual EModRet
OnUserJoin(CString
& sChannel
, CString
& sKey
);
621 /** This hooks is called when a user sends a PART message.
622 * @param sChannel The channel name the part is for.
623 * @param sMessage The part message the client sent.
624 * @return See CModule::EModRet.
626 virtual EModRet
OnUserPart(CString
& sChannel
, CString
& sMessage
);
627 /** This module hook is called when a user wants to change a channel topic.
628 * @param sChannel The channel.
629 * @param sTopic The new topic which the user sent.
630 * @return See CModule::EModRet.
632 virtual EModRet
OnUserTopic(CString
& sChannel
, CString
& sTopic
);
633 /** This hook is called when a user requests a channel's topic.
634 * @param sChannel The channel for which the request is.
635 * @return See CModule::EModRet.
637 virtual EModRet
OnUserTopicRequest(CString
& sChannel
);
639 /** Called when we receive a CTCP reply <em>from IRC</em>.
640 * @param Nick The nick the CTCP reply is from.
641 * @param sMessage The CTCP reply message.
642 * @return See CModule::EModRet.
644 virtual EModRet
OnCTCPReply(CNick
& Nick
, CString
& sMessage
);
645 /** Called when we receive a private CTCP request <em>from IRC</em>.
646 * @param Nick The nick the CTCP request is from.
647 * @param sMessage The CTCP request message.
648 * @return See CModule::EModRet.
650 virtual EModRet
OnPrivCTCP(CNick
& Nick
, CString
& sMessage
);
651 /** Called when we receive a channel CTCP request <em>from IRC</em>.
652 * @param Nick The nick the CTCP request is from.
653 * @param Channel The channel to which the request was sent.
654 * @param sMessage The CTCP request message.
655 * @return See CModule::EModRet.
657 virtual EModRet
OnChanCTCP(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
658 /** Called when we receive a private CTCP ACTION ("/me" in query) <em>from IRC</em>.
659 * This is called after CModule::OnPrivCTCP().
660 * @param Nick The nick the action came from.
661 * @param sMessage The action message
662 * @return See CModule::EModRet.
664 virtual EModRet
OnPrivAction(CNick
& Nick
, CString
& sMessage
);
665 /** Called when we receive a channel CTCP ACTION ("/me" in a channel) <em>from IRC</em>.
666 * This is called after CModule::OnChanCTCP().
667 * @param Nick The nick the action came from.
668 * @param Channel The channel the action was sent to.
669 * @param sMessage The action message
670 * @return See CModule::EModRet.
672 virtual EModRet
OnChanAction(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
673 /** Called when we receive a private message <em>from IRC</em>.
674 * @param Nick The nick which sent the message.
675 * @param sMessage The message.
676 * @return See CModule::EModRet.
678 virtual EModRet
OnPrivMsg(CNick
& Nick
, CString
& sMessage
);
679 /** Called when we receive a channel message <em>from IRC</em>.
680 * @param Nick The nick which sent the message.
681 * @param Channel The channel to which the message was sent.
682 * @param sMessage The message.
683 * @return See CModule::EModRet.
685 virtual EModRet
OnChanMsg(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
686 /** Called when we receive a private notice.
687 * @param Nick The nick which sent the notice.
688 * @param sMessage The notice message.
689 * @return See CModule::EModRet.
691 virtual EModRet
OnPrivNotice(CNick
& Nick
, CString
& sMessage
);
692 /** Called when we receive a channel notice.
693 * @param Nick The nick which sent the notice.
694 * @param Channel The channel to which the notice was sent.
695 * @param sMessage The notice message.
696 * @return See CModule::EModRet.
698 virtual EModRet
OnChanNotice(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
699 /** Called when we receive a channel topic change <em>from IRC</em>.
700 * @param Nick The nick which changed the topic.
701 * @param Channel The channel whose topic was changed.
702 * @param sTopic The new topic.
703 * @return See CModule::EModRet.
705 virtual EModRet
OnTopic(CNick
& Nick
, CChan
& Channel
, CString
& sTopic
);
707 /** Called for every CAP received via CAP LS from server.
708 * @param sCap capability supported by server.
709 * @return true if your module supports this CAP and
710 * needs to turn it on with CAP REQ.
712 virtual bool OnServerCapAvailable(const CString
& sCap
);
713 /** Called for every CAP accepted or rejected by server
714 * (with CAP ACK or CAP NAK after our CAP REQ).
715 * @param sCap capability accepted/rejected by server.
716 * @param bSuccess true if capability was accepted, false if rejected.
718 virtual void OnServerCapResult(const CString
& sCap
, bool bSuccess
);
720 /** This module hook is called just before ZNC tries to join a channel
721 * by itself because it's in the config but wasn't joined yet.
722 * @param Channel The channel which will be joined.
723 * @return See CModule::EModRet.
725 virtual EModRet
OnTimerAutoJoin(CChan
& Channel
);
727 ModHandle
GetDLL() { return m_pDLL
; }
728 static double GetCoreVersion() { return VERSION
; }
730 /** This function sends a given raw IRC line to the IRC server, if we
731 * are connected to one. Else this line is discarded.
732 * @param sLine The line which should be sent.
733 * @return true if the line was queued for sending.
735 virtual bool PutIRC(const CString
& sLine
);
736 /** This function sends a given raw IRC line to a client.
737 * If we are in a module hook which is called for a specific client,
738 * only that client will get the line, else all connected clients will
740 * @param sLine The line which should be sent.
741 * @return true if the line was sent to at least one client.
743 virtual bool PutUser(const CString
& sLine
);
744 /** This function generates a query from *status. If we are in a module
745 * hook for a specific client, only that client gets this message, else
746 * all connected clients will receive it.
747 * @param sLine The message which should be sent from *status.
748 * @return true if the line was sent to at least one client.
750 virtual bool PutStatus(const CString
& sLine
);
751 /** This function sends a query from your module nick. If we are in a
752 * module hook for a specific client, only that client gets this
753 * message, else all connected clients will receive it.
754 * @param sLine The message which should be sent.
755 * @return true if the line was sent to at least one client.
757 virtual bool PutModule(const CString
& sLine
);
758 /** This function calls CModule::PutModule(const CString&, const
759 * CString&, const CString&) for each line in the table.
760 * @param table The table which should be send.
761 * @return The number of lines sent.
763 virtual unsigned int PutModule(const CTable
& table
);
764 /** Send a notice from your module nick. If we are in a module hook for
765 * a specific client, only that client gets this notice, else all
766 * clients will receive it.
767 * @param sLine The line which should be sent.
768 * @return true if the line was sent to at least one client.
770 virtual bool PutModNotice(const CString
& sLine
);
772 /** @returns The name of the module. */
773 const CString
& GetModName() const { return m_sModName
; }
775 /** @returns The nick of the module. This is just the module name
776 * prefixed by the status prefix.
778 CString
GetModNick() const;
780 /** Get the module's data dir.
781 * Modules can be accompanied by static data, e.g. skins for webadmin.
782 * These function will return the path to that data.
784 const CString
& GetModDataDir() const { return m_sDataDir
; }
787 bool AddTimer(CTimer
* pTimer
);
788 bool AddTimer(FPTimer_t pFBCallback
, const CString
& sLabel
, u_int uInterval
, u_int uCycles
= 0, const CString
& sDescription
= "");
789 bool RemTimer(CTimer
* pTimer
);
790 bool RemTimer(const CString
& sLabel
);
791 bool UnlinkTimer(CTimer
* pTimer
);
792 CTimer
* FindTimer(const CString
& sLabel
);
793 set
<CTimer
*>::const_iterator
BeginTimers() const { return m_sTimers
.begin(); }
794 set
<CTimer
*>::const_iterator
EndTimers() const { return m_sTimers
.end(); }
795 virtual void ListTimers();
799 bool AddSocket(CSocket
* pSocket
);
800 bool RemSocket(CSocket
* pSocket
);
801 bool RemSocket(const CString
& sSockName
);
802 bool UnlinkSocket(CSocket
* pSocket
);
803 CSocket
* FindSocket(const CString
& sSockName
);
804 set
<CSocket
*>::const_iterator
BeginSockets() const { return m_sSockets
.begin(); }
805 set
<CSocket
*>::const_iterator
EndSockets() const { return m_sSockets
.end(); }
806 virtual void ListSockets();
810 /// Register the "Help" command.
811 void AddHelpCommand();
812 /// @return True if the command was successfully added.
813 bool AddCommand(const CModCommand
& Command
);
814 /// @return True if the command was successfully added.
815 bool AddCommand(const CString
& sCmd
, CModCommand::ModCmdFunc func
, const CString
& sArgs
= "", const CString
& sDesc
= "");
816 /// @return True if the command was successfully removed.
817 bool RemCommand(const CString
& sCmd
);
818 /// @return The CModCommand instance or NULL if none was found.
819 const CModCommand
* FindCommand(const CString
& sCmd
) const;
820 /** This function tries to dispatch the given command via the correct
821 * instance of CModCommand. Before this can be called, commands have to
822 * be added via AddCommand(). If no matching commands are found then
823 * OnUnknownModCommand will be called.
824 * @param sLine The command line to handle.
825 * @return True if something was done, else false.
827 bool HandleCommand(const CString
& sLine
);
828 /** Send a description of all registered commands via PutModule().
829 * @param sLine The help command that is being asked for.
831 void HandleHelpCommand(const CString
& sLine
= "");
835 bool SaveRegistry() const;
836 bool SetNV(const CString
& sName
, const CString
& sValue
, bool bWriteToDisk
= true);
837 CString
GetNV(const CString
& sName
) const;
838 bool DelNV(const CString
& sName
, bool bWriteToDisk
= true);
839 MCString::iterator
FindNV(const CString
& sName
) { return m_mssRegistry
.find(sName
); }
840 MCString::iterator
EndNV() { return m_mssRegistry
.end(); }
841 MCString::iterator
BeginNV() { return m_mssRegistry
.begin(); }
842 void DelNV(MCString::iterator it
) { m_mssRegistry
.erase(it
); }
843 bool ClearNV(bool bWriteToDisk
= true);
845 const CString
& GetSavePath() const;
848 void SetGlobal(bool b
) { m_bGlobal
= b
; }
849 void SetDescription(const CString
& s
) { m_sDescription
= s
; }
850 void SetModPath(const CString
& s
) { m_sModPath
= s
; }
851 void SetArgs(const CString
& s
) { m_sArgs
= s
; }
855 bool IsGlobal() const { return m_bGlobal
; }
856 const CString
& GetDescription() const { return m_sDescription
; }
857 const CString
& GetArgs() const { return m_sArgs
; }
858 const CString
& GetModPath() const { return m_sModPath
; }
860 /** @returns For user modules this returns the user for which this
861 * module was loaded. For global modules this returns NULL,
862 * except when we are in a user-specific module hook in which
863 * case this is the user pointer.
865 CUser
* GetUser() { return m_pUser
; }
866 /** @returns NULL except when we are in a client-specific module hook in
867 * which case this is the client for which the hook is called.
869 CClient
* GetClient() { return m_pClient
; }
870 CSockManager
* GetManager() { return m_pManager
; }
875 CString m_sDescription
;
876 set
<CTimer
*> m_sTimers
;
877 set
<CSocket
*> m_sSockets
;
879 CSockManager
* m_pManager
;
888 MCString m_mssRegistry
; //!< way to save name/value pairs. Note there is no encryption involved in this
889 VWebSubPages m_vSubPages
;
890 map
<CString
, CModCommand
> m_mCommands
;
893 class CModules
: public vector
<CModule
*> {
898 void SetUser(CUser
* pUser
) { m_pUser
= pUser
; }
899 void SetClient(CClient
* pClient
) { m_pClient
= pClient
; }
900 CUser
* GetUser() { return m_pUser
; }
901 CClient
* GetClient() { return m_pClient
; }
908 bool OnIRCDisconnected();
909 bool OnIRCConnected();
910 bool OnIRCConnecting(CIRCSock
*pIRCSock
);
911 bool OnIRCConnectionError(CIRCSock
*pIRCSock
);
912 bool OnIRCRegistration(CString
& sPass
, CString
& sNick
, CString
& sIdent
, CString
& sRealName
);
913 bool OnBroadcast(CString
& sMessage
);
915 bool OnChanPermission(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, unsigned char uMode
, bool bAdded
, bool bNoChange
);
916 bool OnOp(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
917 bool OnDeop(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
918 bool OnVoice(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
919 bool OnDevoice(const CNick
& OpNick
, const CNick
& Nick
, CChan
& Channel
, bool bNoChange
);
920 bool OnRawMode(const CNick
& OpNick
, CChan
& Channel
, const CString
& sModes
, const CString
& sArgs
);
921 bool OnMode(const CNick
& OpNick
, CChan
& Channel
, char uMode
, const CString
& sArg
, bool bAdded
, bool bNoChange
);
923 bool OnRaw(CString
& sLine
);
925 bool OnStatusCommand(CString
& sCommand
);
926 bool OnModCommand(const CString
& sCommand
);
927 bool OnModNotice(const CString
& sMessage
);
928 bool OnModCTCP(const CString
& sMessage
);
930 bool OnQuit(const CNick
& Nick
, const CString
& sMessage
, const vector
<CChan
*>& vChans
);
931 bool OnNick(const CNick
& Nick
, const CString
& sNewNick
, const vector
<CChan
*>& vChans
);
932 bool OnKick(const CNick
& Nick
, const CString
& sOpNick
, CChan
& Channel
, const CString
& sMessage
);
933 bool OnJoin(const CNick
& Nick
, CChan
& Channel
);
934 bool OnPart(const CNick
& Nick
, CChan
& Channel
, const CString
& sMessage
);
936 bool OnChanBufferStarting(CChan
& Chan
, CClient
& Client
);
937 bool OnChanBufferEnding(CChan
& Chan
, CClient
& Client
);
938 bool OnChanBufferPlayLine(CChan
& Chan
, CClient
& Client
, CString
& sLine
);
939 bool OnPrivBufferPlayLine(CClient
& Client
, CString
& sLine
);
941 bool OnClientLogin();
942 bool OnClientDisconnect();
943 bool OnUserRaw(CString
& sLine
);
944 bool OnUserCTCPReply(CString
& sTarget
, CString
& sMessage
);
945 bool OnUserCTCP(CString
& sTarget
, CString
& sMessage
);
946 bool OnUserAction(CString
& sTarget
, CString
& sMessage
);
947 bool OnUserMsg(CString
& sTarget
, CString
& sMessage
);
948 bool OnUserNotice(CString
& sTarget
, CString
& sMessage
);
949 bool OnUserJoin(CString
& sChannel
, CString
& sKey
);
950 bool OnUserPart(CString
& sChannel
, CString
& sMessage
);
951 bool OnUserTopic(CString
& sChannel
, CString
& sTopic
);
952 bool OnUserTopicRequest(CString
& sChannel
);
954 bool OnCTCPReply(CNick
& Nick
, CString
& sMessage
);
955 bool OnPrivCTCP(CNick
& Nick
, CString
& sMessage
);
956 bool OnChanCTCP(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
957 bool OnPrivAction(CNick
& Nick
, CString
& sMessage
);
958 bool OnChanAction(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
959 bool OnPrivMsg(CNick
& Nick
, CString
& sMessage
);
960 bool OnChanMsg(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
961 bool OnPrivNotice(CNick
& Nick
, CString
& sMessage
);
962 bool OnChanNotice(CNick
& Nick
, CChan
& Channel
, CString
& sMessage
);
963 bool OnTopic(CNick
& Nick
, CChan
& Channel
, CString
& sTopic
);
964 bool OnTimerAutoJoin(CChan
& Channel
);
966 bool OnServerCapAvailable(const CString
& sCap
);
967 bool OnServerCapResult(const CString
& sCap
, bool bSuccess
);
969 CModule
* FindModule(const CString
& sModule
) const;
970 bool LoadModule(const CString
& sModule
, const CString
& sArgs
, CUser
* pUser
, CString
& sRetMsg
);
971 bool UnloadModule(const CString
& sModule
);
972 bool UnloadModule(const CString
& sModule
, CString
& sRetMsg
);
973 bool ReloadModule(const CString
& sModule
, const CString
& sArgs
, CUser
* pUser
, CString
& sRetMsg
);
975 static bool GetModInfo(CModInfo
& ModInfo
, const CString
& sModule
, CString
&sRetMsg
);
976 static bool GetModPathInfo(CModInfo
& ModInfo
, const CString
& sModule
, const CString
& sModPath
, CString
&sRetMsg
);
977 static void GetAvailableMods(set
<CModInfo
>& ssMods
, bool bGlobal
= false);
979 // This returns the path to the .so and to the data dir
980 // which is where static data (webadmin skins) are saved
981 static bool FindModPath(const CString
& sModule
, CString
& sModPath
,
983 // Return a list of <module dir, data dir> pairs for directories in
984 // which modules can be found.
985 typedef std::queue
<std::pair
<CString
, CString
> > ModDirList
;
986 static ModDirList
GetModDirs();
989 static ModHandle
OpenModule(const CString
& sModule
, const CString
& sModPath
,
990 bool &bVersionMismatch
, CModInfo
& Info
, CString
& sRetMsg
);
997 /** Base class for global modules. If you want to write a global module, your
998 * module class has to derive from CGlobalModule instead of CModule.
1000 * All the module hooks from CModule work here, too. The difference is that
1001 * they are now called for all users instead of just a specific one.
1003 * Instead of MODCONSTRUCTOR and MODULEDEFS, you will have to use
1004 * GLOBALMODCONSTRUCTOR and GLOBALMODULEDEFS.
1006 class CGlobalModule
: public CModule
{
1008 CGlobalModule(ModHandle pDLL
, const CString
& sModName
,
1009 const CString
&sDataDir
) : CModule(pDLL
, sModName
, sDataDir
) {}
1010 virtual ~CGlobalModule() {}
1012 /** This module hook is called when a user is being added.
1013 * @param User The user which will be added.
1014 * @param sErrorRet A message that may be displayed to the user if
1015 * the module stops adding the user.
1016 * @return See CModule::EModRet.
1018 virtual EModRet
OnAddUser(CUser
& User
, CString
& sErrorRet
);
1019 /** This module hook is called when a user is deleted.
1020 * @param User The user which will be deleted.
1021 * @return See CModule::EModRet.
1023 virtual EModRet
OnDeleteUser(CUser
& User
);
1024 /** This module hook is called when there is an incoming connection on
1025 * any of ZNC's listening sockets.
1026 * @param pSock The incoming client socket.
1027 * @param sHost The IP the client is connecting from.
1028 * @param uPort The port the client is connecting from.
1030 virtual void OnClientConnect(CZNCSock
* pSock
, const CString
& sHost
, unsigned short uPort
);
1031 /** This module hook is called when a client tries to login. If your
1032 * module wants to handle the login attempt, it must return
1033 * CModule::EModRet::HALT;
1034 * @param Auth The necessary authentication info for this login attempt.
1035 * @return See CModule::EModRet.
1037 virtual EModRet
OnLoginAttempt(CSmartPtr
<CAuthBase
> Auth
);
1038 /** Called after a client login was rejected.
1039 * @param sUsername The username that tried to log in.
1040 * @param sRemoteIP The IP address from which the client tried to login.
1042 virtual void OnFailedLogin(const CString
& sUsername
, const CString
& sRemoteIP
);
1043 /** This function behaves like CModule::OnRaw(), but is also called
1044 * before the client successfully logged in to ZNC. You should always
1045 * prefer to use CModule::OnRaw() if possible.
1046 * @param sLine The raw traffic line which the client sent.
1047 * @todo Why doesn't this use m_pUser and m_pClient?
1048 * (Well, ok, m_pUser isn't known yet...)
1050 virtual EModRet
OnUnknownUserRaw(CString
& sLine
);
1052 /** Called when a client told us CAP LS. Use ssCaps.insert("cap-name")
1053 * for announcing capabilities which your module supports.
1054 * @param ssCaps set of caps which will be sent to client.
1056 virtual void OnClientCapLs(SCString
& ssCaps
);
1057 /** Called only to check if your module supports turning on/off named capability.
1058 * @param sCap name of capability.
1059 * @param bState On or off, depending on which case is interesting for client.
1060 * @return true if your module supports this capability in the specified state.
1062 virtual bool IsClientCapSupported(const CString
& sCap
, bool bState
);
1063 /** Called when we actually need to turn a capability on or off for a client.
1064 * @param sCap name of wanted capability.
1065 * @param bState On or off, depending on which case client needs.
1067 virtual void OnClientCapRequest(const CString
& sCap
, bool bState
);
1069 /** Called when a module is going to be loaded.
1070 * @param sModName name of the module.
1071 * @param sArgs arguments of the module.
1072 * @param[out] bSuccess the module was loaded successfully
1073 * as result of this module hook?
1074 * @param[out] sRetMsg text about loading of the module.
1075 * @return See CModule::EModRet.
1077 virtual EModRet
OnModuleLoading(const CString
& sModName
, const CString
& sArgs
,
1078 bool& bSuccess
, CString
& sRetMsg
);
1079 /** Called when a module is going to be unloaded.
1080 * @param pModule the module.
1081 * @param[out] bSuccess the module was unloaded successfully
1082 * as result of this module hook?
1083 * @param[out] sRetMsg text about unloading of the module.
1084 * @return See CModule::EModRet.
1086 virtual EModRet
OnModuleUnloading(CModule
* pModule
, bool& bSuccess
, CString
& sRetMsg
);
1087 /** Called when info about a module is needed.
1088 * @param[out] ModInfo put result here, if your module knows it.
1089 * @param sModule name of the module.
1090 * @param bSuccess this module provided info about the module.
1091 * @param sRetMsg text describing possible issues.
1092 * @return See CModule::EModRet.
1094 virtual EModRet
OnGetModInfo(CModInfo
& ModInfo
, const CString
& sModule
,
1095 bool& bSuccess
, CString
& sRetMsg
);
1096 /** Called when list of available mods is requested.
1097 * @param ssMods put new modules here.
1098 * @param bGlobal true if global modules are needed.
1100 virtual void OnGetAvailableMods(set
<CModInfo
>& ssMods
, bool bGlobal
);
1104 class CGlobalModules
: public CModules
{
1106 CGlobalModules() : CModules() {}
1107 ~CGlobalModules() {}
1109 bool OnAddUser(CUser
& User
, CString
& sErrorRet
);
1110 bool OnDeleteUser(CUser
& User
);
1111 bool OnClientConnect(CZNCSock
* pSock
, const CString
& sHost
, unsigned short uPort
);
1112 bool OnLoginAttempt(CSmartPtr
<CAuthBase
> Auth
);
1113 bool OnFailedLogin(const CString
& sUsername
, const CString
& sRemoteIP
);
1114 bool OnUnknownUserRaw(CString
& sLine
);
1115 bool OnClientCapLs(SCString
& ssCaps
);
1116 bool IsClientCapSupported(const CString
& sCap
, bool bState
);
1117 bool OnClientCapRequest(const CString
& sCap
, bool bState
);
1118 bool OnModuleLoading(const CString
& sModName
, const CString
& sArgs
,
1119 bool& bSuccess
, CString
& sRetMsg
);
1120 bool OnModuleUnloading(CModule
* pModule
, bool& bSuccess
, CString
& sRetMsg
);
1121 bool OnGetModInfo(CModInfo
& ModInfo
, const CString
& sModule
,
1122 bool& bSuccess
, CString
& sRetMsg
);
1123 bool OnGetAvailableMods(set
<CModInfo
>& ssMods
, bool bGlobal
);
1127 #endif // !_MODULES_H