Add specialized types and hooks for the most common msgs

PRIVMSG, NOTICE, JOIN, PART, QUIT, NICK, KICK, TOPIC
This commit is contained in:
J-P Nurmi
2015-07-13 20:33:48 +02:00
parent 50ab019901
commit ff181a4a85
6 changed files with 431 additions and 65 deletions

View File

@@ -28,6 +28,7 @@ class CChan;
class CUser;
class CIRCNetwork;
class CClient;
class CMessage;
// !Forward Declarations
// TODO: This class needs new name
@@ -49,13 +50,13 @@ public:
// Message Handlers
bool OnCTCPReply(CNick& Nick, CString& sMessage);
bool OnPrivCTCP(CNick& Nick, CString& sMessage);
bool OnChanCTCP(CNick& Nick, const CString& sChan, CString& sMessage);
bool OnGeneralCTCP(CNick& Nick, CString& sMessage);
bool OnPrivMsg(CNick& Nick, CString& sMessage);
bool OnChanMsg(CNick& Nick, const CString& sChan, CString& sMessage);
bool OnPrivNotice(CNick& Nick, CString& sMessage);
bool OnChanNotice(CNick& Nick, const CString& sChan, CString& sMessage);
bool OnPrivCTCP(CMessage& Message);
bool OnChanCTCP(CMessage& Message);
bool OnGeneralCTCP(CMessage& Message);
bool OnPrivMsg(CMessage& Message);
bool OnChanMsg(CMessage& Message);
bool OnPrivNotice(CMessage& Message);
bool OnChanNotice(CMessage& Message);
bool OnServerCapAvailable(const CString& sCap);
// !Message Handlers

View File

@@ -87,4 +87,107 @@ private:
CChan* m_pChan = nullptr;
};
class CChanAction : public CMessage {
public:
CString GetText() const { return GetParam(1).TrimLeft_n("\001ACTION ").TrimRight_n("\001"); }
void SetText(const CString& sText) { SetParam(1, "\001ACTION " + sText + "\001"); }
};
class CChanCTCP : public CMessage {
public:
CString GetText() const { return GetParam(1).TrimLeft_n("\001").TrimRight_n("\001"); }
void SetText(const CString& sText) { SetParam(1, "\001" + sText + "\001"); }
};
class CChanMessage : public CMessage {
public:
CString GetText() const { return GetParam(1); }
void SetText(const CString& sText) { SetParam(1, sText); }
};
class CChanNotice : public CMessage {
public:
CString GetText() const { return GetParam(1); }
void SetText(const CString& sText) { SetParam(1, sText); }
};
class CJoinMessage : public CMessage {
public:
};
class CNickMessage : public CMessage {
public:
CString GetOldNick() const { return GetNick().GetNick(); }
CString GetNewNick() const { return GetParam(0); }
void SetNewNick(const CString& sNick) { SetParam(0, sNick); }
};
class CKickMessage : public CMessage {
public:
CString GetKickedNick() const { return GetParam(1); }
void SetKickedNick(const CString& sNick) { SetParam(1, sNick); }
CString GetReason() const { return GetParam(2); }
void SetReason(const CString& sReason) { SetParam(2, sReason); }
};
class CPartMessage : public CMessage {
public:
CString GetReason() const { return GetParam(1); }
void SetReason(const CString& sReason) { SetParam(1, sReason); }
};
class CPrivAction : public CMessage {
public:
CString GetText() const { return GetParam(1).TrimLeft_n("\001ACTION ").TrimRight_n("\001"); }
void SetText(const CString& sText) { SetParam(1, "\001ACTION " + sText + "\001"); }
};
class CPrivCTCP : public CMessage {
public:
CString GetText() const { return GetParam(1).TrimLeft_n("\001").TrimRight_n("\001"); }
void SetText(const CString& sText) { SetParam(1, "\001" + sText + "\001"); }
};
class CPrivMessage : public CMessage {
public:
CString GetText() const { return GetParam(1); }
void SetText(const CString& sText) { SetParam(1, sText); }
};
class CPrivNotice : public CMessage {
public:
CString GetText() const { return GetParam(1); }
void SetText(const CString& sText) { SetParam(1, sText); }
};
class CQuitMessage : public CMessage {
public:
CString GetReason() const { return GetParam(0); }
void SetReason(const CString& sReason) { SetParam(0, sReason); }
};
class CTopicMessage : public CMessage {
public:
CString GetTopic() const { return GetParam(1); }
void SetTopic(const CString& sTopic) { SetParam(1, sTopic); }
};
// The various CMessage subclasses are "mutable views" to the data held by CMessage.
// They provide convenient access to message type speficic attributes, but are not
// allowed to hold extra data of their own.
static_assert(sizeof(CChanAction) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CChanCTCP) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CChanMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CChanNotice) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CJoinMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CPartMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CPrivAction) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CPrivCTCP) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CPrivMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CPrivNotice) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CNickMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CKickMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CQuitMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
static_assert(sizeof(CTopicMessage) == sizeof(CMessage), "No data members allowed in CMessage subclasses.");
#endif // !_MESSAGE_H

View File

