From 630fe34f1b87a851a5fb1d38ae64ba89303bbab5 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 30 Dec 2009 19:27:03 +0000 Subject: [PATCH] buffer up to 32 recent frame numbers for clc_ack to prevent entity resyncs on the server when the client framerate is much lower than the server framerate, repeat frame numbers of previous input packet (cl_netrepeatinput cvar, just like clc_move repeats) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9752 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_input.c | 26 +++++++++++++++++++++----- client.h | 4 +++- protocol.c | 21 +++++++++------------ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/cl_input.c b/cl_input.c index f5714fa6..f6d90d4f 100644 --- a/cl_input.c +++ b/cl_input.c @@ -1572,6 +1572,15 @@ void QW_MSG_WriteDeltaUsercmd(sizebuf_t *buf, usercmd_t *from, usercmd_t *to) MSG_WriteByte(buf, to->msec); } +void CL_NewFrameReceived(int num) +{ + if (developer_networkentities.integer >= 10) + Con_Printf("recv: svc_entities %i\n", num); + cl.latestframenums[cl.latestframenumsposition] = num; + cl.latestsendnums[cl.latestframenumsposition] = cl.cmd.sequence; + cl.latestframenumsposition = (cl.latestframenumsposition + 1) % LATESTFRAMENUMS; +} + /* ============== CL_SendMove @@ -1882,17 +1891,24 @@ void CL_SendMove(void) if (cls.protocol != PROTOCOL_QUAKEWORLD && buf.cursize) { - // ack the last few frame numbers + // ack entity frame numbers received since the last input was sent // (redundent to improve handling of client->server packet loss) - // for LATESTFRAMENUMS == 3 case this is 15 bytes + // if cl_netrepeatinput is 1 and client framerate matches server + // framerate, this is 10 bytes, if client framerate is lower this + // will be more... + int i, j; + int oldsequence = cl.cmd.sequence - bound(1, cl_netrepeatinput.integer + 1, 3); + if (oldsequence < 1) + oldsequence = 1; for (i = 0;i < LATESTFRAMENUMS;i++) { - if (cl.latestframenums[i] > 0) + j = (cl.latestframenumsposition + i) % LATESTFRAMENUMS; + if (cl.latestsendnums[j] >= oldsequence) { if (developer_networkentities.integer >= 10) - Con_Printf("send clc_ackframe %i\n", cl.latestframenums[i]); + Con_Printf("send clc_ackframe %i\n", cl.latestframenums[j]); MSG_WriteByte(&buf, clc_ackframe); - MSG_WriteLong(&buf, cl.latestframenums[i]); + MSG_WriteLong(&buf, cl.latestframenums[j]); } } } diff --git a/client.h b/client.h index 525754b5..07945307 100644 --- a/client.h +++ b/client.h @@ -1043,8 +1043,10 @@ typedef struct client_state_s // entity database stuff // latest received entity frame numbers -#define LATESTFRAMENUMS 3 +#define LATESTFRAMENUMS 32 + int latestframenumsposition; int latestframenums[LATESTFRAMENUMS]; + int latestsendnums[LATESTFRAMENUMS]; entityframe_database_t *entitydatabase; entityframe4_database_t *entitydatabase4; entityframeqw_database_t *entitydatabaseqw; diff --git a/protocol.c b/protocol.c index 31c2e54c..85826a7a 100644 --- a/protocol.c +++ b/protocol.c @@ -1217,6 +1217,8 @@ void EntityState_ReadFields(entity_state_t *e, unsigned int bits) } } +extern void CL_NewFrameReceived(int num); + // (client and server) allocates a new empty database entityframe_database_t *EntityFrame_AllocDatabase(mempool_t *mempool) { @@ -1423,9 +1425,8 @@ void EntityFrame_CL_ReadFrame(void) // read the frame header info f->time = cl.mtime[0]; number = MSG_ReadLong(); - for (i = 0;i < LATESTFRAMENUMS-1;i++) - cl.latestframenums[i] = cl.latestframenums[i+1]; - cl.latestframenums[LATESTFRAMENUMS-1] = f->framenum = MSG_ReadLong(); + f->framenum = MSG_ReadLong(); + CL_NewFrameReceived(f->framenum); f->eye[0] = MSG_ReadFloat(); f->eye[1] = MSG_ReadFloat(); f->eye[2] = MSG_ReadFloat(); @@ -1690,9 +1691,8 @@ void EntityFrame4_CL_ReadFrame(void) // read the number of the frame this refers to referenceframenum = MSG_ReadLong(); // read the number of this frame - for (i = 0;i < LATESTFRAMENUMS-1;i++) - cl.latestframenums[i] = cl.latestframenums[i+1]; - cl.latestframenums[LATESTFRAMENUMS-1] = framenum = MSG_ReadLong(); + framenum = MSG_ReadLong(); + CL_NewFrameReceived(framenum); // read the start number enumber = (unsigned short) MSG_ReadShort(); if (developer_networkentities.integer >= 10) @@ -2390,15 +2390,12 @@ static int EntityState5_DeltaBits(const entity_state_t *o, const entity_state_t void EntityFrame5_CL_ReadFrame(void) { - int i, n, enumber; + int i, n, enumber, framenum; entity_t *ent; entity_state_t *s; // read the number of this frame to echo back in next input packet - for (i = 0;i < LATESTFRAMENUMS-1;i++) - cl.latestframenums[i] = cl.latestframenums[i+1]; - cl.latestframenums[LATESTFRAMENUMS-1] = MSG_ReadLong(); - if (developer_networkentities.integer >= 10) - Con_Printf("recv: svc_entities %i\n", cl.latestframenums[LATESTFRAMENUMS-1]); + framenum = MSG_ReadLong(); + CL_NewFrameReceived(framenum); if (cls.protocol != PROTOCOL_QUAKE && cls.protocol != PROTOCOL_QUAKEDP && cls.protocol != PROTOCOL_NEHAHRAMOVIE && cls.protocol != PROTOCOL_DARKPLACES1 && cls.protocol != PROTOCOL_DARKPLACES2 && cls.protocol != PROTOCOL_DARKPLACES3 && cls.protocol != PROTOCOL_DARKPLACES4 && cls.protocol != PROTOCOL_DARKPLACES5 && cls.protocol != PROTOCOL_DARKPLACES6) cls.servermovesequence = MSG_ReadLong(); // read entity numbers until we find a 0x8000 -- 2.39.2