Beispiel #1
0
void ModuleSpanningTree::OnMode(User* source, User* u, Channel* c, const Modes::ChangeList& modes, ModeParser::ModeProcessFlag processflags)
{
	if (processflags & ModeParser::MODE_LOCALONLY)
		return;

	if (u)
	{
		if (u->registered != REG_ALL)
			return;

		CmdBuilder params(source, "MODE");
		params.push(u->uuid);
		params.push(ClientProtocol::Messages::Mode::ToModeLetters(modes));
		params.push_raw(Translate::ModeChangeListToParams(modes.getlist()));
		params.Broadcast();
	}
	else
	{
		CmdBuilder params(source, "FMODE");
		params.push(c->name);
		params.push_int(c->age);
		params.push(ClientProtocol::Messages::Mode::ToModeLetters(modes));
		params.push_raw(Translate::ModeChangeListToParams(modes.getlist()));
		params.Broadcast();
	}
}
Beispiel #2
0
unsigned int ModeParser::ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags, unsigned int beginindex)
{
	LastParse.clear();
	LastChangeList.clear();

	unsigned int modes_processed = 0;
	std::string output_mode;
	std::string output_parameters;

	char output_pm = '\0'; // current output state, '+' or '-'
	Modes::ChangeList::List& list = changelist.getlist();
	for (Modes::ChangeList::List::iterator i = list.begin()+beginindex; i != list.end(); ++i)
	{
		modes_processed++;

		Modes::Change& item = *i;
		ModeHandler* mh = item.mh;

		// If the mode is supposed to have a parameter then we first take a look at item.param
		// and, if we were asked to, also handle mode merges now
		if (mh->GetNumParams(item.adding))
		{
			// Skip the mode if the parameter does not pass basic validation
			if (!IsModeParamValid(user, targetchannel, targetuser, item))
				continue;

			// If this is a merge and we won we don't apply this mode
			if ((flags & MODE_MERGE) && (!ShouldApplyMergedMode(targetchannel, item)))
				continue;
		}

		ModeAction ma = TryMode(user, targetuser, targetchannel, item, (!(flags & MODE_CHECKACCESS)));

		if (ma != MODEACTION_ALLOW)
			continue;

		char needed_pm = item.adding ? '+' : '-';
		if (needed_pm != output_pm)
		{
			output_pm = needed_pm;
			output_mode.append(1, output_pm);
		}
		output_mode.push_back(mh->GetModeChar());

		if (!item.param.empty())
		{
			output_parameters.push_back(' ');
			output_parameters.append(item.param);
		}
		LastChangeList.push(mh, item.adding, item.param);

		if ((output_mode.length() + output_parameters.length() > 450)
				|| (output_mode.length() > 100)
				|| (LastChangeList.size() >= ServerInstance->Config->Limits.MaxModes))
		{
			/* mode sequence is getting too long */
			break;
		}
	}

	if (!output_mode.empty())
	{
		LastParse = targetchannel ? targetchannel->name : targetuser->nick;
		LastParse.append(" ");
		LastParse.append(output_mode);
		LastParse.append(output_parameters);

		if (targetchannel)
			targetchannel->WriteChannel(user, "MODE " + LastParse);
		else
			targetuser->WriteFrom(user, "MODE " + LastParse);

		FOREACH_MOD(OnMode, (user, targetuser, targetchannel, LastChangeList, flags, output_mode));
	}

	return modes_processed;
}