Make input_servertime available to ssqc too, so it can guage the player's latency more accurately.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5908 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-06-21 13:46:52 +00:00
parent 8b4a282c47
commit f810be4830
6 changed files with 103 additions and 83 deletions

View File

@ -906,40 +906,10 @@ void CL_PredictEntityMovement(entity_state_t *estate, float age)
}
}
/*
==============
CL_PredictMove
==============
*/
void CL_PredictMovePNum (int seat)
float CL_GetPredictionRealtime(playerview_t *pv)
{
//when this is called, the entity states have been interpolated.
//interpolation state should be updated to match prediction state, so entities move correctly in mirrors/portals.
//this entire function is pure convolouted bollocks.
struct {
int frame;
double time;
player_state_t *state;
usercmd_t *cmd;
} from, to;
playerview_t *pv = &cl.playerview[seat];
int i;
float f;
outframe_t *backdate;
player_state_t framebuf[2]; //need two framebufs so we can interpolate between two states.
static player_state_t nullstate;
int oldphysent;
double simtime; //this is server time if nopred is set (lerp-only), and local time if we're predicting
extern cvar_t cl_netfps;
lerpents_t *le;
qboolean nopred;
qboolean lerpangles = false;
int trackent;
qboolean cam_nowlocked = false;
usercmd_t indcmd;
//these are to make svc_viewentity work better
float simtime;
//these are to make svc_viewentity work better
float netfps = cl_netfps.value;
if (!netfps)
@ -978,6 +948,43 @@ void CL_PredictMovePNum (int seat)
simtime -= cls.latency; //push back when playing demos.
simtime += bound(-0.5, cl_predict_timenudge.value, 0.5);
return simtime;
}
/*
==============
CL_PredictMove
==============
*/
void CL_PredictMovePNum (int seat)
{
//when this is called, the entity states have been interpolated.
//interpolation state should be updated to match prediction state, so entities move correctly in mirrors/portals.
//this entire function is pure convolouted bollocks.
struct {
int frame;
double time;
player_state_t *state;
usercmd_t *cmd;
} from, to;
playerview_t *pv = &cl.playerview[seat];
int i;
float f;
outframe_t *backdate;
player_state_t framebuf[2]; //need two framebufs so we can interpolate between two states.
static player_state_t nullstate;
int oldphysent;
double simtime; //this is server time if nopred is set (lerp-only), and local time if we're predicting
extern cvar_t cl_netfps;
lerpents_t *le;
qboolean nopred;
qboolean lerpangles = false;
int trackent;
qboolean cam_nowlocked = false;
usercmd_t indcmd;
simtime = CL_GetPredictionRealtime(pv);
pv->nolocalplayer = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || (cls.protocol != CP_QUAKEWORLD);
if (!pv->spectator && (pv->cam_state != CAM_FREECAM || pv->cam_spec_track != -1)) //just in case

View File

@ -3941,6 +3941,8 @@ static void cs_get_input_state (usercmd_t *cmd)
cmd->fservertime = *csqcg.input_servertime;
cmd->servertime = *csqcg.input_servertime*1000;
}
if (csqcg.input_clienttime)
cmd->fclienttime = *csqcg.input_clienttime;
if (csqcg.input_cursor_screen)
Vector2Copy(csqcg.input_cursor_screen, cmd->cursor_screen);

View File

