Пример #1
0
bool TreeSocket::PreProcessOldProtocolMessage(User*& who, std::string& cmd, std::vector<std::string>& params)
{
	if ((cmd == "METADATA") && (params.size() >= 3))
	{
		// :20D METADATA #channel extname :extdata
		return InsertCurrentChannelTS(params);
	}
	else if ((cmd == "FTOPIC") && (params.size() >= 4))
	{
		// :20D FTOPIC #channel 100 Attila :topic text
		return InsertCurrentChannelTS(params);
	}
	else if ((cmd == "PING") || (cmd == "PONG"))
	{
		if (params.size() == 1)
		{
			// If it's a PING with 1 parameter, reply with a PONG now, if it's a PONG with 1 parameter (weird), do nothing
			if (cmd[1] == 'I')
				this->WriteData(":" + ServerInstance->Config->GetSID() + " PONG " + params[0] + newline);

			// Don't process this message further
			return false;
		}

		// :20D PING 20D 22D
		// :20D PONG 20D 22D
		// Drop the first parameter
		params.erase(params.begin());

		// If the target is a server name, translate it to a SID
		if (!InspIRCd::IsSID(params[0]))
		{
			TreeServer* server = Utils->FindServer(params[0]);
			if (!server)
			{
				// We've no idea what this is, log and stop processing
				ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Received a " + cmd + " with an unknown target: \"" + params[0] + "\", command dropped");
				return false;
			}

			params[0] = server->GetID();
		}
	}

	return true; // Passthru
}
Пример #2
0
bool TreeSocket::PreProcessOldProtocolMessage(User*& who, std::string& cmd, std::vector<std::string>& params)
{
	if ((cmd == "METADATA") && (params.size() >= 3) && (params[0][0] == '#'))
	{
		// :20D METADATA #channel extname :extdata
		return InsertCurrentChannelTS(params);
	}
	else if ((cmd == "FTOPIC") && (params.size() >= 4))
	{
		// :20D FTOPIC #channel 100 Attila :topic text
		return InsertCurrentChannelTS(params);
	}
	else if ((cmd == "PING") || (cmd == "PONG"))
	{
		if (params.size() == 1)
		{
			// If it's a PING with 1 parameter, reply with a PONG now, if it's a PONG with 1 parameter (weird), do nothing
			if (cmd[1] == 'I')
				this->WriteData(":" + ServerInstance->Config->GetSID() + " PONG " + params[0] + newline);

			// Don't process this message further
			return false;
		}

		// :20D PING 20D 22D
		// :20D PONG 20D 22D
		// Drop the first parameter
		params.erase(params.begin());

		// If the target is a server name, translate it to a SID
		if (!InspIRCd::IsSID(params[0]))
		{
			TreeServer* server = Utils->FindServer(params[0]);
			if (!server)
			{
				// We've no idea what this is, log and stop processing
				ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Received a " + cmd + " with an unknown target: \"" + params[0] + "\", command dropped");
				return false;
			}

			params[0] = server->GetID();
		}
	}
	else if ((cmd == "GLINE") || (cmd == "KLINE") || (cmd == "ELINE") || (cmd == "ZLINE") || (cmd == "QLINE"))
	{
		// Fix undocumented protocol usage: translate GLINE, ZLINE, etc. into ADDLINE or DELLINE
		if ((params.size() != 1) && (params.size() != 3))
			return false;

		parameterlist p;
		p.push_back(cmd.substr(0, 1));
		p.push_back(params[0]);

		if (params.size() == 3)
		{
			cmd = "ADDLINE";
			p.push_back(who->nick);
			p.push_back(ConvToStr(ServerInstance->Time()));
			p.push_back(ConvToStr(InspIRCd::Duration(params[1])));
			p.push_back(params[2]);
		}
		else
			cmd = "DELLINE";

		params.swap(p);
	}
	else if (cmd == "SVSMODE")
	{
		cmd = "MODE";
	}
	else if (cmd == "OPERQUIT")
	{
		// Translate OPERQUIT into METADATA
		if (params.empty())
			return false;

		cmd = "METADATA";
		params.insert(params.begin(), who->uuid);
		params.insert(params.begin()+1, "operquit");
		who = MyRoot->ServerUser;
	}
	else if ((cmd == "TOPIC") && (params.size() >= 2))
	{
		// :20DAAAAAC TOPIC #chan :new topic
		cmd = "FTOPIC";
		if (!InsertCurrentChannelTS(params))
			return false;

		params.insert(params.begin()+2, ConvToStr(ServerInstance->Time()));
	}
	else if (cmd == "MODENOTICE")
	{
		// MODENOTICE is always supported by 2.0 but it's optional in 2.2.
		params.insert(params.begin(), "*");
		params.insert(params.begin()+1, cmd);
		cmd = "ENCAP";
	}
	else if (cmd == "RULES")
	{
		return false;
	}
	else if (cmd == "INVITE")
	{
		// :20D INVITE 22DAAABBB #chan
		// :20D INVITE 22DAAABBB #chan 123456789
		// Insert channel timestamp after the channel name; the 3rd parameter, if there, is the invite expiration time
		return InsertCurrentChannelTS(params, 1, 2);
	}
	else if (cmd == "VERSION")
	{
		// :20D VERSION :InspIRCd-2.0
		// change to
		// :20D SINFO version :InspIRCd-2.0
		cmd = "SINFO";
		params.insert(params.begin(), "version");
	}
	else if (cmd == "JOIN")
	{
		// 2.0 allows and forwards legacy JOINs but we don't, so translate them to FJOINs before processing
		if ((params.size() != 1) || (IS_SERVER(who)))
			return false; // Huh?

		cmd = "FJOIN";
		Channel* chan = ServerInstance->FindChan(params[0]);
		params.push_back(ConvToStr(chan ? chan->age : ServerInstance->Time()));
		params.push_back("+");
		params.push_back(",");
		params.back().append(who->uuid);
		who = TreeServer::Get(who)->ServerUser;
	}
	else if ((cmd == "FMODE") && (params.size() >= 2))
	{
		// Translate user mode changes with timestamp to MODE
		if (params[0][0] != '#')
		{
			User* user = ServerInstance->FindUUID(params[0]);
			if (!user)
				return false;

			// Emulate the old nonsensical behavior
			if (user->age < ServerCommand::ExtractTS(params[1]))
				return false;

			cmd = "MODE";
			params.erase(params.begin()+1);
		}
	}

	return true; // Passthru
}