summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/hashcomp.h41
-rw-r--r--src/modules/m_spanningtree.cpp45
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 &parameter);
+ /** 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;