Implement invite-notify

This commit is contained in:
Alexey Sokolov
2025-04-18 22:23:01 +01:00
parent 9ab81d1dad
commit 5befe2f7f8
14 changed files with 95 additions and 16 deletions
+7 -2
View File
@@ -116,6 +116,7 @@ class CClient : public CIRCSocket {
bool HasCapNotify() const { return m_bCapNotify; }
bool HasAwayNotify() const { return m_bAwayNotify; }
bool HasAccountNotify() const { return m_bAccountNotify; }
bool HasInviteNotify() const { return m_bInviteNotify; }
bool HasExtendedJoin() const { return m_bExtendedJoin; }
bool HasNamesx() const { return m_bNamesx; }
bool HasUHNames() const { return m_bUHNames; }
@@ -180,8 +181,10 @@ class CClient : public CIRCSocket {
*
* Message type | Capability
* ------------ | ----------
* \c ACCOUNT | \l CClient::HasAccountNotify() (<a href="http://ircv3.net/specs/extensions/account-notify-3.1.html">account-notify</a>)
* \c AWAY | \l CClient::HasAwayNotify() (<a href="http://ircv3.net/specs/extensions/away-notify-3.1.html">away-notify</a>)
* \c ACCOUNT | \l CClient::HasAccountNotify() (<a href="http://ircv3.net/specs/extensions/account-notify">account-notify</a>)
* \c AWAY | \l CClient::HasAwayNotify() (<a href="http://ircv3.net/specs/extensions/away-notify">away-notify</a>)
* \c INVITE | \l CClient::HasInviteNotify() (<a href="http://ircv3.net/specs/extensions/invite-notify">invite-notify</a>) if someone else is invited; invites sent to this user are not filtered out regardless of any capability.
* \c TAGMSG | \l CClient::HasMessageTagCap() (<a href="http://ircv3.net/specs/extensions/message-tags">message-tags</a>)
*
* ### Message tags
*
@@ -193,6 +196,7 @@ class CClient : public CIRCSocket {
* ----------- | ----------
* \c time | \l CClient::HasServerTime() (<a href="http://ircv3.net/specs/extensions/server-time-3.2.html">server-time</a>)
* \c batch | \l CClient::HasBatch() (<a href="http://ircv3.net/specs/extensions/batch-3.2.html">batch</a>)
* any tag | \l CClient::HasMessageTagCap() (<a href="http://ircv3.net/specs/extensions/message-tags">message-tags</a>)
*
* Additional tags can be added via \l CClient::SetTagSupport().
*
@@ -321,6 +325,7 @@ class CClient : public CIRCSocket {
bool m_bCapNotify;
bool m_bAwayNotify;
bool m_bAccountNotify;
bool m_bInviteNotify;
bool m_bExtendedJoin;
bool m_bNamesx;
bool m_bUHNames;
+1 -1
View File
@@ -180,7 +180,7 @@ class CIRCSock : public CIRCSocket {
bool OnChgHostMessage(CChgHostMessage& Message);
bool OnCTCPMessage(CCTCPMessage& Message);
bool OnErrorMessage(CMessage& Message);
bool OnInviteMessage(CMessage& Message);
bool OnInviteMessage(CInviteMessage& Message);
bool OnJoinMessage(CJoinMessage& Message);
bool OnKickMessage(CKickMessage& Message);
bool OnModeMessage(CModeMessage& Message);
+9
View File
@@ -311,6 +311,15 @@ class CKickMessage : public CTargetMessage {
};
REGISTER_ZNC_MESSAGE(CKickMessage);
class CInviteMessage : public CMessage {
public:
CString GetInvitedNick() const { return GetParam(0); }
void SetInvitedNick(const CString& sNick) { SetParam(0, sNick); }
CString GetChannel() const { return GetParam(1); }
void SetChannel(const CString& sChannel) { SetParam(1, sChannel); }
};
REGISTER_ZNC_MESSAGE(CInviteMessage);
class CPartMessage : public CTargetMessage {
public:
CString GetReason() const { return GetParam(1); }
+11 -2
View File
@@ -751,11 +751,19 @@ class CModule {
virtual void OnPart(const CNick& Nick, CChan& Channel,
const CString& sMessage);
/** Called when user is invited into a channel
/** Called when a user is invited to a channel.
* That includes the case of `invite-notify`.
* @since 1.10.0
* @param Message The message.
*/
virtual EModRet OnInviteMessage(CInviteMessage& Message);
/** Called when user is invited into a channel.
* @note even in case of `invite-notify` this is only called for "you"
* being invited, as this function has no way to tell you whom is
* invited instead.
* @param Nick The nick who invited you.
* @param sChan The channel the user got invited into
* @return See CModule::EModRet.
* @todo Add OnInviteMessage() hook
*/
virtual EModRet OnInvite(const CNick& Nick, const CString& sChan);
@@ -1610,6 +1618,7 @@ class CModules : public std::vector<CModule*>, private CCoreTranslationMixin {
bool OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage);
bool OnPartMessage(CPartMessage& Message);
bool OnInvite(const CNick& Nick, const CString& sChan);
bool OnInviteMessage(CInviteMessage& Message);
bool OnChanBufferStarting(CChan& Chan, CClient& Client);
bool OnChanBufferEnding(CChan& Chan, CClient& Client);
+1
View File
@@ -106,6 +106,7 @@ EModRet OnSendToIRCMessage(CMessage& Message)
EModRet OnUserTagMessage(CTargetMessage& Message)
EModRet OnChanTagMessage(CTargetMessage& Message)
EModRet OnPrivTagMessage(CTargetMessage& Message)
EModRet OnInviteMessage(CInviteMessage& Message)
void OnClientGetSASLMechanisms(SCString& ssMechanisms)
EModRet OnClientSASLServerInitialChallenge(const CString& sMechanism, CString& sResponse)
+1
View File
@@ -163,6 +163,7 @@ class ZNC_EXPORT_LIB_EXPORT CPerlModule : public CModule {
EModRet OnUserTagMessage(CTargetMessage& Message) override;
EModRet OnChanTagMessage(CTargetMessage& Message) override;
EModRet OnPrivTagMessage(CTargetMessage& Message) override;
EModRet OnInviteMessage(CInviteMessage& Message) override;
void OnClientGetSASLMechanisms(SCString& ssMechanisms) override;
EModRet OnClientSASLServerInitialChallenge(const CString& sMechanism,
+1
View File
@@ -592,6 +592,7 @@ sub OnSendToIRCMessage {}
sub OnUserTagMessage {}
sub OnChanTagMessage {}
sub OnPrivTagMessage {}
sub OnInviteMessage {}
# In Perl "undefined" is allowed value, so perl modules may continue using OnMode and not OnMode2
sub OnChanPermission2 { my $self = shift; $self->OnChanPermission(@_) }
+1
View File
@@ -106,6 +106,7 @@ EModRet OnSendToIRCMessage(CMessage& Message)
EModRet OnUserTagMessage(CTargetMessage& Message)
EModRet OnChanTagMessage(CTargetMessage& Message)
EModRet OnPrivTagMessage(CTargetMessage& Message)
EModRet OnInviteMessage(CInviteMessage& Message)
EModRet OnAddUser(CUser& User, CString& sErrorRet)
EModRet OnDeleteUser(CUser& User)
+1
View File
@@ -183,6 +183,7 @@ class ZNC_EXPORT_LIB_EXPORT CPyModule : public CModule {
EModRet OnUserTagMessage(CTargetMessage& Message) override;
EModRet OnChanTagMessage(CTargetMessage& Message) override;
EModRet OnPrivTagMessage(CTargetMessage& Message) override;
EModRet OnInviteMessage(CInviteMessage& Message) override;
// Global Modules
EModRet OnAddUser(CUser& User, CString& sErrorRet) override;
+3
View File
@@ -713,6 +713,9 @@ class Module:
def OnPrivTagMessage(self, msg):
pass
def OnInviteMessage(self, msg):
pass
class Command:
command = ''
+24 -8
View File
@@ -85,6 +85,7 @@ CClient::CClient()
m_bCapNotify(false),
m_bAwayNotify(false),
m_bAccountNotify(false),
m_bInviteNotify(false),
m_bExtendedJoin(false),
m_bNamesx(false),
m_bUHNames(false),
@@ -587,14 +588,25 @@ void CClient::PutClient(const CString& sLine) {
}
bool CClient::PutClient(const CMessage& Message) {
if (!m_bAwayNotify && Message.GetType() == CMessage::Type::Away) {
return false;
} else if (!m_bAccountNotify &&
Message.GetType() == CMessage::Type::Account) {
return false;
} else if (!m_bMessageTagCap &&
Message.GetType() == CMessage::Type::TagMsg) {
return false;
switch (Message.GetType()) {
case CMessage::Type::Away:
if (!m_bAwayNotify) return false;
break;
case CMessage::Type::Account:
if (!m_bAccountNotify) return false;
break;
case CMessage::Type::TagMsg:
if (!m_bMessageTagCap) return false;
break;
case CMessage::Type::Invite:
if (!m_bInviteNotify &&
!CNick(Message.As<CInviteMessage>().GetInvitedNick())
.NickEquals(m_sNick)) {
return false;
}
break;
default:
break;
}
CMessage Msg(Message);
@@ -854,6 +866,10 @@ CClient::CoreCaps() {
[](CClient* pClient, bool bVal) {
pClient->m_bCapNotify = bVal;
}},
{"invite-notify",
[](CClient* pClient, bool bVal) {
pClient->m_bInviteNotify = bVal;
}},
{"chghost", [](CClient* pClient,
bool bVal) { pClient->m_bChgHost = bVal; }},
{"sasl",
+10 -3
View File
@@ -386,6 +386,7 @@ bool CIRCSock::OnCapabilityMessage(CMessage& Message) {
{"multi-prefix", [this](bool bVal) { m_bNamesx = bVal; }},
{"userhost-in-names", [this](bool bVal) { m_bUHNames = bVal; }},
{"cap-notify", [](bool bVal) {}},
{"invite-notify", [](bool bVal) {}},
{"server-time", [this](bool bVal) { m_bServerTime = bVal; }},
{"znc.in/server-time-iso", [this](bool bVal) { m_bServerTime = bVal; }},
{"chghost", [](bool) {}},
@@ -596,10 +597,16 @@ bool CIRCSock::OnErrorMessage(CMessage& Message) {
return true;
}
bool CIRCSock::OnInviteMessage(CMessage& Message) {
bool CIRCSock::OnInviteMessage(CInviteMessage& Message) {
Message.SetChan(GetNetwork()->FindChan(Message.GetChannel()));
bool bResult = false;
IRCSOCKMODULECALL(OnInvite(Message.GetNick(), Message.GetParam(1)),
&bResult);
IRCSOCKMODULECALL(OnInviteMessage(Message), &bResult);
if (bResult) return true;
CNick InvitedNick = Message.GetInvitedNick();
if (InvitedNick.NickEquals(GetNick())) {
IRCSOCKMODULECALL(OnInvite(Message.GetNick(), Message.GetParam(1)),
&bResult);
}
return bResult;
}
+6
View File
@@ -890,6 +890,9 @@ CModule::EModRet CModule::OnPrivTagMessage(CTargetMessage& Message) {
CModule::EModRet CModule::OnChanTagMessage(CTargetMessage& Message) {
return CONTINUE;
}
CModule::EModRet CModule::OnInviteMessage(CInviteMessage& Message) {
return CONTINUE;
}
CModule::EModRet CModule::OnUserJoin(CString& sChannel, CString& sKey) {
return CONTINUE;
}
@@ -1448,6 +1451,9 @@ bool CModules::OnPrivTagMessage(CTargetMessage& Message) {
bool CModules::OnChanTagMessage(CTargetMessage& Message) {
MODHALTCHK(OnChanTagMessage(Message));
}
bool CModules::OnInviteMessage(CInviteMessage& Message) {
MODHALTCHK(OnInviteMessage(Message));
}
bool CModules::OnUserJoin(CString& sChannel, CString& sKey) {
MODHALTCHK(OnUserJoin(sChannel, sKey));
}
+19
View File
@@ -1040,5 +1040,24 @@ TEST_F(ZNCTest, StatusAction) {
ASSERT_THAT(ircd.ReadRemainder().toStdString(), Not(HasSubstr("PRIVMSG")));
}
TEST_F(ZNCTest, InviteNotify) {
auto znc = Run();
auto ircd = ConnectIRCd();
auto client = LoginClient();
client.Write("CAP REQ invite-notify");
client.ReadUntil("ACK");
auto client2 = LoginClient();
ircd.Write("001 nick Welcome");
ircd.Write(":source!id@ho INVITE nick #chan");
client.ReadUntil(":source!id@ho INVITE nick #chan");
client2.ReadUntil(":source!id@ho INVITE nick #chan");
ircd.Write(":source!id@ho INVITE someone #chan");
client.ReadUntil(":source!id@ho INVITE someone #chan");
ASSERT_THAT(client2.ReadRemainder().toStdString(), Not(HasSubstr("someone")));
}
} // namespace
} // namespace znc_inttest