__cdecl void SV_WriteSnapshotToClient(client_t* client, msg_t* msg){ snapshotInfo_t snapInfo; int lastframe; int from_num_entities; int newindex, oldindex, newnum, oldnum; clientState_ts *newcs, *oldcs; entityState_t *newent, *oldent; clientSnapshot_t *frame, *oldframe; int i; int snapFlags; int var_x, from_first_entity, from_num_clients, from_first_client; snapInfo.clnum = client - svsHeader.clients; snapInfo.cl = (void*)client; snapInfo.var_01 = 0; snapInfo.var_02 = 0; snapInfo.var_03 = 0; frame = &client->frames[client->netchan.outgoingSequence & PACKET_MASK]; frame->var_03 = svsHeader.time; if(client->deltaMessage <= 0 || client->state != CS_ACTIVE) { oldframe = NULL; lastframe = 0; var_x = 0; } else if(client->netchan.outgoingSequence - client->deltaMessage >= PACKET_BACKUP - 3) { Com_DPrintf("%s: Delta request from out of date packet.\n", client->name); oldframe = NULL; lastframe = 0; var_x = 0; } else if(client->demoDeltaFrameCount <= 0 && client->demorecording){ oldframe = NULL; lastframe = 0; var_x = 0; client->demowaiting = qfalse; Com_DPrintf("Force a nondelta frame for %s for demo recording\n", client->name); if(client->demoMaxDeltaFrames < 1024) { client->demoMaxDeltaFrames <<= 1; } client->demoDeltaFrameCount = client->demoMaxDeltaFrames; } else { oldframe = &client->frames[client->deltaMessage & PACKET_MASK]; lastframe = client->netchan.outgoingSequence - client->deltaMessage; var_x = oldframe->var_03; client->demoDeltaFrameCount--; if(oldframe->first_entity < svsHeader.nextSnapshotEntities - svsHeader.numSnapshotEntities) { Com_PrintWarning("%s: Delta request from out of date entities - delta against entity %i, oldest is %i, current is %i. Their old snapshot had %i entities in it\n", client->name, oldframe->first_entity, svs.nextSnapshotEntities - svs.numSnapshotEntities, svs.nextSnapshotEntities, oldframe->num_entities ); oldframe = NULL; lastframe = 0; var_x = 0; } else if(oldframe->first_client < svsHeader.nextSnapshotClients - svsHeader.numSnapshotClients) { Com_PrintWarning("%s: Delta request from out of date clients - delta against client %i, oldest is %i, current is %i. Their old snapshot had %i clients in it\n", client->name, oldframe->first_client, svs.nextSnapshotClients - svs.numSnapshotClients, svs.nextSnapshotClients, oldframe->num_clients); oldframe = NULL; lastframe = 0; var_x = 0; } } MSG_WriteByte(msg, svc_snapshot); MSG_WriteLong(msg, svsHeader.time); MSG_WriteByte(msg, lastframe); snapInfo.var_01 = var_x; snapFlags = svsHeader.snapFlagServerBit; if(client->rateDelayed){ snapFlags |= 1; } if(client->state == CS_ACTIVE) { client->unksnapshotvar = 1; } else { if(client->state != CS_ZOMBIE){ client->unksnapshotvar = 0; } } if(!client->unksnapshotvar){ snapFlags |= 2; } MSG_WriteByte(msg, snapFlags); if(oldframe) { MSG_WriteDeltaPlayerstate( &snapInfo, msg, svsHeader.time, &oldframe->ps, &frame->ps); from_num_entities = oldframe->num_entities; from_first_entity = oldframe->first_entity; from_num_clients = oldframe->num_clients; from_first_client = oldframe->first_client; } else { MSG_WriteDeltaPlayerstate( &snapInfo, msg, svsHeader.time, 0, &frame->ps); from_num_entities = 0; from_first_entity = 0; from_num_clients = 0; from_first_client = 0; } MSG_ClearLastReferencedEntity(msg); newindex = 0; oldindex = 0; // Com_Printf("\nDelta client: %i:\n", snapInfo.clnum); while ( newindex < frame->num_entities || oldindex < from_num_entities){ if ( newindex >= frame->num_entities ) { newnum = 9999; newent = NULL; } else { newent = &svsHeader.snapshotEntities[( frame->first_entity + newindex ) % svsHeader.numSnapshotEntities]; newnum = newent->number; } if ( oldindex >= from_num_entities ) { oldnum = 9999; oldent = NULL; } else { oldent = &svsHeader.snapshotEntities[( from_first_entity + oldindex ) % svsHeader.numSnapshotEntities]; oldnum = oldent->number; } if ( newnum == oldnum ) { // delta update from old position // because the force parm is qfalse, this will not result // in any bytes being emited if the entity has not changed at all // if(newent->number < 64 || oldent->number < 64) // Com_Printf(" Delta Update Entity - New delta: %i, %x Old delta: %i, %x\n", newent->number, newent, oldent->number, oldent); MSG_WriteDeltaEntity( &snapInfo, msg, svsHeader.time, oldent, newent, qfalse ); oldindex++; newindex++; continue; } if ( newnum < oldnum ) { // this is a new entity, send it from the baseline snapInfo.var_02 = 1; // if(newent->number < 64) // Com_Printf(" Delta Add Entity: %i, %x\n", newent->number, newent); MSG_WriteDeltaEntity( &snapInfo, msg, svsHeader.time, &svsHeader.svEntities[newnum].baseline, newent, qtrue ); snapInfo.var_02 = 0; newindex++; continue; } if ( newnum > oldnum ) { // the old entity isn't present in the new message // if(oldent->number < 64) // Com_Printf(" Delta Remove Entity: %i, %x\n", oldent->number, oldent); MSG_WriteDeltaEntity( &snapInfo, msg, svsHeader.time, oldent, NULL, qtrue ); oldindex++; continue; } } MSG_WriteEntityIndex(&snapInfo, msg, ( MAX_GENTITIES - 1 ), GENTITYNUM_BITS); MSG_ClearLastReferencedEntity(msg); newindex = 0; oldindex = 0; while(newindex < frame->num_clients || oldindex < from_num_clients){ if(newindex >= frame->num_clients){ newnum = 9999; newcs = NULL; }else{ newcs = &svsHeader.snapshotClients[(frame->first_client + newindex) % svsHeader.numSnapshotClients]; newnum = newcs->number; } if(oldindex >= from_num_clients){ oldnum = 9999; oldcs = NULL; }else{ oldcs = &svsHeader.snapshotClients[(from_first_client + oldindex) % svsHeader.numSnapshotClients]; oldnum = oldcs->number; } if ( newnum == oldnum ) { // delta update from old position // because the force parm is qfalse, this will not result // in any bytes being emited if the entity has not changed at all MSG_WriteDeltaClient( &snapInfo, msg, svsHeader.time, oldcs, newcs, qfalse ); oldindex++; newindex++; continue; } if ( newnum < oldnum ) { MSG_WriteDeltaClient( &snapInfo, msg, svsHeader.time, NULL, newcs, qtrue ); newindex++; continue; } if ( newnum > oldnum ) { MSG_WriteDeltaClient( &snapInfo, msg, svsHeader.time, oldcs, NULL, qtrue ); oldindex++; continue; } } MSG_WriteBit0(msg); if(sv_padPackets->integer){ for( i=0 ; i < sv_padPackets->integer ; i++){ MSG_WriteByte( msg, 0); //svc_nop } } }
void MSG_WriteDeltaEntity(snapshotInfo_t* snap, msg_t* msg, int time, entityState_t* from, entityState_t* to, int arg_6){ if(!to){ MSG_WriteEntityIndex(snap, msg, from->number, 0x0a); MSG_WriteBit1(msg); return; } if( to->number < 64 && !g_friendlyPlayerCanBlock->boolean && OnSameTeam( &g_entities[to->number], &g_entities[snap->clnum])) to->solid = 1; __asm__ __volatile__( " push %edi\n" " push %esi\n" " push %ebx\n" " sub $0x5c,%esp\n" " mov 0x18(%ebp),%eax\n" " mov 0x4(%eax),%edx\n" " mov $0x11,%eax\n" " cmp $0x11,%edx\n" " cmovle %edx,%eax\n" " shl $0x3,%eax\n" " mov 0x82293c0(%eax),%edx\n" " mov %edx,-0x40(%ebp)\n" " mov 0x82293c4(%eax),%eax\n" " mov %eax,-0x38(%ebp)\n" " mov 0xc(%ebp),%eax\n" " mov %eax,(%esp)\n" " mov $0x81305fe, %eax\n" " call *%eax\n" " mov -0x38(%ebp),%eax\n" " test %eax,%eax\n" " jle MSG_WriteDeltaEntity_loc2\n" " mov -0x40(%ebp),%edi\n" " movl $0x0,-0x34(%ebp)\n" " movl $0x0,-0x3c(%ebp)\n" "MSG_WriteDeltaEntity_loc6:\n" " mov 0x4(%edi),%eax\n" " mov 0x8(%edi),%edx\n" " mov 0x14(%ebp),%ecx\n" " add %eax,%ecx\n" " mov 0x18(%ebp),%esi\n" " add %eax,%esi\n" " mov (%ecx),%eax\n" " mov %eax,-0x48(%ebp)\n" " mov (%esi),%ebx\n" " cmp %ebx,%eax\n" " je MSG_WriteDeltaEntity_loc3\n" " add $0x64,%edx\n" " test %edx,%edx\n" " je MSG_WriteDeltaEntity_case_0_13\n" " cmp $0xd,%edx\n" " je MSG_WriteDeltaEntity_case_0_13\n" " cmp $0x5,%edx\n" " je MSG_WriteDeltaEntity_case_5\n" " cmp $0x8,%edx\n" " je MSG_WriteDeltaEntity_case_8to10\n" " cmp $0x9,%edx\n" " je MSG_WriteDeltaEntity_case_8to10\n" " cmp $0xa,%edx\n" " je MSG_WriteDeltaEntity_case_8to10\n" " jmp MSG_WriteDeltaEntity_case_default\n" "MSG_WriteDeltaEntity_loc9:\n" " movl $0xa,0xc(%esp)\n" " mov 0x18(%ebp),%edx\n" " mov (%edx),%eax\n" " mov %eax,0x8(%esp)\n" " mov 0xc(%ebp),%eax\n" " mov %eax,0x4(%esp)\n" " mov 0x8(%ebp),%edx\n" " mov %edx,(%esp)\n" " mov $0x813de54, %eax\n" " call *%eax\n" " mov 0xc(%ebp),%eax\n" " mov %eax,(%esp)\n" " mov $0x81306a4, %eax\n" " call *%eax\n" " mov 0xc(%ebp),%edx\n" " mov %edx,(%esp)\n" " mov $0x81306a4, %eax\n" " call *%eax\n" "MSG_WriteDeltaEntity_loc11:\n" " mov 0xc(%ebp),%eax\n" " mov %eax,(%esp)\n" " mov $0x81305fe, %eax\n" " call *%eax\n" " jmp MSG_WriteDeltaEntity_term\n" "MSG_WriteDeltaEntity_case_default:\n" " addl $0x1,-0x34(%ebp)\n" " mov -0x34(%ebp),%edx\n" " mov %edx,-0x3c(%ebp)\n" " mov %edx,%eax\n" " cmp %eax,-0x38(%ebp)\n" " jle MSG_WriteDeltaEntity_loc5\n" "MSG_WriteDeltaEntity_loc7:\n" " add $0x10,%edi\n" " jmp MSG_WriteDeltaEntity_loc6\n" "MSG_WriteDeltaEntity_case_5:\n" " mov $0x51eb851f,%esi\n" " mov -0x48(%ebp),%eax\n" " imul %esi\n" " mov %edx,%ecx\n" " sar $0x5,%ecx\n" " mov -0x48(%ebp),%eax\n" " sar $0x1f,%eax\n" " sub %eax,%ecx\n" " mov %ebx,%eax\n" " imul %esi\n" " sar $0x5,%edx\n" " mov %ebx,%eax\n" " sar $0x1f,%eax\n" " sub %eax,%edx\n" " xor %eax,%eax\n" " cmp %edx,%ecx\n" " sete %al\n" "MSG_WriteDeltaEntity_loc10:\n" " test %eax,%eax\n" " je MSG_WriteDeltaEntity_case_default\n" "MSG_WriteDeltaEntity_loc3:\n" " addl $0x1,-0x34(%ebp)\n" " mov -0x34(%ebp),%eax\n" " cmp %eax,-0x38(%ebp)\n" " jg MSG_WriteDeltaEntity_loc7\n" "MSG_WriteDeltaEntity_loc5:\n" " mov -0x3c(%ebp),%eax\n" " test %eax,%eax\n" " jne MSG_WriteDeltaEntity_loc8\n" "MSG_WriteDeltaEntity_loc2:\n" " mov 0x1c(%ebp),%eax\n" " test %eax,%eax\n" " jne MSG_WriteDeltaEntity_loc9\n" " jmp MSG_WriteDeltaEntity_term\n" "MSG_WriteDeltaEntity_case_8to10:\n" " flds 0x8209e08\n" " flds (%ecx)\n" " fadd %st(1),%st\n" " fnstcw -0x14(%ebp)\n" " movzwl -0x14(%ebp),%eax\n" " and $0xf3,%ah\n" " or $0x4,%ah\n" " mov %ax,-0x12(%ebp)\n" " fldcw -0x12(%ebp)\n" " frndint \n" " fxch %st(1)\n" " fldcw -0x14(%ebp)\n" " fadds (%esi)\n" " fnstcw -0x12(%ebp)\n" " movzwl -0x12(%ebp),%eax\n" " and $0xf3,%ah\n" " or $0x4,%ah\n" " mov %ax,-0x14(%ebp)\n" " fldcw -0x14(%ebp)\n" " frndint \n" " fxch %st(1)\n" " fldcw -0x12(%ebp)\n" " fstpl -0x28(%ebp)\n" " fldl -0x28(%ebp)\n" " fnstcw -0x2a(%ebp)\n" " movzwl -0x2a(%ebp),%eax\n" " mov $0xc,%ah\n" " mov %ax,-0x2c(%ebp)\n" " fldcw -0x2c(%ebp)\n" " fistpl -0x30(%ebp)\n" " fldcw -0x2a(%ebp)\n" " mov -0x30(%ebp),%edx\n" " fstpl -0x28(%ebp)\n" " fldl -0x28(%ebp)\n" " fldcw -0x2c(%ebp)\n" " fistpl -0x30(%ebp)\n" " fldcw -0x2a(%ebp)\n" " mov -0x30(%ebp),%eax\n" " cmp %eax,%edx\n" " sete %al\n" " movzbl %al,%eax\n" " jmp MSG_WriteDeltaEntity_loc10\n" "MSG_WriteDeltaEntity_case_0_13:\n" " flds 0x8224f7c\n" " flds (%ecx)\n" " fmul %st(1),%st\n" " flds 0x8209e08\n" " fadd %st,%st(1)\n" " fxch %st(1)\n" " fstps -0x44(%ebp)\n" " fxch %st(1)\n" " movss -0x44(%ebp),%xmm0\n" " cvttss2si %xmm0,%edx\n" " fmuls (%esi)\n" " faddp %st,%st(1)\n" " fstps -0x44(%ebp)\n" " movss -0x44(%ebp),%xmm0\n" " cvttss2si %xmm0,%eax\n" " cmp %dx,%ax\n" " sete %al\n" " movzbl %al,%eax\n" " jmp MSG_WriteDeltaEntity_loc10\n" "MSG_WriteDeltaEntity_loc8:\n" " movl $0xa,0xc(%esp)\n" " mov 0x18(%ebp),%edx\n" " mov (%edx),%eax\n" " mov %eax,0x8(%esp)\n" " mov 0xc(%ebp),%eax\n" " mov %eax,0x4(%esp)\n" " mov 0x8(%ebp),%edx\n" " mov %edx,(%esp)\n" " mov $0x813de54, %eax\n" " call *%eax\n" " mov 0xc(%ebp),%eax\n" " mov %eax,(%esp)\n" " mov $0x81306a4, %eax\n" " call *%eax\n" " mov 0xc(%ebp),%edx\n" " mov %edx,(%esp)\n" " mov $0x81306dc, %eax\n" " call *%eax\n" " mov -0x38(%ebp),%eax\n" " mov %eax,(%esp)\n" " mov $0x8130500, %eax\n" " call *%eax\n" " mov %eax,0x8(%esp)\n" " mov -0x3c(%ebp),%edx\n" " mov %edx,0x4(%esp)\n" " mov 0xc(%ebp),%eax\n" " mov %eax,(%esp)\n" " mov $0x813061c, %eax\n" " call *%eax\n" " mov -0x3c(%ebp),%eax\n" " test %eax,%eax\n" " jle MSG_WriteDeltaEntity_loc11\n" " xor %ebx,%ebx\n" "MSG_WriteDeltaEntity_loc12:\n" " movl $0x0,0x10(%esp)\n" " mov %ebx,0xc(%esp)\n" " mov -0x40(%ebp),%edx\n" " mov %edx,0x8(%esp)\n" " mov 0x18(%ebp),%eax\n" " mov %eax,0x4(%esp)\n" " mov 0x14(%ebp),%edx\n" " mov %edx,(%esp)\n" " mov 0x10(%ebp),%ecx\n" " mov 0xc(%ebp),%edx\n" " mov 0x8(%ebp),%eax\n" " mov $0x813e22a, %esi\n" " call *%esi\n" " add $0x1,%ebx\n" " addl $0x10,-0x40(%ebp)\n" " cmp %ebx,-0x3c(%ebp)\n" " jne MSG_WriteDeltaEntity_loc12\n" " jmp MSG_WriteDeltaEntity_loc11\n" "MSG_WriteDeltaEntity_term:\n" " add $0x5c,%esp\n" " pop %ebx\n" " pop %esi\n" " pop %edi\n"); }