Im working on processing incoming packets in an effort to cache the information sent for A2S_INFO queries, and to block A2C_PRINT packets completely. I havent gotten to the A2C_PRINT packets yet, but im assuming I can just check for packets starting with "\xFF\xFF\xFF\xFF\x6C" according to devicenull's page and block them using a recv() or recvfrom() hook.
Im stuck on the A2S_INFO spam though. I was going to try using ProcessConnectionlessPacket(netpacket_t *packet) but the netpacket_s struct isnt available to look at so I decided to detour ReplyInfo() instead. I have been working on it for 2 days trying to recreate the information and cache it for X seconds, and return it instead of letting CMaster::ReplyInfo() run everytime one comes in. (This function attempts to rebuild the information everytime its called, so getting flooded by A2S_INFO requests lags out the server) My code is crashing out when I issue the Net_SendPacket() and I can only assume I have pieced together the packet incorrectly. Anyways, heres my code in hopes someone spots something.
*Edit*
I have hardcoded some of the information as I have not found a way of getting the game version, type, or protocol via code. I used the information from
http://developer.valvesoftware.com/wiki/Server_Queries to build it.
Code:
unsigned char pData[6144];
bf_write buffer("SVC_ReplyInfo", &pData, 6144, -1);
void BuildReplyInfo()
{
buffer.Reset();
int passByte = 00;
const char *pGamePass = iserver->GetPassword();
if(pGamePass)
passByte = 01;
//http://www.ascii.cl/
//http://developer.valvesoftware.com/wiki/Server_Queries
buffer.WriteLong(-1);
buffer.WriteByte(73); //Type
buffer.WriteByte(14); //Protocol Version (0x07 is Steam Version, 0x30 is Goldsource)
buffer.WriteString(iserver->GetName()); //Hostname
buffer.WriteString(iserver->GetMapName()); //MapName
buffer.WriteString("tf");//pGameDir); //Game Directory
buffer.WriteString(server->GetGameDescription()); //Game Description
buffer.WriteShort(engine->GetAppID()); //AppID
buffer.WriteByte(iserver->GetClientCount()); //Number of Players
buffer.WriteByte(iserver->GetMaxClients()); //Max Players
buffer.WriteByte(iserver->GetNumFakeClients()); //Number of Bots
buffer.WriteByte(100); //"d" (100) for Dedicated
buffer.WriteByte(119); //Operating System "w" (119) for Windows "l" (108) for Linux
buffer.WriteByte(passByte); //Passworded or Not
buffer.WriteByte(01); //VAC Secured
buffer.WriteString("1.0.7.8"); //Game Version
}
DETOUR_DECL_MEMBER2(ReplyInfo, void *, void *, netaddr, void *, gameserver)
{
BuildReplyInfo();
int *x = (int *)(((unsigned char *)gameserver) + 8);
Net_SendPacket(NULL, *x, netaddr, buffer.m_pData, buffer.GetNumBytesWritten());
return NULL;
}