void GetServerInfo(server_data *serv)
{
    socket_t newsocket;
    struct sockaddr_storage server;
    int ret;
    char answer[5000];
    fd_set fd;
    struct timeval tv;

    // so we have a socket
    newsocket = UDP_OpenSocket(PORT_ANY);
    NetadrToSockadr (&(serv->address), &server);

    // send status request
    ret = sendto (newsocket, senddata, sizeof(senddata), 0,
                  (struct sockaddr *)&server, sizeof(server) );

    if (ret == -1)
        return;

    //fd.fd_count = 1;
    //fd.fd_array[0] = newsocket;
    FD_ZERO(&fd);
    FD_SET(newsocket, &fd);
    tv.tv_sec = 0;
    tv.tv_usec = 1000 * 1.5 * sb_infotimeout.value; // multiply timeout by 1.5
    ret = select(newsocket+1, &fd, NULL, NULL, &tv);

    // get answer
    if (ret > 0)
        ret = recvfrom (newsocket, answer, 5000, 0, NULL, NULL);

    if (ret > 0  &&  ret < 5000)
    {
        answer[ret] = 0;
        server_during_update = 1;
        Reset_Server(serv);
        Parse_Serverinfo(serv, answer);
        server_during_update = 0;
    }
    closesocket(newsocket);
}
DWORD WINAPI GetServerInfosProc(void * lpParameter)
{
    infohost *hosts;   // 0 if not sent yet, -1 if data read
    double interval, lastsenttime;

    socket_t newsocket;
    struct sockaddr_storage dest;
    int ret, i;
    fd_set fd;
    struct timeval timeout;

    if (abort_ping)
        return 0;

    // so we have a socket
    newsocket = UDP_OpenSocket(PORT_ANY);

    hosts = (infohost *) Q_malloc (serversn * sizeof(infohost));
    for (i=0; i < serversn; i++)
    {
        hosts[i].phase = 0;
        hosts[i].lastsenttime = -1000;
        Reset_Server(servers[i]);

        // do not update dead servers
		if (servers[i]->ping < 0) {
            hosts[i].phase = -1;//(int)sb_inforetries.value;
		}
		// do not update too distant servers
		else if (sb_hidehighping.integer && servers[i]->ping > sb_pinglimit.integer) {
			hosts[i].phase = -1;
		}
    }

    interval = (1000.0 / sb_infospersec.value) / 1000;
    lastsenttime = Sys_DoubleTime() - interval;
    timeout.tv_sec = 0;
    timeout.tv_usec = (long)(interval * 1000.0 * 1000.0 / 2);

    ping_pos = 0;

    while (1  &&  !abort_ping)
    {
        int index = -1;
        double time = Sys_DoubleTime();

        // if it is time to send next request
        if (time > lastsenttime + interval)
        {
            int finished = 0;
            int to_ask = 0;
            int phase = (int)(sb_inforetries.value);

            // find next server to ask
            for (i=0; i < serversn; i++)
            {
                if (hosts[i].phase < phase  &&  hosts[i].phase >= 0  &&
                    time > hosts[i].lastsenttime + (sb_infotimeout.value / 1000))
                {
                    index = i;
                    phase = hosts[i].phase;
                }

                if (hosts[i].phase >= (int)sb_inforetries.value)
                    finished++;
                else
                    if (hosts[i].phase >= 0)
                        to_ask++;
            }
            //ping_pos = finished / (double)serversn;
            ping_pos = (finished+to_ask <= 0) ? 0 :
            finished / (double)(finished+to_ask);
        }

        // check if we should finish
        if (index < 0)
            if (time > lastsenttime + 1.2 * (sb_infotimeout.value / 1000))
                break;

        // send status request
        if (index >= 0)
        {
            hosts[index].phase ++;
            hosts[index].lastsenttime = time;
            lastsenttime = time;

            NetadrToSockadr (&(servers[index]->address), &dest);

            ret = sendto (newsocket, senddata, sizeof(senddata), 0,
                          (struct sockaddr *)&dest, sizeof(*(struct sockaddr *)&dest));
            if(ret < 0)
            {
                Com_DPrintf("sendto() gave errno = %d : %s\n", errno, strerror(errno));
            }
            if (ret == -1)
                ;//return;

            // requests_sent++;
            // ping_pos = requests_total <= 0 ? 0 : requests_sent / (double)requests_total;
        }

        // check if answer arrived and decode it
        //fd.fd_count = 1;
        //fd.fd_array[0] = newsocket;
        FD_ZERO(&fd);
        FD_SET(newsocket, &fd);

        ret = select(newsocket+1, &fd, NULL, NULL, &timeout);
        if (ret < 1)
        {
            Com_DPrintf("select() gave errno = %d : %s\n", errno, strerror(errno));
        }

        if (FD_ISSET(newsocket, &fd))
        {
            struct sockaddr_storage hostaddr;
            netadr_t from;
            int i;
            char answer[5000];
            answer[0] = 0;

            i = sizeof(hostaddr);
            ret = recvfrom (newsocket, answer, 5000, 0, (struct sockaddr *)&hostaddr, (socklen_t *)&i);
            answer[max(0, min(ret, 4999))] = 0;

            if (ret > 0)
            {
                SockadrToNetadr (&hostaddr, &from);

                for (i=0; i < serversn; i++)
                    if (from.ip[0] == servers[i]->address.ip[0] &&
                        from.ip[1] == servers[i]->address.ip[1] &&
                        from.ip[2] == servers[i]->address.ip[2] &&
                        from.ip[3] == servers[i]->address.ip[3] &&
                        from.port == servers[i]->address.port)
                    {
                        hosts[i].phase = (int)sb_inforetries.value;
                        Parse_Serverinfo(servers[i], answer);
                        break;
                    }
            }
        }
    }

    // reset pings to 999 if server didn't answer
    for (i=0; i < serversn; i++)
        if (servers[i]->keysn <= 0)
            SetPing(servers[i], -1);

    closesocket(newsocket);
    Q_free(hosts);

    return 0;
}
void Split_Incoming(packet_struct_t *packet, bool record)
{
	int old_readcount = 0;
	extern int msg_readcount;
	byte *dptr;
	int type;
	extern message_t net_message;
	unsigned sequence, sequence_ack;
	unsigned reliable_ack, reliable_message;

	int i = 0;
	
	net_message.cursize = packet->payload_size;
	net_message.data = packet->payload;

	MSG_BeginReading();

	if (record)
	{
		sequence = MSG_ReadLong();
		sequence_ack = MSG_ReadLong();
		//MSG_ReadShort();


		reliable_message = sequence >> 31;
		reliable_ack = sequence_ack >> 31;

		sequence &= ~(1 << 31);
		sequence_ack &= ~(1 << 31);

		packet->sequence              = sequence;
		packet->sequence_ack          = sequence_ack;

		packet->reliable_message      = reliable_message;
		packet->reliable_ack          = reliable_ack;

		
		//printf("TEST !%i\n",(unsigned int *)net_message.data[0]);
		//printf("%i %i %i %i\n", sequence, reliable_message, sequence_ack, reliable_ack);
		//printf("%i %i %i %i\n", packet->sequence, packet->reliable_message, packet->sequence_ack, packet->reliable_ack);
		//printf ("%i %i %i %i\n",(int)((char *)packet->sequence),(int)((char *)packet->sequence)+1,(int)((char *)packet->sequence)+2,(int)((char *)packet->sequence)+3);

		

		Dprintf(1,"IN  --> s=%i(%i) a=%i(%i) %i\n",packet->sequence,packet->reliable_message,packet->sequence_ack,\
		packet->reliable_ack, net_message.cursize);


	}

	while (1)
	{
		old_readcount = msg_readcount;
		type = MSG_ReadByte();
		if (type == -1)
			break;

		i++;
		switch (type)
		{

			case svc_serverdata:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Serverdata();
				break;


			case svc_updatestat:
				Dprintf(1,"%s\n", svc_strings[type]);
				Updatestat();
				break;


			case svc_updatestatlong:
				Dprintf(1,"%s\n", svc_strings[type]);
				Updatestat_Long();
				break;


			case svc_playerinfo:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Playerinfo();
				break;


			case svc_packetentities:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Packetentities(false);
				break;


			case svc_serverinfo:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Serverinfo();
				break;

			case svc_cdtrack:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadByte();
				break;

			case svc_stufftext:
				Dprintf(1,"%s\n", svc_strings[type]);
				Dprintf(1,"%s", MSG_ReadString());
				break;

			case svc_updatefrags:
				Dprintf(1,"%s\n", svc_strings[type]);
				//players[MSG_ReadByte()].frags = MSG_ReadShort();
				MSG_ReadByte();
				MSG_ReadShort();

				break;

			case svc_print:
				Dprintf(1,"%s\n", svc_strings[type]);
				Dprintf(1,"LEVEL %i :  ",MSG_ReadByte());
				Dprintf(1,"%s\n",MSG_ReadString());
				break;

			case svc_spawnstaticsound:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadCoord();
				MSG_ReadCoord();
				MSG_ReadCoord();
				MSG_ReadByte();
				MSG_ReadByte();
				MSG_ReadByte();

				break;

			case svc_updateping:
				Dprintf(1,"%s\n", svc_strings[type]);
				players[MSG_ReadByte()].ping = MSG_ReadShort();
				break;

			case svc_updatepl:
				Dprintf(1,"%s\n", svc_strings[type]);
				players[MSG_ReadByte()].pl = MSG_ReadByte();
				break;

			case svc_updateentertime:
				Dprintf(1,"%s\n", svc_strings[type]);
				players[MSG_ReadByte()].entertime = MSG_ReadFloat();
				break;

			case svc_updateuserinfo:
				Dprintf(1,"%s\n", svc_strings[type]);
				Update_Userinfo();
				break;

			case svc_setinfo:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Setinfo();
				break;

			case svc_centerprint:
				Dprintf(1,"%s\n", svc_strings[type]);
				Dprintf(1,"%s\n", MSG_ReadString());
				break;

			case svc_soundlist:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Soundlist();
				break;

			case svc_modellist:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Modellist();
				break;

			case svc_smallkick:
				Dprintf(1,"%s\n", svc_strings[type]);
				break;

			case svc_bigkick:
				Dprintf(1,"%s\n", svc_strings[type]);
				break;

			case svc_chokecount:
				Dprintf(1,"%s\n", svc_strings[type]);
				Dprintf(1,"%i\n", MSG_ReadByte());
				break;

			case svc_stopsound:
				Dprintf(1,"%s\n", svc_strings[type]);
				Dprintf(1,"%i\n", MSG_ReadShort());
				break;

			case svc_setangle:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadAngle();
				MSG_ReadAngle();
				MSG_ReadAngle();
				break;


			case svc_lightstyle:
				Dprintf(1,"%s\n", svc_strings[type]);
//                      Dprintf(1,"%4i: %s\n",MSG_ReadByte(),MSG_ReadString());
//                      msg_readcount++;
				MSG_ReadByte();
				MSG_ReadString();
				break;


			case svc_muzzleflash:
				Dprintf(1,"%s\n", svc_strings[type]);
				Dprintf(1,"%4i\n", MSG_ReadShort());
				break;

			case svc_damage:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Damage();
				break;


			case svc_spawnstatic:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Static();
				break;

			case svc_spawnbaseline:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Spawnbaseline();
				break;

			case svc_deltapacketentities:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Packetentities(true);
				break;

			case svc_sound:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_Sound();
				break;

			case svc_disconnect:
				Dprintf(1,"%s\n", svc_strings[type]);
				break;

			case svc_entgravity:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadFloat();
				break;

			case svc_maxspeed:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadFloat();
				break;

			case svc_setview:
				Dprintf(1,"%s\n", svc_strings[type]);
				
				break;

			case svc_nop:
				Dprintf(1,"%s\n", svc_strings[type]);
				break;

			case svc_temp_entity:
				Dprintf(1,"%s\n", svc_strings[type]);
				Parse_TEnt();
				break;


			case svc_nails:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadByte();
				MSG_ReadByte();
				MSG_ReadByte();
				MSG_ReadByte();
				MSG_ReadByte();
				MSG_ReadByte();
				MSG_ReadByte();
				break;
				

			/*case svc_time:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadFloat();
				break;
	*/
			case nq_svc_signonnum:
				Dprintf(1,"%s\n", svc_strings[type]);
				MSG_ReadByte();
				break;

			default:
				Dprintf(1,"unknown type %i\n", type);
				packet->has_unknown_types = 1;
				debug_unknown(packet,msg_readcount);
				return;




		}

		if (record)
		{
			dptr = malloc(sizeof(char) * (msg_readcount - old_readcount));
			memcpy(dptr, &net_message.data[old_readcount], msg_readcount - old_readcount);
			Create_Packet_Struct(packet, type, dptr, msg_readcount - old_readcount);

		}
	}

		Dprintf(1,"%3i - recorded messages\n",i);

}