diff options
| author | 2021-03-30 18:48:16 +0100 | |
|---|---|---|
| committer | 2021-03-30 19:05:21 +0100 | |
| commit | d121f8d4cfdd422c0cff2201bd344d4ad3027878 (patch) | |
| tree | babccb9a51259412694b8c51968186318f1e343a /src/modules | |
| parent | Fix 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/modules')
| -rw-r--r-- | src/modules/m_spanningtree/commands.h | 8 | ||||
| -rw-r--r-- | src/modules/m_spanningtree/fmode.cpp | 43 | ||||
| -rw-r--r-- | src/modules/m_spanningtree/main.cpp | 37 | ||||
| -rw-r--r-- | src/modules/m_spanningtree/netburst.cpp | 24 | ||||
| -rw-r--r-- | src/modules/m_spanningtree/treesocket.h | 1 |
5 files changed, 106 insertions, 7 deletions
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); |
