patch from sunspot/shadows to make net_drop non-global and a bunch more

work on qtv
This commit is contained in:
Bill Currie 2005-05-08 06:35:46 +00:00
parent bc73af37f2
commit a154ad2835
8 changed files with 290 additions and 51 deletions

View file

@ -104,6 +104,7 @@ typedef struct netchan_s {
float frame_rate; float frame_rate;
int drop_count; // dropped packets, cleared each level int drop_count; // dropped packets, cleared each level
int net_drop; //packets dropped before this one
int good_count; // cleared each level int good_count; // cleared each level
netadr_t remote_address; netadr_t remote_address;
@ -137,7 +138,6 @@ typedef struct netchan_s {
double outgoing_time[MAX_LATENT]; double outgoing_time[MAX_LATENT];
} netchan_t; } netchan_t;
extern int net_drop; // packets dropped before this one
extern int net_nochoke; // don't choke packets extern int net_nochoke; // don't choke packets
extern int net_blocksend; // don't send packets (used by client for demos) extern int net_blocksend; // don't send packets (used by client for demos)
extern double *net_realtime; extern double *net_realtime;

View file

@ -103,7 +103,6 @@ static __attribute__ ((unused)) const char rcsid[] =
to the new value before sending out any replies. to the new value before sending out any replies.
*/ */
int net_drop;
int net_nochoke; int net_nochoke;
int net_blocksend; int net_blocksend;
double *net_realtime; double *net_realtime;
@ -394,8 +393,8 @@ Netchan_Process (netchan_t *chan)
} }
// dropped packets don't keep the message from being used // dropped packets don't keep the message from being used
net_drop = sequence - (chan->incoming_sequence + 1); chan->net_drop = sequence - (chan->incoming_sequence + 1);
if (net_drop > 0) { if (chan->net_drop > 0) {
chan->drop_count += 1; chan->drop_count += 1;
if (showdrop->int_val) if (showdrop->int_val)

View file

@ -43,6 +43,7 @@ typedef struct client_s {
struct client_s *clnext; struct client_s *clnext;
struct info_s *userinfo; struct info_s *userinfo;
struct connection_s *con; struct connection_s *con;
const char *name;
int drop; int drop;
netchan_t netchan; netchan_t netchan;
backbuf_t backbuf; backbuf_t backbuf;
@ -53,6 +54,9 @@ typedef struct client_s {
struct server_s *server; struct server_s *server;
int connected; int connected;
plent_state_t state;
usercmd_t lastcmd;
} client_t; } client_t;
typedef struct challenge_s { typedef struct challenge_s {

View file

@ -80,6 +80,7 @@ typedef struct server_s {
struct info_s *info; struct info_s *info;
char *soundlist[MAX_SOUNDS + 1]; char *soundlist[MAX_SOUNDS + 1];
char *modellist[MAX_MODELS + 1]; char *modellist[MAX_MODELS + 1];
int playermodel;
struct client_s *clients; struct client_s *clients;

View file

@ -47,6 +47,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/cbuf.h" #include "QF/cbuf.h"
#include "QF/cmd.h" #include "QF/cmd.h"
#include "QF/console.h" #include "QF/console.h"
#include "QF/checksum.h"
#include "QF/dstring.h" #include "QF/dstring.h"
#include "QF/hash.h" #include "QF/hash.h"
#include "QF/idparse.h" #include "QF/idparse.h"
@ -282,7 +283,7 @@ cl_disconnect_f (client_t *cl, void *unused)
qtv_printf ("not connected to a server\n"); qtv_printf ("not connected to a server\n");
return; return;
} }
Server_Disconnect (cl); client_drop (cl);
} }
static ucmd_t ucmds[] = { static ucmd_t ucmds[] = {
@ -351,6 +352,90 @@ client_exec_command (client_t *cl, const char *s)
} }
} }
static void
spectator_move (client_t *cl, usercmd_t *ucmd)
{
float frametime = ucmd->msec * 0.001;
float control, drop, friction, fmove, smove, speed, newspeed;
float currentspeed, addspeed, accelspeed, wishspeed;
int i;
vec3_t wishdir, wishvel;
vec3_t forward, right, up;
server_t *sv = cl->server;
AngleVectors (cl->state.cmd.angles, forward, right, up);
speed = DotProduct (cl->state.velocity, cl->state.velocity);
if (speed < 1) {
VectorZero (cl->state.velocity);
} else {
speed = sqrt (speed);
drop = 0;
friction = sv->movevars.friction * 1.5;
control = speed < sv->movevars.stopspeed ? sv->movevars.stopspeed
: speed;
drop += control * friction * frametime;
newspeed = speed - drop;
if (newspeed < 0)
newspeed = 0;
newspeed /= speed;
VectorScale (cl->state.velocity, newspeed, cl->state.velocity);
}
fmove = ucmd->forwardmove;
smove = ucmd->sidemove;
VectorNormalize (forward);
VectorNormalize (right);
for (i = 0; i < 3; i++)
wishvel[i] = forward[i] * fmove + right[i] * smove;
wishvel[2] += ucmd->upmove;
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize (wishdir);
if (wishspeed > sv->movevars.spectatormaxspeed) {
VectorScale (wishvel, sv->movevars.spectatormaxspeed / wishspeed,
wishvel);
wishspeed = sv->movevars.spectatormaxspeed;
}
currentspeed = DotProduct (cl->state.velocity, wishdir);
addspeed = wishspeed - currentspeed;
if (addspeed <= 0)
return;
accelspeed = sv->movevars.accelerate * frametime * wishspeed;
if (accelspeed > addspeed)
accelspeed = addspeed;
VectorMultAdd (cl->state.velocity, accelspeed, wishdir,
cl->state.velocity);
VectorMultAdd (cl->state.origin, frametime, cl->state.velocity,
cl->state.origin);
}
static void
run_command (client_t *cl, usercmd_t *ucmd)
{
if (ucmd->msec > 50) {
usercmd_t cmd = *ucmd;
int oldmsec = ucmd->msec;
cmd.msec = oldmsec / 2;
run_command (cl, &cmd);
cmd.msec = oldmsec / 2;
cmd.impulse = 0;
run_command (cl, &cmd);
return;
}
VectorCopy (ucmd->angles, cl->state.cmd.angles);
spectator_move (cl, ucmd);
}
static void static void
client_parse_message (client_t *cl) client_parse_message (client_t *cl)
{ {
@ -358,6 +443,11 @@ client_parse_message (client_t *cl)
vec3_t o; vec3_t o;
const char *s; const char *s;
usercmd_t oldest, oldcmd, newcmd; usercmd_t oldest, oldcmd, newcmd;
byte checksum, calculatedChecksum;
int checksumIndex, seq_hash;
qboolean move_issued = false;
seq_hash = cl->netchan.incoming_sequence;
while (1) { while (1) {
if (net_message->badread) { if (net_message->badread) {
@ -381,19 +471,20 @@ client_parse_message (client_t *cl)
/*cl->delta_sequence = */MSG_ReadByte (net_message); /*cl->delta_sequence = */MSG_ReadByte (net_message);
break; break;
case clc_move: case clc_move:
/*if (move_issued) checksumIndex = MSG_GetReadCount (net_message);
return; // someone is trying to cheat... checksum = MSG_ReadByte (net_message);
move_issued = true;*/
/*checksumIndex = */MSG_GetReadCount (net_message);
/*checksum = (byte) */MSG_ReadByte (net_message);
// read loss percentage // read loss percentage
/*cl->lossage = */MSG_ReadByte (net_message); /*cl->lossage = */MSG_ReadByte (net_message);
MSG_ReadDeltaUsercmd (net_message, &nullcmd, &oldest); MSG_ReadDeltaUsercmd (net_message, &nullcmd, &oldest);
MSG_ReadDeltaUsercmd (net_message, &oldest, &oldcmd); MSG_ReadDeltaUsercmd (net_message, &oldest, &oldcmd);
MSG_ReadDeltaUsercmd (net_message, &oldcmd, &newcmd); MSG_ReadDeltaUsercmd (net_message, &oldcmd, &newcmd);
#if 0 if (!cl->server)
if (cl->state != cs_spawned)
break; break;
if (move_issued)
break; // someone is trying to cheat...
move_issued = true;
// if (cl->state != cs_spawned)
// break;
// if the checksum fails, ignore the rest of the packet // if the checksum fails, ignore the rest of the packet
calculatedChecksum = calculatedChecksum =
COM_BlockSequenceCRCByte (net_message->message->data + COM_BlockSequenceCRCByte (net_message->message->data +
@ -403,28 +494,28 @@ client_parse_message (client_t *cl)
if (calculatedChecksum != checksum) { if (calculatedChecksum != checksum) {
Con_DPrintf Con_DPrintf
("Failed command checksum for %s(%d) (%d != %d)\n", ("Failed command checksum for %s(%d) (%d != %d)\n",
cl->name, cl->netchan.incoming_sequence, checksum, Info_ValueForKey (cl->userinfo, "name"),
cl->netchan.incoming_sequence, checksum,
calculatedChecksum); calculatedChecksum);
return; return;
} }
if (!sv.paused) { // if (!sv.paused) {
SV_PreRunCmd (); // SV_PreRunCmd ();
if (net_drop < 20) { if (cl->netchan.net_drop < 20) {
while (net_drop > 2) { while (cl->netchan.net_drop > 2) {
SV_RunCmd (&cl->lastcmd, 0); run_command (cl, &cl->lastcmd);
net_drop--; cl->netchan.net_drop--;
} }
if (net_drop > 1) if (cl->netchan.net_drop > 1)
SV_RunCmd (&oldest, 0); run_command (cl, &oldest);
if (net_drop > 0) if (cl->netchan.net_drop > 0)
SV_RunCmd (&oldcmd, 0); run_command (cl, &oldcmd);
}
SV_RunCmd (&newcmd, 0);
SV_PostRunCmd ();
} }
run_command (cl, &newcmd);
// SV_PostRunCmd ();
// }
cl->lastcmd = newcmd; cl->lastcmd = newcmd;
cl->lastcmd.buttons = 0; // avoid multiple fires on lag cl->lastcmd.buttons = 0; // avoid multiple fires on lag
#endif
break; break;
case clc_stringcmd: case clc_stringcmd:
s = MSG_ReadString (net_message); s = MSG_ReadString (net_message);
@ -432,13 +523,7 @@ client_parse_message (client_t *cl)
break; break;
case clc_tmove: case clc_tmove:
MSG_ReadCoordV (net_message, o); MSG_ReadCoordV (net_message, o);
#if 0 VectorCopy (o, cl->state.origin);
// only allowed by spectators
if (host_client->spectator) {
VectorCopy (o, SVvector (sv_player, origin));
SV_LinkEdict (sv_player, false);
}
#endif
break; break;
case clc_upload: case clc_upload:
size = MSG_ReadShort (net_message); size = MSG_ReadShort (net_message);
@ -449,6 +534,128 @@ client_parse_message (client_t *cl)
} }
} }
static void
write_player (int num, plent_state_t *pl, server_t *sv, sizebuf_t *msg)
{
int i;
int pflags = (pl->flags & (PF_GIB | PF_DEAD))
| PF_MSEC | PF_COMMAND;
int qf_bits = 0;
if (pl->modelindex != sv->playermodel)
pflags |= PF_MODEL;
for (i = 0; i < 3; i++)
if (pl->velocity[i])
pflags |= PF_VELOCITY1 << i;
if (pl->effects & 0xff)
pflags |= PF_EFFECTS;
if (pl->skinnum)
pflags |= PF_SKINNUM;
qf_bits = 0;
#if 0
if (client->stdver > 1) {
if (sv_fields.alpha != -1 && pl->alpha)
qf_bits |= PF_ALPHA;
if (sv_fields.scale != -1 && pl->scale)
qf_bits |= PF_SCALE;
if (pl->effects & 0xff00)
qf_bits |= PF_EFFECTS2;
if (sv_fields.glow_size != -1 && pl->glow_size)
qf_bits |= PF_GLOWSIZE;
if (sv_fields.glow_color != -1 && pl->glow_color)
qf_bits |= PF_GLOWCOLOR;
if (sv_fields.colormod != -1
&& !VectorIsZero (pl->colormod))
qf_bits |= PF_COLORMOD;
if (pl->frame & 0xff00)
qf_bits |= PF_FRAME2;
if (qf_bits)
pflags |= PF_QF;
}
#endif
// if (cl->spectator) {
// // only sent origin and velocity to spectators
// pflags &= PF_VELOCITY1 | PF_VELOCITY2 | PF_VELOCITY3;
// } else if (ent == clent) {
// // don't send a lot of data on personal entity
// pflags &= ~(PF_MSEC | PF_COMMAND);
// if (pl->weaponframe)
// pflags |= PF_WEAPONFRAME;
// }
// if (client->spec_track && client->spec_track - 1 == j
// && pl->weaponframe)
// pflags |= PF_WEAPONFRAME;
MSG_WriteByte (msg, svc_playerinfo);
MSG_WriteByte (msg, num);
MSG_WriteShort (msg, pflags);
MSG_WriteCoordV (msg, pl->origin);
MSG_WriteByte (msg, pl->frame);
if (pflags & PF_MSEC) {
//msec = 1000 * (sv.time - cl->localtime);
//if (msec > 255)
// msec = 255;
MSG_WriteByte (msg, pl->msec);
}
if (pflags & PF_COMMAND) {
MSG_WriteDeltaUsercmd (msg, &nullcmd, &pl->cmd);
}
for (i = 0; i < 3; i++)
if (pflags & (PF_VELOCITY1 << i))
MSG_WriteShort (msg, pl->velocity[i]);
if (pflags & PF_MODEL)
MSG_WriteByte (msg, pl->modelindex);
if (pflags & PF_SKINNUM)
MSG_WriteByte (msg, pl->skinnum);
if (pflags & PF_EFFECTS)
MSG_WriteByte (msg, pl->effects);
if (pflags & PF_WEAPONFRAME)
MSG_WriteByte (msg, pl->weaponframe);
if (pflags & PF_QF) {
MSG_WriteByte (msg, qf_bits);
if (qf_bits & PF_ALPHA)
MSG_WriteByte (msg, pl->alpha);
if (qf_bits & PF_SCALE)
MSG_WriteByte (msg, pl->scale);
if (qf_bits & PF_EFFECTS2)
MSG_WriteByte (msg, pl->effects >> 8);
if (qf_bits & PF_GLOWSIZE)
MSG_WriteByte (msg, pl->scale);
if (qf_bits & PF_GLOWCOLOR)
MSG_WriteByte (msg, pl->glow_color);
if (qf_bits & PF_COLORMOD)
MSG_WriteByte (msg, pl->colormod);
if (qf_bits & PF_FRAME2)
MSG_WriteByte (msg, pl->frame >> 8);
}
}
static void
write_entities (client_t *client, sizebuf_t *msg)
{
server_t *sv = client->server;
int i;
for (i = 0; i < MAX_SV_PLAYERS; i++) {
if (!sv->players[i].info)
continue;
write_player (i, &sv->players[i].ent, sv, msg);
}
}
static void static void
cl_send_messages (client_t *cl) cl_send_messages (client_t *cl)
{ {
@ -463,6 +670,8 @@ cl_send_messages (client_t *cl)
if (cl->backbuf.num_backbuf) if (cl->backbuf.num_backbuf)
MSG_Reliable_Send (&cl->backbuf); MSG_Reliable_Send (&cl->backbuf);
if (cl->connected) { if (cl->connected) {
write_entities (cl, &msg);
write_player (31, &cl->state, cl->server, &msg);
MSG_WriteByte (&msg, svc_packetentities); MSG_WriteByte (&msg, svc_packetentities);
MSG_WriteShort (&msg, 0); MSG_WriteShort (&msg, 0);
} }
@ -488,12 +697,6 @@ client_handler (connection_t *con, void *object)
cl->send_message = true; cl->send_message = true;
//if (cl->state != cs_zombie) //if (cl->state != cs_zombie)
client_parse_message (cl); client_parse_message (cl);
cl_send_messages (cl);
if (cl->drop) {
Connection_Del (cl->con);
Info_Destroy (cl->userinfo);
free (cl);
}
} }
} }
@ -546,9 +749,10 @@ client_connect (connection_t *con, void *object)
Netchan_Setup (&cl->netchan, con->address, qport, NC_READ_QPORT); Netchan_Setup (&cl->netchan, con->address, qport, NC_READ_QPORT);
cl->clnext = clients; cl->clnext = clients;
clients = cl; clients = cl;
cl->backbuf.netchan = &cl->netchan;
cl->backbuf.name = "FIXME";
cl->userinfo = userinfo; cl->userinfo = userinfo;
cl->name = Info_ValueForKey (userinfo, "name");
cl->backbuf.name = cl->name;
cl->backbuf.netchan = &cl->netchan;
cl->con = con; cl->con = con;
con->object = cl; con->object = cl;
con->handler = client_handler; con->handler = client_handler;
@ -631,14 +835,42 @@ Client_New (client_t *cl)
Info_MakeString (sv->info, 0))); Info_MakeString (sv->info, 0)));
} }
static void
delete_client (client_t *cl)
{
if (cl->server)
Server_Disconnect (cl);
Connection_Del (cl->con);
Info_Destroy (cl->userinfo);
free (cl);
}
void void
Client_Frame (void) Client_Frame (void)
{ {
client_t *cl; client_t **c;
for (cl = clients; cl; cl = cl->next) { for (c = &clients; *c; ) {
client_t *cl = *c;
if (realtime - cl->netchan.last_received > 60) {
qtv_printf ("client %s timed out\n", (*c)->name);
client_drop (cl);
}
if (cl->netchan.message.overflowed) {
qtv_printf ("client %s overflowed\n", cl->name);
client_drop (cl);
}
if (cl->drop) {
qtv_printf ("client %s dropped\n", cl->name);
*c = cl->clnext;
delete_client (cl);
continue;
}
if (cl->send_message) { if (cl->send_message) {
cl_send_messages (cl); cl_send_messages (cl);
cl->send_message = false;
} }
c = &(*c)->clnext;
} }
} }

