Merge pull request #825 from OGAWAHirofumi/extend-clearbuffer

Extend clearbufferonmsg module and some znc commands for flexible buffer clear
This commit is contained in:
Alexey Sokolov
2015-02-22 10:05:37 -08:00
10 changed files with 114 additions and 13 deletions
+6
View File
@@ -720,6 +720,11 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnUserTopicRequest(CString& sChannel);
/** This module hook is called when a user requests to quit from network.
* @param sMessage The quit message the client sent.
* @return See CModule::EModRet.
*/
virtual EModRet OnUserQuit(CString& sMessage);
/** Called when we receive a CTCP reply <em>from IRC</em>.
* @param Nick The nick the CTCP reply is from.
@@ -1190,6 +1195,7 @@ public:
bool OnUserPart(CString& sChannel, CString& sMessage);
bool OnUserTopic(CString& sChannel, CString& sTopic);
bool OnUserTopicRequest(CString& sChannel);
bool OnUserQuit(CString& sMessage);
bool OnCTCPReply(CNick& Nick, CString& sMessage);
bool OnPrivCTCP(CNick& Nick, CString& sMessage);
+95 -13
View File
@@ -15,72 +15,154 @@
*/
#include <znc/IRCNetwork.h>
#include <znc/User.h>
#include <znc/Chan.h>
#include <znc/Query.h>
using std::vector;
enum {
RULE_MSG,
RULE_CTCP,
RULE_ACTION,
RULE_NOTICE,
RULE_PART,
RULE_TOPIC,
RULE_QUIT,
RULE_MAX,
};
class CClearBufferOnMsgMod : public CModule {
public:
MODCONSTRUCTOR(CClearBufferOnMsgMod) {}
MODCONSTRUCTOR(CClearBufferOnMsgMod) {
SetAllRules(true);
// false for backward compatibility
m_bRules[RULE_QUIT] = false;
}
void ClearAllBuffers() {
CIRCNetwork* pNetwork = GetNetwork();
if (pNetwork) {
const vector<CChan*>& vChans = pNetwork->GetChans();
for (vector<CChan*>::const_iterator it = vChans.begin(); it != vChans.end(); ++it) {
for (CChan* pChan : vChans) {
// Skip detached channels, they weren't read yet
if ((*it)->IsDetached())
if (pChan->IsDetached())
continue;
(*it)->ClearBuffer();
pChan->ClearBuffer();
// We deny AutoClearChanBuffer on all channels since this module
// doesn't make any sense with it
(*it)->SetAutoClearChanBuffer(false);
pChan->SetAutoClearChanBuffer(false);
}
vector<CQuery*> VQueries = pNetwork->GetQueries();
for (vector<CQuery*>::const_iterator it = VQueries.begin(); it != VQueries.end(); ++it) {
pNetwork->DelQuery((*it)->GetName());
for (CQuery* pQuery : VQueries) {
pNetwork->DelQuery(pQuery->GetName());
}
// We deny AutoClearQueryBuffer since this module
// doesn't make any sense with it
GetUser()->SetAutoClearQueryBuffer(false);
}
}
virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage) override {
ClearAllBuffers();
if (m_bRules[RULE_MSG])
ClearAllBuffers();
return CONTINUE;
}
virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage) override {
ClearAllBuffers();
if (m_bRules[RULE_CTCP])
ClearAllBuffers();
return CONTINUE;
}
virtual EModRet OnUserAction(CString& sTarget, CString& sMessage) override {
ClearAllBuffers();
if (m_bRules[RULE_ACTION])
ClearAllBuffers();
return CONTINUE;
}
virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage) override {
ClearAllBuffers();
if (m_bRules[RULE_NOTICE])
ClearAllBuffers();
return CONTINUE;
}
virtual EModRet OnUserPart(CString& sChannel, CString& sMessage) override {
ClearAllBuffers();
if (m_bRules[RULE_PART])
ClearAllBuffers();
return CONTINUE;
}
virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) override {
ClearAllBuffers();
if (m_bRules[RULE_TOPIC])
ClearAllBuffers();
return CONTINUE;
}
virtual EModRet OnUserQuit(CString& sMessage) override {
if (m_bRules[RULE_QUIT])
ClearAllBuffers();
return CONTINUE;
}
void SetAllRules(bool bVal) {
for (int i = 0; i < RULE_MAX; i++)
m_bRules[i] = bVal;
}
void SetRule(const CString& sOpt, bool bVal) {
static const struct {
CString sName;
int Index;
} Names[RULE_MAX] = {
{ "msg", RULE_MSG },
{ "ctcp", RULE_CTCP },
{ "action", RULE_ACTION },
{ "notice", RULE_NOTICE },
{ "part", RULE_PART },
{ "topic", RULE_TOPIC },
{ "quit", RULE_QUIT },
};
if (sOpt.Equals("all")) {
SetAllRules(bVal);
} else {
for (int i = 0; i < RULE_MAX; i++) {
if (sOpt.Equals(Names[i].sName))
m_bRules[Names[i].Index] = bVal;
}
}
}
virtual bool OnLoad(const CString& sArgs, CString& sMessage) override {
VCString vsOpts;
sArgs.Split(" ", vsOpts, false);
for (CString& sOpt : vsOpts) {
if (sOpt.StartsWith("!"))
SetRule(sOpt.substr(1), false);
else if (!sOpt.empty())
SetRule(sOpt, true);
}
return true;
}
private:
bool m_bRules[RULE_MAX];
};
template<> void TModInfo<CClearBufferOnMsgMod>(CModInfo& Info) {
Info.SetWikiPage("clearbufferonmsg");
Info.SetHasArgs(true);
Info.SetArgsHelpText("[ [!]<msg|ctcp|action|notice|part|topic|quit|all> ]");
}
USERMODULEDEFS(CClearBufferOnMsgMod, "Clear all channel and query buffers whenever the user does something")
+1
View File
@@ -47,6 +47,7 @@ EModRet OnUserJoin(CString& sChannel, CString& sKey)
EModRet OnUserPart(CString& sChannel, CString& sMessage)
EModRet OnUserTopic(CString& sChannel, CString& sTopic)
EModRet OnUserTopicRequest(CString& sChannel)
EModRet OnUserQuit(CString& sMessage)
EModRet OnCTCPReply(CNick& Nick, CString& sMessage)
EModRet OnPrivCTCP(CNick& Nick, CString& sMessage)
EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage)
+1
View File
@@ -86,6 +86,7 @@ public:
virtual EModRet OnUserJoin(CString& sChannel, CString& sKey) override;
virtual EModRet OnUserPart(CString& sChannel, CString& sMessage) override;
virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) override;
virtual EModRet OnUserQuit(CString& sMessage) override;
virtual EModRet OnUserTopicRequest(CString& sChannel) override;
virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override;
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override;
+1
View File
@@ -356,6 +356,7 @@ sub OnUserJoin {}
sub OnUserPart {}
sub OnUserTopic {}
sub OnUserTopicRequest {}
sub OnUserQuit {}
sub OnCTCPReply {}
sub OnPrivCTCP {}
sub OnChanCTCP {}
+1
View File
@@ -47,6 +47,7 @@ EModRet OnUserJoin(CString& sChannel, CString& sKey)
EModRet OnUserPart(CString& sChannel, CString& sMessage)
EModRet OnUserTopic(CString& sChannel, CString& sTopic)
EModRet OnUserTopicRequest(CString& sChannel)
EModRet OnUserQuit(CString& sMessage)
EModRet OnCTCPReply(CNick& Nick, CString& sMessage)
EModRet OnPrivCTCP(CNick& Nick, CString& sMessage)
EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage)
+1
View File
@@ -103,6 +103,7 @@ public:
virtual EModRet OnUserPart(CString& sChannel, CString& sMessage) override;
virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) override;
virtual EModRet OnUserTopicRequest(CString& sChannel) override;
virtual EModRet OnUserQuit(CString& sMessage) override;
virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage) override;
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) override;
virtual EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) override;
+3
View File
@@ -339,6 +339,9 @@ class Module:
def OnUserTopicRequest(self, sChannel):
pass
def OnUserQuit(self, sMessage):
pass
def OnCTCPReply(self, Nick, sMessage):
pass
+3
View File
@@ -198,6 +198,9 @@ void CClient::ReadLine(const CString& sData) {
// Block PONGs, we already responded to the pings
return;
} else if (sCommand.Equals("QUIT")) {
CString sMsg = sLine.Token(1, true).TrimPrefix_n();
NETWORKMODULECALL(OnUserQuit(sMsg), m_pUser, m_pNetwork, this, &bReturn);
if (bReturn) return;
Close(Csock::CLT_AFTERWRITE); // Treat a client quit as a detach
return; // Don't forward this msg. We don't want the client getting us disconnected.
} else if (sCommand.Equals("PROTOCTL")) {
+2
View File
@@ -693,6 +693,7 @@ CModule::EModRet CModule::OnUserJoin(CString& sChannel, CString& sKey) { return
CModule::EModRet CModule::OnUserPart(CString& sChannel, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnUserTopic(CString& sChannel, CString& sTopic) { return CONTINUE; }
CModule::EModRet CModule::OnUserTopicRequest(CString& sChannel) { return CONTINUE; }
CModule::EModRet CModule::OnUserQuit(CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnCTCPReply(CNick& Nick, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnPrivCTCP(CNick& Nick, CString& sMessage) { return CONTINUE; }
@@ -854,6 +855,7 @@ bool CModules::OnUserJoin(CString& sChannel, CString& sKey) { MODHALTCHK(OnUserJ
bool CModules::OnUserPart(CString& sChannel, CString& sMessage) { MODHALTCHK(OnUserPart(sChannel, sMessage)); }
bool CModules::OnUserTopic(CString& sChannel, CString& sTopic) { MODHALTCHK(OnUserTopic(sChannel, sTopic)); }
bool CModules::OnUserTopicRequest(CString& sChannel) { MODHALTCHK(OnUserTopicRequest(sChannel)); }
bool CModules::OnUserQuit(CString& sMessage) { MODHALTCHK(OnUserQuit(sMessage)); }
bool CModules::OnQuit(const CNick& Nick, const CString& sMessage, const vector<CChan*>& vChans) { MODUNLOADCHK(OnQuit(Nick, sMessage, vChans)); return false; }
bool CModules::OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans) { MODUNLOADCHK(OnNick(Nick, sNewNick, vChans)); return false; }