/** * @brief Send data to the specified TCP stream. */ _Bool Net_SendStream(int32_t sock, const void *data, size_t len) { mem_buf_t buf; byte buffer[MAX_MSG_SIZE]; Mem_InitBuffer(&buf, buffer, sizeof(buffer)); // write the packet length Net_WriteLong(&buf, (int32_t) len); // and copy the payload Net_WriteData(&buf, data, len); ssize_t sent = 0; while ((size_t) sent < buf.size) { const ssize_t s = send(sock, (void *)(buf.data + sent), buf.size - sent, 0); if (s == -1) { if (Net_GetError() != EWOULDBLOCK) { Com_Warn("%s\n", Net_GetErrorString()); return false; } } sent += s; } return sent == (ssize_t) buf.size; }
/** * @brief */ void Sv_WriteClientFrame(sv_client_t *client, mem_buf_t *msg) { sv_frame_t *frame, *delta_frame; int32_t delta_frame_num; // this is the frame we are creating frame = &client->frames[sv.frame_num & PACKET_MASK]; if (client->last_frame < 0) { // client is asking for a retransmit delta_frame = NULL; delta_frame_num = -1; } else if (sv.frame_num - client->last_frame >= (PACKET_BACKUP - 3)) { // client hasn't gotten a good message through in a long time delta_frame = NULL; delta_frame_num = -1; } else { // we have a valid message to delta from delta_frame = &client->frames[client->last_frame & PACKET_MASK]; delta_frame_num = client->last_frame; } Net_WriteByte(msg, SV_CMD_FRAME); Net_WriteLong(msg, sv.frame_num); Net_WriteLong(msg, delta_frame_num); // what we are delta'ing from Net_WriteByte(msg, client->suppress_count); // rate dropped packets client->suppress_count = 0; // send over the area bits Net_WriteByte(msg, frame->area_bytes); Net_WriteData(msg, frame->area_bits, frame->area_bytes); // delta encode the player state Sv_WritePlayerState(delta_frame, frame, msg); // delta encode the entities Sv_WriteEntities(delta_frame, frame, msg); }