mirror of
https://github.com/znc/znc.git
synced 2026-08-06 08:52:57 +02:00
Create network modules
This commit is contained in:
+61
-37
@@ -10,6 +10,7 @@
|
||||
#include "FileUtils.h"
|
||||
#include "Template.h"
|
||||
#include "User.h"
|
||||
#include "IRCNetwork.h"
|
||||
#include "WebModules.h"
|
||||
#include "znc.h"
|
||||
#include <dlfcn.h>
|
||||
@@ -25,14 +26,21 @@
|
||||
CModule* pMod = (CModule *) (*this)[a]; \
|
||||
CClient* pOldClient = pMod->GetClient(); \
|
||||
pMod->SetClient(m_pClient); \
|
||||
if (m_pUser) { \
|
||||
CUser* pOldUser = pMod->GetUser(); \
|
||||
CUser* pOldUser; \
|
||||
if (m_pUser) { \
|
||||
pOldUser = pMod->GetUser(); \
|
||||
pMod->SetUser(m_pUser); \
|
||||
pMod->func; \
|
||||
} \
|
||||
CIRCNetwork* pNetwork; \
|
||||
if (m_pNetwork) { \
|
||||
pNetwork = pMod->GetNetwork(); \
|
||||
pMod->SetNetwork(m_pNetwork); \
|
||||
} \
|
||||
pMod->func; \
|
||||
if (m_pUser) \
|
||||
pMod->SetUser(pOldUser); \
|
||||
} else { \
|
||||
pMod->func; \
|
||||
} \
|
||||
if (m_pNetwork) \
|
||||
pMod->SetNetwork(pNetwork); \
|
||||
pMod->SetClient(pOldClient); \
|
||||
} catch (CModule::EModException e) { \
|
||||
if (e == CModule::UNLOAD) { \
|
||||
@@ -50,14 +58,21 @@
|
||||
CModule::EModRet e = CModule::CONTINUE; \
|
||||
CClient* pOldClient = pMod->GetClient(); \
|
||||
pMod->SetClient(m_pClient); \
|
||||
if (m_pUser) { \
|
||||
CUser* pOldUser = pMod->GetUser(); \
|
||||
CUser* pOldUser; \
|
||||
if (m_pUser) { \
|
||||
pOldUser = pMod->GetUser(); \
|
||||
pMod->SetUser(m_pUser); \
|
||||
e = pMod->func; \
|
||||
} \
|
||||
CIRCNetwork* pNetwork; \
|
||||
if (m_pNetwork) { \
|
||||
pNetwork = pMod->GetNetwork(); \
|
||||
pMod->SetNetwork(m_pNetwork); \
|
||||
} \
|
||||
e = pMod->func; \
|
||||
if (m_pUser) \
|
||||
pMod->SetUser(pOldUser); \
|
||||
} else { \
|
||||
e = pMod->func; \
|
||||
} \
|
||||
if (m_pNetwork) \
|
||||
pMod->SetNetwork(pNetwork); \
|
||||
pMod->SetClient(pOldClient); \
|
||||
if (e == CModule::HALTMODS) { \
|
||||
break; \
|
||||
@@ -99,15 +114,18 @@ const CString& CTimer::GetDescription() const { return m_sDescription; }
|
||||
/////////////////// !Timer ///////////////////
|
||||
|
||||
|
||||
CModule::CModule(ModHandle pDLL, CUser* pUser, const CString& sModName, const CString& sDataDir) {
|
||||
CModule::CModule(ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, const CString& sDataDir) {
|
||||
m_pDLL = pDLL;
|
||||
m_pManager = &(CZNC::Get().GetManager());;
|
||||
m_pUser = pUser;
|
||||
m_pNetwork = pNetwork;
|
||||
m_pClient = NULL;
|
||||
m_sModName = sModName;
|
||||
m_sDataDir = sDataDir;
|
||||
|
||||
if (m_pUser) {
|
||||
if (m_pNetwork) {
|
||||
m_sSavePath = m_pNetwork->GetNetworkPath() + "/moddata/" + m_sModName;
|
||||
} else if (m_pUser) {
|
||||
m_sSavePath = m_pUser->GetUserPath() + "/moddata/" + m_sModName;
|
||||
} else {
|
||||
m_sSavePath = CZNC::Get().GetZNCPath() + "/moddata/" + m_sModName;
|
||||
@@ -128,6 +146,7 @@ CModule::~CModule() {
|
||||
}
|
||||
|
||||
void CModule::SetUser(CUser* pUser) { m_pUser = pUser; }
|
||||
void CModule::SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; }
|
||||
void CModule::SetClient(CClient* pClient) { m_pClient = pClient; }
|
||||
|
||||
const CString& CModule::GetSavePath() const {
|
||||
@@ -524,13 +543,13 @@ bool CModule::OnServerCapAvailable(const CString& sCap) { return false; }
|
||||
void CModule::OnServerCapResult(const CString& sCap, bool bSuccess) {}
|
||||
|
||||
bool CModule::PutIRC(const CString& sLine) {
|
||||
return (m_pUser) ? m_pUser->PutIRC(sLine) : false;
|
||||
return (m_pNetwork) ? m_pNetwork->PutIRC(sLine) : false;
|
||||
}
|
||||
bool CModule::PutUser(const CString& sLine) {
|
||||
return (m_pUser) ? m_pUser->PutUser(sLine, m_pClient) : false;
|
||||
return (m_pNetwork) ? m_pNetwork->PutUser(sLine, m_pClient) : false;
|
||||
}
|
||||
bool CModule::PutStatus(const CString& sLine) {
|
||||
return (m_pUser) ? m_pUser->PutStatus(sLine, m_pClient) : false;
|
||||
return (m_pNetwork) ? m_pNetwork->PutStatus(sLine, m_pClient) : false;
|
||||
}
|
||||
unsigned int CModule::PutModule(const CTable& table) {
|
||||
if (!m_pUser)
|
||||
@@ -545,12 +564,24 @@ unsigned int CModule::PutModule(const CTable& table) {
|
||||
bool CModule::PutModule(const CString& sLine) {
|
||||
if (!m_pUser)
|
||||
return false;
|
||||
return m_pUser->PutModule(GetModName(), sLine, m_pClient);
|
||||
|
||||
if (m_pClient) {
|
||||
m_pClient->PutModule(GetModName(), sLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_pUser->PutModule(GetModName(), sLine);
|
||||
}
|
||||
bool CModule::PutModNotice(const CString& sLine) {
|
||||
if (!m_pUser)
|
||||
return false;
|
||||
return m_pUser->PutModNotice(GetModName(), sLine, m_pClient);
|
||||
|
||||
if (m_pClient) {
|
||||
m_pClient->PutModNotice(GetModName(), sLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_pUser->PutModNotice(GetModName(), sLine);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
@@ -577,6 +608,7 @@ void CModule::OnGetAvailableMods(set<CModInfo>& ssMods, CModInfo::EModuleType eT
|
||||
|
||||
CModules::CModules() {
|
||||
m_pUser = NULL;
|
||||
m_pNetwork = NULL;
|
||||
m_pClient = NULL;
|
||||
}
|
||||
|
||||
@@ -788,7 +820,7 @@ CModule* CModules::FindModule(const CString& sModule) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CModInfo::EModuleType eType, CUser* pUser, CString& sRetMsg) {
|
||||
bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CModInfo::EModuleType eType, CUser* pUser, CIRCNetwork *pNetwork, CString& sRetMsg) {
|
||||
sRetMsg = "";
|
||||
|
||||
if (FindModule(sModule) != NULL) {
|
||||
@@ -797,7 +829,7 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CModInfo
|
||||
}
|
||||
|
||||
bool bSuccess;
|
||||
GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, eType, bSuccess, sRetMsg), pUser, NULL, return bSuccess);
|
||||
GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, eType, bSuccess, sRetMsg), pUser, pNetwork, NULL, return bSuccess);
|
||||
|
||||
CString sModPath, sDataPath;
|
||||
bool bVersionMismatch;
|
||||
@@ -832,21 +864,13 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CModInfo
|
||||
return false;
|
||||
}
|
||||
|
||||
CModule* pModule = NULL;
|
||||
|
||||
switch (eType) {
|
||||
case CModInfo::UserModule:
|
||||
pModule = Info.GetLoader()(p, pUser, sModule, sDataPath);
|
||||
break;
|
||||
case CModInfo::GlobalModule:
|
||||
pModule = Info.GetLoader()(p, NULL, sModule, sDataPath);
|
||||
break;
|
||||
default:
|
||||
if (!pNetwork && eType == CModInfo::NetworkModule) {
|
||||
dlclose(p);
|
||||
sRetMsg = "Unsupported module type";
|
||||
sRetMsg = "Module [" + sModule + "] requires a network.";
|
||||
return false;
|
||||
}
|
||||
|
||||
CModule* pModule = Info.GetLoader()(p, pUser, pNetwork, sModule, sDataPath);
|
||||
pModule->SetDescription(Info.GetDescription());
|
||||
pModule->SetType(eType);
|
||||
pModule->SetArgs(sArgs);
|
||||
@@ -893,7 +917,7 @@ bool CModules::UnloadModule(const CString& sModule, CString& sRetMsg) {
|
||||
}
|
||||
|
||||
bool bSuccess;
|
||||
GLOBALMODULECALL(OnModuleUnloading(pModule, bSuccess, sRetMsg), pModule->GetUser(), NULL, return bSuccess);
|
||||
GLOBALMODULECALL(OnModuleUnloading(pModule, bSuccess, sRetMsg), pModule->GetUser(), pModule->GetNetwork(), NULL, return bSuccess);
|
||||
|
||||
ModHandle p = pModule->GetDLL();
|
||||
|
||||
@@ -917,7 +941,7 @@ bool CModules::UnloadModule(const CString& sModule, CString& sRetMsg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CModules::ReloadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg) {
|
||||
bool CModules::ReloadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CIRCNetwork* pNetwork, CString& sRetMsg) {
|
||||
CString sMod = sModule; // Make a copy incase the reference passed in is from CModule::GetModName()
|
||||
CModule *pModule = FindModule(sMod);
|
||||
|
||||
@@ -934,7 +958,7 @@ bool CModules::ReloadModule(const CString& sModule, const CString& sArgs, CUser*
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LoadModule(sMod, sArgs, eType, pUser, sRetMsg)) {
|
||||
if (!LoadModule(sMod, sArgs, eType, pUser, pNetwork, sRetMsg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -946,7 +970,7 @@ bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule, CString& sR
|
||||
CString sModPath, sTmp;
|
||||
|
||||
bool bSuccess;
|
||||
GLOBALMODULECALL(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg), NULL, NULL, return bSuccess);
|
||||
GLOBALMODULECALL(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg), NULL, NULL, NULL, return bSuccess);
|
||||
|
||||
if (!FindModPath(sModule, sModPath, sTmp)) {
|
||||
sRetMsg = "Unable to find module [" + sModule + "]";
|
||||
@@ -1004,7 +1028,7 @@ void CModules::GetAvailableMods(set<CModInfo>& ssMods, CModInfo::EModuleType eTy
|
||||
}
|
||||
}
|
||||
|
||||
GLOBALMODULECALL(OnGetAvailableMods(ssMods, eType), NULL, NULL, NOTHING);
|
||||
GLOBALMODULECALL(OnGetAvailableMods(ssMods, eType), NULL, NULL, NULL, NOTHING);
|
||||
}
|
||||
|
||||
bool CModules::FindModPath(const CString& sModule, CString& sModPath,
|
||||
|
||||
@@ -20,6 +20,7 @@ using std::set;
|
||||
// Forward Declarations
|
||||
class CAuthBase;
|
||||
class CChan;
|
||||
class CIRCNetwork;
|
||||
class CClient;
|
||||
class CWebSock;
|
||||
class CTemplate;
|
||||
@@ -44,8 +45,9 @@ typedef void* ModHandle;
|
||||
template<class M> void TModInfo(CModInfo& Info) {}
|
||||
|
||||
template<class M> CModule* TModLoad(ModHandle p, CUser* pUser,
|
||||
const CString& sModName, const CString& sModPath) {
|
||||
return new M(p, pUser, sModName, sModPath);
|
||||
CIRCNetwork* pNetwork, const CString& sModName,
|
||||
const CString& sModPath) {
|
||||
return new M(p, pUser, pNetwork, sModName, sModPath);
|
||||
}
|
||||
|
||||
#if HAVE_VISIBILITY
|
||||
@@ -84,9 +86,9 @@ template<class M> CModule* TModLoad(ModHandle p, CUser* pUser,
|
||||
* @param CLASS The name of your module's class.
|
||||
*/
|
||||
#define MODCONSTRUCTOR(CLASS) \
|
||||
CLASS(ModHandle pDLL, CUser* pUser, const CString& sModName, \
|
||||
CLASS(ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, \
|
||||
const CString& sModPath) \
|
||||
: CModule(pDLL, pUser, sModName, sModPath)
|
||||
: CModule(pDLL, pUser, pNetwork, sModName, sModPath)
|
||||
|
||||
/** At the end of your source file, you must call this macro in global context.
|
||||
* It defines some static functions which ZNC needs to load this module.
|
||||
@@ -104,6 +106,12 @@ template<class M> CModule* TModLoad(ModHandle p, CUser* pUser,
|
||||
MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::GlobalModule)
|
||||
// !Global Module Macros
|
||||
|
||||
// Network Module Macros
|
||||
/** This works exactly like MODULEDEFS, but for network modules. */
|
||||
#define NETWORKMODULEDEFS(CLASS, DESCRIPTION) \
|
||||
MODCOMMONDEFS(CLASS, DESCRIPTION, CModInfo::NetworkModule)
|
||||
// !Network Module Macros
|
||||
|
||||
// Forward Declarations
|
||||
class CZNC;
|
||||
class CUser;
|
||||
@@ -161,11 +169,12 @@ private:
|
||||
|
||||
class CModInfo {
|
||||
public:
|
||||
typedef CModule* (*ModLoader)(ModHandle p, CUser* pUser, const CString& sModName, const CString& sModPath);
|
||||
typedef CModule* (*ModLoader)(ModHandle p, CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName, const CString& sModPath);
|
||||
|
||||
typedef enum {
|
||||
GlobalModule,
|
||||
UserModule
|
||||
UserModule,
|
||||
NetworkModule
|
||||
} EModuleType;
|
||||
|
||||
CModInfo() {
|
||||
@@ -198,6 +207,7 @@ public:
|
||||
switch (eType) {
|
||||
case GlobalModule: return "Global";
|
||||
case UserModule: return "User";
|
||||
case NetworkModule: return "Network";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
@@ -294,7 +304,7 @@ private:
|
||||
*/
|
||||
class CModule {
|
||||
public:
|
||||
CModule(ModHandle pDLL, CUser* pUser, const CString& sModName,
|
||||
CModule(ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork, const CString& sModName,
|
||||
const CString& sDataDir);
|
||||
virtual ~CModule();
|
||||
|
||||
@@ -330,6 +340,7 @@ public:
|
||||
} EModException;
|
||||
|
||||
void SetUser(CUser* pUser);
|
||||
void SetNetwork(CIRCNetwork* pNetwork);
|
||||
void SetClient(CClient* pClient);
|
||||
|
||||
/** This function throws CModule::UNLOAD which causes this module to be unloaded.
|
||||
@@ -870,6 +881,7 @@ public:
|
||||
/** @returns NULL except when we are in a client-specific module hook in
|
||||
* which case this is the client for which the hook is called.
|
||||
*/
|
||||
CIRCNetwork* GetNetwork() { return m_pNetwork; }
|
||||
CClient* GetClient() { return m_pClient; }
|
||||
CSockManager* GetManager() { return m_pManager; }
|
||||
// !Getters
|
||||
@@ -975,6 +987,7 @@ protected:
|
||||
ModHandle m_pDLL;
|
||||
CSockManager* m_pManager;
|
||||
CUser* m_pUser;
|
||||
CIRCNetwork* m_pNetwork;
|
||||
CClient* m_pClient;
|
||||
CString m_sModName;
|
||||
CString m_sDataDir;
|
||||
@@ -993,8 +1006,10 @@ public:
|
||||
~CModules();
|
||||
|
||||
void SetUser(CUser* pUser) { m_pUser = pUser; }
|
||||
void SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; }
|
||||
void SetClient(CClient* pClient) { m_pClient = pClient; }
|
||||
CUser* GetUser() { return m_pUser; }
|
||||
CIRCNetwork* GetNetwork() { return m_pNetwork; }
|
||||
CClient* GetClient() { return m_pClient; }
|
||||
|
||||
void UnloadAll();
|
||||
@@ -1064,10 +1079,10 @@ public:
|
||||
bool OnServerCapResult(const CString& sCap, bool bSuccess);
|
||||
|
||||
CModule* FindModule(const CString& sModule) const;
|
||||
bool LoadModule(const CString& sModule, const CString& sArgs, CModInfo::EModuleType eType, CUser* pUser, CString& sRetMsg);
|
||||
bool LoadModule(const CString& sModule, const CString& sArgs, CModInfo::EModuleType eType, CUser* pUser, CIRCNetwork* pNetwork, CString& sRetMsg);
|
||||
bool UnloadModule(const CString& sModule);
|
||||
bool UnloadModule(const CString& sModule, CString& sRetMsg);
|
||||
bool ReloadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg);
|
||||
bool ReloadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CIRCNetwork* pNetwork, CString& sRetMsg);
|
||||
|
||||
static bool GetModInfo(CModInfo& ModInfo, const CString& sModule, CString &sRetMsg);
|
||||
static bool GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const CString& sModPath, CString &sRetMsg);
|
||||
@@ -1105,8 +1120,9 @@ private:
|
||||
bool &bVersionMismatch, CModInfo& Info, CString& sRetMsg);
|
||||
|
||||
protected:
|
||||
CUser* m_pUser;
|
||||
CClient* m_pClient;
|
||||
CUser* m_pUser;
|
||||
CIRCNetwork* m_pNetwork;
|
||||
CClient* m_pClient;
|
||||
};
|
||||
|
||||
#endif // !_MODULES_H
|
||||
|
||||
@@ -42,15 +42,18 @@
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define GLOBALMODULECALL(macFUNC, macUSER, macCLIENT, macEXITER) \
|
||||
#define GLOBALMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER) \
|
||||
do { \
|
||||
CModules& GMods = CZNC::Get().GetModules(); \
|
||||
CUser* pOldGUser = GMods.GetUser(); \
|
||||
CIRCNetwork* pOldGNetwork = GMods.GetNetwork(); \
|
||||
CClient* pOldGClient = GMods.GetClient(); \
|
||||
GMods.SetUser(macUSER); \
|
||||
GMods.SetNetwork(macNETWORK); \
|
||||
GMods.SetClient(macCLIENT); \
|
||||
if (GMods.macFUNC) { \
|
||||
GMods.SetUser(pOldGUser); \
|
||||
GMods.SetNetwork(pOldGNetwork); \
|
||||
GMods.SetClient(pOldGClient); \
|
||||
macEXITER; \
|
||||
} \
|
||||
@@ -58,19 +61,39 @@
|
||||
GMods.SetClient(pOldGClient); \
|
||||
} while (false)
|
||||
|
||||
#define MODULECALL(macFUNC, macUSER, macCLIENT, macEXITER) \
|
||||
#define USERMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER) \
|
||||
if (macUSER) { \
|
||||
GLOBALMODULECALL(macFUNC, macUSER, macCLIENT, macEXITER); \
|
||||
CModules& UMods = macUSER->GetModules(); \
|
||||
CIRCNetwork* pOldUNetwork = UMods.GetNetwork(); \
|
||||
CClient* pOldUClient = UMods.GetClient(); \
|
||||
UMods.SetNetwork(macNETWORK); \
|
||||
UMods.SetClient(macCLIENT); \
|
||||
if (UMods.macFUNC) { \
|
||||
UMods.SetNetwork(pOldUNetwork); \
|
||||
UMods.SetClient(pOldUClient); \
|
||||
macEXITER; \
|
||||
} \
|
||||
UMods.SetNetwork(pOldUNetwork); \
|
||||
UMods.SetClient(pOldUClient); \
|
||||
}
|
||||
|
||||
#define NETWORKMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER) \
|
||||
if (macNETWORK) { \
|
||||
CModules& NMods = ((CIRCNetwork*)macNETWORK)->GetModules(); \
|
||||
CClient* pOldNClient = NMods.GetClient(); \
|
||||
NMods.SetClient(macCLIENT); \
|
||||
if (NMods.macFUNC) { \
|
||||
NMods.SetClient(pOldNClient); \
|
||||
macEXITER; \
|
||||
} \
|
||||
NMods.SetClient(pOldNClient); \
|
||||
}
|
||||
|
||||
#define MODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER) \
|
||||
GLOBALMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER); \
|
||||
USERMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER); \
|
||||
NETWORKMODULECALL(macFUNC, macUSER, macNETWORK, macCLIENT, macEXITER);
|
||||
|
||||
/** @mainpage
|
||||
* Welcome to the API documentation for ZNC.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user