Beispiel #1
0
	CmdResult HandleServerTarget(User* source, const Params& parameters)
	{
		// If the source isn't allowed to mass message users then reject
		// the attempt to mass-message users.
		if (!source->HasPrivPermission("users/mass-message"))
			return CMD_FAILURE;

		// Extract the server glob match from the target parameter.
		std::string servername(parameters[0], 1);

		// Fire the pre-message events.
		MessageTarget msgtarget(&servername);
		CTCTags::TagMessageDetails msgdetails(parameters.GetTags());
		if (!FirePreEvents(source, msgtarget, msgdetails))
			return CMD_FAILURE;

		// If the current server name matches the server name glob then send
		// the message out to the local users.
		if (InspIRCd::Match(ServerInstance->Config->ServerName, servername))
		{
			CTCTags::TagMessage message(source, "$*", parameters.GetTags());
			const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
			for (UserManager::LocalList::const_iterator iter = list.begin(); iter != list.end(); ++iter)
			{
				LocalUser* luser = IS_LOCAL(*iter);

				// Don't send to unregistered users or the user who is the source.
				if (luser->registered != REG_ALL || luser == source)
					continue;

				// Don't send to exempt users.
				if (msgdetails.exemptions.count(luser))
					continue;

				// Send to users if they have the capability.
				if (cap.get(luser))
					luser->Send(msgevprov, message);
			}
		}

		// Fire the post-message event.
		return FirePostEvent(source, msgtarget, msgdetails);
	}
Beispiel #2
0
	CmdResult HandleChannelTarget(User* source, const Params& parameters, const char* target, PrefixMode* pm)
	{
		Channel* chan = ServerInstance->FindChan(target);
		if (!chan)
		{
			// The target channel does not exist.
			source->WriteNumeric(Numerics::NoSuchChannel(parameters[0]));
			return CMD_FAILURE;
		}

		if (IS_LOCAL(source))
		{
			if (chan->IsModeSet(noextmsgmode) && !chan->HasUser(source))
			{
				// The noextmsg mode is set and the source is not in the channel.
				source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (no external messages)");
				return CMD_FAILURE;
			}

			bool no_chan_priv = chan->GetPrefixValue(source) < VOICE_VALUE;
			if (no_chan_priv && chan->IsModeSet(moderatedmode))
			{
				// The moderated mode is set and the source has no status rank.
				source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (+m)");
				return CMD_FAILURE;
			}

			if (no_chan_priv && ServerInstance->Config->RestrictBannedUsers != ServerConfig::BUT_NORMAL && chan->IsBanned(source))
			{
				// The source is banned in the channel and restrictbannedusers is enabled.
				if (ServerInstance->Config->RestrictBannedUsers == ServerConfig::BUT_RESTRICT_NOTIFY)
					source->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (you're banned)");
				return CMD_FAILURE;
			}
		}

		// Fire the pre-message events.
		MessageTarget msgtarget(chan, pm ? pm->GetPrefix() : 0);
		CTCTags::TagMessageDetails msgdetails(parameters.GetTags());
		if (!FirePreEvents(source, msgtarget, msgdetails))
			return CMD_FAILURE;

		unsigned int minrank = pm ? pm->GetPrefixRank() : 0;
		CTCTags::TagMessage message(source, chan, parameters.GetTags());
		const Channel::MemberMap& userlist = chan->GetUsers();
		for (Channel::MemberMap::const_iterator iter = userlist.begin(); iter != userlist.end(); ++iter)
		{
			LocalUser* luser = IS_LOCAL(iter->first);

			// Don't send to remote users or the user who is the source. 
			if (!luser || luser == source)
				continue;

			// Don't send to unprivileged or exempt users.
			if (iter->second->getRank() < minrank || msgdetails.exemptions.count(luser))
				continue;

			// Send to users if they have the capability.
			if (cap.get(luser))
				luser->Send(msgevprov, message);
		}
		return FirePostEvent(source, msgtarget, msgdetails);
	}