================= SV_ReadPackets ================= */
| 297 | ================= |
| 298 | */ |
| 299 | void SV_PacketEvent( netadr_t from, msg_t *msg ) { |
| 300 | int i; |
| 301 | client_t *cl; |
| 302 | int qport; |
| 303 | |
| 304 | // check for connectionless packet (0xffffffff) first |
| 305 | if ( msg->cursize >= 4 && *(int *)msg->data == -1) { |
| 306 | SV_ConnectionlessPacket( from, msg ); |
| 307 | return; |
| 308 | } |
| 309 | |
| 310 | // read the qport out of the message so we can fix up |
| 311 | // stupid address translating routers |
| 312 | MSG_BeginReading( msg ); |
| 313 | MSG_ReadLong( msg ); // sequence number |
| 314 | MSG_ReadLong( msg ); // sequence number |
| 315 | qport = MSG_ReadShort( msg ) & 0xffff; |
| 316 | |
| 317 | // find which client the message is from |
| 318 | for (i=0, cl=svs.clients ; i < 1 ; i++,cl++) { |
| 319 | if (cl->state == CS_FREE) { |
| 320 | continue; |
| 321 | } |
| 322 | if ( !NET_CompareBaseAdr( from, cl->netchan.remoteAddress ) ) { |
| 323 | continue; |
| 324 | } |
| 325 | // it is possible to have multiple clients from a single IP |
| 326 | // address, so they are differentiated by the qport variable |
| 327 | if (cl->netchan.qport != qport) { |
| 328 | continue; |
| 329 | } |
| 330 | |
| 331 | // the IP port can't be used to differentiate them, because |
| 332 | // some address translating routers periodically change UDP |
| 333 | // port assignments |
| 334 | if (cl->netchan.remoteAddress.port != from.port) { |
| 335 | Com_Printf( "SV_ReadPackets: fixing up a translated port\n" ); |
| 336 | cl->netchan.remoteAddress.port = from.port; |
| 337 | } |
| 338 | |
| 339 | // make sure it is a valid, in sequence packet |
| 340 | if (Netchan_Process(&cl->netchan, msg)) { |
| 341 | // zombie clients stil neet to do the Netchan_Process |
| 342 | // to make sure they don't need to retransmit the final |
| 343 | // reliable message, but they don't do any other processing |
| 344 | if (cl->state != CS_ZOMBIE) { |
| 345 | cl->lastPacketTime = sv.time; // don't timeout |
| 346 | cl->frames[ cl->netchan.incomingAcknowledged & PACKET_MASK ] |
| 347 | .messageAcked = sv.time; |
| 348 | SV_ExecuteClientMessage( cl, msg ); |
| 349 | } |
| 350 | } |
| 351 | return; |
| 352 | } |
| 353 | |
| 354 | // if we received a sequenced packet from an address we don't reckognize, |
| 355 | // send an out of band disconnect packet to it |
| 356 | NET_OutOfBandPrint( NS_SERVER, from, "disconnect" ); |
no test coverage detected