View file

@ -308,6 +308,7 @@ server_connect (connection_t *con, void *object)
Netchan_Setup (&sv->netchan, con->address, sv->qport, NC_SEND_QPORT); Netchan_Setup (&sv->netchan, con->address, sv->qport, NC_SEND_QPORT);
sv->netchan.outgoing_sequence = 1; sv->netchan.outgoing_sequence = 1;
sv->connected = 1; sv->connected = 1;
sv->playermodel = -1;
MSG_WriteByte (msg, qtv_stringcmd); MSG_WriteByte (msg, qtv_stringcmd);
MSG_WriteString (msg, "new"); MSG_WriteString (msg, "new");
sv->next_run = realtime; sv->next_run = realtime;

View file

@ -156,14 +156,16 @@ sv_modellist (server_t *sv, qmsg_t *msg)
if (!str[0]) if (!str[0])
break; break;
//qtv_printf ("%s\n", str); //qtv_printf ("%s\n", str);
nummodels++; n = nummodels++;
if (nummodels == MAX_MODELS) { if (nummodels == MAX_MODELS) {
while (str[0]) while (str[0])
str = MSG_ReadString (msg); str = MSG_ReadString (msg);
MSG_ReadByte (msg); MSG_ReadByte (msg);
return; return;
} }
sv->modellist[nummodels - 1] = strdup (str); sv->modellist[n] = strdup (str);
if (!strcmp (sv->modellist[n], "progs/player.mdl"))
sv->playermodel = n;
} }
n = MSG_ReadByte (msg); n = MSG_ReadByte (msg);
if (n) { if (n) {

View file

@ -1904,14 +1904,14 @@ SV_ExecuteClientMessage (client_t *cl)
if (!sv.paused) { if (!sv.paused) {
SV_PreRunCmd (); SV_PreRunCmd ();
if (net_drop < 20) { if (cl->netchan.net_drop < 20) {
while (net_drop > 2) { while (cl->netchan.net_drop > 2) {
SV_RunCmd (&cl->lastcmd, 0); SV_RunCmd (&cl->lastcmd, 0);
net_drop--; cl->netchan.net_drop--;
} }
if (net_drop > 1) if (cl->netchan.net_drop > 1)
SV_RunCmd (&oldest, 0); SV_RunCmd (&oldest, 0);
if (net_drop > 0) if (cl->netchan.net_drop > 0)
SV_RunCmd (&oldcmd, 0); SV_RunCmd (&oldcmd, 0);
} }
SV_RunCmd (&newcmd, 0); SV_RunCmd (&newcmd, 0);