Example #1
0
void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
{
	/* Server origin */
	if (user == NULL)
		return;

	if (target_type == TYPE_USER)
	{
		// route private messages which are targetted at clients only to the server
		// which needs to receive them
		User* d = (User*)dest;
		if ((d->GetFd() < 0) && (IS_LOCAL(user)))
		{
			std::deque<std::string> params;
			params.clear();
			params.push_back(d->uuid);
			params.push_back(":"+text);
			Utils->DoOneToOne(user->uuid,"PRIVMSG",params,d->server);
		}
	}
	else if (target_type == TYPE_CHANNEL)
	{
		if (IS_LOCAL(user))
		{
			Channel *c = (Channel*)dest;
			if (c)
			{
				std::string cname = c->name;
				if (status)
					cname = status + cname;
				TreeServerList list;
				Utils->GetListOfServersForChannel(c,list,status,exempt_list);
				for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
				{
					TreeSocket* Sock = i->second->GetSocket();
					if (Sock)
						Sock->WriteLine(":"+std::string(user->uuid)+" PRIVMSG "+cname+" :"+text);
				}
			}
		}
	}
	else if (target_type == TYPE_SERVER)
	{
		if (IS_LOCAL(user))
		{
			char* target = (char*)dest;
			std::deque<std::string> par;
			par.push_back(target);
			par.push_back(":"+text);
			Utils->DoOneToMany(user->uuid,"PRIVMSG",par);
		}
	}
}
Example #2
0
/* returns a list of DIRECT servernames for a specific channel */
void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeServerList &list, char status, const CUList &exempt_list)
{
	unsigned int minrank = 0;
	if (status)
	{
		ModeHandler* 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 = this->BestRouteTo(i->first->server);
			if (best)
				list.insert(best);
		}
	}
	return;
}
Example #3
0
void ModuleSpanningTree::OnUserNotice(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
{
	if (target_type == TYPE_USER)
	{
		userrec* d = (userrec*)dest;
		if ((d->GetFd() < 0) && (IS_LOCAL(user)))
		{
			std::deque<std::string> params;
			params.clear();
			params.push_back(d->nick);
			params.push_back(":"+text);
			Utils->DoOneToOne(user->nick,"NOTICE",params,d->server);
		}
	}
	else if (target_type == TYPE_CHANNEL)
	{
		if (IS_LOCAL(user))
		{
			chanrec *c = (chanrec*)dest;
			if (c)
			{
				std::string cname = c->name;
				if (status)
					cname = status + cname;
				TreeServerList list;
				Utils->GetListOfServersForChannel(c,list,status,exempt_list);
				for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
				{
					TreeSocket* Sock = i->second->GetSocket();
					if (Sock)
						Sock->WriteLine(":"+std::string(user->nick)+" NOTICE "+cname+" :"+text);
				}
			}
		}
	}
	else if (target_type == TYPE_SERVER)
	{
		if (IS_LOCAL(user))
		{
			char* target = (char*)dest;
			std::deque<std::string> par;
			par.push_back(target);
			par.push_back(":"+text);
			Utils->DoOneToMany(user->nick,"NOTICE",par);
		}
	}
}
Example #4
0
void SpanningTreeUtilities::SendChannelMessage(const std::string& prefix, Channel* target, const std::string &text, char status, const CUList& exempt_list, const char* message_type)
{
	std::string raw(":");
	raw.append(prefix).append(1, ' ').append(message_type).push_back(' ');
	if (status)
		raw.push_back(status);
	raw.append(target->name).append(" :").append(text);

	TreeServerList list;
	this->GetListOfServersForChannel(target, list, status, exempt_list);
	for (TreeServerList::iterator i = list.begin(); i != list.end(); ++i)
	{
		TreeSocket* Sock = (*i)->GetSocket();
		if (Sock)
			Sock->WriteLine(raw);
	}
}
Example #5
0
void SpanningTreeUtilities::RouteCommand(TreeServer* origin, Command* thiscmd, const parameterlist& parameters, User* user)
{
	const std::string& command = thiscmd->name;
	RouteDescriptor routing = thiscmd->GetRouting(user, parameters);

	std::string sent_cmd = command;
	parameterlist params;

	if (routing.type == ROUTE_TYPE_LOCALONLY)
	{
		return;
	}
	else if (routing.type == ROUTE_TYPE_OPT_BCAST)
	{
		params.push_back("*");
		params.push_back(command);
		sent_cmd = "ENCAP";
	}
	else if (routing.type == ROUTE_TYPE_OPT_UCAST)
	{
		TreeServer* sdest = FindServer(routing.serverdest);
		if (!sdest)
		{
			ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Trying to route ENCAP to nonexistant server %s",
				routing.serverdest.c_str());
			return;
		}
		params.push_back(sdest->GetID());
		params.push_back(command);
		sent_cmd = "ENCAP";
	}
	else
	{
		Module* srcmodule = thiscmd->creator;
		Version ver = srcmodule->GetVersion();

		if (!(ver.Flags & (VF_COMMON | VF_CORE)) && srcmodule != Creator)
		{
			ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Routed command %s from non-VF_COMMON module %s",
				command.c_str(), srcmodule->ModuleSourceFile.c_str());
			return;
		}
	}

	std::string output_text = CommandParser::TranslateUIDs(thiscmd->translation, parameters, true, thiscmd);

	params.push_back(output_text);

	if (routing.type == ROUTE_TYPE_MESSAGE)
	{
		char pfx = 0;
		std::string dest = routing.serverdest;
		if (ServerInstance->Modes->FindPrefix(dest[0]))
		{
			pfx = dest[0];
			dest = dest.substr(1);
		}
		if (dest[0] == '#')
		{
			Channel* c = ServerInstance->FindChan(dest);
			if (!c)
				return;
			TreeServerList list;
			// TODO OnBuildExemptList hook was here
			GetListOfServersForChannel(c,list,pfx, CUList());
			std::string data = ":" + user->uuid + " " + sent_cmd;
			for (unsigned int x = 0; x < params.size(); x++)
				data += " " + params[x];
			for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
			{
				TreeSocket* Sock = (*i)->GetSocket();
				if (origin && origin->GetSocket() == Sock)
					continue;
				if (Sock)
					Sock->WriteLine(data);
			}
		}
		else if (dest[0] == '$')
		{
			if (origin)
				DoOneToAllButSender(user->uuid, sent_cmd, params, origin->GetName());
			else
				DoOneToMany(user->uuid, sent_cmd, params);
		}
		else
		{
			// user target?
			User* d = ServerInstance->FindNick(dest);
			if (!d)
				return;
			TreeServer* tsd = BestRouteTo(d->server);
			if (tsd == origin)
				// huh? no routing stuff around in a circle, please.
				return;
			DoOneToOne(user->uuid, sent_cmd, params, d->server);
		}
	}
	else if (routing.type == ROUTE_TYPE_BROADCAST || routing.type == ROUTE_TYPE_OPT_BCAST)
	{
		if (origin)
			DoOneToAllButSender(user->uuid, sent_cmd, params, origin->GetName());
		else
			DoOneToMany(user->uuid, sent_cmd, params);
	}
	else if (routing.type == ROUTE_TYPE_UNICAST || routing.type == ROUTE_TYPE_OPT_UCAST)
	{
		if (origin && routing.serverdest == origin->GetName())
			return;
		DoOneToOne(user->uuid, sent_cmd, params, routing.serverdest);
	}
}