mirror of
https://github.com/znc/znc.git
synced 2026-08-07 01:13:25 +02:00
@@ -155,6 +155,7 @@ class CIRCNetwork {
|
||||
void CheckIRCConnect();
|
||||
|
||||
bool PutIRC(const CString& sLine);
|
||||
bool PutIRC(const CMessage& Message);
|
||||
|
||||
// Buffers
|
||||
void AddRawBuffer(const CMessage& Format, const CString& sText = "") {
|
||||
|
||||
+51
-2
@@ -56,8 +56,46 @@ class CIRCSock : public CIRCSocket {
|
||||
void SockError(int iErrno, const CString& sDescription) override;
|
||||
void Timeout() override;
|
||||
void ReachedMaxBuffer() override;
|
||||
|
||||
/** Sends a raw data line to the server.
|
||||
* @param sLine The line to be sent.
|
||||
*
|
||||
* The line is first passed \e unmodified to the \ref
|
||||
* CModule::OnSendToIRC() module hook. If no module halts the process,
|
||||
* the line is then sent to the server.
|
||||
*
|
||||
* Prefer \l PutIRC() instead.
|
||||
*/
|
||||
void PutIRCRaw(const CString& sLine);
|
||||
/** Sends a message to the server.
|
||||
* See \l PutIRC(const CMessage&) for details.
|
||||
*/
|
||||
void PutIRC(const CString& sLine);
|
||||
/** Sends a message to the server.
|
||||
* @param Message The message to be sent.
|
||||
* @note Only known and compatible messages and tags are sent.
|
||||
*
|
||||
* This method can delay the delivery of the message to honor protection
|
||||
* from flood.
|
||||
*
|
||||
* This method ensures that only tags, that were negotiated with CAP REQ
|
||||
* and CAP ACK, are sent. Not all IRC server are capable of handling all
|
||||
* messages and tags. Thus, in order to stay compatible with a variety of
|
||||
* IRC servers, ZNC has to filter out messages and tags that the server
|
||||
* has not explicitly acknowleged.
|
||||
*
|
||||
* Additional tags can be added via \l CIRCSock::SetTagSupport().
|
||||
*
|
||||
* @warning Bypassing the filter may cause troubles to some older IRC
|
||||
* servers.
|
||||
*
|
||||
* It is possible to bypass the filter by converting a message to a string
|
||||
* using \l CMessage::ToString(), and passing the resulting raw line to the
|
||||
* \l CIRCSock::PutIRCRaw(const CString& sLine):
|
||||
* \code
|
||||
* pServer->PutIRCRaw(Message.ToString());
|
||||
* \endcode
|
||||
*/
|
||||
void PutIRC(const CMessage& Message);
|
||||
void PutIRCQuick(const CString& sLine); //!< Should be used for PONG only
|
||||
void ResetChans();
|
||||
void Quit(const CString& sQuitMsg = "");
|
||||
@@ -71,6 +109,16 @@ class CIRCSock : public CIRCSocket {
|
||||
* should be resumed again.
|
||||
*/
|
||||
void ResumeCap();
|
||||
|
||||
bool IsTagEnabled(const CString& sTag) const {
|
||||
return 1 == m_ssSupportedTags.count(sTag);
|
||||
}
|
||||
/** Registers a tag as being supported or unsupported by the server.
|
||||
* This doesn't affect tags which the server sends.
|
||||
* @param sTag The tag to register.
|
||||
* @param bState Whether the client supports the tag.
|
||||
*/
|
||||
void SetTagSupport(const CString& sTag, bool bState);
|
||||
|
||||
// Setters
|
||||
void SetPass(const CString& s) { m_sPass = s; }
|
||||
@@ -175,11 +223,12 @@ class CIRCSock : public CIRCSocket {
|
||||
static const time_t m_uCTCPFloodTime;
|
||||
static const unsigned int m_uCTCPFloodCount;
|
||||
MCString m_mISupport;
|
||||
std::deque<CString> m_vsSendQueue;
|
||||
std::deque<CMessage> m_vSendQueue;
|
||||
short int m_iSendsAllowed;
|
||||
unsigned short int m_uFloodBurst;
|
||||
double m_fFloodRate;
|
||||
bool m_bFloodProtection;
|
||||
SCString m_ssSupportedTags;
|
||||
|
||||
friend class CIRCFloodTimer;
|
||||
};
|
||||
|
||||
@@ -1052,12 +1052,18 @@ class CModule {
|
||||
|
||||
ModHandle GetDLL() { return m_pDLL; }
|
||||
|
||||
/** This function sends a given raw IRC line to the IRC server, if we
|
||||
/** This function sends a given IRC line to the IRC server, if we
|
||||
* are connected to one. Else this line is discarded.
|
||||
* @param sLine The line which should be sent.
|
||||
* @return true if the line was queued for sending.
|
||||
*/
|
||||
virtual bool PutIRC(const CString& sLine);
|
||||
/** This function sends a given IRC message to the IRC server, if we
|
||||
* are connected to one. Else this message is discarded.
|
||||
* @param Message The message which should be sent.
|
||||
* @return true if the message was queued for sending.
|
||||
*/
|
||||
virtual bool PutIRC(const CMessage& Message);
|
||||
/** This function sends a given raw IRC line to a client.
|
||||
* If we are in a module hook which is called for a specific client,
|
||||
* only that client will get the line, else all connected clients will
|
||||
|
||||
@@ -1376,6 +1376,17 @@ bool CIRCNetwork::PutIRC(const CString& sLine) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CIRCNetwork::PutIRC(const CMessage& Message) {
|
||||
CIRCSock* pIRCSock = GetIRCSock();
|
||||
|
||||
if (!pIRCSock) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pIRCSock->PutIRC(Message);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIRCNetwork::ClearQueryBuffer() {
|
||||
std::for_each(m_vQueries.begin(), m_vQueries.end(),
|
||||
std::default_delete<CQuery>());
|
||||
|
||||
+42
-17
@@ -84,7 +84,7 @@ CIRCSock::CIRCSock(CIRCNetwork* pNetwork)
|
||||
m_lastCTCP(0),
|
||||
m_uNumCTCP(0),
|
||||
m_mISupport(),
|
||||
m_vsSendQueue(),
|
||||
m_vSendQueue(),
|
||||
m_iSendsAllowed(pNetwork->GetFloodBurst()),
|
||||
m_uFloodBurst(pNetwork->GetFloodBurst()),
|
||||
m_fFloodRate(pNetwork->GetFloodRate()),
|
||||
@@ -1131,14 +1131,18 @@ bool CIRCSock::OnWallopsMessage(CMessage& Message) {
|
||||
}
|
||||
|
||||
void CIRCSock::PutIRC(const CString& sLine) {
|
||||
PutIRC(CMessage(sLine));
|
||||
}
|
||||
|
||||
void CIRCSock::PutIRC(const CMessage& Message) {
|
||||
// Only print if the line won't get sent immediately (same condition as in
|
||||
// TrySend()!)
|
||||
if (m_bFloodProtection && m_iSendsAllowed <= 0) {
|
||||
DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/"
|
||||
<< m_pNetwork->GetName() << ") ZNC -> IRC ["
|
||||
<< CDebug::Filter(sLine) << "] (queued)");
|
||||
<< CDebug::Filter(Message.ToString()) << "] (queued)");
|
||||
}
|
||||
m_vsSendQueue.push_back(sLine);
|
||||
m_vSendQueue.push_back(Message);
|
||||
TrySend();
|
||||
}
|
||||
|
||||
@@ -1150,33 +1154,45 @@ void CIRCSock::PutIRCQuick(const CString& sLine) {
|
||||
<< m_pNetwork->GetName() << ") ZNC -> IRC ["
|
||||
<< CDebug::Filter(sLine) << "] (queued to front)");
|
||||
}
|
||||
m_vsSendQueue.push_front(sLine);
|
||||
m_vSendQueue.emplace_front(sLine);
|
||||
TrySend();
|
||||
}
|
||||
|
||||
void CIRCSock::TrySend() {
|
||||
// This condition must be the same as in PutIRC() and PutIRCQuick()!
|
||||
while (!m_vsSendQueue.empty() &&
|
||||
while (!m_vSendQueue.empty() &&
|
||||
(!m_bFloodProtection || m_iSendsAllowed > 0)) {
|
||||
m_iSendsAllowed--;
|
||||
bool bSkip = false;
|
||||
CString& sLine = m_vsSendQueue.front();
|
||||
CMessage& Message = m_vSendQueue.front();
|
||||
|
||||
CMessage Message(sLine);
|
||||
MCString mssTags;
|
||||
for (const auto& it : Message.GetTags()) {
|
||||
if (IsTagEnabled(it.first)) {
|
||||
mssTags[it.first] = it.second;
|
||||
}
|
||||
}
|
||||
Message.SetTags(mssTags);
|
||||
Message.SetNetwork(m_pNetwork);
|
||||
|
||||
bool bSkip = false;
|
||||
IRCSOCKMODULECALL(OnSendToIRCMessage(Message), &bSkip);
|
||||
|
||||
if (!bSkip) {
|
||||
CString sCopy = Message.ToString();
|
||||
IRCSOCKMODULECALL(OnSendToIRC(sCopy), &bSkip);
|
||||
if (!bSkip) {
|
||||
DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/"
|
||||
<< m_pNetwork->GetName() << ") ZNC -> IRC ["
|
||||
<< CDebug::Filter(sCopy) << "]");
|
||||
Write(sCopy + "\r\n");
|
||||
}
|
||||
PutIRCRaw(Message.ToString());
|
||||
}
|
||||
m_vsSendQueue.pop_front();
|
||||
m_vSendQueue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void CIRCSock::PutIRCRaw(const CString& sLine) {
|
||||
CString sCopy = sLine;
|
||||
bool bSkip = false;
|
||||
IRCSOCKMODULECALL(OnSendToIRC(sCopy), &bSkip);
|
||||
if (!bSkip) {
|
||||
DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/"
|
||||
<< m_pNetwork->GetName() << ") ZNC -> IRC ["
|
||||
<< CDebug::Filter(sCopy) << "]");
|
||||
Write(sCopy + "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1473,3 +1489,12 @@ void CIRCSock::ResetChans() {
|
||||
it.second->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CIRCSock::SetTagSupport(const CString& sTag, bool bState) {
|
||||
if (bState) {
|
||||
m_ssSupportedTags.insert(sTag);
|
||||
} else {
|
||||
m_ssSupportedTags.erase(sTag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -1001,13 +1001,16 @@ bool CModule::OnServerCapAvailable(const CString& sCap) { return false; }
|
||||
void CModule::OnServerCapResult(const CString& sCap, bool bSuccess) {}
|
||||
|
||||
bool CModule::PutIRC(const CString& sLine) {
|
||||
return (m_pNetwork) ? m_pNetwork->PutIRC(sLine) : false;
|
||||
return m_pNetwork ? m_pNetwork->PutIRC(sLine) : false;
|
||||
}
|
||||
bool CModule::PutIRC(const CMessage& Message) {
|
||||
return m_pNetwork ? m_pNetwork->PutIRC(Message) : false;
|
||||
}
|
||||
bool CModule::PutUser(const CString& sLine) {
|
||||
return (m_pNetwork) ? m_pNetwork->PutUser(sLine, m_pClient) : false;
|
||||
return m_pNetwork ? m_pNetwork->PutUser(sLine, m_pClient) : false;
|
||||
}
|
||||
bool CModule::PutStatus(const CString& sLine) {
|
||||
return (m_pNetwork) ? m_pNetwork->PutStatus(sLine, m_pClient) : false;
|
||||
return m_pNetwork ? m_pNetwork->PutStatus(sLine, m_pClient) : false;
|
||||
}
|
||||
unsigned int CModule::PutModule(const CTable& table) {
|
||||
if (!m_pUser) return 0;
|
||||
|
||||
Reference in New Issue
Block a user