示例#1
0
void wxVideoTerminal::Consume(wxChar chr)
{
	switch (m_stream_state)
	{
	case STATE_STREAM:
		TryStream(chr);
		break;
	case STATE_ESCAPE:
		TryEscapeSequence(chr);
		break;
	case STATE_ESCAPE_LB:
	case STATE_XTERM_HACK:
		TryEscapeParameters(chr);
		break;
	case STATE_MODE:
		TryMode(chr);
		break;
	case STATE_CHARSET_G0:
		TryCharsetG0(chr);
		break;
	case STATE_CHARSET_G1:
		TryCharsetG1(chr);
		break;
	}
}
示例#2
0
文件: mode.cpp 项目: Merbo/inspircd
void ModeParser::Process(const std::vector<std::string>& parameters, User* user, ModeProcessFlag flags)
{
	std::string target = parameters[0];
	Channel* targetchannel = ServerInstance->FindChan(target);
	User* targetuser  = ServerInstance->FindNick(target);
	ModeType type = targetchannel ? MODETYPE_CHANNEL : MODETYPE_USER;

	LastParse.clear();
	LastParseParams.clear();
	LastParseTranslate.clear();

	if ((!targetchannel) && ((!targetuser) || (IS_SERVER(targetuser))))
	{
		user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(),target.c_str());
		return;
	}
	if (parameters.size() == 1)
	{
		this->DisplayCurrentModes(user, targetuser, targetchannel, target.c_str());
		return;
	}

	ModResult MOD_RESULT;
	FIRST_MOD_RESULT(OnPreMode, MOD_RESULT, (user, targetuser, targetchannel, parameters));

	bool SkipAccessChecks = false;

	if (!IS_LOCAL(user) || ServerInstance->ULine(user->server) || MOD_RESULT == MOD_RES_ALLOW)
		SkipAccessChecks = true;
	else if (MOD_RESULT == MOD_RES_DENY)
		return;

	if (targetuser && !SkipAccessChecks && user != targetuser)
	{
		user->WriteNumeric(ERR_USERSDONTMATCH, "%s :Can't change mode for other users", user->nick.c_str());
		return;
	}

	std::string mode_sequence = parameters[1];

	std::string output_mode;
	std::ostringstream output_parameters;
	LastParseParams.push_back(output_mode);
	LastParseTranslate.push_back(TR_TEXT);

	bool adding = true;
	char output_pm = '\0'; // current output state, '+' or '-'
	unsigned int param_at = 2;

	for (std::string::const_iterator letter = mode_sequence.begin(); letter != mode_sequence.end(); letter++)
	{
		unsigned char modechar = *letter;
		if (modechar == '+' || modechar == '-')
		{
			adding = (modechar == '+');
			continue;
		}

		ModeHandler *mh = this->FindMode(modechar, type);
		if (!mh)
		{
			/* No mode handler? Unknown mode character then. */
			user->WriteServ("%d %s %c :is unknown mode char to me", type == MODETYPE_CHANNEL ? 472 : 501, user->nick.c_str(), modechar);
			continue;
		}

		std::string parameter;
		int pcnt = mh->GetNumParams(adding);
		if (pcnt && param_at == parameters.size())
		{
			/* No parameter, continue to the next mode */
			mh->OnParameterMissing(user, targetuser, targetchannel);
			continue;
		}
		else if (pcnt)
		{
			parameter = parameters[param_at++];
			/* Make sure the user isn't trying to slip in an invalid parameter */
			if ((parameter.find(':') == 0) || (parameter.rfind(' ') != std::string::npos))
				continue;
			if ((flags & MODE_MERGE) && targetchannel && targetchannel->IsModeSet(mh) && !mh->IsListMode())
			{
				std::string ours = targetchannel->GetModeParameter(mh);
				if (!mh->ResolveModeConflict(parameter, ours, targetchannel))
					/* we won the mode merge, don't apply this mode */
					continue;
			}
		}

		ModeAction ma = TryMode(user, targetuser, targetchannel, adding, modechar, parameter, SkipAccessChecks);

		if (ma != MODEACTION_ALLOW)
			continue;

		char needed_pm = adding ? '+' : '-';
		if (needed_pm != output_pm)
		{
			output_pm = needed_pm;
			output_mode.append(1, output_pm);
		}
		output_mode.append(1, modechar);

		if (pcnt)
		{
			output_parameters << " " << parameter;
			LastParseParams.push_back(parameter);
			LastParseTranslate.push_back(mh->GetTranslateType());
		}

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

	LastParseParams[0] = output_mode;

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

		if (!(flags & MODE_LOCALONLY))
			ServerInstance->PI->SendMode(user, targetuser, targetchannel, LastParseParams, LastParseTranslate);

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

		FOREACH_MOD(OnMode, (user, targetuser, targetchannel, LastParseParams, LastParseTranslate));
	}
	else if (targetchannel && parameters.size() == 2)
	{
		/* Special case for displaying the list for listmodes,
		 * e.g. MODE #chan b, or MODE #chan +b without a parameter
		 */
		this->DisplayListModes(user, targetchannel, mode_sequence);
	}
}
示例#3
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;
}