diff options
-rw-r--r-- | include/hashcomp.h | 41 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 45 |
2 files changed, 66 insertions, 20 deletions
diff --git a/include/hashcomp.h b/include/hashcomp.h index 76c7750a0..fac1d4ed2 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -123,17 +123,58 @@ namespace irc bool operator()(const insp_inaddr &s1, const insp_inaddr &s2) const; }; + /** irc::modestacker stacks mode sequences into a list. + * It can then reproduce this list, clamped to a maximum of MAXMODES + * values per line. + */ class modestacker { private: + /** The mode sequence and its parameters + */ std::deque<std::string> sequence; + /** True if the mode sequence is initially adding + * characters, false if it is initially removing + * them + */ bool adding; public: + /** Construct a new modestacker. + * @param add True if the stack is adding modes, + * false if it is removing them + */ modestacker(bool add); + /** Push a modeletter and its parameter onto the stack. + * No checking is performed as to if this mode actually + * requires a parameter. If you stack invalid mode + * sequences, they will be tidied if and when they are + * passed to a mode parser. + * @param modeletter The mode letter to insert + * @param parameter The parameter for the mode + */ void Push(char modeletter, const std::string ¶meter); + /** Push a modeletter without parameter onto the stack. + * No checking is performed as to if this mode actually + * requires a parameter. If you stack invalid mode + * sequences, they will be tidied if and when they are + * passed to a mode parser. + * @param modeletter The mode letter to insert + */ void Push(char modeletter); + /** Push a '+' symbol onto the stack. + */ void PushPlus(); + /** Push a '-' symbol onto the stack. + */ void PushMinus(); + /** Return zero or more elements which form the + * mode line. This will be clamped to a max of + * MAXMODES+1 items (MAXMODES mode parameters and + * one mode dequence string). + * @param result The deque to populate. This will + * be cleared before it is used. + * @return The number of elements in the deque + */ int GetStackedLine(std::deque<std::string> &result); }; diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index d46cd6234..e410c5135 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -2616,38 +2616,43 @@ class TreeSocket : public InspSocket if (c) { + irc::modestacker modestack(false); CUList *ulist = c->GetUsers(); + const char* y[127]; + std::deque<std::string> stackresult; + std::string x; + for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) { std::string modesequence = Instance->Modes->ModeString(i->second, c); if (modesequence.length()) { - modesequence = "-" + modesequence; - - std::deque<std::string> items; - const char* y[127]; - unsigned int z = 0; - std::string x = "*"; irc::spacesepstream sep(modesequence); + std::string modeletters = sep.GetToken(); - while ((x = sep.GetToken()) != "") + while (!modeletters.empty()) { - if (!z) - { - y[z++] = c->name; - items.push_back(c->name); - items.push_back(ConvToStr(c->age)); - } - items.push_back(x); - y[z++] = (items.end() - 1)->c_str(); + char mletter = *(modeletters.begin()); + modestack.Push(mletter,sep.GetToken()); + modeletters.erase(modeletters.begin()); } + } + } - DoOneToMany(Instance->Config->ServerName, "FMODE", items); - userrec* n = new userrec(Instance); - n->SetFd(FD_MAGIC_NUMBER); - Instance->SendMode(y,z,n); - delete n; + while (modestack.GetStackedLine(stackresult)) + { + stackresult.push_front(ConvToStr(c->age)); + stackresult.push_front(c->name); + DoOneToMany(Instance->Config->ServerName, "FMODE", stackresult); + stackresult.erase(stackresult.begin() + 1); + for (size_t z = 0; z < stackresult.size(); z++) + { + y[z] = stackresult[z].c_str(); } + userrec* n = new userrec(Instance); + n->SetFd(FD_MAGIC_NUMBER); + Instance->SendMode(y, stackresult.size(), n); + delete n; } } return true; |