bottom[1] = top[1];
bottom[2] = top[2] - 160;
- tr = SV_Move (top, vec3_origin, vec3_origin, bottom, MOVE_NOMONSTERS, host_client->edict, SUPERCONTENTS_SOLID);
+ tr = SV_TraceLine(top, bottom, MOVE_NOMONSTERS, host_client->edict, SUPERCONTENTS_SOLID);
// if looking at a wall, leave ideal the way is was
if (tr.startsolid)
return;
start[2] = host_client->edict->fields.server->origin[2] + host_client->edict->fields.server->mins[2];
stop[2] = start[2] - 34;
- trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, host_client->edict, SV_GenericHitSuperContentsMask(host_client->edict));
+ trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, host_client->edict, SV_GenericHitSuperContentsMask(host_client->edict));
if (trace.fraction == 1.0)
friction = sv_friction.value*sv_edgefriction.value;
// (we have to buffer the moves because of old ones being repeated)
if (sv_numreadmoves < CL_MAX_USERCMDS)
sv_readmoves[sv_numreadmoves++] = *move;
+
+ // movement packet loss tracking
+ if(move->sequence)
+ {
+ if(move->sequence > host_client->movement_highestsequence_seen)
+ {
+ if(host_client->movement_highestsequence_seen)
+ {
+ // mark moves in between as lost
+ if(move->sequence - host_client->movement_highestsequence_seen - 1 < NETGRAPH_PACKETS)
+ for(i = host_client->movement_highestsequence_seen + 1; i < move->sequence; ++i)
+ host_client->movement_count[i % NETGRAPH_PACKETS] = -1;
+ else
+ memset(host_client->movement_count, -1, sizeof(host_client->movement_count));
+ }
+ // mark THIS move as seen for the first time
+ host_client->movement_count[move->sequence % NETGRAPH_PACKETS] = 1;
+ // update highest sequence seen
+ host_client->movement_highestsequence_seen = move->sequence;
+ }
+ else
+ if(host_client->movement_count[move->sequence % NETGRAPH_PACKETS] >= 0)
+ ++host_client->movement_count[move->sequence % NETGRAPH_PACKETS];
+ }
+ else
+ {
+ host_client->movement_highestsequence_seen = 0;
+ memset(host_client->movement_count, 0, sizeof(host_client->movement_count));
+ }
}
void SV_ExecuteClientMoves(void)
// discard (treat like lost) moves with too low distance from
// the previous one to prevent hacks using float inaccuracy
// clients will see this as packet loss in the netgraph
+ // this should also apply if a move cannot get
+ // executed because it came too late and
+ // already was performed serverside
if(moveframetime < 0.0005)
+ {
+ // count the move as LOST if we don't
+ // execute it but it has higher
+ // sequence count
+ if(host_client->movesequence)
+ if(move->sequence > host_client->movesequence)
+ host_client->movement_count[(move->sequence) % NETGRAPH_PACKETS] = -1;
continue;
+ }
//Con_Printf("movesequence = %i (%i lost), moveframetime = %f\n", move->sequence, move->sequence ? move->sequence - host_client->movesequence - 1 : 0, moveframetime);
host_client->cmd = *move;
{
prvm_eval_t *val;
usercmd_t *move = &host_client->cmd;
+ int j, movementloss, packetloss;
if (!move->receivetime)
return;
host_client->edict->fields.server->impulse = move->impulse;
// only send the impulse to qc once
move->impulse = 0;
+
+ movementloss = packetloss = 0;
+ if(host_client->netconnection)
+ {
+ for (j = 0;j < NETGRAPH_PACKETS;j++)
+ if (host_client->netconnection->incoming_netgraph[j].unreliablebytes == NETGRAPH_LOSTPACKET)
+ packetloss++;
+ for (j = 0;j < NETGRAPH_PACKETS;j++)
+ if (host_client->movement_count[j] < 0)
+ movementloss++;
+ }
+
VectorCopy(move->viewangles, host_client->edict->fields.server->v_angle);
if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button3))) val->_float = ((move->buttons >> 2) & 1);
if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button4))) val->_float = ((move->buttons >> 3) & 1);
if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector);
if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_trace_ent))) val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(move->cursor_entitynumber));
if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ping))) val->_float = host_client->ping * 1000.0;
+ if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.packetloss))) val->_float = packetloss / (float) NETGRAPH_PACKETS;
+ if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.movementloss))) val->_float = movementloss / (float) NETGRAPH_PACKETS;
}
void SV_FrameLost(int framenum)