summaryrefslogtreecommitdiff
path: root/src/protocol.cpp
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2025-05-03 17:07:07 +0100
committerSadie Powell <sadie@witchery.services>2025-05-03 21:28:56 +0100
commit010beb52b1f3c697a07f9a130d2ed9335fe1cd98 (patch)
tree734750a5677afff443f2117dc34ba14d3351fb28 /src/protocol.cpp
parentc95594141346ef6fb65a5af177bed35ed865234d (diff)
Store the setter and ts for all modes and try to restore them.
This is mostly for preserving channel list mode info.
Diffstat (limited to 'src/protocol.cpp')
-rw-r--r--src/protocol.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 7a167582a..882ef6c5c 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -113,6 +113,61 @@ void IRCDProto::SendSVSKill(const MessageSource &source, User *user, const Anope
Uplink::Send(source, "KILL", user->GetUID(), buf);
}
+static auto BuildModeChange(const ModeManager::Change &change)
+{
+ std::list<std::pair<Anope::string, std::vector<Anope::string>>> modes;
+
+ Anope::string modebuf;
+ size_t modecount = 0;
+ std::vector<Anope::string> parambuf;
+ size_t paramlen;
+
+ auto adding = true;
+ for (const auto &[mode, info] : change)
+ {
+ const auto reached_max_line = IRCD->MaxLine && modebuf.length() + paramlen > IRCD->MaxLine - 100; // Leave room for command, channel, etc
+ const auto reached_max_modes = IRCD->MaxModes && ++modecount > IRCD->MaxModes;
+ if (reached_max_modes || reached_max_line)
+ {
+ modes.push_back({modebuf, parambuf});
+
+ modebuf.clear();
+ modecount = 0;
+
+ parambuf.clear();
+ paramlen = 0;
+ }
+
+ // Push the mode.
+ const auto direction = info.first;
+ if (modebuf.empty() || adding != direction)
+ {
+ adding = direction;
+ modebuf += (adding ? '+' : '-');
+ }
+ modebuf += mode->mchar;
+
+ // If it has a value push that too.
+ const auto &data = info.second;
+ if (!data.value.empty())
+ {
+ parambuf.push_back(data.value);
+ paramlen += data.value.length() + 1;
+ }
+ }
+
+ if (!modebuf.empty())
+ modes.push_back({modebuf, parambuf});
+
+ return modes;
+}
+
+void IRCDProto::SendMode(const MessageSource &source, Channel *chan, const ModeManager::Change &change)
+{
+ for (const auto &[modes, params] : BuildModeChange(change))
+ IRCD->SendModeInternal(source, chan, modes, params);
+}
+
void IRCDProto::SendModeInternal(const MessageSource &source, Channel *chan, const Anope::string &modes, const std::vector<Anope::string> &values)
{
auto params = values;
@@ -120,6 +175,12 @@ void IRCDProto::SendModeInternal(const MessageSource &source, Channel *chan, con
Uplink::SendInternal({}, source, "MODE", params);
}
+void IRCDProto::SendMode(const MessageSource &source, User *dest, const ModeManager::Change &change)
+{
+ for (const auto &[modes, params] : BuildModeChange(change))
+ IRCD->SendModeInternal(source, dest, modes, params);
+}
+
void IRCDProto::SendModeInternal(const MessageSource &source, User *dest, const Anope::string &modes, const std::vector<Anope::string> &values)
{
auto params = values;