/* ================= SV_ReadPackets ================= */ static void SV_ReadPackets (void) { int i; client_t *cl; while (NET_GetPacket ()) { if (SV_FilterPacket ()) { SV_SendBan (); // tell them we aren't listening... continue; } // check for connectionless packet (0xffffffff) first if (*(int *)net_message.data == -1) { SV_ConnectionlessPacket (); continue; } // check for packets from connected clients for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) { if (cl->state == cs_free) continue; if (!NET_CompareAdr (net_from, cl->netchan.remote_address)) continue; if (Netchan_Process(&cl->netchan)) { // this is a valid, sequenced packet, so process it svs.stats.packets++; cl->send_message = true; // reply at end of frame if (cl->state != cs_zombie) SV_ExecuteClientMessage (cl); } break; } if (i != MAX_CLIENTS) continue; // packet is not from a known client // Con_Printf ("%s:sequenced packet without connection\n", NET_AdrToString(net_from)); } }
/* ================= SV_ReadPackets ================= */ void SV_ReadPackets (void) { int i; client_t *cl; int qport; // first deal with delayed packets from connected clients for (i = 0, cl=svs.clients; i < MAX_CLIENTS; i++, cl++) { if (cl->state == cs_free) continue; net_from = cl->netchan.remote_address; while (cl->packets && svs.realtime - cl->packets->time >= cl->delay) { SZ_Clear(&net_message); SZ_Write(&net_message, cl->packets->msg.data, cl->packets->msg.cursize); SV_ExecuteClientMessage(cl); SV_FreeHeadDelayedPacket(cl); } } // now deal with new packets while (NET_GetPacket(NS_SERVER)) { if (SV_FilterPacket ()) { SV_SendBan (); // tell them we aren't listening... continue; } // check for connectionless packet (0xffffffff) first if (*(int *)net_message.data == -1) { SV_ConnectionlessPacket (); continue; } // read the qport out of the message so we can fix up // stupid address translating routers MSG_BeginReading (); MSG_ReadLong (); // sequence number MSG_ReadLong (); // sequence number qport = MSG_ReadShort () & 0xffff; // check which client sent this packet for (i=0, cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++) { if (cl->state == cs_free) continue; if (!NET_CompareBaseAdr (net_from, cl->netchan.remote_address)) continue; if (cl->netchan.qport != qport) continue; if (cl->netchan.remote_address.port != net_from.port) { Com_DPrintf ("SV_ReadPackets: fixing up a translated port\n"); cl->netchan.remote_address.port = net_from.port; } break; } if (i == MAX_CLIENTS) continue; // ok, we know who sent this packet, but do we need to delay executing it? if (cl->delay > 0) { if (!svs.free_packets) // packet has to be dropped.. break; // insert at end of list if (!cl->packets) { cl->last_packet = cl->packets = svs.free_packets; } else { // this works because '=' associates from right to left cl->last_packet = cl->last_packet->next = svs.free_packets; } svs.free_packets = svs.free_packets->next; cl->last_packet->next = NULL; cl->last_packet->time = svs.realtime; SZ_Clear(&cl->last_packet->msg); SZ_Write(&cl->last_packet->msg, net_message.data, net_message.cursize); } else { SV_ExecuteClientMessage (cl); } } }