本文整理汇总了C++中PrefixMode类的典型用法代码示例。如果您正苦于以下问题:C++ PrefixMode类的具体用法?C++ PrefixMode怎么用?C++ PrefixMode使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了PrefixMode类的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GetListOfServersForChannel
/* returns a list of DIRECT servernames for a specific channel */
void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeSocketSet& list, char status, const CUList& exempt_list)
{
unsigned int minrank = 0;
if (status)
{
PrefixMode* mh = ServerInstance->Modes->FindPrefix(status);
if (mh)
minrank = mh->GetPrefixRank();
}
const UserMembList *ulist = c->GetUsers();
for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++)
{
if (IS_LOCAL(i->first))
continue;
if (minrank && i->second->getRank() < minrank)
continue;
if (exempt_list.find(i->first) == exempt_list.end())
{
TreeServer* best = TreeServer::Get(i->first);
list.insert(best->GetSocket());
}
}
return;
}
示例2: Call
ModResult Call(User* user, Channel* chan, const std::string& restriction)
{
unsigned int mypfx = chan->GetPrefixValue(user);
std::string minmode;
ListModeBase::ModeList* list = ec.GetList(chan);
if (list)
{
for (ListModeBase::ModeList::iterator i = list->begin(); i != list->end(); ++i)
{
std::string::size_type pos = (*i).mask.find(':');
if (pos == std::string::npos)
continue;
if ((*i).mask.substr(0,pos) == restriction)
minmode = (*i).mask.substr(pos + 1);
}
}
PrefixMode* mh = FindMode(minmode);
if (mh && mypfx >= mh->GetPrefixRank())
return MOD_RES_ALLOW;
if (mh || minmode == "*")
return MOD_RES_DENY;
return ServerInstance->HandleOnCheckExemption.Call(user, chan, restriction);
}
示例3: Handle
CmdResult Handle(User* user, const Params& parameters) override
{
Channel* channel = ServerInstance->FindChan(parameters[0]);
if (!channel)
{
user->WriteNumeric(Numerics::NoSuchChannel(parameters[0]));
return CMD_FAILURE;
}
unsigned int cm = channel->GetPrefixValue(user);
if (cm < HALFOP_VALUE)
{
user->WriteNumeric(ERR_CHANOPRIVSNEEDED, channel->name, "You do not have permission to set bans on this channel");
return CMD_FAILURE;
}
TimedBan T;
unsigned long duration;
if (!InspIRCd::Duration(parameters[1], duration))
{
user->WriteNotice("Invalid ban time");
return CMD_FAILURE;
}
unsigned long expire = duration + ServerInstance->Time();
std::string mask = parameters[2];
bool isextban = ((mask.size() > 2) && (mask[1] == ':'));
if (!isextban && !InspIRCd::IsValidMask(mask))
mask.append("!*@*");
if (IsBanSet(channel, mask))
{
user->WriteNotice("Ban already set");
return CMD_FAILURE;
}
Modes::ChangeList setban;
setban.push_add(ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL), mask);
// Pass the user (instead of ServerInstance->FakeClient) to ModeHandler::Process() to
// make it so that the user sets the mode themselves
ServerInstance->Modes.Process(user, channel, NULL, setban);
if (ServerInstance->Modes.GetLastChangeList().empty())
{
user->WriteNotice("Invalid ban mask");
return CMD_FAILURE;
}
T.mask = mask;
T.expire = expire + (IS_REMOTE(user) ? 5 : 0);
T.chan = channel;
TimedBanList.push_back(T);
const std::string addban = user->nick + " added a timed ban on " + mask + " lasting for " + InspIRCd::DurationString(duration) + ".";
// If halfop is loaded, send notice to halfops and above, otherwise send to ops and above
PrefixMode* mh = ServerInstance->Modes.FindPrefixMode('h');
char pfxchar = (mh && mh->name == "halfop") ? mh->GetPrefix() : '@';
ClientProtocol::Messages::Privmsg notice(ServerInstance->FakeClient, channel, addban, MSG_NOTICE);
channel->Write(ServerInstance->GetRFCEvents().privmsg, notice, pfxchar);
ServerInstance->PI->SendChannelNotice(channel, pfxchar, addban);
return CMD_SUCCESS;
}
示例4: OnBackgroundTimer
void OnBackgroundTimer(time_t curtime) override
{
timedbans expired;
for (timedbans::iterator i = TimedBanList.begin(); i != TimedBanList.end();)
{
if (curtime > i->expire)
{
expired.push_back(*i);
i = TimedBanList.erase(i);
}
else
++i;
}
for (timedbans::iterator i = expired.begin(); i != expired.end(); i++)
{
std::string mask = i->mask;
Channel* cr = i->chan;
{
const std::string expiry = "*** Timed ban on " + cr->name + " expired.";
// If halfop is loaded, send notice to halfops and above, otherwise send to ops and above
PrefixMode* mh = ServerInstance->Modes.FindPrefixMode('h');
char pfxchar = (mh && mh->name == "halfop") ? mh->GetPrefix() : '@';
ClientProtocol::Messages::Privmsg notice(ClientProtocol::Messages::Privmsg::nocopy, ServerInstance->FakeClient, cr, expiry, MSG_NOTICE);
cr->Write(ServerInstance->GetRFCEvents().privmsg, notice, pfxchar);
ServerInstance->PI->SendChannelNotice(cr, pfxchar, expiry);
Modes::ChangeList setban;
setban.push_remove(ServerInstance->Modes.FindMode('b', MODETYPE_CHANNEL), mask);
ServerInstance->Modes.Process(ServerInstance->FakeClient, cr, NULL, setban);
}
}
}
示例5: GetPrefixModes
PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter)
{
const PrefixModeList& list = GetPrefixModes();
for (PrefixModeList::const_iterator i = list.begin(); i != list.end(); ++i)
{
PrefixMode* pm = *i;
if (pm->GetPrefix() == pfxletter)
return pm;
}
return NULL;
}
示例6: ModuleException
void ModeParser::AddMode(ModeHandler* mh)
{
/* Yes, i know, this might let people declare modes like '_' or '^'.
* If they do that, thats their problem, and if i ever EVER see an
* official InspIRCd developer do that, i'll beat them with a paddle!
*/
if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z'))
throw ModuleException("Invalid letter for mode " + mh->name);
/* A mode prefix of ',' is not acceptable, it would fuck up server to server.
* A mode prefix of ':' will fuck up both server to server, and client to server.
* A mode prefix of '#' will mess up /whois and /privmsg
*/
PrefixMode* pm = mh->IsPrefixMode();
if (pm)
{
if ((pm->GetPrefix() > 126) || (pm->GetPrefix() == ',') || (pm->GetPrefix() == ':') || (pm->GetPrefix() == '#'))
throw ModuleException("Invalid prefix for mode " + mh->name);
if (FindPrefix(pm->GetPrefix()))
throw ModuleException("Prefix already exists for mode " + mh->name);
}
ModeHandler*& slot = modehandlers[mh->GetModeType()][mh->GetModeChar()-65];
if (slot)
throw ModuleException("Letter is already in use for mode " + mh->name);
// The mode needs an id if it is either a user mode, a simple mode (flag) or a parameter mode.
// Otherwise (for listmodes and prefix modes) the id remains MODEID_MAX, which is invalid.
ModeHandler::Id modeid = MODEID_MAX;
if ((mh->GetModeType() == MODETYPE_USER) || (mh->IsParameterMode()) || (!mh->IsListMode()))
modeid = AllocateModeId(mh->GetModeType());
if (!modehandlersbyname[mh->GetModeType()].insert(std::make_pair(mh->name, mh)).second)
throw ModuleException("Mode name already in use: " + mh->name);
// Everything is fine, add the mode
// If we allocated an id for this mode then save it and put the mode handler into the slot
if (modeid != MODEID_MAX)
{
mh->modeid = modeid;
modehandlersbyid[mh->GetModeType()][modeid] = mh;
}
slot = mh;
if (pm)
mhlist.prefix.push_back(pm);
else if (mh->IsListModeBase())
mhlist.list.push_back(mh->IsListModeBase());
RecreateModeListFor004Numeric();
}
示例7: GiveModeList
std::string ModeParser::GiveModeList(ModeMasks m)
{
std::string type1; /* Listmodes EXCEPT those with a prefix */
std::string type2; /* Modes that take a param when adding or removing */
std::string type3; /* Modes that only take a param when adding */
std::string type4; /* Modes that dont take a param */
for (unsigned char mode = 'A'; mode <= 'z'; mode++)
{
unsigned char pos = (mode-65) | m;
/* One parameter when adding */
if (modehandlers[pos])
{
if (modehandlers[pos]->GetNumParams(true))
{
PrefixMode* pm = modehandlers[pos]->IsPrefixMode();
if ((modehandlers[pos]->IsListMode()) && ((!pm) || (pm->GetPrefix() == 0)))
{
type1 += modehandlers[pos]->GetModeChar();
}
else
{
/* ... and one parameter when removing */
if (modehandlers[pos]->GetNumParams(false))
{
/* But not a list mode */
if (!pm)
{
type2 += modehandlers[pos]->GetModeChar();
}
}
else
{
/* No parameters when removing */
type3 += modehandlers[pos]->GetModeChar();
}
}
}
else
{
type4 += modehandlers[pos]->GetModeChar();
}
}
}
return type1 + "," + type2 + "," + type3 + "," + type4;
}
示例8: init
void init() override
{
ConfigTagList tags = ServerInstance->Config->ConfTags("customprefix");
for (ConfigIter iter = tags.first; iter != tags.second; ++iter)
{
ConfigTag* tag = iter->second;
const std::string name = tag->getString("name");
if (name.empty())
throw ModuleException("<customprefix:name> must be specified at " + tag->getTagLocation());
if (tag->getBool("change"))
{
ModeHandler* mh = ServerInstance->Modes.FindMode(name, MODETYPE_CHANNEL);
if (!mh)
throw ModuleException("<customprefix:change> specified for a non-existent mode at " + tag->getTagLocation());
PrefixMode* pm = mh->IsPrefixMode();
if (!pm)
throw ModuleException("<customprefix:change> specified for a non-prefix mode at " + tag->getTagLocation());
unsigned long rank = tag->getUInt("rank", pm->GetPrefixRank(), 0, UINT_MAX);
unsigned long setrank = tag->getUInt("ranktoset", pm->GetLevelRequired(true), rank, UINT_MAX);
unsigned long unsetrank = tag->getUInt("ranktounset", pm->GetLevelRequired(false), setrank, UINT_MAX);
bool depriv = tag->getBool("depriv", pm->CanSelfRemove());
pm->Update(rank, setrank, unsetrank, depriv);
ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Changed the %s prefix: depriv=%u rank=%u ranktoset=%u ranktounset=%u",
pm->name.c_str(), pm->CanSelfRemove(), pm->GetPrefixRank(), pm->GetLevelRequired(true), pm->GetLevelRequired(false));
continue;
}
const std::string letter = tag->getString("letter");
if (letter.length() != 1)
throw ModuleException("<customprefix:letter> must be set to a mode character at " + tag->getTagLocation());
const std::string prefix = tag->getString("prefix");
if (prefix.length() != 1)
throw ModuleException("<customprefix:prefix> must be set to a mode prefix at " + tag->getTagLocation());
try
{
CustomPrefixMode* mh = new CustomPrefixMode(this, name, letter[0], prefix[0], tag);
modes.push_back(mh);
ServerInstance->Modules.AddService(*mh);
}
catch (ModuleException& e)
{
throw ModuleException(e.GetReason() + " (while creating mode from " + tag->getTagLocation() + ")");
}
}
}
示例9: AddMode
bool ModeParser::AddMode(ModeHandler* mh)
{
unsigned char mask = 0;
unsigned char pos = 0;
/* Yes, i know, this might let people declare modes like '_' or '^'.
* If they do that, thats their problem, and if i ever EVER see an
* official InspIRCd developer do that, i'll beat them with a paddle!
*/
if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z'))
return false;
/* A mode prefix of ',' is not acceptable, it would fuck up server to server.
* A mode prefix of ':' will fuck up both server to server, and client to server.
* A mode prefix of '#' will mess up /whois and /privmsg
*/
PrefixMode* pm = mh->IsPrefixMode();
if (pm)
{
if ((pm->GetPrefix() > 126) || (pm->GetPrefix() == ',') || (pm->GetPrefix() == ':') || (pm->GetPrefix() == '#'))
return false;
if (FindPrefix(pm->GetPrefix()))
return false;
}
mh->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL;
pos = (mh->GetModeChar()-65) | mask;
if (modehandlers[pos])
return false;
// Everything is fine, add the mode
modehandlers[pos] = mh;
if (pm)
mhlist.prefix.push_back(pm);
else if (mh->IsListModeBase())
mhlist.list.push_back(mh->IsListModeBase());
RecreateModeListFor004Numeric();
return true;
}
示例10: defaultstream
ModResult OnCheckExemptionHandler::Call(User* user, Channel* chan, const std::string& restriction)
{
unsigned int mypfx = chan->GetPrefixValue(user);
char minmode = 0;
std::string current;
irc::spacesepstream defaultstream(ServerInstance->Config->ConfValue("options")->getString("exemptchanops"));
while (defaultstream.GetToken(current))
{
std::string::size_type pos = current.find(':');
if (pos == std::string::npos)
continue;
if (!current.compare(0, pos, restriction))
minmode = current[pos+1];
}
PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(minmode);
if (mh && mypfx >= mh->GetPrefixRank())
return MOD_RES_ALLOW;
if (mh || minmode == '*')
return MOD_RES_DENY;
return MOD_RES_PASSTHRU;
}
示例11: Handle
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;
}
示例12: FindMode
ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool adding, const unsigned char modechar,
std::string ¶meter, bool SkipACL)
{
ModeType type = chan ? MODETYPE_CHANNEL : MODETYPE_USER;
ModeHandler *mh = FindMode(modechar, type);
int pcnt = mh->GetNumParams(adding);
// crop mode parameter size to 250 characters
if (parameter.length() > 250 && adding)
parameter = parameter.substr(0, 250);
ModResult MOD_RESULT;
FIRST_MOD_RESULT(OnRawMode, MOD_RESULT, (user, chan, modechar, parameter, adding, pcnt));
if (IS_LOCAL(user) && (MOD_RESULT == MOD_RES_DENY))
return MODEACTION_DENY;
if (chan && !SkipACL && (MOD_RESULT != MOD_RES_ALLOW))
{
MOD_RESULT = mh->AccessCheck(user, chan, parameter, adding);
if (MOD_RESULT == MOD_RES_DENY)
return MODEACTION_DENY;
if (MOD_RESULT == MOD_RES_PASSTHRU)
{
unsigned int neededrank = mh->GetLevelRequired();
/* Compare our rank on the channel against the rank of the required prefix,
* allow if >= ours. Because mIRC and xchat throw a tizz if the modes shown
* in NAMES(X) are not in rank order, we know the most powerful mode is listed
* first, so we don't need to iterate, we just look up the first instead.
*/
unsigned int ourrank = chan->GetPrefixValue(user);
if (ourrank < neededrank)
{
PrefixMode* neededmh = NULL;
for(char c='A'; c <= 'z'; c++)
{
PrefixMode* privmh = FindPrefixMode(c);
if (privmh && privmh->GetPrefixRank() >= neededrank)
{
// this mode is sufficient to allow this action
if (!neededmh || privmh->GetPrefixRank() < neededmh->GetPrefixRank())
neededmh = privmh;
}
}
if (neededmh)
user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must have channel %s access or above to %sset channel mode %c",
user->nick.c_str(), chan->name.c_str(), neededmh->name.c_str(), adding ? "" : "un", modechar);
else
user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You cannot %sset channel mode %c",
user->nick.c_str(), chan->name.c_str(), adding ? "" : "un", modechar);
return MODEACTION_DENY;
}
}
}
// Ask mode watchers whether this mode change is OK
std::pair<ModeWatchIter, ModeWatchIter> itpair = modewatchermap.equal_range(mh->name);
for (ModeWatchIter i = itpair.first; i != itpair.second; ++i)
{
ModeWatcher* mw = i->second;
if (mw->GetModeType() == type)
{
if (!mw->BeforeMode(user, targetuser, chan, parameter, adding))
return MODEACTION_DENY;
// A module whacked the parameter completely, and there was one. Abort.
if (pcnt && parameter.empty())
return MODEACTION_DENY;
}
}
if (IS_LOCAL(user) && !user->IsOper())
{
char* disabled = (type == MODETYPE_CHANNEL) ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes;
if (disabled[modechar - 'A'])
{
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - %s mode %c has been locked by the administrator",
user->nick.c_str(), type == MODETYPE_CHANNEL ? "channel" : "user", modechar);
return MODEACTION_DENY;
}
}
if (adding && IS_LOCAL(user) && mh->NeedsOper() && !user->HasModePermission(modechar, type))
{
/* It's an oper only mode, and they don't have access to it. */
if (user->IsOper())
{
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Oper type %s does not have access to set %s mode %c",
user->nick.c_str(), user->oper->name.c_str(), type == MODETYPE_CHANNEL ? "channel" : "user", modechar);
}
else
{
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Only operators may set %s mode %c",
user->nick.c_str(), type == MODETYPE_CHANNEL ? "channel" : "user", modechar);
}
return MODEACTION_DENY;
}
//.........这里部分代码省略.........
示例13: if
/** Handle /INVITE
*/
CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, User *user)
{
ModResult MOD_RESULT;
if (parameters.size() >= 2)
{
User* u;
if (IS_LOCAL(user))
u = ServerInstance->FindNickOnly(parameters[0]);
else
u = ServerInstance->FindNick(parameters[0]);
Channel* c = ServerInstance->FindChan(parameters[1]);
time_t timeout = 0;
if (parameters.size() >= 3)
{
if (IS_LOCAL(user))
timeout = ServerInstance->Time() + InspIRCd::Duration(parameters[2]);
else if (parameters.size() > 3)
timeout = ConvToInt(parameters[3]);
}
if ((!c) || (!u) || (u->registered != REG_ALL))
{
user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c ? parameters[0].c_str() : parameters[1].c_str());
return CMD_FAILURE;
}
// Verify channel timestamp if the INVITE is coming from a remote server
if (!IS_LOCAL(user))
{
// Remote INVITE commands must carry a channel timestamp
if (parameters.size() < 3)
return CMD_INVALID;
// Drop the invite if our channel TS is lower
time_t RemoteTS = ConvToInt(parameters[2]);
if (c->age < RemoteTS)
return CMD_FAILURE;
}
if ((IS_LOCAL(user)) && (!c->HasUser(user)))
{
user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", c->name.c_str());
return CMD_FAILURE;
}
if (c->HasUser(u))
{
user->WriteNumeric(ERR_USERONCHANNEL, "%s %s :is already on channel", u->nick.c_str(), c->name.c_str());
return CMD_FAILURE;
}
FIRST_MOD_RESULT(OnUserPreInvite, MOD_RESULT, (user,u,c,timeout));
if (MOD_RESULT == MOD_RES_DENY)
{
return CMD_FAILURE;
}
else if (MOD_RESULT == MOD_RES_PASSTHRU)
{
if (IS_LOCAL(user))
{
unsigned int rank = c->GetPrefixValue(user);
if (rank < HALFOP_VALUE)
{
// Check whether halfop mode is available and phrase error message accordingly
ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You must be a channel %soperator",
c->name.c_str(), (mh && mh->name == "halfop" ? "half-" : ""));
return CMD_FAILURE;
}
}
}
if (IS_LOCAL(u))
{
Invitation::Create(c, IS_LOCAL(u), timeout);
u->WriteFrom(user,"INVITE %s :%s",u->nick.c_str(),c->name.c_str());
}
if (IS_LOCAL(user))
user->WriteNumeric(RPL_INVITING, "%s %s", u->nick.c_str(),c->name.c_str());
if (ServerInstance->Config->AnnounceInvites != ServerConfig::INVITE_ANNOUNCE_NONE)
{
char prefix;
switch (ServerInstance->Config->AnnounceInvites)
{
case ServerConfig::INVITE_ANNOUNCE_OPS:
{
prefix = '@';
break;
}
case ServerConfig::INVITE_ANNOUNCE_DYNAMIC:
{
PrefixMode* mh = ServerInstance->Modes->FindPrefixMode('h');
prefix = (mh && mh->name == "halfop" ? mh->GetPrefix() : '@');
//.........这里部分代码省略.........
示例14: Handle
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;
}