mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 09:51:41 +00:00
lots of progress, however mvd player deltas are borked atm
This commit is contained in:
parent
978ad6ff48
commit
d017b87c2b
6 changed files with 489 additions and 161 deletions
|
@ -210,99 +210,6 @@ qtv_modellist (server_t *sv)
|
|||
sv->next_run = realtime;
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_p_signon_f (server_t *sv, int len)
|
||||
{
|
||||
int c, start;
|
||||
vec3_t v, a;
|
||||
|
||||
start = net_message->readcount;
|
||||
while (net_message->readcount - start < len) {
|
||||
c = MSG_ReadByte (net_message);
|
||||
if (c == -1)
|
||||
break;
|
||||
//qtv_printf ("svc: %d\n", c);
|
||||
switch (c) {
|
||||
case svc_serverdata:
|
||||
qtv_serverdata (sv);
|
||||
break;
|
||||
case svc_soundlist:
|
||||
qtv_soundlist (sv);
|
||||
break;
|
||||
case svc_modellist:
|
||||
qtv_modellist (sv);
|
||||
break;
|
||||
case svc_spawnstaticsound:
|
||||
MSG_ReadCoordV (net_message, v);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
MSG_ReadShort (net_message);
|
||||
case svc_spawnstatic:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadCoordAngleV (net_message, v, a);
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadString (net_message);
|
||||
break;
|
||||
case svc_updatestatlong:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadLong (net_message);
|
||||
break;
|
||||
case svc_updatestat:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
break;
|
||||
default:
|
||||
qtv_printf ("unkown svc: %d\n", c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_packet_f (server_t *sv)
|
||||
{
|
||||
int len_type, len, type, pos;
|
||||
byte *buf;
|
||||
|
||||
len_type = MSG_ReadShort (net_message);
|
||||
len = len_type & 0x0fff;
|
||||
type = len_type & 0xf000;
|
||||
pos = net_message->readcount;
|
||||
qtv_printf ("qtv_packet: %d %d\n", type, len);
|
||||
switch (type) {
|
||||
case qtv_p_signon:
|
||||
qtv_p_signon_f (sv, len);
|
||||
break;
|
||||
case qtv_p_print:
|
||||
qtv_printf ("%s\n", MSG_ReadString (net_message));
|
||||
break;
|
||||
case qtv_p_reliable:
|
||||
case qtv_p_unreliable:
|
||||
default:
|
||||
//absorb unhandled packet types
|
||||
qtv_printf ("unknown packet type %x (%d bytes)\n", type, len);
|
||||
break;
|
||||
}
|
||||
if (net_message->readcount - pos != len) {
|
||||
qtv_printf ("packet not completely read\n");
|
||||
|
||||
len -= net_message->readcount - pos;
|
||||
if (len > 0) {
|
||||
buf = malloc (len);
|
||||
MSG_ReadBytes (net_message, buf, len);
|
||||
free (buf); //XXX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_cmd_f (server_t *sv)
|
||||
{
|
||||
|
@ -358,6 +265,378 @@ qtv_stringcmd_f (server_t *sv)
|
|||
c->func (sv);
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_p_signon_f (server_t *sv, int len)
|
||||
{
|
||||
int c, start;
|
||||
vec3_t v, a;
|
||||
|
||||
start = net_message->readcount;
|
||||
while (net_message->readcount - start < len) {
|
||||
c = MSG_ReadByte (net_message);
|
||||
if (c == -1)
|
||||
break;
|
||||
//qtv_printf ("svc: %d\n", c);
|
||||
switch (c) {
|
||||
case svc_serverdata:
|
||||
qtv_serverdata (sv);
|
||||
break;
|
||||
case svc_stufftext:
|
||||
qtv_stringcmd_f (sv);
|
||||
break;
|
||||
case svc_soundlist:
|
||||
qtv_soundlist (sv);
|
||||
break;
|
||||
case svc_modellist:
|
||||
qtv_modellist (sv);
|
||||
break;
|
||||
case svc_spawnstaticsound:
|
||||
MSG_ReadCoordV (net_message, v);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
MSG_ReadShort (net_message);
|
||||
case svc_spawnstatic:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadCoordAngleV (net_message, v, a);
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadString (net_message);
|
||||
break;
|
||||
case svc_updatestatlong:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadLong (net_message);
|
||||
break;
|
||||
case svc_updatestat:
|
||||
MSG_ReadByte (net_message);
|
||||
MSG_ReadByte (net_message);
|
||||
break;
|
||||
default:
|
||||
qtv_printf ("unknown svc: %d\n", c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_parse_delta (server_t *sv, qmsg_t *msg, int bits)
|
||||
{
|
||||
bits &= ~511;
|
||||
|
||||
if (bits & U_MOREBITS)
|
||||
bits |= MSG_ReadByte (msg);
|
||||
if (bits & U_EXTEND1) {
|
||||
bits |= MSG_ReadByte (msg) << 16;
|
||||
if (bits & U_EXTEND2)
|
||||
bits |= MSG_ReadByte (msg) << 24;
|
||||
}
|
||||
if (bits & U_MODEL)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_FRAME)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_COLORMAP)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_SKIN)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_EFFECTS)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_ORIGIN1)
|
||||
MSG_ReadCoord (msg);
|
||||
if (bits & U_ANGLE1)
|
||||
MSG_ReadAngle (msg);
|
||||
if (bits & U_ORIGIN2)
|
||||
MSG_ReadCoord (msg);
|
||||
if (bits & U_ANGLE2)
|
||||
MSG_ReadAngle (msg);
|
||||
if (bits & U_ORIGIN3)
|
||||
MSG_ReadCoord (msg);
|
||||
if (bits & U_ANGLE3)
|
||||
MSG_ReadAngle (msg);
|
||||
if (bits & U_SOLID) {
|
||||
// FIXME
|
||||
}
|
||||
if (!(bits & U_EXTEND1))
|
||||
return;
|
||||
if (bits & U_ALPHA)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_SCALE)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_EFFECTS2)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_GLOWSIZE)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_GLOWCOLOR)
|
||||
MSG_ReadByte (msg);
|
||||
if (bits & U_COLORMOD)
|
||||
MSG_ReadByte (msg);
|
||||
if (!(bits & U_EXTEND1))
|
||||
return;
|
||||
if (bits & U_FRAME2)
|
||||
MSG_ReadByte (msg);
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_packetentities (server_t *sv, qmsg_t *msg, int delta)
|
||||
{
|
||||
unsigned short word;
|
||||
int newnum, oldnum;
|
||||
|
||||
newnum = oldnum = 0;
|
||||
if (delta) {
|
||||
/*from =*/ MSG_ReadByte (msg);
|
||||
} else {
|
||||
}
|
||||
sv->delta = sv->netchan.incoming_sequence;
|
||||
while (1) {
|
||||
word = (unsigned short) MSG_ReadShort (msg);
|
||||
if (msg->badread) { // something didn't parse right...
|
||||
qtv_printf ("msg_badread in packetentities\n");
|
||||
return;
|
||||
}
|
||||
if (!word) {
|
||||
// copy rest of ents from old packet
|
||||
break;
|
||||
}
|
||||
if (newnum < oldnum) {
|
||||
if (word & U_REMOVE) {
|
||||
continue;
|
||||
}
|
||||
qtv_parse_delta (sv, msg, word);
|
||||
continue;
|
||||
}
|
||||
if (newnum == oldnum) {
|
||||
if (word & U_REMOVE) {
|
||||
continue;
|
||||
}
|
||||
qtv_parse_delta (sv, msg, word);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_parse_updates (server_t *sv, int reliable, int len)
|
||||
{
|
||||
int c, msec, type, to, start;
|
||||
sizebuf_t sub_message_buf;
|
||||
qmsg_t sub_message;
|
||||
vec3_t v;
|
||||
|
||||
memset (&sub_message_buf, 0, sizeof (sub_message_buf));
|
||||
memset (&sub_message, 0, sizeof (sub_message));
|
||||
sub_message.message = &sub_message_buf;
|
||||
|
||||
start = net_message->readcount;
|
||||
while (net_message->readcount - start < len) {
|
||||
msec = MSG_ReadByte (net_message);
|
||||
type = MSG_ReadByte (net_message);
|
||||
if (type == dem_multiple) {
|
||||
to = MSG_ReadLong (net_message);
|
||||
} else if (type == dem_single) {
|
||||
to = MSG_ReadByte (net_message);
|
||||
}
|
||||
|
||||
sub_message_buf.cursize = MSG_ReadLong (net_message);
|
||||
sub_message_buf.maxsize = sub_message_buf.cursize;
|
||||
sub_message_buf.data = net_message->message->data;
|
||||
sub_message_buf.data += net_message->readcount;
|
||||
sub_message.readcount = 0;
|
||||
sub_message.badread = 0;
|
||||
net_message->readcount += sub_message_buf.cursize;
|
||||
|
||||
while (1) {
|
||||
c = MSG_ReadByte (&sub_message);
|
||||
if (c == -1)
|
||||
break;
|
||||
//qtv_printf ("qtv_parse_updates: svc: %d\n", c);
|
||||
switch (c) {
|
||||
default:
|
||||
qtv_printf ("qtv_parse_updates: unknown svc: %d\n", c);
|
||||
return;
|
||||
case svc_nop:
|
||||
break;
|
||||
case svc_updatestat:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadByte (&sub_message);
|
||||
break;
|
||||
case svc_setview:
|
||||
break;
|
||||
case svc_sound:
|
||||
c = MSG_ReadShort (&sub_message);
|
||||
if (c & SND_VOLUME)
|
||||
MSG_ReadByte (&sub_message);
|
||||
if (c & SND_ATTENUATION)
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadCoordV (&sub_message, v);
|
||||
break;
|
||||
case svc_print:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_stufftext:
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_setangle:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadAngleV(&sub_message, v);
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_updatefrags:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadShort (&sub_message);
|
||||
break;
|
||||
case svc_stopsound:
|
||||
MSG_ReadShort (&sub_message);
|
||||
break;
|
||||
case svc_damage:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadCoordV (&sub_message, v);
|
||||
break;
|
||||
case svc_temp_entity:
|
||||
//XXX
|
||||
break;
|
||||
case svc_setpause:
|
||||
MSG_ReadByte (&sub_message);
|
||||
break;
|
||||
case svc_centerprint:
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_killedmonster:
|
||||
//XXX
|
||||
break;
|
||||
case svc_foundsecret:
|
||||
//XXX
|
||||
break;
|
||||
case svc_intermission:
|
||||
MSG_ReadCoordV (&sub_message, v);
|
||||
MSG_ReadAngleV (&sub_message, v);
|
||||
break;
|
||||
case svc_finale:
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_cdtrack:
|
||||
MSG_ReadByte (&sub_message);
|
||||
break;
|
||||
case svc_sellscreen:
|
||||
//XXX
|
||||
break;
|
||||
case svc_smallkick:
|
||||
//XXX
|
||||
break;
|
||||
case svc_bigkick:
|
||||
//XXX
|
||||
break;
|
||||
case svc_updateping:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadShort (&sub_message);
|
||||
break;
|
||||
case svc_updateentertime:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadFloat (&sub_message);
|
||||
break;
|
||||
case svc_updatestatlong:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadLong (&sub_message);
|
||||
break;
|
||||
case svc_muzzleflash:
|
||||
MSG_ReadShort (&sub_message);
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadLong (&sub_message);
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_playerinfo:
|
||||
//XXX
|
||||
break;
|
||||
case svc_nails:
|
||||
//XXX
|
||||
break;
|
||||
case svc_packetentities:
|
||||
qtv_packetentities (sv, &sub_message, 0);
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
qtv_packetentities (sv, &sub_message, 1);
|
||||
break;
|
||||
case svc_maxspeed:
|
||||
MSG_ReadFloat (&sub_message);
|
||||
break;
|
||||
case svc_entgravity:
|
||||
MSG_ReadFloat (&sub_message);
|
||||
break;
|
||||
case svc_setinfo:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadString (&sub_message);
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_serverinfo:
|
||||
MSG_ReadString (&sub_message);
|
||||
MSG_ReadString (&sub_message);
|
||||
break;
|
||||
case svc_updatepl:
|
||||
MSG_ReadByte (&sub_message);
|
||||
MSG_ReadByte (&sub_message);
|
||||
break;
|
||||
case svc_nails2:
|
||||
//XXX
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qtv_packet_f (server_t *sv)
|
||||
{
|
||||
int len_type, len, type, pos;
|
||||
byte *buf;
|
||||
int reliable = 0;
|
||||
|
||||
len_type = MSG_ReadShort (net_message);
|
||||
len = len_type & 0x0fff;
|
||||
type = len_type & 0xf000;
|
||||
pos = net_message->readcount;
|
||||
qtv_printf ("qtv_packet: %x %d\n", type, len);
|
||||
switch (type) {
|
||||
case qtv_p_signon:
|
||||
qtv_p_signon_f (sv, len);
|
||||
break;
|
||||
case qtv_p_print:
|
||||
qtv_printf ("%s\n", MSG_ReadString (net_message));
|
||||
break;
|
||||
case qtv_p_reliable:
|
||||
reliable = 1;
|
||||
case qtv_p_unreliable:
|
||||
qtv_parse_updates (sv, reliable, len);
|
||||
break;
|
||||
default:
|
||||
//absorb unhandled packet types
|
||||
qtv_printf ("unknown packet type %x (%d bytes)\n", type, len);
|
||||
break;
|
||||
}
|
||||
if (net_message->readcount - pos != len) {
|
||||
qtv_printf ("packet not completely read\n");
|
||||
|
||||
len -= net_message->readcount - pos;
|
||||
if (len > 0) {
|
||||
buf = malloc (len);
|
||||
MSG_ReadBytes (net_message, buf, len);
|
||||
free (buf); //XXX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
server_handler (connection_t *con, void *object)
|
||||
{
|
||||
|
@ -380,7 +659,13 @@ server_handler (connection_t *con, void *object)
|
|||
//qtv_printf ("cmd: %d\n", cmd);
|
||||
switch (cmd) {
|
||||
default:
|
||||
qtv_printf ("Illegible server message: %d\n", cmd);
|
||||
qtv_printf ("Illegible server message: %d [%d]\n", cmd,
|
||||
net_message->readcount);
|
||||
while ((cmd = MSG_ReadByte (net_message)) != -1) {
|
||||
qtv_printf ("%02x (%c) ", cmd, cmd ? sys_char_map[cmd]
|
||||
: '#');
|
||||
}
|
||||
qtv_printf ("\n");
|
||||
goto bail;
|
||||
case qtv_disconnect:
|
||||
qtv_printf ("%s: disconnected\n", sv->name);
|
||||
|
@ -549,7 +834,7 @@ sv_del_f (void)
|
|||
}
|
||||
name = Cmd_Argv (1);
|
||||
if (!(sv = Hash_Del (server_hash, name))) {
|
||||
qtv_printf ("sv_new: %s unkown\n", name);
|
||||
qtv_printf ("sv_new: %s unknown\n", name);
|
||||
return;
|
||||
}
|
||||
Hash_Free (server_hash, sv);
|
||||
|
@ -588,14 +873,20 @@ server_shutdown (void)
|
|||
static void
|
||||
server_run (server_t *sv)
|
||||
{
|
||||
static byte msg[2] = {qtv_delta};
|
||||
static byte delta_msg[2] = {qtv_delta};
|
||||
static byte nop_msg[1] = {qtv_nop};
|
||||
if (sv->connected > 1) {
|
||||
sv->next_run = realtime + 0.03;
|
||||
msg[1] = sv->delta;
|
||||
Netchan_Transmit (&sv->netchan, sizeof (msg), msg);
|
||||
} else {
|
||||
Netchan_Transmit (&sv->netchan, 0, 0);
|
||||
if (sv->delta != -1) {
|
||||
delta_msg[1] = sv->delta;
|
||||
Netchan_Transmit (&sv->netchan, sizeof (delta_msg), delta_msg);
|
||||
return;
|
||||
} else if (!sv->netchan.message.cursize) {
|
||||
Netchan_Transmit (&sv->netchan, sizeof (nop_msg), nop_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Netchan_Transmit (&sv->netchan, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -38,13 +38,14 @@ typedef struct recorder_s recorder_t;
|
|||
void SVR_Init (void);
|
||||
recorder_t *SVR_AddUser (void (*writer)(void *, struct sizebuf_s *, int),
|
||||
int (*frame)(void *),
|
||||
void (*end_frame)(recorder_t *, void *),
|
||||
void (*finish)(void *, struct sizebuf_s *),
|
||||
int demo, void *user);
|
||||
void SVR_RemoveUser (recorder_t *r);
|
||||
struct sizebuf_s *SVR_WriteBegin (byte type, int to, int size);
|
||||
struct sizebuf_s *SVR_Datagram (void);
|
||||
void SVR_ForceFrame (void);
|
||||
int SVR_Frame (void);
|
||||
void SVR_SetDelta (recorder_t *r, int delta, int in_frame);
|
||||
void SV_SendDemoMessage (void);
|
||||
|
||||
#endif//__sv_recorder_h
|
||||
|
|
|
@ -63,6 +63,7 @@ static void *demo_dest;
|
|||
static double demo_time;
|
||||
|
||||
static recorder_t *recorder;
|
||||
static int delta_sequence;
|
||||
|
||||
#define MIN_DEMO_MEMORY 0x100000
|
||||
#define USECACHE (sv_demoUseCache->int_val && svs.demomemsize)
|
||||
|
@ -123,6 +124,12 @@ demo_frame (void *unused)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
demo_end_frame (recorder_t *r, void *unused)
|
||||
{
|
||||
SVR_SetDelta (r, ++delta_sequence, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_finish (void *unused, sizebuf_t *msg)
|
||||
{
|
||||
|
@ -406,7 +413,9 @@ SV_Record (char *name)
|
|||
} else
|
||||
QFS_Remove (demo_text->str);
|
||||
|
||||
recorder = SVR_AddUser (demo_write, demo_frame, demo_finish, 1, 0);
|
||||
recorder = SVR_AddUser (demo_write, demo_frame, demo_end_frame,
|
||||
demo_finish, 1, 0);
|
||||
delta_sequence = -1;
|
||||
demo_time = sv.time;
|
||||
|
||||
/*-------------------------------------------------*/
|
||||
|
|
|
@ -556,7 +556,7 @@ SV_WritePlayersToClient (delta_t *delta, byte *pvs, sizebuf_t *msg)
|
|||
int stdver = 2, full = stdver;
|
||||
edict_t *ent;
|
||||
packet_players_t *pack;
|
||||
client_frame_t *frame = &delta->frames[delta->cur_frame];
|
||||
client_frame_t *frame = &delta->frames[delta->in_frame];
|
||||
packet_players_t *from_pack = 0;
|
||||
plent_state_t dummy_player_state, *state = &dummy_player_state;
|
||||
static plent_state_t null_player_state;
|
||||
|
|
|
@ -59,10 +59,11 @@ typedef struct {
|
|||
backbuf_t backbuf;
|
||||
info_t *info;
|
||||
info_key_t *name_key;
|
||||
int packet;
|
||||
qboolean packet;
|
||||
recorder_t *recorder;
|
||||
sizebuf_t datagram;
|
||||
byte datagram_buf[MAX_DATAGRAM];
|
||||
int begun;
|
||||
} sv_qtv_t;
|
||||
|
||||
#define MAX_PROXIES 2
|
||||
|
@ -91,7 +92,7 @@ drop_proxy (sv_qtv_t *proxy)
|
|||
}
|
||||
MSG_WriteByte (&proxy->netchan.message, qtv_disconnect);
|
||||
Netchan_Transmit (&proxy->netchan, 0, 0);
|
||||
proxy->packet = 0;
|
||||
proxy->packet = false;
|
||||
Info_Destroy (proxy->info);
|
||||
proxy->info = 0;
|
||||
}
|
||||
|
@ -196,7 +197,7 @@ qtv_prespawn_f (sv_qtv_t *proxy)
|
|||
command = va ("cmd spawn %i 0\n", svs.spawncount);
|
||||
else
|
||||
command = va ("cmd prespawn %i %i\n", svs.spawncount, buf + 1);
|
||||
size = 5 + sv.signon_buffer_size[buf] + 1 + strlen (command) + 2;
|
||||
size = (5 + sv.signon_buffer_size[buf]) + (1 + strlen (command) + 1);
|
||||
|
||||
msg = MSG_ReliableCheckBlock (&proxy->backbuf, size);
|
||||
|
||||
|
@ -211,24 +212,28 @@ qtv_prespawn_f (sv_qtv_t *proxy)
|
|||
static void
|
||||
qtv_spawn_f (sv_qtv_t *proxy)
|
||||
{
|
||||
int pos, len;
|
||||
byte *buf;
|
||||
int pos = -1, len = 0;
|
||||
byte *buf = 0;
|
||||
|
||||
if (atoi (Cmd_Argv (1)) != svs.spawncount) {
|
||||
qtv_new_f (proxy);
|
||||
return;
|
||||
}
|
||||
MSG_WriteByte (&proxy->netchan.message, qtv_packet);
|
||||
pos = proxy->netchan.message.cursize;
|
||||
MSG_WriteShort (&proxy->netchan.message, qtv_p_signon);
|
||||
if (!proxy->backbuf.num_backbuf) {
|
||||
MSG_WriteByte (&proxy->netchan.message, qtv_packet);
|
||||
pos = proxy->netchan.message.cursize;
|
||||
MSG_WriteShort (&proxy->netchan.message, qtv_p_signon);
|
||||
}
|
||||
SV_WriteSpawn1 (&proxy->backbuf, 0);
|
||||
SV_WriteSpawn2 (&proxy->backbuf);
|
||||
len = proxy->netchan.message.cursize - pos - 2;
|
||||
buf = proxy->netchan.message.data + pos;
|
||||
buf[0] = len & 0xff;
|
||||
buf[1] |= (len >> 8) & 0x0f;
|
||||
MSG_ReliableWrite_Begin (&proxy->backbuf, qtv_stringcmd, 8);
|
||||
MSG_ReliableWrite_Begin (&proxy->backbuf, svc_stufftext, 8);
|
||||
MSG_ReliableWrite_String (&proxy->backbuf, "skins\n");
|
||||
if (pos != -1) {
|
||||
len = proxy->netchan.message.cursize - pos - 2;
|
||||
buf = proxy->netchan.message.data + pos;
|
||||
buf[0] = len & 0xff;
|
||||
buf[1] |= (len >> 8) & 0x0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -236,22 +241,20 @@ qtv_write (void *r, sizebuf_t *msg, int reliable)
|
|||
{
|
||||
sv_qtv_t *proxy = (sv_qtv_t *) r;
|
||||
sizebuf_t *buf;
|
||||
int size;
|
||||
int type;
|
||||
|
||||
if (!msg->cursize)
|
||||
return;
|
||||
if (reliable) {
|
||||
if (msg->cursize) {
|
||||
size = msg->cursize + 3;
|
||||
buf = MSG_ReliableCheckBlock (&proxy->backbuf, size);
|
||||
|
||||
MSG_WriteByte (buf, qtv_packet);
|
||||
MSG_WriteShort (buf, qtv_p_reliable | msg->cursize);
|
||||
SZ_Write (buf, msg->data, msg->cursize);
|
||||
}
|
||||
buf = MSG_ReliableCheckBlock (&proxy->backbuf, msg->cursize);
|
||||
type = qtv_p_reliable;
|
||||
} else {
|
||||
MSG_WriteByte (&proxy->datagram, qtv_packet);
|
||||
MSG_WriteShort (&proxy->datagram, qtv_p_unreliable | msg->cursize);
|
||||
SZ_Write (&proxy->datagram, msg->data, msg->cursize);
|
||||
buf = &proxy->datagram;
|
||||
type = qtv_p_unreliable;
|
||||
}
|
||||
MSG_WriteByte (buf, qtv_packet);
|
||||
MSG_WriteShort (buf, type | msg->cursize);
|
||||
SZ_Write (buf, msg->data, msg->cursize);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -273,7 +276,9 @@ qtv_begin_f (sv_qtv_t *proxy)
|
|||
qtv_new_f (proxy);
|
||||
return;
|
||||
}
|
||||
proxy->recorder = SVR_AddUser (qtv_write, qtv_frame, qtv_finish, 0, proxy);
|
||||
proxy->recorder = SVR_AddUser (qtv_write, qtv_frame, 0, qtv_finish, 0,
|
||||
proxy);
|
||||
proxy->begun = 1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -317,9 +322,19 @@ qtv_command (sv_qtv_t *proxy, const char *s)
|
|||
static void
|
||||
qtv_parse (sv_qtv_t *proxy)
|
||||
{
|
||||
int c;
|
||||
int c, delta;
|
||||
|
||||
proxy->packet = 1;
|
||||
// make sure the reply sequence number matches the incoming
|
||||
// sequence number
|
||||
if (proxy->netchan.incoming_sequence >= proxy->netchan.outgoing_sequence) {
|
||||
proxy->netchan.outgoing_sequence = proxy->netchan.incoming_sequence;
|
||||
proxy->packet = true;
|
||||
} else {
|
||||
proxy->packet = false; // don't reply, sequences have slipped
|
||||
return; // FIXME right thing?
|
||||
}
|
||||
if (proxy->recorder)
|
||||
SVR_SetDelta (proxy->recorder, -1, proxy->netchan.incoming_sequence);
|
||||
while (1) {
|
||||
if (net_message->badread) {
|
||||
SV_Printf ("SV_ReadClientMessage: badread\n");
|
||||
|
@ -344,7 +359,10 @@ qtv_parse (sv_qtv_t *proxy)
|
|||
break;
|
||||
|
||||
case qtv_delta:
|
||||
MSG_ReadByte (net_message);
|
||||
delta = MSG_ReadByte (net_message);
|
||||
if (proxy->recorder)
|
||||
SVR_SetDelta (proxy->recorder, delta,
|
||||
proxy->netchan.incoming_sequence);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -353,17 +371,22 @@ qtv_parse (sv_qtv_t *proxy)
|
|||
static void
|
||||
qtv_reliable_send (sv_qtv_t *proxy)
|
||||
{
|
||||
int pos, len;
|
||||
byte *buf;
|
||||
int pos = 0, len = 0;
|
||||
byte *buf = 0;
|
||||
|
||||
MSG_WriteByte (&proxy->netchan.message, qtv_packet);
|
||||
pos = proxy->netchan.message.cursize;
|
||||
MSG_WriteShort (&proxy->netchan.message, qtv_p_reliable);
|
||||
SV_Printf ("proxy->begun: %d\n", proxy->begun);
|
||||
if (!proxy->begun) {
|
||||
MSG_WriteByte (&proxy->netchan.message, qtv_packet);
|
||||
pos = proxy->netchan.message.cursize;
|
||||
MSG_WriteShort (&proxy->netchan.message, qtv_p_signon);
|
||||
}
|
||||
MSG_Reliable_Send (&proxy->backbuf);
|
||||
len = proxy->netchan.message.cursize - pos - 2;
|
||||
buf = proxy->netchan.message.data + pos;
|
||||
buf[0] = len & 0xff;
|
||||
buf[1] |= (len >> 8) & 0x0f;
|
||||
if (!proxy->begun) {
|
||||
len = proxy->netchan.message.cursize - pos - 2;
|
||||
buf = proxy->netchan.message.data + pos;
|
||||
buf[0] = len & 0xff;
|
||||
buf[1] |= (len >> 8) & 0x0f;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -371,8 +394,7 @@ SV_qtvConnect (int qport, info_t *info)
|
|||
{
|
||||
sv_qtv_t *proxy;
|
||||
|
||||
SV_Printf ("QTV proxy connection: %d %s\n", Cmd_Argc (), Cmd_Args (1));
|
||||
SV_Printf ("qport: %d\n", qport);
|
||||
SV_Printf ("QTV proxy connection: %s\n", NET_AdrToString (net_from));
|
||||
|
||||
if (!(proxy = alloc_proxy ())) {
|
||||
SV_Printf ("%s:full proxy connect\n", NET_AdrToString (net_from));
|
||||
|
@ -388,6 +410,7 @@ SV_qtvConnect (int qport, info_t *info)
|
|||
proxy->backbuf.name = proxy->name_key->value;
|
||||
proxy->datagram.data = proxy->datagram_buf;
|
||||
proxy->datagram.maxsize = sizeof (proxy->datagram_buf);
|
||||
proxy->begun = 0;
|
||||
|
||||
Netchan_OutOfBandPrint (net_from, "%c", S2C_CONNECTION);
|
||||
}
|
||||
|
@ -411,8 +434,8 @@ SV_qtvPacket (int qport)
|
|||
if (Netchan_Process (&proxies[i].netchan)) {
|
||||
// this is a valid, sequenced packet, so process it
|
||||
svs.stats.packets++;
|
||||
qtv_parse (&proxies[i]);
|
||||
}
|
||||
qtv_parse (&proxies[i]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -104,6 +104,7 @@ struct recorder_s {
|
|||
recorder_t *next;
|
||||
void (*write)(void *, sizebuf_t *, int);
|
||||
int (*frame)(void *);
|
||||
void (*end_frame)(recorder_t *, void *);
|
||||
void (*finish)(void *, sizebuf_t *);
|
||||
void *user;
|
||||
delta_t delta;
|
||||
|
@ -327,6 +328,7 @@ SVR_Init (void)
|
|||
|
||||
recorder_t *
|
||||
SVR_AddUser (void (*write)(void *, sizebuf_t *, int), int (*frame)(void *),
|
||||
void (*end_frame)(recorder_t *, void *),
|
||||
void (*finish)(void *, sizebuf_t *), int demo, void *user)
|
||||
{
|
||||
recorder_t *r;
|
||||
|
@ -356,8 +358,11 @@ SVR_AddUser (void (*write)(void *, sizebuf_t *, int), int (*frame)(void *),
|
|||
r->delta.frames[i].entities.entities = r->entities[i];
|
||||
r->delta.frames[i].players.players = r->players[i];
|
||||
}
|
||||
r->delta.delta_sequence = -1;
|
||||
|
||||
r->write = write;
|
||||
r->frame = frame;
|
||||
r->end_frame = end_frame;
|
||||
r->finish = finish;
|
||||
r->user = user;
|
||||
|
||||
|
@ -415,32 +420,17 @@ write_datagram (recorder_t *r)
|
|||
dst.maxsize = sizeof (msg_buffer[1]);
|
||||
dst.allowoverflow = true;
|
||||
|
||||
// MSG_WriteByte (&msg, 0);
|
||||
// MSG_WriteByte (&msg, dem_all);
|
||||
// MSG_WriteLong (&msg, 0);
|
||||
|
||||
if (!r->delta.delta_sequence)
|
||||
r->delta.delta_sequence = -1;
|
||||
r->delta.cur_frame = (r->delta.delta_sequence + 1) & UPDATE_MASK;
|
||||
r->delta.out_frame = r->delta.cur_frame;
|
||||
SV_WriteEntitiesToClient (&r->delta, &msg);
|
||||
// copy the accumulated multicast datagram
|
||||
// for this client out to the message
|
||||
if (rec.datagram.cursize)
|
||||
SZ_Write (&msg, rec.datagram.data, rec.datagram.cursize);
|
||||
// if (msg.cursize > 6) {
|
||||
if (msg.cursize) {
|
||||
// msg.data[2] = ((msg.cursize - 6) >> 0) & 0xff;
|
||||
// msg.data[3] = ((msg.cursize - 6) >> 8) & 0xff;
|
||||
// msg.data[4] = ((msg.cursize - 6) >> 16) & 0xff;
|
||||
// msg.data[5] = ((msg.cursize - 6) >> 24) & 0xff;
|
||||
double time = rec.frames[rec.lastwritten & DEMO_FRAMES_MASK].time;
|
||||
write_msg (&msg, dem_all, 0, time, &dst);
|
||||
r->write (r->user, &dst, 0);
|
||||
}
|
||||
|
||||
r->delta.delta_sequence++;
|
||||
r->delta.delta_sequence &= UPDATE_MASK;
|
||||
rec.frames[rec.parsecount & DEMO_FRAMES_MASK].time = rec.time = sv.time;
|
||||
}
|
||||
|
||||
|
@ -522,7 +512,7 @@ SVR_ForceFrame (void)
|
|||
rec.forceFrame = 1;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
SVR_Frame (void)
|
||||
{
|
||||
recorder_t *r;
|
||||
|
@ -605,11 +595,25 @@ SV_SendDemoMessage (void)
|
|||
// send over all the objects that are in the PVS
|
||||
// this will include clients, a packetentities, and
|
||||
// possibly a nails update
|
||||
for (r = sv.recorders; r; r = r->next)
|
||||
for (r = sv.recorders; r; r = r->next) {
|
||||
write_datagram (r);
|
||||
if (r->end_frame)
|
||||
r->end_frame (r, r->user);
|
||||
}
|
||||
SZ_Clear (&rec.datagram);
|
||||
|
||||
rec.parsecount++;
|
||||
set_msgbuf (rec.dbuf, &rec.frames[rec.parsecount & DEMO_FRAMES_MASK].buf);
|
||||
rec.lastwritten++;
|
||||
}
|
||||
|
||||
void
|
||||
SVR_SetDelta (recorder_t *r, int delta, int in_frame)
|
||||
{
|
||||
r->delta.delta_sequence = -1;
|
||||
if (delta != -1)
|
||||
r->delta.delta_sequence = delta & UPDATE_MASK;
|
||||
r->delta.in_frame = (r->delta.delta_sequence + 1) & UPDATE_MASK;
|
||||
if (in_frame != -1)
|
||||
r->delta.in_frame = in_frame & UPDATE_MASK;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue