mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 15:41:59 +00:00
patch from sunspot/shadows to make net_drop non-global and a bunch more
work on qtv
This commit is contained in:
parent
bc73af37f2
commit
a154ad2835
8 changed files with 290 additions and 51 deletions
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue