watch module: Don't handle multiple matching patterns for each target

Keep track of the targets which have already been notified of a matching
message, and do not notify them again if other patterns in the same
message match also. For example, consider the following match patterns:

  1) <*watch> /msg *watch ADD *!*@* *highlight *%nick%*
  2) <*watch> /msg *watch ADD *!*@* *highlight *testuser*
  3) <*watch> /msg *watch ADD *!*@* *testhilights *test*

If %nick% ist something like "testuser123", all of the these patterns
match the following message:

  <otheruser> hey testuser123, look at this: ...

Without this patch, the watch module would generate two notify messages
for target *highlight, and one notify message for target *testhilights.
This is unneccessary because patterns 1 and 2 will result in
generating the same notify message twice for target *highlight.

By using a std::set, the implementation in this patch keeps track of
which targets have already been notified and does not notify them more
than once.
This commit is contained in:
Roland Hieber
2012-06-27 16:15:51 +02:00
parent 8f6b5977aa
commit 84fae4ce97

View File

@@ -10,8 +10,10 @@
#include <znc/User.h>
#include <znc/IRCNetwork.h>
#include <list>
#include <set>
using std::list;
using std::set;
class CWatchSource {
public:
@@ -286,15 +288,19 @@ public:
private:
void Process(const CNick& Nick, const CString& sMessage, const CString& sSource) {
set<CString> sHandledTargets;
for (list<CWatchEntry>::iterator it = m_lsWatchers.begin(); it != m_lsWatchers.end(); ++it) {
CWatchEntry& WatchEntry = *it;
if (WatchEntry.IsMatch(Nick, sMessage, sSource, m_pNetwork)) {
if (WatchEntry.IsMatch(Nick, sMessage, sSource, m_pNetwork) &&
sHandledTargets.count(WatchEntry.GetTarget()) < 1) {
if (m_pNetwork->IsUserAttached()) {
m_pNetwork->PutUser(":" + WatchEntry.GetTarget() + "!watch@znc.in PRIVMSG " + m_pNetwork->GetCurNick() + " :" + sMessage);
} else {
m_Buffer.AddLine(":" + _NAMEDFMT(WatchEntry.GetTarget()) + "!watch@znc.in PRIVMSG {target} :{text}", sMessage);
}
sHandledTargets.insert(WatchEntry.GetTarget());
}
}
}