From c14445a9ecffd579cddcac3ba842b549601db652 Mon Sep 17 00:00:00 2001 From: paradix Date: Fri, 3 Jan 2020 21:58:30 +0100 Subject: [PATCH 1/4] watch module: changed internal buffer to query for multi-client support --- modules/watch.cpp | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/modules/watch.cpp b/modules/watch.cpp index c23e6271..46819f88 100644 --- a/modules/watch.cpp +++ b/modules/watch.cpp @@ -16,6 +16,7 @@ #include #include +#include using std::list; using std::vector; @@ -173,7 +174,6 @@ class CWatchEntry { class CWatcherMod : public CModule { public: MODCONSTRUCTOR(CWatcherMod) { - m_Buffer.SetLineCount(500); Load(); } @@ -186,17 +186,6 @@ class CWatcherMod : public CModule { Channel.GetName()); } - void OnClientLogin() override { - MCString msParams; - msParams["target"] = GetNetwork()->GetCurNick(); - - size_t uSize = m_Buffer.Size(); - for (unsigned int uIdx = 0; uIdx < uSize; uIdx++) { - PutUser(m_Buffer.GetLine(uIdx, *GetClient(), msParams)); - } - m_Buffer.Clear(); - } - void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage) override { Process(OpNick, @@ -333,15 +322,6 @@ class CWatcherMod : public CModule { m_lsWatchers.clear(); PutModule(t_s("All entries cleared.")); Save(); - } else if (sCmdName.Equals("BUFFER")) { - CString sCount = sCommand.Token(1); - - if (sCount.size()) { - m_Buffer.SetLineCount(sCount.ToUInt()); - } - - PutModule( - t_f("Buffer count is set to {1}")(m_Buffer.GetLineCount())); } else if (sCmdName.Equals("DEL")) { Remove(sCommand.Token(1).ToUInt()); } else { @@ -377,10 +357,14 @@ class CWatcherMod : public CModule { "!watch@znc.in PRIVMSG " + pNetwork->GetCurNick() + " :" + sMessage); } else { - m_Buffer.AddLine( + CQuery* pQuery = pNetwork->AddQuery(WatchEntry.GetTarget()); + if (pQuery) { + + pQuery->AddBuffer( ":" + _NAMEDFMT(WatchEntry.GetTarget()) + "!watch@znc.in PRIVMSG {target} :{text}", sMessage); + } } sHandledTargets.insert(WatchEntry.GetTarget()); } @@ -649,12 +633,6 @@ class CWatcherMod : public CModule { t_s("Description"), t_s("Enable or disable detached channel only for an entry.")); - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Buffer [Count]")); - Table.SetCell( - t_s("Description"), - t_s("Show/Set the amount of buffered lines while detached.")); - Table.AddRow(); Table.SetCell(t_s("Command"), t_s("SetSources [#chan priv #foo* !#bar]")); @@ -766,7 +744,6 @@ class CWatcherMod : public CModule { } list m_lsWatchers; - CBuffer m_Buffer; }; template <> From af4a1dc4cce4832548ac451bf5fb8eb40e1a44ca Mon Sep 17 00:00:00 2001 From: paradix Date: Mon, 6 Jan 2020 17:06:50 +0100 Subject: [PATCH 2/4] refactor: added AddCommand instead of manual handling with OnModCommand --- modules/watch.cpp | 295 ++++++++++++++++++---------------------------- 1 file changed, 116 insertions(+), 179 deletions(-) diff --git a/modules/watch.cpp b/modules/watch.cpp index 46819f88..7366f685 100644 --- a/modules/watch.cpp +++ b/modules/watch.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include using std::list; using std::vector; @@ -174,11 +174,61 @@ class CWatchEntry { class CWatcherMod : public CModule { public: MODCONSTRUCTOR(CWatcherMod) { - Load(); + AddHelpCommand(); + AddCommand("Add", static_cast(&CWatcherMod::Watch), " [Target] [Pattern]", "Used to add an entry to watch for."); + AddCommand("List", static_cast(&CWatcherMod::List), "", "List all entries being watched."); + AddCommand("Dump", static_cast(&CWatcherMod::Dump), "", "Dump a list of all current entries to be used later."); + AddCommand("Del", static_cast(&CWatcherMod::Remove), "", "Deletes Id from the list of watched entries."); + AddCommand("Clear", static_cast(&CWatcherMod::Clear), "", "Delete all entries."); + AddCommand("Enable", static_cast(&CWatcherMod::Enable), "", "Enable a disabled entry."); + AddCommand("Disable", static_cast(&CWatcherMod::Disable), "", "Disable (but don't delete) an entry."); + AddCommand("SetDetachedClientOnly", static_cast(&CWatcherMod::SetDetachedClientOnly), " ", "Enable or disable detached client only for an entry."); + AddCommand("SetDetachedChannelOnly", static_cast(&CWatcherMod::SetDetachedChannelOnly), " ", "Enable or disable detached channel only for an entry."); + AddCommand("SetSources", static_cast(&CWatcherMod::SetSources), " [#chan priv #foo* !#bar]", "Set the source channels that you care about."); } ~CWatcherMod() override {} + + bool OnLoad(const CString& sArgs, CString& sMessage) override { + // Just to make sure we don't mess up badly + m_lsWatchers.clear(); + + bool bWarn = false; + + for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { + VCString vList; + it->first.Split("\n", vList); + + // Backwards compatibility with the old save format + if (vList.size() != 5 && vList.size() != 7) { + bWarn = true; + continue; + } + + CWatchEntry WatchEntry(vList[0], vList[1], vList[2]); + if (vList[3].Equals("disabled")) + WatchEntry.SetDisabled(true); + else + WatchEntry.SetDisabled(false); + + // Backwards compatibility with the old save format + if (vList.size() == 5) { + WatchEntry.SetSources(vList[4]); + } else { + WatchEntry.SetDetachedClientOnly(vList[4].ToBool()); + WatchEntry.SetDetachedChannelOnly(vList[5].ToBool()); + WatchEntry.SetSources(vList[6]); + } + m_lsWatchers.push_back(WatchEntry); + } + + if (bWarn) + sMessage = t_s("WARNING: malformed entry found while loading"); + + return true; + } + void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, const CString& sArgs) override { Process(OpNick, "* " + OpNick.GetNick() + " sets mode: " + sModes + @@ -271,64 +321,6 @@ class CWatcherMod : public CModule { return CONTINUE; } - void OnModCommand(const CString& sCommand) override { - CString sCmdName = sCommand.Token(0); - if (sCmdName.Equals("ADD") || sCmdName.Equals("WATCH")) { - Watch(sCommand.Token(1), sCommand.Token(2), - sCommand.Token(3, true)); - } else if (sCmdName.Equals("HELP")) { - Help(); - } else if (sCmdName.Equals("LIST")) { - List(); - } else if (sCmdName.Equals("DUMP")) { - Dump(); - } else if (sCmdName.Equals("ENABLE")) { - CString sTok = sCommand.Token(1); - - if (sTok == "*") { - SetDisabled(~0, false); - } else { - SetDisabled(sTok.ToUInt(), false); - } - } else if (sCmdName.Equals("DISABLE")) { - CString sTok = sCommand.Token(1); - - if (sTok == "*") { - SetDisabled(~0, true); - } else { - SetDisabled(sTok.ToUInt(), true); - } - } else if (sCmdName.Equals("SETDETACHEDCLIENTONLY")) { - CString sTok = sCommand.Token(1); - bool bDetachedClientOnly = sCommand.Token(2).ToBool(); - - if (sTok == "*") { - SetDetachedClientOnly(~0, bDetachedClientOnly); - } else { - SetDetachedClientOnly(sTok.ToUInt(), bDetachedClientOnly); - } - } else if (sCmdName.Equals("SETDETACHEDCHANNELONLY")) { - CString sTok = sCommand.Token(1); - bool bDetachedchannelOnly = sCommand.Token(2).ToBool(); - - if (sTok == "*") { - SetDetachedChannelOnly(~0, bDetachedchannelOnly); - } else { - SetDetachedChannelOnly(sTok.ToUInt(), bDetachedchannelOnly); - } - } else if (sCmdName.Equals("SETSOURCES")) { - SetSources(sCommand.Token(1).ToUInt(), sCommand.Token(2, true)); - } else if (sCmdName.Equals("CLEAR")) { - m_lsWatchers.clear(); - PutModule(t_s("All entries cleared.")); - Save(); - } else if (sCmdName.Equals("DEL")) { - Remove(sCommand.Token(1).ToUInt()); - } else { - PutModule(t_f("Unknown command: {1}")(sCmdName)); - } - } - private: void Process(const CNick& Nick, const CString& sMessage, const CString& sSource) { @@ -401,7 +393,17 @@ class CWatcherMod : public CModule { Save(); } - void SetDetachedClientOnly(unsigned int uIdx, bool bDetachedClientOnly) { + void SetDetachedClientOnly(const CString& line) { + bool bDetachedClientOnly = line.Token(2).ToBool(); + CString sTok = line.Token(1); + unsigned int uIdx; + + if (sTok == "*") { + uIdx = ~0; + } else { + uIdx = sTok.ToUInt(); + } + if (uIdx == (unsigned int)~0) { for (list::iterator it = m_lsWatchers.begin(); it != m_lsWatchers.end(); ++it) { @@ -433,7 +435,17 @@ class CWatcherMod : public CModule { Save(); } - void SetDetachedChannelOnly(unsigned int uIdx, bool bDetachedChannelOnly) { + void SetDetachedChannelOnly(const CString& line) { + bool bDetachedChannelOnly = line.Token(2).ToBool(); + CString sTok = line.Token(1); + unsigned int uIdx; + + if (sTok == "*") { + uIdx = ~0; + } else { + uIdx = sTok.ToUInt(); + } + if (uIdx == (unsigned int)~0) { for (list::iterator it = m_lsWatchers.begin(); it != m_lsWatchers.end(); ++it) { @@ -441,8 +453,7 @@ class CWatcherMod : public CModule { } if (bDetachedChannelOnly) - PutModule( - t_s("Set DetachedChannelOnly for all entries to Yes")); + PutModule(t_s("Set DetachedChannelOnly for all entries to Yes")); else PutModule(t_s("Set DetachedChannelOnly for all entries to No")); Save(); @@ -466,7 +477,7 @@ class CWatcherMod : public CModule { Save(); } - void List() { + void List(const CString& line) { CTable Table; Table.AddColumn(t_s("Id")); Table.AddColumn(t_s("HostMask")); @@ -506,7 +517,7 @@ class CWatcherMod : public CModule { } } - void Dump() { + void Dump(const CString& line) { if (m_lsWatchers.empty()) { PutModule(t_s("You have no entries.")); return; @@ -548,7 +559,10 @@ class CWatcherMod : public CModule { PutModule("---------------"); } - void SetSources(unsigned int uIdx, const CString& sSources) { + void SetSources(const CString& line) { + unsigned int uIdx = line.Token(1).ToUInt(); + CString sSources = line.Token(2, true); + uIdx--; // "convert" index to zero based if (uIdx >= m_lsWatchers.size()) { PutModule(t_s("Invalid Id")); @@ -563,7 +577,34 @@ class CWatcherMod : public CModule { Save(); } - void Remove(unsigned int uIdx) { + void Enable(const CString& line) { + CString sTok = line.Token(1); + if (sTok == "*") { + SetDisabled(~0, false); + } else { + SetDisabled(sTok.ToUInt(), false); + } + } + + void Disable(const CString& line) { + CString sTok = line.Token(1); + if (sTok == "*") { + SetDisabled(~0, true); + } else { + SetDisabled(sTok.ToUInt(), true); + } + } + + void Clear(const CString& line) { + m_lsWatchers.clear(); + PutModule(t_s("All entries cleared.")); + Save(); + } + + void Remove(const CString& line) { + + unsigned int uIdx = line.Token(1).ToUInt(); + uIdx--; // "convert" index to zero based if (uIdx >= m_lsWatchers.size()) { PutModule(t_s("Invalid Id")); @@ -578,76 +619,12 @@ class CWatcherMod : public CModule { Save(); } - void Help() { - CTable Table; + void Watch(const CString& line) { + + CString sHostMask = line.Token(1); + CString sTarget = line.Token(2); + CString sPattern = line.Token(3); - Table.AddColumn(t_s("Command")); - Table.AddColumn(t_s("Description")); - Table.SetStyle(CTable::ListStyle); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Add [Target] [Pattern]")); - Table.SetCell(t_s("Description"), - t_s("Used to add an entry to watch for.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("List")); - Table.SetCell(t_s("Description"), - t_s("List all entries being watched.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Dump")); - Table.SetCell( - t_s("Description"), - t_s("Dump a list of all current entries to be used later.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Del ")); - Table.SetCell(t_s("Description"), - t_s("Deletes Id from the list of watched entries.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Clear")); - Table.SetCell(t_s("Description"), t_s("Delete all entries.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Enable ")); - Table.SetCell(t_s("Description"), t_s("Enable a disabled entry.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Disable ")); - Table.SetCell(t_s("Description"), - t_s("Disable (but don't delete) an entry.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), - t_s("SetDetachedClientOnly ")); - Table.SetCell( - t_s("Description"), - t_s("Enable or disable detached client only for an entry.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), - t_s("SetDetachedChannelOnly ")); - Table.SetCell( - t_s("Description"), - t_s("Enable or disable detached channel only for an entry.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), - t_s("SetSources [#chan priv #foo* !#bar]")); - Table.SetCell(t_s("Description"), - t_s("Set the source channels that you care about.")); - - Table.AddRow(); - Table.SetCell(t_s("Command"), t_s("Help")); - Table.SetCell(t_s("Description"), t_s("This help.")); - - PutModule(Table); - } - - void Watch(const CString& sHostMask, const CString& sTarget, - const CString& sPattern, bool bNotice = false) { CString sMessage; if (sHostMask.size()) { @@ -674,11 +651,8 @@ class CWatcherMod : public CModule { sMessage = t_s("Watch: Not enough arguments. Try Help"); } - if (bNotice) { - PutModNotice(sMessage); - } else { - PutModule(sMessage); - } + PutModNotice(sMessage); + Save(); } @@ -706,43 +680,6 @@ class CWatcherMod : public CModule { SaveRegistry(); } - void Load() { - // Just to make sure we don't mess up badly - m_lsWatchers.clear(); - - bool bWarn = false; - - for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { - VCString vList; - it->first.Split("\n", vList); - - // Backwards compatibility with the old save format - if (vList.size() != 5 && vList.size() != 7) { - bWarn = true; - continue; - } - - CWatchEntry WatchEntry(vList[0], vList[1], vList[2]); - if (vList[3].Equals("disabled")) - WatchEntry.SetDisabled(true); - else - WatchEntry.SetDisabled(false); - - // Backwards compatibility with the old save format - if (vList.size() == 5) { - WatchEntry.SetSources(vList[4]); - } else { - WatchEntry.SetDetachedClientOnly(vList[4].ToBool()); - WatchEntry.SetDetachedChannelOnly(vList[5].ToBool()); - WatchEntry.SetSources(vList[6]); - } - m_lsWatchers.push_back(WatchEntry); - } - - if (bWarn) - PutModule(t_s("WARNING: malformed entry found while loading")); - } - list m_lsWatchers; }; From 7d5562a9bdcc810244443a2982135577f0fc8848 Mon Sep 17 00:00:00 2001 From: paradix Date: Wed, 8 Jan 2020 10:06:34 +0100 Subject: [PATCH 3/4] review changes implemented --- modules/watch.cpp | 74 +++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/modules/watch.cpp b/modules/watch.cpp index 7366f685..b117322b 100644 --- a/modules/watch.cpp +++ b/modules/watch.cpp @@ -175,16 +175,26 @@ class CWatcherMod : public CModule { public: MODCONSTRUCTOR(CWatcherMod) { AddHelpCommand(); - AddCommand("Add", static_cast(&CWatcherMod::Watch), " [Target] [Pattern]", "Used to add an entry to watch for."); - AddCommand("List", static_cast(&CWatcherMod::List), "", "List all entries being watched."); - AddCommand("Dump", static_cast(&CWatcherMod::Dump), "", "Dump a list of all current entries to be used later."); - AddCommand("Del", static_cast(&CWatcherMod::Remove), "", "Deletes Id from the list of watched entries."); - AddCommand("Clear", static_cast(&CWatcherMod::Clear), "", "Delete all entries."); - AddCommand("Enable", static_cast(&CWatcherMod::Enable), "", "Enable a disabled entry."); - AddCommand("Disable", static_cast(&CWatcherMod::Disable), "", "Disable (but don't delete) an entry."); - AddCommand("SetDetachedClientOnly", static_cast(&CWatcherMod::SetDetachedClientOnly), " ", "Enable or disable detached client only for an entry."); - AddCommand("SetDetachedChannelOnly", static_cast(&CWatcherMod::SetDetachedChannelOnly), " ", "Enable or disable detached channel only for an entry."); - AddCommand("SetSources", static_cast(&CWatcherMod::SetSources), " [#chan priv #foo* !#bar]", "Set the source channels that you care about."); + AddCommand("Add", t_d(" [Target] [Pattern]"), t_d("Used to add an entry to watch for."), + [=](const CString& sLine) { Watch(sLine); }); + AddCommand("List", "", t_d("List all entries being watched."), + [=](const CString& sLine) { List(); }); + AddCommand("Dump", "", t_d("Dump a list of all current entries to be used later."), + [=](const CString& sLine) { Dump(); }); + AddCommand("Del", t_d(""), t_d("Deletes Id from the list of watched entries."), + [=](const CString& sLine) { Remove(sLine); }); + AddCommand("Clear", "", t_d("Delete all entries."), + [=](const CString& sLine) { Clear(); }); + AddCommand("Enable", t_d(""), t_d("Enable a disabled entry."), + [=](const CString& sLine) { Enable(sLine); }); + AddCommand("Disable", t_d(""), t_d("Disable (but don't delete) an entry."), + [=](const CString& sLine) { Disable(sLine); }); + AddCommand("SetDetachedClientOnly", t_d(" "), t_d("Enable or disable detached client only for an entry."), + [=](const CString& sLine) { SetDetachedClientOnly(sLine); }); + AddCommand("SetDetachedChannelOnly", t_d(" "), t_d("Enable or disable detached channel only for an entry."), + [=](const CString& sLine) { SetDetachedChannelOnly(sLine); }); + AddCommand("SetSources", t_d(" [#chan priv #foo* !#bar]"), t_d("Set the source channels that you care about."), + [=](const CString& sLine) { SetSources(sLine); }); } ~CWatcherMod() override {} @@ -393,9 +403,9 @@ class CWatcherMod : public CModule { Save(); } - void SetDetachedClientOnly(const CString& line) { - bool bDetachedClientOnly = line.Token(2).ToBool(); - CString sTok = line.Token(1); + void SetDetachedClientOnly(const CString& sLine) { + bool bDetachedClientOnly = sLine.Token(2).ToBool(); + CString sTok = sLine.Token(1); unsigned int uIdx; if (sTok == "*") { @@ -435,9 +445,9 @@ class CWatcherMod : public CModule { Save(); } - void SetDetachedChannelOnly(const CString& line) { - bool bDetachedChannelOnly = line.Token(2).ToBool(); - CString sTok = line.Token(1); + void SetDetachedChannelOnly(const CString& sLine) { + bool bDetachedChannelOnly = sLine.Token(2).ToBool(); + CString sTok = sLine.Token(1); unsigned int uIdx; if (sTok == "*") { @@ -477,7 +487,7 @@ class CWatcherMod : public CModule { Save(); } - void List(const CString& line) { + void List() { CTable Table; Table.AddColumn(t_s("Id")); Table.AddColumn(t_s("HostMask")); @@ -517,7 +527,7 @@ class CWatcherMod : public CModule { } } - void Dump(const CString& line) { + void Dump() { if (m_lsWatchers.empty()) { PutModule(t_s("You have no entries.")); return; @@ -559,9 +569,9 @@ class CWatcherMod : public CModule { PutModule("---------------"); } - void SetSources(const CString& line) { - unsigned int uIdx = line.Token(1).ToUInt(); - CString sSources = line.Token(2, true); + void SetSources(const CString& sLine) { + unsigned int uIdx = sLine.Token(1).ToUInt(); + CString sSources = sLine.Token(2, true); uIdx--; // "convert" index to zero based if (uIdx >= m_lsWatchers.size()) { @@ -577,8 +587,8 @@ class CWatcherMod : public CModule { Save(); } - void Enable(const CString& line) { - CString sTok = line.Token(1); + void Enable(const CString& sLine) { + CString sTok = sLine.Token(1); if (sTok == "*") { SetDisabled(~0, false); } else { @@ -586,8 +596,8 @@ class CWatcherMod : public CModule { } } - void Disable(const CString& line) { - CString sTok = line.Token(1); + void Disable(const CString& sLine) { + CString sTok = sLine.Token(1); if (sTok == "*") { SetDisabled(~0, true); } else { @@ -595,15 +605,15 @@ class CWatcherMod : public CModule { } } - void Clear(const CString& line) { + void Clear() { m_lsWatchers.clear(); PutModule(t_s("All entries cleared.")); Save(); } - void Remove(const CString& line) { + void Remove(const CString& sLine) { - unsigned int uIdx = line.Token(1).ToUInt(); + unsigned int uIdx = sLine.Token(1).ToUInt(); uIdx--; // "convert" index to zero based if (uIdx >= m_lsWatchers.size()) { @@ -619,11 +629,11 @@ class CWatcherMod : public CModule { Save(); } - void Watch(const CString& line) { + void Watch(const CString& sLine) { - CString sHostMask = line.Token(1); - CString sTarget = line.Token(2); - CString sPattern = line.Token(3); + CString sHostMask = sLine.Token(1); + CString sTarget = sLine.Token(2); + CString sPattern = sLine.Token(3); CString sMessage; From 4c11a26429d9612b67a8486b28f954c52e6851a7 Mon Sep 17 00:00:00 2001 From: paradix Date: Wed, 8 Jan 2020 11:48:18 +0100 Subject: [PATCH 4/4] review: fixed indentation --- modules/watch.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/watch.cpp b/modules/watch.cpp index b117322b..634cd553 100644 --- a/modules/watch.cpp +++ b/modules/watch.cpp @@ -362,10 +362,9 @@ class CWatcherMod : public CModule { CQuery* pQuery = pNetwork->AddQuery(WatchEntry.GetTarget()); if (pQuery) { - pQuery->AddBuffer( - ":" + _NAMEDFMT(WatchEntry.GetTarget()) + - "!watch@znc.in PRIVMSG {target} :{text}", - sMessage); + pQuery->AddBuffer(":" + _NAMEDFMT(WatchEntry.GetTarget()) + + "!watch@znc.in PRIVMSG {target} :{text}", + sMessage); } } sHandledTargets.insert(WatchEntry.GetTarget());