Пример #1
0
static std::string BuildModeList(ModeType type)
{
	std::vector<std::string> modes;
	for(char c='A'; c <= 'z'; c++)
	{
		ModeHandler* mh = ServerInstance->Modes->FindMode(c, type);
		if (mh)
		{
			std::string mdesc = mh->name;
			mdesc.push_back('=');
			if (mh->GetPrefix())
				mdesc.push_back(mh->GetPrefix());
			if (mh->GetModeChar())
				mdesc.push_back(mh->GetModeChar());
			modes.push_back(mdesc);
		}
	}
	sort(modes.begin(), modes.end());
	irc::stringjoiner line(" ", modes, 0, modes.size() - 1);
	return line.GetJoined();
}
Пример #2
0
/** Handle /INVITE
 */
CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, User *user)
{
	ModResult MOD_RESULT;

	if (parameters.size() == 2 || parameters.size() == 3)
	{
		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[1]);
			else
				timeout = ConvToInt(parameters[2]);
		}

		if ((!c) || (!u) || (u->registered != REG_ALL))
		{
			user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), c ? parameters[0].c_str() : parameters[1].c_str());
			return CMD_FAILURE;
		}

		if ((IS_LOCAL(user)) && (!c->HasUser(user)))
		{
			user->WriteNumeric(ERR_NOTONCHANNEL, "%s %s :You're not on that channel!",user->nick.c_str(), c->name.c_str());
			return CMD_FAILURE;
		}

		if (c->HasUser(u))
		{
			user->WriteNumeric(ERR_USERONCHANNEL, "%s %s %s :is already on channel",user->nick.c_str(),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 %s :You must be a channel %soperator",
						user->nick.c_str(), 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 %s",user->nick.c_str(),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() : '@');
					break;
				}
				default:
				{
					prefix = 0;
					break;
				}
			}
			c->WriteAllExceptSender(user, true, prefix, "NOTICE %s :*** %s invited %s into the channel", c->name.c_str(), user->nick.c_str(), u->nick.c_str());
		}
		FOREACH_MOD(OnUserInvite, (user,u,c,timeout));
	}
	else if (IS_LOCAL(user))
	{
		// pinched from ircu - invite with not enough parameters shows channels
		// youve been invited to but haven't joined yet.
		InviteList& il = IS_LOCAL(user)->GetInviteList();
		for (InviteList::const_iterator i = il.begin(); i != il.end(); ++i)
		{
			user->WriteNumeric(RPL_INVITELIST, "%s :%s",user->nick.c_str(), (*i)->chan->name.c_str());
		}
		user->WriteNumeric(RPL_ENDOFINVITELIST, "%s :End of INVITE list",user->nick.c_str());
	}
	return CMD_SUCCESS;
}
Пример #3
0
	CmdResult Handle(const std::vector<std::string> &parameters, 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;
		}

		unsigned int prefixrank;
		char prefixchar;
		std::string pattern = parameters.size() > 2 ? parameters[2] : "*";
		ListModeBase* lm;
		ListModeBase::ModeList* ml;
		irc::modestacker modestack(false);

		if (!mh->IsListMode())
		{
			if (chan->IsModeSet(mh))
				modestack.Push(modeletter);
		}
		else if (((prefixrank = mh->GetPrefixRank()) && (prefixchar = mh->GetPrefix())))
		{
			// As user prefix modes don't have a GetList() method, let's iterate through the channel's users.
			for (UserMembIter it = chan->userlist.begin(); it != chan->userlist.end(); ++it)
			{
				if (!InspIRCd::Match(it->first->nick, pattern))
					continue;
				if (((strchr(chan->GetAllPrefixChars(user), prefixchar)) != NULL) && !(it->first == user && prefixrank > VOICE_VALUE))
					modestack.Push(modeletter, it->first->nick);
			}
		}
		else if (((lm = dynamic_cast<ListModeBase*>(mh)) != NULL) && ((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
		{
			user->WriteNotice("Could not remove channel mode " + ConvToStr(modeletter));
			return CMD_FAILURE;
		}

		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;
	}