mirror of
https://github.com/znc/znc.git
synced 2026-07-03 00:11:59 +02:00
Add OnSendToIRCMessage and OnSendToClientMessage
This also alters PutClient such that the CMessage variant handles sending messages, rather than the CString variant. As a side bonus, this gives callers better information on whether the message was sent to the client. Additionally, it eliminates the need for a hook to let modules set the tags sent to a client, as that can now be done inside OnSendToClientMessage.
This commit is contained in:
+13
-5
@@ -1026,18 +1026,24 @@ class CModule {
|
||||
*/
|
||||
virtual EModRet OnDeleteNetwork(CIRCNetwork& Network);
|
||||
|
||||
/** Called when ZNC sends a raw traffic line to a client.
|
||||
* @param sLine The raw traffic line sent.
|
||||
* @param Client The client this line is sent to.
|
||||
/** Called immediately before ZNC sends a raw traffic line to a client.
|
||||
* @since 1.7.0
|
||||
* @param Message The message being sent to the client.
|
||||
* @warning Calling PutUser() from within this hook leads to infinite recursion.
|
||||
* @return See CModule::EModRet.
|
||||
*/
|
||||
virtual EModRet OnSendToClientMessage(CMessage& Message);
|
||||
/// @deprecated Use OnSendToClientMessage() instead.
|
||||
virtual EModRet OnSendToClient(CString& sLine, CClient& Client);
|
||||
/** Called when ZNC sends a raw traffic line to the IRC server.
|
||||
* @param sLine The raw traffic line sent.
|
||||
|
||||
/** Called immediately before ZNC sends a raw traffic line to the IRC server.
|
||||
* @since 1.7.0
|
||||
* @param Message The message being sent to the IRC server.
|
||||
* @warning Calling PutIRC() from within this hook leads to infinite recursion.
|
||||
* @return See CModule::EModRet.
|
||||
*/
|
||||
virtual EModRet OnSendToIRCMessage(CMessage& Message);
|
||||
/// @deprecated Use OnSendToIRCMessage() instead.
|
||||
virtual EModRet OnSendToIRC(CString& sLine);
|
||||
|
||||
ModHandle GetDLL() { return m_pDLL; }
|
||||
@@ -1515,7 +1521,9 @@ class CModules : public std::vector<CModule*> {
|
||||
bool OnDeleteNetwork(CIRCNetwork& Network);
|
||||
|
||||
bool OnSendToClient(CString& sLine, CClient& Client);
|
||||
bool OnSendToClientMessage(CMessage& Message);
|
||||
bool OnSendToIRC(CString& sLine);
|
||||
bool OnSendToIRCMessage(CMessage& Message);
|
||||
|
||||
bool OnServerCapAvailable(const CString& sCap);
|
||||
bool OnServerCapResult(const CString& sCap, bool bSuccess);
|
||||
|
||||
@@ -97,3 +97,5 @@ EModRet OnChanTextMessage(CTextMessage& Message)
|
||||
EModRet OnPrivNoticeMessage(CNoticeMessage& Message)
|
||||
EModRet OnChanNoticeMessage(CNoticeMessage& Message)
|
||||
EModRet OnTopicMessage(CTopicMessage& Message)
|
||||
EModRet OnSendToClientMessage(CMessage& Message)
|
||||
EModRet OnSendToIRCMessage(CMessage& Message)
|
||||
|
||||
@@ -153,6 +153,8 @@ class ZNC_EXPORT_LIB_EXPORT CPerlModule : public CModule {
|
||||
EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override;
|
||||
EModRet OnChanNoticeMessage(CNoticeMessage& Message) override;
|
||||
EModRet OnTopicMessage(CTopicMessage& Message) override;
|
||||
EModRet OnSendToClientMessage(CMessage& Message) override;
|
||||
EModRet OnSendToIRCMessage(CMessage& Message) override;
|
||||
};
|
||||
|
||||
static inline CPerlModule* AsPerlModule(CModule* p) {
|
||||
|
||||
@@ -577,6 +577,8 @@ sub OnTopicMessage {
|
||||
$msg->SetTopic($topic);
|
||||
return $ret;
|
||||
}
|
||||
sub OnSendToClientMessage {}
|
||||
sub OnSendToIRCMessage {}
|
||||
|
||||
# In Perl "undefined" is allowed value, so perl modules may continue using OnMode and not OnMode2
|
||||
sub OnChanPermission2 { my $self = shift; $self->OnChanPermission(@_) }
|
||||
|
||||
@@ -97,6 +97,8 @@ EModRet OnChanTextMessage(CTextMessage& Message)
|
||||
EModRet OnPrivNoticeMessage(CNoticeMessage& Message)
|
||||
EModRet OnChanNoticeMessage(CNoticeMessage& Message)
|
||||
EModRet OnTopicMessage(CTopicMessage& Message)
|
||||
EModRet OnSendToClientMessage(CMessage& Message)
|
||||
EModRet OnSendToIRCMessage(CMessage& Message)
|
||||
|
||||
EModRet OnAddUser(CUser& User, CString& sErrorRet)
|
||||
EModRet OnDeleteUser(CUser& User)
|
||||
|
||||
@@ -173,6 +173,8 @@ class ZNC_EXPORT_LIB_EXPORT CPyModule : public CModule {
|
||||
EModRet OnPrivNoticeMessage(CNoticeMessage& Message) override;
|
||||
EModRet OnChanNoticeMessage(CNoticeMessage& Message) override;
|
||||
EModRet OnTopicMessage(CTopicMessage& Message) override;
|
||||
EModRet OnSendToClientMessage(CMessage& Message) override;
|
||||
EModRet OnSendToIRCMessage(CMessage& Message) override;
|
||||
|
||||
// Global Modules
|
||||
EModRet OnAddUser(CUser& User, CString& sErrorRet) override;
|
||||
|
||||
@@ -655,6 +655,12 @@ class Module:
|
||||
def OnUnknownUserRawMessage(self, msg):
|
||||
pass
|
||||
|
||||
def OnSendToClientMessage(self, msg):
|
||||
pass
|
||||
|
||||
def OnSendToIRCMessage(self, msg):
|
||||
pass
|
||||
|
||||
|
||||
def make_inherit(cl, parent, attr):
|
||||
def make_caller(parent, name, attr):
|
||||
|
||||
+18
-15
@@ -483,13 +483,8 @@ CString CClient::GetFullName() const {
|
||||
}
|
||||
|
||||
void CClient::PutClient(const CString& sLine) {
|
||||
bool bReturn = false;
|
||||
CString sCopy = sLine;
|
||||
NETWORKMODULECALL(OnSendToClient(sCopy, *this), m_pUser, m_pNetwork, this,
|
||||
&bReturn);
|
||||
if (bReturn) return;
|
||||
DEBUG("(" << GetFullName() << ") ZNC -> CLI [" << sCopy << "]");
|
||||
Write(sCopy + "\r\n");
|
||||
CMessage Message(sLine);
|
||||
PutClient(Message);
|
||||
}
|
||||
|
||||
bool CClient::PutClient(const CMessage& Message) {
|
||||
@@ -563,10 +558,7 @@ bool CClient::PutClient(const CMessage& Message) {
|
||||
}
|
||||
}
|
||||
|
||||
CString sLine = Msg.ToString(CMessage::ExcludeTags);
|
||||
|
||||
// TODO: introduce a module hook that gives control over the tags that are
|
||||
// sent
|
||||
// TODO: add the ability to set a list of tags to send
|
||||
MCString mssTags;
|
||||
|
||||
if (HasServerTime()) {
|
||||
@@ -585,11 +577,22 @@ bool CClient::PutClient(const CMessage& Message) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!mssTags.empty()) {
|
||||
CUtils::SetMessageTags(sLine, mssTags);
|
||||
}
|
||||
Msg.SetTags(mssTags);
|
||||
Msg.SetClient(this);
|
||||
Msg.SetNetwork(m_pNetwork);
|
||||
|
||||
PutClient(sLine);
|
||||
bool bReturn = false;
|
||||
NETWORKMODULECALL(OnSendToClientMessage(Msg), m_pUser, m_pNetwork, this,
|
||||
&bReturn);
|
||||
if (bReturn) return false;
|
||||
|
||||
CString sCopy = Msg.ToString();
|
||||
NETWORKMODULECALL(OnSendToClient(sCopy, *this), m_pUser, m_pNetwork, this,
|
||||
&bReturn);
|
||||
if (bReturn) return false;
|
||||
|
||||
DEBUG("(" << GetFullName() << ") ZNC -> CLI [" << sCopy << "]");
|
||||
Write(sCopy + "\r\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+13
-6
@@ -1154,13 +1154,20 @@ void CIRCSock::TrySend() {
|
||||
m_iSendsAllowed--;
|
||||
bool bSkip = false;
|
||||
CString& sLine = m_vsSendQueue.front();
|
||||
IRCSOCKMODULECALL(OnSendToIRC(sLine), &bSkip);
|
||||
|
||||
CMessage Message(sLine);
|
||||
Message.SetNetwork(m_pNetwork);
|
||||
IRCSOCKMODULECALL(OnSendToIRCMessage(Message), &bSkip);
|
||||
|
||||
if (!bSkip) {
|
||||
;
|
||||
DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/"
|
||||
<< m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine
|
||||
<< "]");
|
||||
Write(sLine + "\r\n");
|
||||
CString sCopy = Message.ToString();
|
||||
IRCSOCKMODULECALL(OnSendToIRC(sCopy), &bSkip);
|
||||
if (!bSkip) {
|
||||
DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/"
|
||||
<< m_pNetwork->GetName() << ") ZNC -> IRC [" << sCopy
|
||||
<< "]");
|
||||
Write(sCopy + "\r\n");
|
||||
}
|
||||
}
|
||||
m_vsSendQueue.pop_front();
|
||||
}
|
||||
|
||||
@@ -983,7 +983,14 @@ CModule::EModRet CModule::OnDeleteNetwork(CIRCNetwork& Network) {
|
||||
CModule::EModRet CModule::OnSendToClient(CString& sLine, CClient& Client) {
|
||||
return CONTINUE;
|
||||
}
|
||||
CModule::EModRet CModule::OnSendToClientMessage(CMessage& Message) {
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
CModule::EModRet CModule::OnSendToIRC(CString& sLine) { return CONTINUE; }
|
||||
CModule::EModRet CModule::OnSendToIRCMessage(CMessage& Message) {
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
bool CModule::OnServerCapAvailable(const CString& sCap) { return false; }
|
||||
void CModule::OnServerCapResult(const CString& sCap, bool bSuccess) {}
|
||||
@@ -1444,7 +1451,13 @@ bool CModules::OnDeleteNetwork(CIRCNetwork& Network) {
|
||||
bool CModules::OnSendToClient(CString& sLine, CClient& Client) {
|
||||
MODHALTCHK(OnSendToClient(sLine, Client));
|
||||
}
|
||||
bool CModules::OnSendToClientMessage(CMessage& Message) {
|
||||
MODHALTCHK(OnSendToClientMessage(Message));
|
||||
}
|
||||
bool CModules::OnSendToIRC(CString& sLine) { MODHALTCHK(OnSendToIRC(sLine)); }
|
||||
bool CModules::OnSendToIRCMessage(CMessage& Message) {
|
||||
MODHALTCHK(OnSendToIRCMessage(Message));
|
||||
}
|
||||
bool CModules::OnStatusCommand(CString& sCommand) {
|
||||
MODHALTCHK(OnStatusCommand(sCommand));
|
||||
}
|
||||
|
||||
@@ -343,3 +343,23 @@ TEST_F(ClientTest, OnUserQuitMessage) {
|
||||
m_pTestClient->ReadLine(msg.ToString());
|
||||
EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // quit is never forwarded
|
||||
}
|
||||
|
||||
TEST_F(ClientTest, OnSendToClientMessage) {
|
||||
CMessage msg("PRIVMSG #chan :text");
|
||||
m_pTestModule->eAction = CModule::HALT;
|
||||
m_pTestModule->bSendHooks = true;
|
||||
m_pTestClient->PutClient(msg.ToString());
|
||||
|
||||
EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnSendToClientMessage"));
|
||||
EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString()));
|
||||
EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestClient->GetNetwork()));
|
||||
EXPECT_THAT(m_pTestModule->vClients, ElementsAre(m_pTestClient));
|
||||
EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr));
|
||||
EXPECT_THAT(m_pTestSock->vsLines, IsEmpty()); // halt
|
||||
|
||||
m_pTestModule->eAction = CModule::CONTINUE;
|
||||
m_pTestClient->ReadLine(msg.ToString());
|
||||
|
||||
EXPECT_THAT(m_pTestSock->vsLines, ElementsAre(msg.ToString()));
|
||||
m_pTestModule->bSendHooks = false;
|
||||
}
|
||||
|
||||
@@ -361,6 +361,25 @@ TEST_F(IRCSockTest, OnQuitMessage) {
|
||||
EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString()));
|
||||
}
|
||||
|
||||
TEST_F(IRCSockTest, OnSendToIRCMessage) {
|
||||
CMessage msg(":nick PRIVMSG #chan :hello");
|
||||
m_pTestModule->eAction = CModule::HALT;
|
||||
m_pTestModule->bSendHooks = true;
|
||||
m_pTestSock->PutIRC(msg.ToString());
|
||||
|
||||
EXPECT_THAT(m_pTestModule->vsHooks, ElementsAre("OnSendToIRCMessage"));
|
||||
EXPECT_THAT(m_pTestModule->vsMessages, ElementsAre(msg.ToString()));
|
||||
EXPECT_THAT(m_pTestModule->vNetworks, ElementsAre(m_pTestNetwork));
|
||||
EXPECT_THAT(m_pTestModule->vChannels, ElementsAre(nullptr));
|
||||
EXPECT_THAT(m_pTestClient->vsLines, IsEmpty()); // halt
|
||||
|
||||
m_pTestModule->eAction = CModule::CONTINUE;
|
||||
m_pTestSock->ReadLine(msg.ToString());
|
||||
|
||||
EXPECT_THAT(m_pTestClient->vsLines, ElementsAre(msg.ToString()));
|
||||
m_pTestModule->bSendHooks = false;
|
||||
}
|
||||
|
||||
TEST_F(IRCSockTest, OnTextMessage) {
|
||||
CMessage msg(":nick PRIVMSG #chan :hello");
|
||||
m_pTestModule->eAction = CModule::HALT;
|
||||
|
||||
@@ -129,6 +129,16 @@ class TestModule : public CModule {
|
||||
OnMessage(msg);
|
||||
}
|
||||
|
||||
EModRet OnSendToClientMessage(CMessage& msg) override {
|
||||
if (!bSendHooks) return CONTINUE;
|
||||
vsHooks.push_back("OnSendToClientMessage");
|
||||
return OnMessage(msg);
|
||||
}
|
||||
EModRet OnSendToIRCMessage(CMessage& msg) override {
|
||||
if (!bSendHooks) return CONTINUE;
|
||||
vsHooks.push_back("OnSendToIRCMessage");
|
||||
return OnMessage(msg);
|
||||
}
|
||||
EModRet OnUserCTCPReplyMessage(CCTCPMessage& msg) override {
|
||||
vsHooks.push_back("OnUserCTCPReplyMessage");
|
||||
return OnMessage(msg);
|
||||
@@ -188,6 +198,7 @@ class TestModule : public CModule {
|
||||
std::vector<CClient*> vClients;
|
||||
std::vector<CChan*> vChannels;
|
||||
EModRet eAction = CONTINUE;
|
||||
bool bSendHooks = false;
|
||||
};
|
||||
|
||||
class IRCTest : public ::testing::Test {
|
||||
|
||||
Reference in New Issue
Block a user