+ std::string chanmodes = chan->ChanModes(true);
+ if (save_listmodes)
+ {
+ ListModeData lm;
+
+ // Bans are managed by the core, so we have to process them separately
+ lm.modes = std::string(chan->bans.size(), 'b');
+ for (BanList::const_iterator j = chan->bans.begin(); j != chan->bans.end(); ++j)
+ {
+ lm.params += j->data;
+ lm.params += ' ';
+ }
+
+ // All other listmodes are managed by modules, so we need to ask them (call their
+ // OnSyncChannel() handler) to give our ProtoSendMode() a list of modes that are
+ // set on the channel. The ListModeData struct is passed as an opaque pointer
+ // that will be passed back to us by the module handling the mode.
+ FOREACH_MOD(I_OnSyncChannel, OnSyncChannel(chan, mod, &lm));
+
+ if (!lm.modes.empty())
+ {
+ // Remove the last space
+ lm.params.erase(lm.params.end()-1);
+
+ // If there is at least a space in chanmodes (that is, a non-listmode has a parameter)
+ // insert the listmode mode letters before the space. Otherwise just append them.
+ std::string::size_type p = chanmodes.find(' ');
+ if (p == std::string::npos)
+ chanmodes += lm.modes;
+ else
+ chanmodes.insert(p, lm.modes);
+
+ // Append the listmode parameters (the masks themselves)
+ chanmodes += ' ';
+ chanmodes += lm.params;
+ }
+ }
+
+ std::string chants = ConvToStr(chan->age);
+ std::string topicts = ConvToStr(chan->topicset);