@ -1454,21 +1454,21 @@ void MSGFTE_WriteDeltaUsercmd (sizebuf_t *buf, const usercmd_t *from, const user
if (bits & UC_FORWARD)
{
if (bits & UC_BIGMOVES)
MSG_WriteShort(buf, cmd->forwardmove);
MSG_WriteInt64(buf, cmd->forwardmove);
else
MSG_WriteChar(buf, cmd->forwardmove/5);
}
if (bits & UC_RIGHT)
{
if (bits & UC_BIGMOVES)
MSG_WriteShort(buf, cmd->sidemove);
MSG_WriteInt64(buf, cmd->sidemove);
else
MSG_WriteChar(buf, cmd->sidemove/5);
}
if (bits & UC_UP)
{
if (bits & UC_BIGMOVES)
MSG_WriteShort(buf, cmd->upmove);
MSG_WriteInt64(buf, cmd->upmove);
else
MSG_WriteChar(buf, cmd->upmove/5);
}
@ -1548,6 +1548,7 @@ void MSGFTE_ReadDeltaUsercmd (const usercmd_t *from, usercmd_t *cmd)
}
*cmd = *from;
cmd->servertime = from->servertime+MSG_ReadUInt64();
cmd->fservertime = cmd->servertime/1000.0;
for (i = 0; i < 3; i++)
{
if (bits & (UC_ANGLE1<<i))
@ -1561,21 +1562,21 @@ void MSGFTE_ReadDeltaUsercmd (const usercmd_t *from, usercmd_t *cmd)
if (bits & UC_FORWARD)
{
if (bits & UC_BIGMOVES)
cmd->forwardmove = MSG_ReadShort();
cmd->forwardmove = MSG_ReadInt64();
else
cmd->forwardmove = MSG_ReadChar()*5;
}
if (bits & UC_RIGHT)
{
if (bits & UC_BIGMOVES)
cmd->sidemove = MSG_ReadShort();
cmd->sidemove = MSG_ReadInt64();
else
cmd->sidemove = MSG_ReadChar()*5;
}
if (bits & UC_UP)
{
if (bits & UC_BIGMOVES)
cmd->upmove = MSG_ReadShort();
cmd->upmove = MSG_ReadInt64();
else
cmd->upmove = MSG_ReadChar()*5;
}

View File

@ -1008,6 +1008,7 @@ void PR_LoadGlabalStruct(qboolean muted)
globalvec (false, input_right_angles) \
globalvec (false, input_right_velocity) \
globalvec (false, input_right_avelocity) \
globalfloat (false, input_servertime) \
\
globalint (false, serverid) \
globalvec (false, global_gravitydir) \
@ -10321,6 +10322,10 @@ static void SV_SetSSQCInputs(usercmd_t *ucmd)
(pr_global_struct->input_movevalues)[1] = ucmd->sidemove;
(pr_global_struct->input_movevalues)[2] = ucmd->upmove;
}
if (pr_global_ptrs->input_servertime)
pr_global_struct->input_servertime = ucmd->fservertime;
if (pr_global_ptrs->input_clienttime)
pr_global_struct->input_clienttime = ucmd->fclienttime;
if (pr_global_ptrs->input_buttons)
pr_global_struct->input_buttons = ucmd->buttons;
if (pr_global_ptrs->input_weapon)
@ -10462,6 +10467,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
}
//prethink should be consistant with what the engine normally does
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, client->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
WPhys_RunThink (&sv.world, (wedict_t*)client->edict);
@ -12706,6 +12712,8 @@ void PR_DumpPlatform_f(void)
{"end_sys_fields", "void", QW|NQ|CS|MENU},
{"time", "float", MENU, D("The current local time. Increases while paused.")},
{"input_servertime", "float", QW|NQ|CS, D("Server's timestamp of the client's interpolation state.")},
// {"input_clienttime", "float", QW|NQ|CS, D("This is the timestamp that player prediction is simulating.")},
{"input_timelength", "float", QW|NQ},
{"input_angles", "vector", QW|NQ, D("+x=DOWN")},
{"input_movevalues", "vector", QW|NQ},

View File

@ -104,6 +104,8 @@ typedef struct nqglobalvars_s
pvec_t *physics_mode;
pvec_t *clientcommandframe;
pvec_t *input_servertime;
pvec_t *input_clienttime;
pvec_t *input_timelength;
pvec_t *input_impulse;
pvec3_t *input_angles;

View File

