Add CCapability

This commit is contained in:
Alexey Sokolov
2024-01-13 21:22:42 +00:00
parent 236755444b
commit 99e6869b28
3 changed files with 152 additions and 109 deletions

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <znc/IRCSock.h>
#include <znc/Modules.h>
#include <znc/FileUtils.h>
#include <znc/Template.h>
@@ -160,6 +161,37 @@ CModule::CModule(ModHandle pDLL, CUser* pUser, CIRCNetwork* pNetwork,
}
CModule::~CModule() {
for (const auto& [sName, pCap] : m_mCaps) {
switch (GetType()) {
case CModInfo::NetworkModule:
GetNetwork()->NotifyClientsAboutServerDependentCap(
sName, false, [&](CClient* pClient, bool bState) {});
for (CClient* pClient : GetNetwork()->GetClients()) {
pCap->OnClientChangedSupport(pClient, false);
}
break;
case CModInfo::UserModule:
for (CIRCNetwork* pNetwork : GetUser()->GetNetworks()) {
pNetwork->NotifyClientsAboutServerDependentCap(
sName, false, [&](CClient* pClient, bool bState) {});
for (CClient* pClient : pNetwork->GetClients()) {
pCap->OnClientChangedSupport(pClient, false);
}
}
break;
case CModInfo::GlobalModule:
for (auto& [_, pUser] : CZNC::Get().GetUserMap()) {
for (CIRCNetwork* pNetwork : pUser->GetNetworks()) {
pNetwork->NotifyClientsAboutServerDependentCap(
sName, false, [&](CClient* pClient, bool bState) {});
for (CClient* pClient : pNetwork->GetClients()) {
pCap->OnClientChangedSupport(pClient, false);
}
}
}
}
}
while (!m_sTimers.empty()) {
RemTimer(*m_sTimers.begin());
}
@@ -605,8 +637,22 @@ bool CModule::OnLoad(const CString& sArgs, CString& sMessage) {
bool CModule::OnBoot() { return true; }
void CModule::OnPreRehash() {}
void CModule::OnPostRehash() {}
void CModule::OnIRCDisconnected() {}
void CModule::OnIRCConnected() {}
void CModule::OnIRCDisconnected() {
for (const auto& [sName, pCap] : m_mCaps) {
GetNetwork()->NotifyClientsAboutServerDependentCap(
sName, false, [&](CClient* pClient, bool bState) {});
for (CClient* pClient : GetNetwork()->GetClients()) {
pCap->OnClientChangedSupport(pClient, false);
}
}
}
void CModule::OnIRCConnected() {
for (const auto& [sName, pCap] : m_mCaps) {
if (GetNetwork()->IsServerCapAccepted(sName)) {
GetNetwork()->NotifyClientsAboutServerDependentCap(sName, true, [](CClient* pClient, bool bState){});
}
}
}
CModule::EModRet CModule::OnIRCConnecting(CIRCSock* IRCSock) {
return CONTINUE;
}
@@ -997,14 +1043,48 @@ CModule::EModRet CModule::OnSendToIRC(CString& sLine) { return CONTINUE; }
CModule::EModRet CModule::OnSendToIRCMessage(CMessage& Message) {
return CONTINUE;
}
void CModule::OnClientAttached() {}
void CModule::OnClientDetached() {}
void CModule::OnClientAttached() {
if (!GetNetwork()) return;
for (const auto& [sName, pCap] : m_mCaps) {
if (GetNetwork()->IsServerCapAccepted(sName)) {
GetClient()->NotifyServerDependentCap(sName, true, GetNetwork()->GetIRCSock()->GetCapLsValue(sName), nullptr);
}
}
}
void CModule::OnClientDetached() {
for (const auto& [sName, pCap] : m_mCaps) {
GetClient()->NotifyServerDependentCap(sName, false, "",
[](CClient*, bool) {});
pCap->OnClientChangedSupport(GetClient(), false);
}
}
bool CModule::OnServerCapAvailable(const CString& sCap) { return false; }
bool CModule::OnServerCap302Available(const CString& sCap, const CString& sValue) {
return OnServerCapAvailable(sCap);
bool CModule::OnServerCap302Available(const CString& sCap,
const CString& sValue) {
auto it = m_mCaps.find(sCap);
if (it == m_mCaps.end()) return OnServerCapAvailable(sCap);
if (GetNetwork()->IsServerCapAccepted(sCap)) {
// This can happen when server sent CAP NEW with another value.
GetNetwork()->NotifyClientsAboutServerDependentCap(sCap, true, nullptr);
// It's enabled already, no need to REQ it again.
return false;
}
return true;
}
void CModule::OnServerCapResult(const CString& sCap, bool bSuccess) {
auto it = m_mCaps.find(sCap);
if (it == m_mCaps.end()) return;
it->second->OnServerChangedSupport(GetNetwork(), bSuccess);
if (GetNetwork()->GetIRCSock()->IsAuthed()) {
GetNetwork()->NotifyClientsAboutServerDependentCap(
sCap, bSuccess, [&](CClient* pClient, bool bState) {});
if (!bSuccess)
for (CClient* pClient : GetNetwork()->GetClients()) {
it->second->OnClientChangedSupport(pClient, false);
}
}
}
void CModule::OnServerCapResult(const CString& sCap, bool bSuccess) {}
bool CModule::PutIRC(const CString& sLine) {
return m_pNetwork ? m_pNetwork->PutIRC(sLine) : false;
@@ -1073,13 +1153,36 @@ CModule::EModRet CModule::OnUnknownUserRaw(CClient* pClient, CString& sLine) {
CModule::EModRet CModule::OnUnknownUserRawMessage(CMessage& Message) {
return CONTINUE;
}
void CModule::OnClientCapLs(CClient* pClient, SCString& ssCaps) {}
void CModule::OnClientCapLs(CClient* pClient, SCString& ssCaps) {
for (const auto& [sName, pCap] : m_mCaps) {
if (GetNetwork() && GetNetwork()->IsServerCapAccepted(sName)) {
if (pClient->HasCap302()) {
CString sValue =
GetNetwork()->GetIRCSock()->GetCapLsValue(sName);
if (!sValue.empty()) {
ssCaps.insert(sName + '=' + sValue);
} else {
ssCaps.insert(sName);
}
} else {
ssCaps.insert(sName);
}
}
}
}
bool CModule::IsClientCapSupported(CClient* pClient, const CString& sCap,
bool bState) {
return false;
auto it = m_mCaps.find(sCap);
if (it == m_mCaps.end()) return false;
if (!bState) return true;
return GetNetwork() && GetNetwork()->IsServerCapAccepted(sCap);
}
void CModule::OnClientCapRequest(CClient* pClient, const CString& sCap,
bool bState) {}
bool bState) {
auto it = m_mCaps.find(sCap);
if (it == m_mCaps.end()) return;
it->second->OnClientChangedSupport(pClient, bState);
}
CModule::EModRet CModule::OnModuleLoading(const CString& sModName,
const CString& sArgs,
CModInfo::EModuleType eType,
@@ -1097,6 +1200,11 @@ CModule::EModRet CModule::OnGetModInfo(CModInfo& ModInfo,
}
void CModule::OnGetAvailableMods(set<CModInfo>& ssMods,
CModInfo::EModuleType eType) {}
void CModule::AddCapability(const CString& sName,
std::unique_ptr<CCapability> pCap) {
pCap->SetModule(this);
m_mCaps[sName] = std::move(pCap);
}
CModules::CModules()
: m_pUser(nullptr), m_pNetwork(nullptr), m_pClient(nullptr) {}