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); }