@ -7946,56 +7946,54 @@ void SV_ExecuteClientMessage (client_t *cl)
qbyte checksum, calculatedChecksum;
int seq_hash;
// calc ping time
if (cl->frameunion.frames)
{ //split screen doesn't always have frames.
frame = &cl->frameunion.frames[cl->netchan.incoming_acknowledged & UPDATE_MASK];
if (cl->lastsequence_acknowledged + UPDATE_BACKUP > cl->netchan.incoming_acknowledged)
{
/*note that if there is packetloss, we can change a single frame's ping_time multiple times
this means that the 'ping' is more latency than ping times*/
if (frame->ping_time == -1 || !sv_ping_ignorepl.ival)
frame->ping_time = realtime - frame->senttime; //no more phenomanally low pings please
if (cl->spectator)
cl->delay = 0;
else
{
float diff = frame->ping_time*1000 - sv_minping.value;
if (fabs(diff) > 1)
{
//FIXME: we should use actual arrival times instead, so we don't get so much noise and seesawing.
diff = bound(-25, diff, 25); //don't swing wildly
cl->delay -= 0.001*(diff/25); //scale towards the ideal value
cl->delay = bound(0, cl->delay, 1); //but make sure things don't go crazy
}
}
if (cl->penalties & BAN_LAGGED)
if (cl->delay < 0.2)
cl->delay = 0.2;
}
if (sv_antilag.ival || !*sv_antilag.string)
{
#ifdef warningmsg
#pragma warningmsg("FIXME: make antilag optionally support non-player ents too")
#endif
cl->laggedents_count = sv.allocated_client_slots;
memcpy(cl->laggedents, frame->laggedplayer, sizeof(*cl->laggedents)*cl->laggedents_count);
cl->laggedents_time = frame->laggedtime;
cl->laggedents_frac = !*sv_antilag_frac.string?1:sv_antilag_frac.value;
}
else
cl->laggedents_count = 0;
}
else
if (!cl->frameunion.frames)
{
Con_Printf("Server bug: No frames!\n");
cl->send_message = false;
return; //shouldn't happen...
}
// calc ping time
frame = &cl->frameunion.frames[cl->netchan.incoming_acknowledged & UPDATE_MASK];
if (cl->lastsequence_acknowledged + UPDATE_BACKUP > cl->netchan.incoming_acknowledged)
{
/*note that if there is packetloss, we can change a single frame's ping_time multiple times
this means that the 'ping' is more latency than ping times*/
if (frame->ping_time == -1 || !sv_ping_ignorepl.ival)
frame->ping_time = realtime - frame->senttime; //no more phenomanally low pings please
if (cl->spectator)
cl->delay = 0;
else
{
float diff = frame->ping_time*1000 - sv_minping.value;
if (fabs(diff) > 1)
{
//FIXME: we should use actual arrival times instead, so we don't get so much noise and seesawing.
diff = bound(-25, diff, 25); //don't swing wildly
cl->delay -= 0.001*(diff/25); //scale towards the ideal value
cl->delay = bound(0, cl->delay, 1); //but make sure things don't go crazy
}
}
if (cl->penalties & BAN_LAGGED)
if (cl->delay < 0.2)
cl->delay = 0.2;
}
if (sv_antilag.ival || !*sv_antilag.string)
{
#ifdef warningmsg
#pragma warningmsg("FIXME: make antilag optionally support non-player ents too")
#endif
cl->laggedents_count = sv.allocated_client_slots;
memcpy(cl->laggedents, frame->laggedplayer, sizeof(*cl->laggedents)*cl->laggedents_count);
cl->laggedents_time = frame->laggedtime;
cl->laggedents_frac = !*sv_antilag_frac.string?1:sv_antilag_frac.value;
}
else
cl->laggedents_count = 0;
// make sure the reply sequence number matches the incoming
// sequence number
if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence)
@ -8076,6 +8074,8 @@ void SV_ExecuteClientMessage (client_t *cl)
else
{
MSGQW_ReadDeltaUsercmd (&nullcmd, &oldest, PROTOCOL_VERSION_QW);
oldest.fservertime = frame->laggedtime; //not very accurate, but our best guess.
oldest.servertime = frame->laggedtime*1000; //not very accurate
Vector2Copy(split->lastcmd.cursor_screen, oldest.cursor_screen);
VectorCopy(split->lastcmd.cursor_start, oldest.cursor_start);
VectorCopy(split->lastcmd.cursor_impact, oldest.cursor_impact);