@@ -21,6 +21,7 @@
#include <znc/WebModules.h>
#include <znc/Utils.h>
#include <znc/Threads.h>
#include <znc/Message.h>
#include <znc/main.h>
#include <functional>
#include <set>
@@ -593,6 +594,7 @@ public:
* @param vChans List of channels which you and nick share.
*/
virtual void OnQuit(const CNick& Nick, const CString& sMessage, const std::vector<CChan*>& vChans);
virtual void OnQuitMessage(CQuitMessage& Message, const std::vector<CChan*>& vChans);
/** Called when a nickname change occurs. If we are changing our nick,
* sNewNick will equal m_pIRCSock->GetNick().
* @param Nick The nick which changed its nickname
@@ -600,6 +602,7 @@ public:
* @param vChans Channels which we and nick share.
*/
virtual void OnNick(const CNick& Nick, const CString& sNewNick, const std::vector<CChan*>& vChans);
virtual void OnNickMessage(CNickMessage& Message, const std::vector<CChan*>& vChans);
/** Called when a nick is kicked from a channel.
* @param OpNick The nick which generated the kick.
* @param sKickedNick The nick which was kicked.
@@ -607,6 +610,7 @@ public:
* @param sMessage The kick message.
*/
virtual void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage);
virtual void OnKickMessage(CKickMessage& Message);
/** This module hook is called just before ZNC tries to join an IRC channel.
* @param Chan The channel which is about to get joined.
* @return See CModule::EModRet.
@@ -617,12 +621,14 @@ public:
* @param Channel The channel which was joined.
*/
virtual void OnJoin(const CNick& Nick, CChan& Channel);
virtual void OnJoinMessage(CJoinMessage& Message);
/** Called when a nick parts a channel.
* @param Nick The nick who parted.
* @param Channel The channel which was parted.
* @param sMessage The part message.
*/
virtual void OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage);
virtual void OnPartMessage(CPartMessage& Message);
/** Called when user is invited into a channel
* @param Nick The nick who invited you.
* @param sChan The channel the user got invited into
@@ -749,6 +755,7 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage);
virtual EModRet OnPrivCTCPMessage(CPrivCTCP& Message);
/** Called when we receive a channel CTCP request <em>from IRC</em>.
* @param Nick The nick the CTCP request is from.
* @param Channel The channel to which the request was sent.
@@ -756,6 +763,7 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnChanCTCPMessage(CChanCTCP& Message);
/** Called when we receive a private CTCP ACTION ("/me" in query) <em>from IRC</em>.
* This is called after CModule::OnPrivCTCP().
* @param Nick The nick the action came from.
@@ -763,6 +771,7 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage);
virtual EModRet OnPrivActionMessage(CPrivAction& Message);
/** Called when we receive a channel CTCP ACTION ("/me" in a channel) <em>from IRC</em>.
* This is called after CModule::OnChanCTCP().
* @param Nick The nick the action came from.
@@ -771,12 +780,14 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnChanActionMessage(CChanAction& Message);
/** Called when we receive a private message <em>from IRC</em>.
* @param Nick The nick which sent the message.
* @param sMessage The message.
* @return See CModule::EModRet.
*/
virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage);
virtual EModRet OnPrivMessage(CPrivMessage& Message);
/** Called when we receive a channel message <em>from IRC</em>.
* @param Nick The nick which sent the message.
* @param Channel The channel to which the message was sent.
@@ -784,12 +795,14 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnChanMessage(CChanMessage& Message);
/** Called when we receive a private notice.
* @param Nick The nick which sent the notice.
* @param sMessage The notice message.
* @return See CModule::EModRet.
*/
virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage);
virtual EModRet OnPrivNoticeMessage(CPrivNotice& Message);
/** Called when we receive a channel notice.
* @param Nick The nick which sent the notice.
* @param Channel The channel to which the notice was sent.
@@ -797,6 +810,7 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnChanNoticeMessage(CChanNotice& Message);
/** Called when we receive a channel topic change <em>from IRC</em>.
* @param Nick The nick which changed the topic.
* @param Channel The channel whose topic was changed.
@@ -804,6 +818,7 @@ public:
* @return See CModule::EModRet.
*/
virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic);
virtual EModRet OnTopicMessage(CTopicMessage& Message);
/** Called for every CAP received via CAP LS from server.
* @param sCap capability supported by server.
@@ -1186,11 +1201,16 @@ public:
bool OnModCTCP(const CString& sMessage);
bool OnQuit(const CNick& Nick, const CString& sMessage, const std::vector<CChan*>& vChans);
bool OnQuitMessage(CQuitMessage& Message, const std::vector<CChan*>& vChans);
bool OnNick(const CNick& Nick, const CString& sNewNick, const std::vector<CChan*>& vChans);
bool OnNickMessage(CNickMessage& Message, const std::vector<CChan*>& vChans);
bool OnKick(const CNick& Nick, const CString& sOpNick, CChan& Channel, const CString& sMessage);
bool OnKickMessage(CKickMessage& Message);
bool OnJoining(CChan& Channel);
bool OnJoin(const CNick& Nick, CChan& Channel);
bool OnJoinMessage(CJoinMessage& Message);
bool OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage);
bool OnPartMessage(CPartMessage& Message);
bool OnInvite(const CNick& Nick, const CString& sChan);
bool OnChanBufferStarting(CChan& Chan, CClient& Client);
@@ -1216,14 +1236,23 @@ public:
bool OnCTCPReply(CNick& Nick, CString& sMessage);
bool OnPrivCTCP(CNick& Nick, CString& sMessage);
bool OnPrivCTCPMessage(CPrivCTCP& Message);
bool OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage);
bool OnChanCTCPMessage(CChanCTCP& Message);
bool OnPrivAction(CNick& Nick, CString& sMessage);
bool OnPrivActionMessage(CPrivAction& Message);
bool OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage);
bool OnChanActionMessage(CChanAction& Message);
bool OnPrivMsg(CNick& Nick, CString& sMessage);
bool OnPrivMessage(CPrivMessage& Message);
bool OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage);
bool OnChanMessage(CChanMessage& Message);
bool OnPrivNotice(CNick& Nick, CString& sMessage);
bool OnPrivNoticeMessage(CPrivNotice& Message);
bool OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage);
bool OnChanNoticeMessage(CChanNotice& Message);
bool OnTopic(CNick& Nick, CChan& Channel, CString& sTopic);
bool OnTopicMessage(CTopicMessage& Message);
bool OnTimerAutoJoin(CChan& Channel);
bool OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet);

View File

@@ -507,7 +507,8 @@ void CIRCSock::ReadLine(const CString& sData) {
CNick Nick = Message.GetNick();
if (sCmd.Equals("NICK")) {
CString sNewNick = Message.GetParam(0);
CNickMessage& NickMsg = static_cast<CNickMessage&>(Message);
CString sNewNick = NickMsg.GetNewNick();
bool bIsVisible = false;
vector<CChan*> vFoundChans;
@@ -530,19 +531,19 @@ void CIRCSock::ReadLine(const CString& sData) {
m_pNetwork->PutUser(sLine);
}
IRCSOCKMODULECALL(OnNick(Nick, sNewNick, vFoundChans), NOTHING);
IRCSOCKMODULECALL(OnNickMessage(NickMsg, vFoundChans), NOTHING);
if (!bIsVisible) {
return;
}
} else if (sCmd.Equals("QUIT")) {
CString sMessage = Message.GetParam(0);
CQuitMessage& QuitMsg = static_cast<CQuitMessage&>(Message);
bool bIsVisible = false;
// :nick!ident@host.com QUIT :message
if (Nick.NickEquals(GetNick())) {
m_pNetwork->PutStatus("You quit [" + sMessage + "]");
m_pNetwork->PutStatus("You quit [" + QuitMsg.GetReason() + "]");
// We don't call module hooks and we don't
// forward this quit to clients (Some clients
// disconnect if they receive such a QUIT)
@@ -562,14 +563,15 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
IRCSOCKMODULECALL(OnQuit(Nick, sMessage, vFoundChans), NOTHING);
IRCSOCKMODULECALL(OnQuitMessage(QuitMsg, vFoundChans), NOTHING);
if (!bIsVisible) {
return;
}
} else if (sCmd.Equals("JOIN")) {
CString sChan = Message.GetParam(0);
CChan* pChan;
CJoinMessage& JoinMsg = static_cast<CJoinMessage&>(Message);
CString sChan = JoinMsg.GetParam(0);
CChan* pChan = nullptr;
if (Nick.NickEquals(GetNick())) {
m_pNetwork->AddChan(sChan, false);
@@ -585,7 +587,8 @@ void CIRCSock::ReadLine(const CString& sData) {
if (pChan) {
pChan->AddNick(Nick.GetNickMask());
IRCSOCKMODULECALL(OnJoin(Nick.GetNickMask(), *pChan), NOTHING);
JoinMsg.SetChan(pChan);
IRCSOCKMODULECALL(OnJoinMessage(JoinMsg), NOTHING);
if (pChan->IsDetached()) {
return;
@@ -607,14 +610,15 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
} else if (sCmd.Equals("PART")) {
CString sChan = Message.GetParam(0);
CString sMsg = Message.GetParam(1);
CPartMessage& PartMsg = static_cast<CPartMessage&>(Message);
CString sChan = PartMsg.GetParam(0);
CChan* pChan = m_pNetwork->FindChan(sChan);
bool bDetached = false;
if (pChan) {
pChan->RemNick(Nick.GetNick());
IRCSOCKMODULECALL(OnPart(Nick.GetNickMask(), *pChan, sMsg), NOTHING);
PartMsg.SetChan(pChan);
IRCSOCKMODULECALL(OnPartMessage(PartMsg), NOTHING);
if (pChan->IsDetached())
bDetached = true;
@@ -667,15 +671,16 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
} else if (sCmd.Equals("KICK")) {
CKickMessage& KickMsg = static_cast<CKickMessage&>(Message);
// :opnick!ident@host.com KICK #chan nick :msg
CString sChan = Message.GetParam(0);
CString sKickedNick = Message.GetParam(1);
CString sMsg = Message.GetParam(2);
CString sChan = KickMsg.GetParam(0);
CString sKickedNick = KickMsg.GetKickedNick();
CChan* pChan = m_pNetwork->FindChan(sChan);
if (pChan) {
IRCSOCKMODULECALL(OnKick(Nick, sKickedNick, *pChan, sMsg), NOTHING);
KickMsg.SetChan(pChan);
IRCSOCKMODULECALL(OnKickMessage(KickMsg), NOTHING);
// do not remove the nick till after the OnKick call, so modules
// can do Chan.FindNick or something to get more info.
pChan->RemNick(sKickedNick);
@@ -710,11 +715,11 @@ void CIRCSock::ReadLine(const CString& sData) {
return;
} else {
if (sTarget.Equals(GetNick())) {
if (OnPrivNotice(Nick, sMsg)) {
if (OnPrivNotice(Message)) {
return;
}
} else {
if (OnChanNotice(Nick, sTarget, sMsg)) {
if (OnChanNotice(Message)) {
return;
}
}
@@ -728,24 +733,24 @@ void CIRCSock::ReadLine(const CString& sData) {
return;
} else if (sCmd.Equals("TOPIC")) {
CTopicMessage& TopicMsg = static_cast<CTopicMessage&>(Message);
// :nick!ident@host.com TOPIC #chan :This is a topic
CChan* pChan = m_pNetwork->FindChan(Message.GetParam(0));
CChan* pChan = m_pNetwork->FindChan(TopicMsg.GetParam(0));
if (pChan) {
CString sTopic = Message.GetParam(1);
IRCSOCKMODULECALL(OnTopic(Nick, *pChan, sTopic), &bReturn);
TopicMsg.SetChan(pChan);
IRCSOCKMODULECALL(OnTopicMessage(TopicMsg), &bReturn);
if (bReturn) return;
pChan->SetTopicOwner(Nick.GetNick());
pChan->SetTopicDate((unsigned long) time(nullptr));
pChan->SetTopic(sTopic);
pChan->SetTopic(TopicMsg.GetTopic());
if (pChan->IsDetached()) {
return; // Don't forward this
}
sLine = ":" + Nick.GetNickMask() + " TOPIC " + pChan->GetName() + " :" + sTopic;
sLine = ":" + Nick.GetNickMask() + " TOPIC " + pChan->GetName() + " :" + pChan->GetTopic();
}
} else if (sCmd.Equals("PRIVMSG")) {
// :nick!ident@host.com PRIVMSG #chan :Message
@@ -757,11 +762,11 @@ void CIRCSock::ReadLine(const CString& sData) {
sMsg.RightChomp();
if (sTarget.Equals(GetNick())) {
if (OnPrivCTCP(Nick, sMsg)) {
if (OnPrivCTCP(Message)) {
return;
}
} else {
if (OnChanCTCP(Nick, sTarget, sMsg)) {
if (OnChanCTCP(Message)) {
return;
}
}
@@ -770,11 +775,11 @@ void CIRCSock::ReadLine(const CString& sData) {
return;
} else {
if (sTarget.Equals(GetNick())) {
if (OnPrivMsg(Nick, sMsg)) {
if (OnPrivMsg(Message)) {
return;
}
} else {
if (OnChanMsg(Nick, sTarget, sMsg)) {
if (OnChanMsg(Message)) {
return;
}
}
@@ -911,31 +916,34 @@ bool CIRCSock::OnCTCPReply(CNick& Nick, CString& sMessage) {
return bResult;
}
bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
bool CIRCSock::OnPrivCTCP(CMessage& Message) {
CPrivCTCP& PrivCTCP = static_cast<CPrivCTCP&>(Message);
bool bResult = false;
IRCSOCKMODULECALL(OnPrivCTCP(Nick, sMessage), &bResult);
IRCSOCKMODULECALL(OnPrivCTCPMessage(PrivCTCP), &bResult);
if (bResult) return true;
if (sMessage.TrimPrefix("ACTION ")) {
if (PrivCTCP.GetText().StartsWith("ACTION ")) {
bResult = false;
IRCSOCKMODULECALL(OnPrivAction(Nick, sMessage), &bResult);
CPrivAction& PrivAction = static_cast<CPrivAction&>(Message);
IRCSOCKMODULECALL(OnPrivActionMessage(PrivAction), &bResult);
if (bResult) return true;
if (!m_pNetwork->IsUserOnline() || !m_pNetwork->GetUser()->AutoClearQueryBuffer()) {
const CNick& Nick = PrivAction.GetNick();
CQuery* pQuery = m_pNetwork->AddQuery(Nick.GetNick());
if (pQuery) {
pQuery->AddBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " PRIVMSG {target} :\001ACTION {text}\001", sMessage);
pQuery->AddBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " PRIVMSG {target} :\001ACTION {text}\001", PrivAction.GetText());
}
}
sMessage = "ACTION " + sMessage;
}
// This handles everything which wasn't handled yet
return OnGeneralCTCP(Nick, sMessage);
return OnGeneralCTCP(Message);
}
bool CIRCSock::OnGeneralCTCP(CNick& Nick, CString& sMessage) {
bool CIRCSock::OnGeneralCTCP(CMessage& Message) {
const CNick& Nick = Message.GetNick();
const CString& sMessage = Message.GetParam(1);
const MCString& mssCTCPReplies = m_pNetwork->GetUser()->GetCTCPReplies();
CString sQuery = sMessage.Token(0).AsUpper();
MCString::const_iterator it = mssCTCPReplies.find(sQuery);
@@ -979,83 +987,92 @@ bool CIRCSock::OnGeneralCTCP(CNick& Nick, CString& sMessage) {
return false;
}
bool CIRCSock::OnPrivNotice(CNick& Nick, CString& sMessage) {
bool CIRCSock::OnPrivNotice(CMessage& Message) {
CPrivNotice& PrivNotice = static_cast<CPrivNotice&>(Message);
bool bResult = false;
IRCSOCKMODULECALL(OnPrivNotice(Nick, sMessage), &bResult);
IRCSOCKMODULECALL(OnPrivNoticeMessage(PrivNotice), &bResult);
if (bResult) return true;
if (!m_pNetwork->IsUserOnline()) {
// If the user is detached, add to the buffer
m_pNetwork->AddNoticeBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " NOTICE {target} :{text}", sMessage);
m_pNetwork->AddNoticeBuffer(":" + _NAMEDFMT(PrivNotice.GetNick().GetNickMask()) + " NOTICE {target} :{text}", PrivNotice.GetText());
}
return false;
}
bool CIRCSock::OnPrivMsg(CNick& Nick, CString& sMessage) {
bool CIRCSock::OnPrivMsg(CMessage& Message) {
CPrivMessage& PrivMsg = static_cast<CPrivMessage&>(Message);
bool bResult = false;
IRCSOCKMODULECALL(OnPrivMsg(Nick, sMessage), &bResult);
IRCSOCKMODULECALL(OnPrivMessage(PrivMsg), &bResult);
if (bResult) return true;
if (!m_pNetwork->IsUserOnline() || !m_pNetwork->GetUser()->AutoClearQueryBuffer()) {
const CNick& Nick = PrivMsg.GetNick();
CQuery* pQuery = m_pNetwork->AddQuery(Nick.GetNick());
if (pQuery) {
pQuery->AddBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " PRIVMSG {target} :{text}", sMessage);
pQuery->AddBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " PRIVMSG {target} :{text}", PrivMsg.GetText());
}
}
return false;
}
bool CIRCSock::OnChanCTCP(CNick& Nick, const CString& sChan, CString& sMessage) {
CChan* pChan = m_pNetwork->FindChan(sChan);
bool CIRCSock::OnChanCTCP(CMessage& Message) {
CChanCTCP& ChanCTCP = static_cast<CChanCTCP&>(Message);
CChan* pChan = m_pNetwork->FindChan(ChanCTCP.GetParam(0));
if (pChan) {
bool bResult = false;
IRCSOCKMODULECALL(OnChanCTCP(Nick, *pChan, sMessage), &bResult);
ChanCTCP.SetChan(pChan);
IRCSOCKMODULECALL(OnChanCTCPMessage(ChanCTCP), &bResult);
if (bResult) return true;
// Record a /me
if (sMessage.TrimPrefix("ACTION ")) {
if (ChanCTCP.GetText().StartsWith("ACTION ")) {
bResult = false;
IRCSOCKMODULECALL(OnChanAction(Nick, *pChan, sMessage), &bResult);
CChanAction& ChanAction = static_cast<CChanAction&>(Message);
IRCSOCKMODULECALL(OnChanActionMessage(ChanAction), &bResult);
if (bResult) return true;
if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || pChan->IsDetached()) {
pChan->AddBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " PRIVMSG " + _NAMEDFMT(sChan) + " :\001ACTION {text}\001", sMessage);
pChan->AddBuffer(":" + _NAMEDFMT(Message.GetNick().GetNickMask()) + " PRIVMSG " + _NAMEDFMT(pChan->GetName()) + " :\001ACTION {text}\001", ChanAction.GetText());
}
sMessage = "ACTION " + sMessage;
}
}
if (OnGeneralCTCP(Nick, sMessage))
if (OnGeneralCTCP(Message))
return true;
return (pChan && pChan->IsDetached());
}
bool CIRCSock::OnChanNotice(CNick& Nick, const CString& sChan, CString& sMessage) {
CChan* pChan = m_pNetwork->FindChan(sChan);
bool CIRCSock::OnChanNotice(CMessage& Message) {
CChanNotice& ChanNotice = static_cast<CChanNotice&>(Message);
CChan* pChan = m_pNetwork->FindChan(ChanNotice.GetParam(0));
if (pChan) {
bool bResult = false;
IRCSOCKMODULECALL(OnChanNotice(Nick, *pChan, sMessage), &bResult);
ChanNotice.SetChan(pChan);
IRCSOCKMODULECALL(OnChanNoticeMessage(ChanNotice), &bResult);
if (bResult) return true;
if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || pChan->IsDetached()) {
pChan->AddBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " NOTICE " + _NAMEDFMT(sChan) + " :{text}", sMessage);
pChan->AddBuffer(":" + _NAMEDFMT(ChanNotice.GetNick().GetNickMask()) + " NOTICE " + _NAMEDFMT(pChan->GetName()) + " :{text}", ChanNotice.GetText());
}
}
return ((pChan) && (pChan->IsDetached()));
}
bool CIRCSock::OnChanMsg(CNick& Nick, const CString& sChan, CString& sMessage) {
CChan* pChan = m_pNetwork->FindChan(sChan);
bool CIRCSock::OnChanMsg(CMessage& Message) {
CChanMessage& ChanMsg = static_cast<CChanMessage&>(Message);
CChan* pChan = m_pNetwork->FindChan(ChanMsg.GetParam(0));
if (pChan) {
bool bResult = false;
IRCSOCKMODULECALL(OnChanMsg(Nick, *pChan, sMessage), &bResult);
ChanMsg.SetChan(pChan);
IRCSOCKMODULECALL(OnChanMessage(ChanMsg), &bResult);
if (bResult) return true;
if (!pChan->AutoClearChanBuffer() || !m_pNetwork->IsUserOnline() || pChan->IsDetached()) {
pChan->AddBuffer(":" + _NAMEDFMT(Nick.GetNickMask()) + " PRIVMSG " + _NAMEDFMT(sChan) + " :{text}", sMessage);
pChan->AddBuffer(":" + _NAMEDFMT(ChanMsg.GetNick().GetNickMask()) + " PRIVMSG " + _NAMEDFMT(pChan->GetName()) + " :{text}", ChanMsg.GetText());
}
}

View File

@@ -636,11 +636,16 @@ void CModule::OnUnknownModCommand(const CString& sLine) {
}
void CModule::OnQuit(const CNick& Nick, const CString& sMessage, const vector<CChan*>& vChans) {}
void CModule::OnQuitMessage(CQuitMessage& Message, const vector<CChan*>& vChans) { OnQuit(Message.GetNick(), Message.GetReason(), vChans); }
void CModule::OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans) {}
void CModule::OnNickMessage(CNickMessage& Message, const vector<CChan*>& vChans) { OnNick(Message.GetNick(), Message.GetNewNick(), vChans); }
void CModule::OnKick(const CNick& Nick, const CString& sKickedNick, CChan& Channel, const CString& sMessage) {}
void CModule::OnKickMessage(CKickMessage& Message) { OnKick(Message.GetNick(), Message.GetKickedNick(), *Message.GetChan(), Message.GetReason()); }
CModule::EModRet CModule::OnJoining(CChan& Channel) { return CONTINUE; }
void CModule::OnJoin(const CNick& Nick, CChan& Channel) {}
void CModule::OnJoinMessage(CJoinMessage& Message) { OnJoin(Message.GetNick(), *Message.GetChan()); }
void CModule::OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage) {}
void CModule::OnPartMessage(CPartMessage& Message) { OnPart(Message.GetNick(), *Message.GetChan(), Message.GetReason()); }
CModule::EModRet CModule::OnInvite(const CNick& Nick, const CString& sChan) { return CONTINUE; }
CModule::EModRet CModule::OnChanBufferStarting(CChan& Chan, CClient& Client) { return CONTINUE; }
@@ -671,14 +676,68 @@ 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; }
CModule::EModRet CModule::OnPrivCTCPMessage(CPrivCTCP& Message) {
CString sText = Message.GetText();
EModRet ret = OnPrivCTCP(Message.GetNick(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnChanCTCPMessage(CChanCTCP& Message) {
CString sText = Message.GetText();
EModRet ret = OnChanCTCP(Message.GetNick(), *Message.GetChan(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnPrivAction(CNick& Nick, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnPrivActionMessage(CPrivAction& Message) {
CString sText = Message.GetText();
EModRet ret = OnPrivAction(Message.GetNick(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnChanActionMessage(CChanAction& Message) {
CString sText = Message.GetText();
EModRet ret = OnChanAction(Message.GetNick(), *Message.GetChan(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnPrivMsg(CNick& Nick, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnPrivMessage(CPrivMessage& Message) {
CString sText = Message.GetText();
EModRet ret = OnPrivMsg(Message.GetNick(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnChanMessage(CChanMessage& Message) {
CString sText = Message.GetText();
EModRet ret = OnChanMsg(Message.GetNick(), *Message.GetChan(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnPrivNotice(CNick& Nick, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnPrivNoticeMessage(CPrivNotice& Message) {
CString sText = Message.GetText();
EModRet ret = OnPrivNotice(Message.GetNick(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) { return CONTINUE; }
CModule::EModRet CModule::OnChanNoticeMessage(CChanNotice& Message) {
CString sText = Message.GetText();
EModRet ret = OnChanNotice(Message.GetNick(), *Message.GetChan(), sText);
Message.SetText(sText);
return ret;
}
CModule::EModRet CModule::OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) { return CONTINUE; }
CModule::EModRet CModule::OnTopicMessage(CTopicMessage& Message) {
CString sTopic = Message.GetTopic();
EModRet ret = OnTopic(Message.GetNick(), *Message.GetChan(), sTopic);
Message.SetTopic(sTopic);
return ret;
}
CModule::EModRet CModule::OnTimerAutoJoin(CChan& Channel) { return CONTINUE; }
CModule::EModRet CModule::OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) { return CONTINUE; }
CModule::EModRet CModule::OnDeleteNetwork(CIRCNetwork& Network) { return CONTINUE; }
@@ -829,11 +888,16 @@ bool CModules::OnUserTopicRequest(CString& sChannel) { MODHALTCHK(OnUserTopicReq
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::OnQuitMessage(CQuitMessage& Message, const vector<CChan*>& vChans) { MODUNLOADCHK(OnQuitMessage(Message, vChans)); return false; }
bool CModules::OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans) { MODUNLOADCHK(OnNick(Nick, sNewNick, vChans)); return false; }
bool CModules::OnNickMessage(CNickMessage& Message, const vector<CChan*>& vChans) { MODUNLOADCHK(OnNickMessage(Message, vChans)); return false; }
bool CModules::OnKick(const CNick& Nick, const CString& sKickedNick, CChan& Channel, const CString& sMessage) { MODUNLOADCHK(OnKick(Nick, sKickedNick, Channel, sMessage)); return false; }
bool CModules::OnKickMessage(CKickMessage& Message) { MODUNLOADCHK(OnKickMessage(Message)); return false; }
bool CModules::OnJoining(CChan& Channel) { MODHALTCHK(OnJoining(Channel)); }
bool CModules::OnJoin(const CNick& Nick, CChan& Channel) { MODUNLOADCHK(OnJoin(Nick, Channel)); return false; }
bool CModules::OnJoinMessage(CJoinMessage& Message) { MODUNLOADCHK(OnJoinMessage(Message)); return false; }
bool CModules::OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage) { MODUNLOADCHK(OnPart(Nick, Channel, sMessage)); return false; }
bool CModules::OnPartMessage(CPartMessage& Message) { MODUNLOADCHK(OnPartMessage(Message)); return false; }
bool CModules::OnInvite(const CNick& Nick, const CString& sChan) { MODHALTCHK(OnInvite(Nick, sChan)); }
bool CModules::OnChanBufferStarting(CChan& Chan, CClient& Client) { MODHALTCHK(OnChanBufferStarting(Chan, Client)); }
bool CModules::OnChanBufferEnding(CChan& Chan, CClient& Client) { MODHALTCHK(OnChanBufferEnding(Chan, Client)); }
@@ -843,14 +907,23 @@ bool CModules::OnPrivBufferPlayLine2(CClient& Client, CString& sLine, const time
bool CModules::OnPrivBufferPlayLine(CClient& Client, CString& sLine) { MODHALTCHK(OnPrivBufferPlayLine(Client, sLine)); }
bool CModules::OnCTCPReply(CNick& Nick, CString& sMessage) { MODHALTCHK(OnCTCPReply(Nick, sMessage)); }
bool CModules::OnPrivCTCP(CNick& Nick, CString& sMessage) { MODHALTCHK(OnPrivCTCP(Nick, sMessage)); }
bool CModules::OnPrivCTCPMessage(CPrivCTCP& Message) { MODHALTCHK(OnPrivCTCPMessage(Message)); }
bool CModules::OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) { MODHALTCHK(OnChanCTCP(Nick, Channel, sMessage)); }
bool CModules::OnChanCTCPMessage(CChanCTCP& Message) { MODHALTCHK(OnChanCTCPMessage(Message)); }
bool CModules::OnPrivAction(CNick& Nick, CString& sMessage) { MODHALTCHK(OnPrivAction(Nick, sMessage)); }
bool CModules::OnPrivActionMessage(CPrivAction& Message) { MODHALTCHK(OnPrivActionMessage(Message)); }
bool CModules::OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) { MODHALTCHK(OnChanAction(Nick, Channel, sMessage)); }
bool CModules::OnChanActionMessage(CChanAction& Message) { MODHALTCHK(OnChanActionMessage(Message)); }
bool CModules::OnPrivMsg(CNick& Nick, CString& sMessage) { MODHALTCHK(OnPrivMsg(Nick, sMessage)); }
bool CModules::OnPrivMessage(CPrivMessage& Message) { MODHALTCHK(OnPrivMessage(Message)); }
bool CModules::OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) { MODHALTCHK(OnChanMsg(Nick, Channel, sMessage)); }
bool CModules::OnChanMessage(CChanMessage& Message) { MODHALTCHK(OnChanMessage(Message)); }
bool CModules::OnPrivNotice(CNick& Nick, CString& sMessage) { MODHALTCHK(OnPrivNotice(Nick, sMessage)); }
bool CModules::OnPrivNoticeMessage(CPrivNotice& Message) { MODHALTCHK(OnPrivNoticeMessage(Message)); }
bool CModules::OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) { MODHALTCHK(OnChanNotice(Nick, Channel, sMessage)); }
bool CModules::OnChanNoticeMessage(CChanNotice& Message) { MODHALTCHK(OnChanNoticeMessage(Message)); }
bool CModules::OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) { MODHALTCHK(OnTopic(Nick, Channel, sTopic)); }
bool CModules::OnTopicMessage(CTopicMessage& Message) { MODHALTCHK(OnTopicMessage(Message)); }
bool CModules::OnTimerAutoJoin(CChan& Channel) { MODHALTCHK(OnTimerAutoJoin(Channel)); }
bool CModules::OnAddNetwork(CIRCNetwork& Network, CString& sErrorRet) { MODHALTCHK(OnAddNetwork(Network, sErrorRet)); }
bool CModules::OnDeleteNetwork(CIRCNetwork& Network) { MODHALTCHK(OnDeleteNetwork(Network)); }

View File

@@ -55,6 +55,149 @@ TEST(MessageTest, FormatFlags) {
EXPECT_EQ("COMMAND param", msg.ToString(CMessage::ExcludePrefix|CMessage::ExcludeTags));
}
TEST(MessageTest, ChanAction) {
CMessage msg(":sender PRIVMSG #chan :\001ACTION text\001");
CChanAction& chan = static_cast<CChanAction&>(msg);
EXPECT_EQ("sender", chan.GetNick().GetNick());
EXPECT_EQ("PRIVMSG", chan.GetCommand());
EXPECT_EQ("text", chan.GetText());
chan.SetText("foo bar");
EXPECT_EQ("foo bar", chan.GetText());
EXPECT_EQ(":sender PRIVMSG #chan :\001ACTION foo bar\001", chan.ToString());
}
TEST(MessageTest, ChanCTCP) {
CMessage msg(":sender PRIVMSG #chan :\001text\001");
CChanCTCP& chan = static_cast<CChanCTCP&>(msg);
EXPECT_EQ("sender", chan.GetNick().GetNick());
EXPECT_EQ("PRIVMSG", chan.GetCommand());
EXPECT_EQ("text", chan.GetText());
chan.SetText("foo bar");
EXPECT_EQ("foo bar", chan.GetText());
EXPECT_EQ(":sender PRIVMSG #chan :\001foo bar\001", chan.ToString());
}
TEST(MessageTest, ChanMsg) {
CMessage msg(":sender PRIVMSG #chan :text");
CChanMessage& priv = static_cast<CChanMessage&>(msg);
EXPECT_EQ("sender", priv.GetNick().GetNick());
EXPECT_EQ("PRIVMSG", priv.GetCommand());
EXPECT_EQ("text", priv.GetText());
priv.SetText("foo bar");
EXPECT_EQ("foo bar", priv.GetText());
EXPECT_EQ(":sender PRIVMSG #chan :foo bar", priv.ToString());
}
TEST(MessageTest, Kick) {
CMessage msg(":nick KICK #chan person :reason");
CKickMessage& kick = static_cast<CKickMessage&>(msg);
EXPECT_EQ("nick", kick.GetNick().GetNick());
EXPECT_EQ("KICK", kick.GetCommand());
EXPECT_EQ("person", kick.GetKickedNick());
EXPECT_EQ("reason", kick.GetReason());
kick.SetKickedNick("noone");
EXPECT_EQ("noone", kick.GetKickedNick());
kick.SetReason("test");
EXPECT_EQ("test", kick.GetReason());
EXPECT_EQ(":nick KICK #chan noone test", kick.ToString());
}
TEST(MessageTest, Join) {
CMessage msg(":nick JOIN #chan");
EXPECT_EQ("nick", msg.GetNick().GetNick());
EXPECT_EQ("JOIN", msg.GetCommand());
EXPECT_EQ("#chan", msg.GetParam(0));
}
TEST(MessageTest, Nick) {
CMessage msg(":nick NICK person");
CNickMessage& nick = static_cast<CNickMessage&>(msg);
EXPECT_EQ("nick", nick.GetNick().GetNick());
EXPECT_EQ("NICK", nick.GetCommand());
EXPECT_EQ("nick", nick.GetOldNick());
EXPECT_EQ("person", nick.GetNewNick());
nick.SetNewNick("test");
EXPECT_EQ("test", nick.GetNewNick());
EXPECT_EQ(":nick NICK test", nick.ToString());
}
TEST(MessageTest, Part) {
CMessage msg(":nick PART #chan :reason");
CPartMessage& part = static_cast<CPartMessage&>(msg);
EXPECT_EQ("nick", part.GetNick().GetNick());
EXPECT_EQ("PART", part.GetCommand());
EXPECT_EQ("reason", part.GetReason());
part.SetReason("test");
EXPECT_EQ("test", part.GetReason());
EXPECT_EQ(":nick PART #chan test", part.ToString());
}
TEST(MessageTest, PrivAction) {
CMessage msg(":sender PRIVMSG receiver :\001ACTION text\001");
CPrivAction& priv = static_cast<CPrivAction&>(msg);
EXPECT_EQ("sender", priv.GetNick().GetNick());
EXPECT_EQ("PRIVMSG", priv.GetCommand());
EXPECT_EQ("text", priv.GetText());
priv.SetText("foo bar");
EXPECT_EQ("foo bar", priv.GetText());
EXPECT_EQ(":sender PRIVMSG receiver :\001ACTION foo bar\001", priv.ToString());
}
TEST(MessageTest, PrivCTCP) {
CMessage msg(":sender PRIVMSG receiver :\001text\001");
CPrivCTCP& priv = static_cast<CPrivCTCP&>(msg);
EXPECT_EQ("sender", priv.GetNick().GetNick());
EXPECT_EQ("PRIVMSG", priv.GetCommand());
EXPECT_EQ("text", priv.GetText());
priv.SetText("foo bar");
EXPECT_EQ("foo bar", priv.GetText());
EXPECT_EQ(":sender PRIVMSG receiver :\001foo bar\001", priv.ToString());
}
TEST(MessageTest, PrivMsg) {
CMessage msg(":sender PRIVMSG receiver :text");
CPrivMessage& priv = static_cast<CPrivMessage&>(msg);
EXPECT_EQ("sender", priv.GetNick().GetNick());
EXPECT_EQ("PRIVMSG", priv.GetCommand());
EXPECT_EQ("text", priv.GetText());
priv.SetText("foo bar");
EXPECT_EQ("foo bar", priv.GetText());
EXPECT_EQ(":sender PRIVMSG receiver :foo bar", priv.ToString());
}
TEST(MessageTest, Quit) {
CMessage msg(":nick QUIT :reason");
CQuitMessage& quit = static_cast<CQuitMessage&>(msg);
EXPECT_EQ("nick", quit.GetNick().GetNick());
EXPECT_EQ("QUIT", quit.GetCommand());
EXPECT_EQ("reason", quit.GetReason());
quit.SetReason("test");
EXPECT_EQ("test", quit.GetReason());
EXPECT_EQ(":nick QUIT test", quit.ToString());
}
TEST(MessageTest, Topic) {
CMessage msg(":nick TOPIC #chan :topic");
CTopicMessage& topic = static_cast<CTopicMessage&>(msg);
EXPECT_EQ("nick", topic.GetNick().GetNick());
EXPECT_EQ("TOPIC", topic.GetCommand());
EXPECT_EQ("topic", topic.GetTopic());
topic.SetTopic("test");
EXPECT_EQ("test", topic.GetTopic());
EXPECT_EQ(":nick TOPIC #chan test", topic.ToString());
}
// The test data for MessageTest.Parse originates from https://github.com/SaberUK/ircparser
//
// IRCParser - Internet Relay Chat Message Parser