fix the "blue bars" problem when connecting to qtv over a laggy network.

also flush the entities packet when things go wrong to avoid crashing:)
(thanks for your help, Spike)
This commit is contained in:
Bill Currie 2005-05-10 02:39:54 +00:00
parent 9482a7c0b7
commit 5480c38da5
4 changed files with 38 additions and 9 deletions

View file

@ -92,6 +92,7 @@ typedef struct server_s {
struct client_s *clients; struct client_s *clients;
int delta; int delta;
int validsequence;
frame_t frames[UPDATE_BACKUP]; frame_t frames[UPDATE_BACKUP];
entity_state_t entities[MAX_SV_ENTITIES]; entity_state_t entities[MAX_SV_ENTITIES];

View file

@ -525,6 +525,13 @@ client_parse_message (client_t *cl)
int checksumIndex, seq_hash; int checksumIndex, seq_hash;
qboolean move_issued = false; qboolean move_issued = false;
// make sure the reply sequence number matches the incoming
// sequence number
if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence)
cl->netchan.outgoing_sequence = cl->netchan.incoming_sequence;
else
cl->send_message = false; // don't reply, sequences have slipped
seq_hash = cl->netchan.incoming_sequence; seq_hash = cl->netchan.incoming_sequence;
cl->delta_sequence = -1; cl->delta_sequence = -1;
while (1) { while (1) {

View file

@ -472,7 +472,7 @@ server_run (server_t *sv)
int frame = (sv->netchan.outgoing_sequence) & UPDATE_MASK; int frame = (sv->netchan.outgoing_sequence) & UPDATE_MASK;
sv->next_run = realtime + 0.03; sv->next_run = realtime + 0.03;
sv->frames[frame].delta_sequence = sv->delta; sv->frames[frame].delta_sequence = sv->delta;
if (sv->delta != -1) { if (sv->validsequence && sv->delta != -1) {
delta_msg[1] = sv->delta; delta_msg[1] = sv->delta;
Netchan_Transmit (&sv->netchan, sizeof (delta_msg), delta_msg); Netchan_Transmit (&sv->netchan, sizeof (delta_msg), delta_msg);
return; return;

View file

@ -303,6 +303,26 @@ sv_parse_delta (qmsg_t *msg, int bits, entity_state_t *ent)
ent->frame = (ent->frame & 0x00ff) | (MSG_ReadByte (msg) << 8); ent->frame = (ent->frame & 0x00ff) | (MSG_ReadByte (msg) << 8);
} }
static void
flush_entity_packet (server_t *sv, qmsg_t *msg)
{
entity_state_t dummy;
int word;
memset (&dummy, 0, sizeof (dummy));
sv->frames[sv->netchan.incoming_sequence & UPDATE_MASK].invalid = true;
while (1) {
word = MSG_ReadShort (msg);
if (msg->badread) {
qtv_printf ("msg_badread in packetentities\n");
return;
}
if (!word)
break;
sv_parse_delta (msg, word, &dummy);
}
}
static void static void
sv_packetentities (server_t *sv, qmsg_t *msg, int delta) sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
{ {
@ -328,13 +348,15 @@ sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
full = 0; full = 0;
if (oldpacket != -1) { if (oldpacket != -1) {
if (sv->netchan.outgoing_sequence - oldpacket > UPDATE_BACKUP) { if (sv->netchan.outgoing_sequence - oldpacket > UPDATE_BACKUP) {
//XXX flush_entity_packet (); flush_entity_packet (sv, msg);
return; return;
} }
oldp = &sv->frames[oldpacket & UPDATE_MASK].entities; oldp = &sv->frames[oldpacket & UPDATE_MASK].entities;
sv->validsequence = sv->netchan.incoming_sequence;
} else { } else {
oldp = &dummy; oldp = &dummy;
dummy.num_entities = 0; dummy.num_entities = 0;
sv->validsequence = sv->netchan.incoming_sequence;
full = 1; full = 1;
memset (sv->ent_valid, 0, sizeof (sv->ent_valid)); memset (sv->ent_valid, 0, sizeof (sv->ent_valid));
} }
@ -355,7 +377,7 @@ sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
if (newindex >= MAX_DEMO_PACKET_ENTITIES) { if (newindex >= MAX_DEMO_PACKET_ENTITIES) {
qtv_printf ("A too many packet entities\n"); qtv_printf ("A too many packet entities\n");
Sys_Quit (); Sys_Quit ();
//XXX flush_entitiy_packet flush_entity_packet (sv, msg);
return; return;
} }
newp->entities[newindex] = oldp->entities[oldindex]; newp->entities[newindex] = oldp->entities[oldindex];
@ -376,13 +398,13 @@ sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
while (newnum > oldnum) { while (newnum > oldnum) {
if (full) { if (full) {
qtv_printf ("WARNING: oldcopy on full update\n"); qtv_printf ("WARNING: oldcopy on full update\n");
//XXX flush_entitiy_packet flush_entity_packet (sv, msg);
return; return;
} }
if (newindex >= MAX_DEMO_PACKET_ENTITIES) { if (newindex >= MAX_DEMO_PACKET_ENTITIES) {
qtv_printf ("B too many packet entities\n"); qtv_printf ("B too many packet entities\n");
Sys_Quit (); Sys_Quit ();
//XXX flush_entitiy_packet flush_entity_packet (sv, msg);
return; return;
} }
newp->entities[newindex] = oldp->entities[oldindex]; newp->entities[newindex] = oldp->entities[oldindex];
@ -400,9 +422,8 @@ sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
if (newnum < oldnum) { if (newnum < oldnum) {
if (word & U_REMOVE) { if (word & U_REMOVE) {
if (full) { if (full) {
sv->delta = 0; //XXX -1?
qtv_printf ("WARNING: U_REMOVE on full update\n"); qtv_printf ("WARNING: U_REMOVE on full update\n");
//XXX flush_entitiy_packet flush_entity_packet (sv, msg);
return; return;
} }
continue; continue;
@ -410,7 +431,7 @@ sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
if (newindex >= MAX_DEMO_PACKET_ENTITIES) { if (newindex >= MAX_DEMO_PACKET_ENTITIES) {
qtv_printf ("C too many packet entities\n"); qtv_printf ("C too many packet entities\n");
Sys_Quit (); Sys_Quit ();
//XXX flush_entitiy_packet flush_entity_packet (sv, msg);
return; return;
} }
newp->entities[newindex] = sv->baselines[newnum]; newp->entities[newindex] = sv->baselines[newnum];
@ -421,7 +442,7 @@ sv_packetentities (server_t *sv, qmsg_t *msg, int delta)
} }
if (newnum == oldnum) { if (newnum == oldnum) {
if (full) { if (full) {
sv->delta = 0; //XXX -1? sv->validsequence = 0;
qtv_printf ("WARNING: delta on full update\n"); qtv_printf ("WARNING: delta on full update\n");
} }
if (word & U_REMOVE) { if (word & U_REMOVE) {