void DataKeeper::DoSaveChans() { ModesExts currdata; std::vector<OwnedModesExts> currmemberdata; const chan_hash& chans = ServerInstance->GetChans(); for (chan_hash::const_iterator i = chans.begin(); i != chans.end(); ++i) { Channel* const chan = i->second; // Serialize channel modes for (size_t j = 0; j < handledmodes[MODETYPE_CHANNEL].size(); j++) { ModeHandler* mh = handledmodes[MODETYPE_CHANNEL][j].mh; ListModeBase* lm = mh->IsListModeBase(); if (lm) SaveListModes(chan, lm, j, currdata); else if (chan->IsModeSet(mh)) currdata.modelist.push_back(InstanceData(j, chan->GetModeParameter(mh))); } // Serialize all extensions attached to the Channel SaveExtensions(chan, currdata.extlist); // Serialize all extensions attached to and all modes set on all members of the channel SaveMemberData(chan, currmemberdata); // Same logic as in DoSaveUsers() plus we consider the modes and extensions of all members if ((!currdata.empty()) || (!currmemberdata.empty())) { chandatalist.push_back(ChanData(chan)); chandatalist.back().swap(currdata); chandatalist.back().memberdatalist.swap(currmemberdata); } } }
CmdResult Handle(User* user, const Params& parameters) override { ModeHandler* mh; Channel* chan = ServerInstance->FindChan(parameters[0]); char modeletter = parameters[1][0]; if (chan == NULL) { user->WriteNotice("The channel " + parameters[0] + " does not exist."); return CMD_FAILURE; } mh = ServerInstance->Modes.FindMode(modeletter, MODETYPE_CHANNEL); if (mh == NULL || parameters[1].size() > 1) { user->WriteNotice(parameters[1] + " is not a valid channel mode."); return CMD_FAILURE; } if (chan->GetPrefixValue(user) < mh->GetLevelRequired(false)) { user->WriteNotice("You do not have access to unset " + ConvToStr(modeletter) + " on " + chan->name + "."); return CMD_FAILURE; } std::string pattern = parameters.size() > 2 ? parameters[2] : "*"; PrefixMode* pm; ListModeBase* lm; ListModeBase::ModeList* ml; Modes::ChangeList changelist; if ((pm = mh->IsPrefixMode())) { // As user prefix modes don't have a GetList() method, let's iterate through the channel's users. const Channel::MemberMap& users = chan->GetUsers(); for (Channel::MemberMap::const_iterator it = users.begin(); it != users.end(); ++it) { if (!InspIRCd::Match(it->first->nick, pattern)) continue; if (it->second->HasMode(pm) && !((it->first == user) && (pm->GetPrefixRank() > VOICE_VALUE))) changelist.push_remove(mh, it->first->nick); } } else if ((lm = mh->IsListModeBase()) && ((ml = lm->GetList(chan)) != NULL)) { for (ListModeBase::ModeList::iterator it = ml->begin(); it != ml->end(); ++it) { if (!InspIRCd::Match(it->mask, pattern)) continue; changelist.push_remove(mh, it->mask); } } else { if (chan->IsModeSet(mh)) changelist.push_remove(mh); } ServerInstance->Modes.Process(user, chan, NULL, changelist); return CMD_SUCCESS; }
CmdResult Handle(const std::vector<std::string> ¶meters, User *user) { ModeHandler* mh; Channel* chan = ServerInstance->FindChan(parameters[0]); char modeletter = parameters[1][0]; if (chan == NULL) { user->WriteNotice("The channel " + parameters[0] + " does not exist."); return CMD_FAILURE; } mh = ServerInstance->Modes->FindMode(modeletter, MODETYPE_CHANNEL); if (mh == NULL || parameters[1].size() > 1) { user->WriteNotice(parameters[1] + " is not a valid channel mode."); return CMD_FAILURE; } if (chan->GetPrefixValue(user) < mh->GetLevelRequired()) { user->WriteNotice("You do not have access to unset " + ConvToStr(modeletter) + " on " + chan->name + "."); return CMD_FAILURE; } std::string pattern = parameters.size() > 2 ? parameters[2] : "*"; PrefixMode* pm; ListModeBase* lm; ListModeBase::ModeList* ml; irc::modestacker modestack(false); if ((pm = mh->IsPrefixMode())) { // As user prefix modes don't have a GetList() method, let's iterate through the channel's users. const Channel::MemberMap& users = chan->GetUsers(); for (Channel::MemberMap::const_iterator it = users.begin(); it != users.end(); ++it) { if (!InspIRCd::Match(it->first->nick, pattern)) continue; if (it->second->hasMode(modeletter) && !((it->first == user) && (pm->GetPrefixRank() > VOICE_VALUE))) modestack.Push(modeletter, it->first->nick); } } else if ((lm = mh->IsListModeBase()) && ((ml = lm->GetList(chan)) != NULL)) { for (ListModeBase::ModeList::iterator it = ml->begin(); it != ml->end(); ++it) { if (!InspIRCd::Match(it->mask, pattern)) continue; modestack.Push(modeletter, it->mask); } } else { if (chan->IsModeSet(mh)) modestack.Push(modeletter); } parameterlist stackresult; stackresult.push_back(chan->name); while (modestack.GetStackedLine(stackresult)) { ServerInstance->Modes->Process(stackresult, user); stackresult.erase(stackresult.begin() + 1, stackresult.end()); } return CMD_SUCCESS; }