void SV_Netchan_Transmit( client_t *client, msg_t *msg) { MSG_WriteByte( msg, svc_EOF ); if(client->netchan.unsentFragments || client->netchan_start_queue) { netchan_buffer_t *netbuf; Com_DPrintf("#462 SV_Netchan_Transmit: unsent fragments, stacked\n"); netbuf = (netchan_buffer_t *) Z_Malloc(sizeof(netchan_buffer_t)); // store the msg, we can't store it encoded, as the encoding depends on stuff we still have to finish sending MSG_Copy(&netbuf->msg, netbuf->msgBuffer, sizeof( netbuf->msgBuffer ), msg); #ifdef LEGACY_PROTOCOL if(client->compat) { Q_strncpyz(netbuf->clientCommandString, client->lastClientCommandString, sizeof(netbuf->clientCommandString)); } #endif netbuf->next = NULL; // insert it in the queue, the message will be encoded and sent later *client->netchan_end_queue = netbuf; client->netchan_end_queue = &(*client->netchan_end_queue)->next; } else { #ifdef LEGACY_PROTOCOL if(client->compat) SV_Netchan_Encode(client, msg, client->lastClientCommandString); #endif Netchan_Transmit( &client->netchan, msg->cursize, msg->data ); } }
/* Write a message to a server-side demo file. */ void SVD_WriteDemoFile(const client_t *client, const msg_t *msg) { int len; msg_t cmsg; byte cbuf[MAX_MSGLEN]; fileHandle_t file = client->demo_file; if (*(int *)msg->data == -1) { // TODO: do we need this? Com_DPrintf("Ignored connectionless packet, not written to demo!\n"); return; } // TODO: we only copy because we want to add svc_EOF; can we add it and then // "back off" from it, thus avoiding the copy? MSG_Copy(&cmsg, cbuf, sizeof(cbuf), (msg_t*) msg); MSG_WriteByte(&cmsg, svc_EOF); // XXX server code doesn't do this, SV_Netchan_Transmit adds it! // TODO: the headerbytes stuff done in the client seems unnecessary // here because we get the packet *before* the netchan has it's way // with it; just not sure that's really true :-/ len = LittleLong(client->netchan.outgoingSequence); FS_Write(&len, 4, file); len = LittleLong(cmsg.cursize); FS_Write(&len, 4, file); FS_Write(cmsg.data, cmsg.cursize, file); // XXX don't use len! FS_Flush(file); }
/* =============== SV_Netchan_Transmit TTimo show_bug.cgi?id=462 if there are some unsent fragments (which may happen if the snapshots and the gamestate are fragmenting, and collide on send for instance) then buffer them and make sure they get sent in correct order ================ */ void SV_Netchan_Transmit( client_t *client, msg_t *msg ) { //int length, const byte *data ) { MSG_WriteByte( msg, svc_EOF ); SV_WriteBinaryMessage( msg, client ); if ( client->netchan.unsentFragments ) { netchan_buffer_t *netbuf; //Com_DPrintf("SV_Netchan_Transmit: there are unsent fragments remaining\n"); netbuf = ( netchan_buffer_t * ) Z_Malloc( sizeof( netchan_buffer_t ) ); // store the msg, we can't store it encoded, as the encoding depends on stuff we still have to finish sending MSG_Copy( &netbuf->msg, netbuf->msgBuffer, sizeof( netbuf->msgBuffer ), msg ); // copy the command, since the command number used for encryption is // already compressed in the buffer, and receiving a new command would // otherwise lose the proper encryption key strcpy( netbuf->lastClientCommandString, client->lastClientCommandString ); // insert it in the queue, the message will be encoded and sent later //% *client->netchan_end_queue = netbuf; //% client->netchan_end_queue = &(*client->netchan_end_queue)->next; netbuf->next = NULL; if ( !client->netchan_start_queue ) { client->netchan_start_queue = netbuf; } else { client->netchan_end_queue->next = netbuf; } client->netchan_end_queue = netbuf; // emit the next fragment of the current message for now Netchan_TransmitNextFragment( &client->netchan ); } else { SV_Netchan_Encode( client, msg, client->lastClientCommandString ); Netchan_Transmit( &client->netchan, msg->cursize, msg->data ); } }
/* =============== SV_Netchan_Transmit TTimo show_bug.cgi?id=462 if there are some unsent fragments (which may happen if the snapshots and the gamestate are fragmenting, and collide on send for instance) then buffer them and make sure they get sent in correct order ================ */ void SV_Netchan_Transmit( client_t *client, msg_t *msg ) { //int length, const byte *data ) { MSG_WriteByte( msg, svc_EOF ); if ( client->netchan.unsentFragments ) { netchan_buffer_t *netbuf; //Com_DPrintf("SV_Netchan_Transmit: there are unsent fragments remaining\n"); netbuf = (netchan_buffer_t *)Z_Malloc( sizeof( netchan_buffer_t ) ); // store the msg, we can't store it encoded, as the encoding depends on stuff we still have to finish sending MSG_Copy( &netbuf->msg, netbuf->msgBuffer, sizeof( netbuf->msgBuffer ), msg ); netbuf->next = NULL; // insert it in the queue, the message will be encoded and sent later *client->netchan_end_queue = netbuf; client->netchan_end_queue = &( *client->netchan_end_queue )->next; // emit the next fragment of the current message for now Netchan_TransmitNextFragment( &client->netchan ); } else { SV_Netchan_Encode( client, msg ); Netchan_Transmit( &client->netchan, msg->cursize, msg->data ); } }
/* =============== SV_Netchan_Transmit TTimo show_bug.cgi?id=462 if there are some unsent fragments (which may happen if the snapshots and the gamestate are fragmenting, and collide on send for instance) then buffer them and make sure they get sent in correct order ================ */ void SV_Netchan_Transmit( client_t *client, msg_t *msg ) { //int length, const byte *data ) { MSG_WriteByte( msg, svc_EOF ); SV_WriteBinaryMessage( msg, client ); if ( client->netchan.unsentFragments ) { netchan_buffer_t *netbuf; //Log::Debug("SV_Netchan_Transmit: there are unsent fragments remaining"); netbuf = ( netchan_buffer_t * ) Z_Malloc( sizeof( netchan_buffer_t ) ); MSG_Copy( &netbuf->msg, netbuf->msgBuffer, sizeof( netbuf->msgBuffer ), msg ); // copy the command, since the command number used for encryption is // already compressed in the buffer, and receiving a new command would // otherwise lose the proper encryption key strcpy( netbuf->lastClientCommandString, client->lastClientCommandString ); netbuf->next = nullptr; if ( !client->netchan_start_queue ) { client->netchan_start_queue = netbuf; } else { client->netchan_end_queue->next = netbuf; } client->netchan_end_queue = netbuf; // emit the next fragment of the current message for now Netchan_TransmitNextFragment( &client->netchan ); } else { Netchan_Transmit( &client->netchan, msg->cursize, msg->data ); } }