qstat.c
/* First packet for a QuakeWorld master server
 */
First packet for a QuakeWorld master server
First packet for a QuakeWorld master server
query_status_t send_qwmaster_request_packet(struct qserver *server)
{
	int rc = 0;
	server->next_player_info = NO_PLAYER_INFO;
	if (server->type->id == Q2_MASTER)
	{
		struct sockaddr_in addr;
		addr.sin_family = AF_INET;
		if (no_port_offset || server->flags &TF_NO_PORT_OFFSET)
		{
			addr.sin_port = htons(server->port);
		}
		else
		{
			addr.sin_port = htons((unsigned short)(server->port + server->type->port_offset));
		}
		addr.sin_addr.s_addr = server->ipaddr;
		memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero));
		rc = sendto(server->fd, server->type->master_packet, server->type->master_len, 0, (struct sockaddr*) &addr, sizeof(addr));
	}
	else
	{
		char *packet;
		int packet_len;
		char query_buf[4096] = { 0 };
		packet = server->type->master_packet;
		packet_len = server->type->master_len;
		if (server->type->id == HL_MASTER)
		{
			memcpy(server->type->master_packet + 1, server->master_query_tag, 3);
			if (server->query_arg)
			{
				packet_len = server->type->master_len;
				packet = build_hlmaster_packet(server, &packet_len);
			}
		}
		else if (server->type->flags &TF_MASTER_STEAM)
		{
			int tag_len = strlen(server->master_query_tag);
			if (tag_len < 9)
			{
				tag_len = 9;
				strcpy(server->master_query_tag, "0.0.0.0:0");
			}
			packet_len = 2+tag_len + 1;
			if (server->query_arg)
			{
				strcpy(server->type->master_packet + 2, server->master_query_tag);
				packet = build_hlmaster_packet(server, &packet_len);
			}
			else
			{
				*(packet + 1) = 0xff;
				memcpy(packet + 2, server->master_query_tag, tag_len);
				*(packet + packet_len) = 0x00;
				packet_len++;
			}
		}
		else if (server->type->flags &TF_QUERY_ARG)
		{
			char *master_protocol = server->query_arg;
			if (master_protocol == NULL)
			{
				master_protocol = server->type->master_protocol;
			}
			packet_len = sprintf(query_buf, server->type->master_packet,
				master_protocol ? master_protocol : "",
				server->type->master_query 	? server->type->master_query: ""
			);
			packet = query_buf;
		}
		rc = send(server->fd, packet, packet_len, 0);
	}
	if (rc == SOCKET_ERROR)
	{
		return send_error( server, rc );
	}
	if (server->retry1 == n_retries)
	{
		gettimeofday(&server->packet_time1, NULL);
		server->n_requests++;
	}
	else
	{
		server->n_retries++;
	}
	server->retry1--;
	server->n_packets++;
	return INPROGRESS;
}
query_status_t send_qwmaster_request_packet ( struct qserver * server ) { int rc = 0 ; server -> next_player_info = NO_PLAYER_INFO ; if ( server -> type -> id == Q2_MASTER ) { struct sockaddr_in addr ; addr . sin_family = AF_INET ; if ( no_port_offset || server -> flags & TF_NO_PORT_OFFSET ) { addr . sin_port = htons ( server -> port ) ; } else { addr . sin_port = htons ( ( unsigned short ) ( server -> port + server -> type -> port_offset ) ) ; } addr . sin_addr . s_addr = server -> ipaddr ; memset ( & ( addr . sin_zero ) , 0 , sizeof ( addr . sin_zero ) ) ; rc = sendto ( server -> fd , server -> type -> master_packet , server -> type -> master_len , 0 , ( struct sockaddr * ) & addr , sizeof ( addr ) ) ; } else { char * packet ; int packet_len ; char query_buf [ 4096 ] = { 0 } ; packet = server -> type -> master_packet ; packet_len = server -> type -> master_len ; if ( server -> type -> id == HL_MASTER ) { memcpy ( server -> type -> master_packet + 1 , server -> master_query_tag , 3 ) ; if ( server -> query_arg ) { packet_len = server -> type -> master_len ; packet = build_hlmaster_packet ( server , & packet_len ) ; } } else if ( server -> type -> flags & TF_MASTER_STEAM ) { int tag_len = strlen ( server -> master_query_tag ) ; if ( tag_len < 9 ) { tag_len = 9 ; strcpy ( server -> master_query_tag , " " ) ; } packet_len = 2 + tag_len + 1 ; if ( server -> query_arg ) { strcpy ( server -> type -> master_packet + 2 , server -> master_query_tag ) ; packet = build_hlmaster_packet ( server , & packet_len ) ; } else { * ( packet + 1 ) = 0xff ; memcpy ( packet + 2 , server -> master_query_tag , tag_len ) ; * ( packet + packet_len ) = 0x00 ; packet_len ++ ; } } else if ( server -> type -> flags & TF_QUERY_ARG ) { char * master_protocol = server -> query_arg ; if ( master_protocol == NULL ) { master_protocol = server -> type -> master_protocol ; } packet_len = sprintf ( query_buf , server -> type -> master_packet , master_protocol ? master_protocol : " " , server -> type -> master_query ? server -> type -> master_query : " " ) ; packet = query_buf ; } rc = send ( server -> fd , packet , packet_len , 0 ) ; } if ( rc == SOCKET_ERROR ) { return send_error ( server , rc ) ; } if ( server -> retry1 == n_retries ) { gettimeofday ( & server -> packet_time1 , NULL ) ; server -> n_requests ++ ; } else { server -> n_retries ++ ; } server -> retry1 -- ; server -> n_packets ++ ; return INPROGRESS ; }
First packet for a QuakeWorld master server
First packet for a QuakeWorld master server
// region // initial case // 1 byte packet id // 1 byte region // ip:port // 1 byte null // build_hlmaster_packet uses server->type->master_packet // as the basis so copy from server->master_query_tag // default region // filter null // fill in the master protocol details