aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Sadie Powell2021-03-30 18:48:16 +0100
committerGravatar Sadie Powell2021-03-30 19:05:21 +0100
commitd121f8d4cfdd422c0cff2201bd344d4ad3027878 (patch)
treebabccb9a51259412694b8c51968186318f1e343a /src
parentFix a compiler warning caused by an unused variable. (diff)
Fix the setter and set time of list modes being lost on netburst.
Closes #1812.
Diffstat (limited to 'src')
-rw-r--r--src/listmode.cpp2
-rw-r--r--src/modules/m_spanningtree/commands.h8
-rw-r--r--src/modules/m_spanningtree/fmode.cpp43
-rw-r--r--src/modules/m_spanningtree/main.cpp37
-rw-r--r--src/modules/m_spanningtree/netburst.cpp24
-rw-r--r--src/modules/m_spanningtree/treesocket.h1
6 files changed, 107 insertions, 8 deletions
diff --git a/src/listmode.cpp b/src/listmode.cpp
index 4cc9cc6b9..2303065b1 100644
--- a/src/listmode.cpp
+++ b/src/listmode.cpp
@@ -202,7 +202,7 @@ ModeAction ListModeBase::OnModeChange(User* source, User*, Channel* channel, Mod
if (ValidateParam(source, channel, change.param))
{
// And now add the mask onto the list...
- cd->list.push_back(ListItem(change.param, source->nick, ServerInstance->Time()));
+ cd->list.emplace_back(change.param, change.set_by.value_or(source->nick), change.set_at.value_or(ServerInstance->Time()));
return MODEACTION_ALLOW;
}
else
diff --git a/src/modules/m_spanningtree/commands.h b/src/modules/m_spanningtree/commands.h
index ab89fbd1c..ef9f1ac39 100644
--- a/src/modules/m_spanningtree/commands.h
+++ b/src/modules/m_spanningtree/commands.h
@@ -398,6 +398,13 @@ class CommandNum : public ServerOnlyServerCommand<CommandNum>
};
};
+class CommandLMode : public ServerCommand
+{
+ public:
+ CommandLMode(Module* Creator) : ServerCommand(Creator, "LMODE", 3) { }
+ CmdResult Handle(User* user, Params& params) override;
+};
+
class SpanningTreeCommands
{
public:
@@ -430,5 +437,6 @@ class SpanningTreeCommands
CommandEndBurst endburst;
CommandSInfo sinfo;
CommandNum num;
+ CommandLMode lmode;
SpanningTreeCommands(ModuleSpanningTree* module);
};
diff --git a/src/modules/m_spanningtree/fmode.cpp b/src/modules/m_spanningtree/fmode.cpp
index b7430b348..d836b05e5 100644
--- a/src/modules/m_spanningtree/fmode.cpp
+++ b/src/modules/m_spanningtree/fmode.cpp
@@ -57,3 +57,46 @@ CmdResult CommandFMode::Handle(User* who, Params& params)
ServerInstance->Modes.Process(who, chan, NULL, changelist, flags);
return CmdResult::SUCCESS;
}
+
+CmdResult CommandLMode::Handle(User* who, Params& params)
+{
+ // :<sid> LMODE <chan> <chants> <modechr> [<mask> <setts> <setter>]+
+ time_t chants = ServerCommand::ExtractTS(params[1]);
+
+ Channel* const chan = ServerInstance->FindChan(params[0]);
+ if (!chan)
+ return CmdResult::FAILURE; // Channel doesn't exist.
+
+ // If the TS is greater than ours, we drop the mode and don't pass it anywhere.
+ if (chants > chan->age)
+ return CmdResult::FAILURE;
+
+ ModeHandler* mh = ServerInstance->Modes.FindMode(params[2][0], MODETYPE_CHANNEL);
+ if (!mh || !mh->IsListMode())
+ return CmdResult::FAILURE; // Mode doesn't exist or isn't a list mode.
+
+ if (params.size() % 3)
+ return CmdResult::FAILURE; // Invalid parameter count.
+
+ Modes::ChangeList changelist;
+ for (Params::const_iterator iter = params.begin() + 3; iter != params.end(); )
+ {
+ // The mode mask (e.g. foo!bar@baz).
+ const std::string& mask = *iter++;
+
+ // Who the mode was set by (e.g. Sadie!sadie@sadie.moe).
+ const std::string& set_by = *iter++;
+
+ // The time at which the mode was set (e.g. 956204400).
+ time_t set_at = ServerCommand::ExtractTS(*iter++);
+
+ changelist.push(mh, true, mask, set_by, set_at);
+ }
+
+ ModeParser::ModeProcessFlag flags = ModeParser::MODE_LOCALONLY;
+ if (chants == chan->age && IS_SERVER(who))
+ flags |= ModeParser::MODE_MERGE;
+
+ ServerInstance->Modes.Process(who, chan, NULL, changelist, flags);
+ return CmdResult::SUCCESS;
+}
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index f93d9fe27..c8cc89890 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -62,13 +62,36 @@ ModuleSpanningTree::ModuleSpanningTree()
}
SpanningTreeCommands::SpanningTreeCommands(ModuleSpanningTree* module)
- : svsjoin(module), svspart(module), svsnick(module), metadata(module),
- uid(module), opertype(module), fjoin(module), ijoin(module), resync(module),
- fmode(module), ftopic(module), fhost(module), fident(module), fname(module),
- away(module), addline(module), delline(module), encap(module), idle(module),
- nick(module), ping(module), pong(module), save(module),
- server(module), squit(module), snonotice(module),
- endburst(module), sinfo(module), num(module)
+ : svsjoin(module)
+ , svspart(module)
+ , svsnick(module)
+ , metadata(module)
+ , uid(module)
+ , opertype(module)
+ , fjoin(module)
+ , ijoin(module)
+ , resync(module)
+ , fmode(module)
+ , ftopic(module)
+ , fhost(module)
+ , fident(module)
+ , fname(module)
+ , away(module)
+ , addline(module)
+ , delline(module)
+ , encap(module)
+ , idle(module)
+ , nick(module)
+ , ping(module)
+ , pong(module)
+ , save(module)
+ , server(module)
+ , squit(module)
+ , snonotice(module)
+ , endburst(module)
+ , sinfo(module)
+ , num(module)
+ , lmode(module)
{
}
diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp
index 183fbd7c3..9b9fa7d87 100644
--- a/src/modules/m_spanningtree/netburst.cpp
+++ b/src/modules/m_spanningtree/netburst.cpp
@@ -197,6 +197,30 @@ void TreeSocket::SendXLines()
void TreeSocket::SendListModes(Channel* chan)
{
+ if (proto_version < PROTO_INSPIRCD_40_A1)
+ {
+ SendLegacyListModes(chan);
+ return;
+ }
+
+ for (const auto& mode : ServerInstance->Modes.GetListModes())
+ {
+ ListModeBase::ModeList* list = mode->GetList(chan);
+ if (!list || list->empty())
+ continue;
+
+ CmdBuilder lmode("LMODE");
+ lmode.push(chan->name).push_int(chan->age).push(mode->GetModeChar());
+
+ for (const auto& entry : *list)
+ lmode.push(entry.mask).push(entry.setter).push_int(entry.time);
+
+ this->WriteLine(lmode.str());
+ }
+}
+
+void TreeSocket::SendLegacyListModes(Channel* chan)
+{
FModeBuilder fmode(chan);
for (const auto& mode : ServerInstance->Modes.GetListModes())
{
diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h
index f496eb069..72bff8ab0 100644
--- a/src/modules/m_spanningtree/treesocket.h
+++ b/src/modules/m_spanningtree/treesocket.h
@@ -128,6 +128,7 @@ class TreeSocket : public BufferedSocket
/** Send all ListModeBase modes set on the channel
*/
void SendListModes(Channel* chan);
+ void SendLegacyListModes(Channel* chan);
/** Send all known information about a channel */
void SyncChannel(Channel* chan, BurstState& bs);