diff --git a/qw/include/sv_recorder.h b/qw/include/sv_recorder.h index 555d36021..0f570c6e3 100644 --- a/qw/include/sv_recorder.h +++ b/qw/include/sv_recorder.h @@ -36,7 +36,9 @@ struct sizebuf_s; typedef struct recorder_s recorder_t; void SVR_Init (void); -recorder_t *SVR_AddUser (void (*)(struct sizebuf_s *), int (*)(void)); +recorder_t *SVR_AddUser (void (*writer)(struct sizebuf_s *), + int (*frame)(void), + void (*finish)(struct sizebuf_s *)); void SVR_RemoveUser (recorder_t *r); struct sizebuf_s *SVR_WriteBegin (byte type, int to, int size); struct sizebuf_s *SVR_Datagram (void); diff --git a/qw/source/sv_demo.c b/qw/source/sv_demo.c index 3ca9d5630..b1b6f530f 100644 --- a/qw/source/sv_demo.c +++ b/qw/source/sv_demo.c @@ -123,6 +123,15 @@ demo_frame (void) return 1; } +static void +demo_finish (sizebuf_t *msg) +{ + // write a disconnect message to the demo file + MSG_WriteByte (msg, svc_disconnect); + MSG_WriteString (msg, "EndOfDemo"); + recorder = 0; +} + /* SV_Stop @@ -131,8 +140,6 @@ demo_frame (void) void SV_Stop (int reason) { - sizebuf_t *dbuf; - if (!recorder) { Con_Printf ("Not recording a demo.\n"); return; @@ -148,7 +155,6 @@ SV_Stop (int reason) demo_file = NULL; SVR_RemoveUser (recorder); - recorder = 0; SV_BroadcastPrintf (PRINT_CHAT, "Server recording canceled, demo removed\n"); @@ -157,30 +163,13 @@ SV_Stop (int reason) return; } - // write a disconnect message to the demo file // clearup to be sure message will fit - dbuf = SVR_WriteBegin (dem_all, 0, 2 + strlen ("EndOfDemo")); - MSG_WriteByte (dbuf, svc_disconnect); - MSG_WriteString (dbuf, "EndOfDemo"); -/* XXX - demo.dbuf->sz.cursize = 0; - demo.dbuf->h = NULL; - demo.dbuf->bufsize = 0; - DemoWrite_Begin ( - SV_DemoWritePackets (demo.parsecount - demo.lastwritten + 1); - - // finish up - if (!demo_disk) { - Qwrite (demo_file, svs.demomem, demo.size - demo_size); - Qflush (demo_file); - } -*/ - Qclose (demo_file); - - demo_file = NULL; SVR_RemoveUser (recorder); + + Qclose (demo_file); + demo_file = NULL; recorder = 0; if (!reason) SV_BroadcastPrintf (PRINT_CHAT, "Server recording completed\n"); @@ -417,7 +406,7 @@ SV_Record (char *name) } else QFS_Remove (demo_text->str); - recorder = SVR_AddUser (demo_write, demo_frame); + recorder = SVR_AddUser (demo_write, demo_frame, demo_finish); demo_time = sv.time; /*-------------------------------------------------*/ diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index 3a4dba7ac..18f76ae5c 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -601,13 +601,14 @@ PF_stuffcmd (progs_t *pr) p = strrchr (buf, '\n'); if (p) { - char t = p[1]; + char t = p[1]; + int len = (p - buf) + 2; p[1] = 0; - MSG_ReliableWrite_Begin (&cl->backbuf, svc_stufftext, 2 + p - buf); + MSG_ReliableWrite_Begin (&cl->backbuf, svc_stufftext, len + 1); MSG_ReliableWrite_String (&cl->backbuf, buf); if (sv.recorders) { sizebuf_t *dbuf; - dbuf = SVR_WriteBegin (dem_single, cl - svs.clients, 2 + p - buf); + dbuf = SVR_WriteBegin (dem_single, cl - svs.clients, len + 1); MSG_WriteByte (dbuf, svc_stufftext); MSG_WriteString (dbuf, buf); } diff --git a/qw/source/sv_recorder.c b/qw/source/sv_recorder.c index 2adcec427..718fb1b94 100644 --- a/qw/source/sv_recorder.c +++ b/qw/source/sv_recorder.c @@ -103,8 +103,9 @@ typedef struct rec_s { struct recorder_s { recorder_t *next; - void (*writer)(sizebuf_t *); + void (*write)(sizebuf_t *); int (*frame)(void); + void (*finish)(sizebuf_t *); }; static rec_t rec; @@ -182,7 +183,8 @@ write_msg (sizebuf_t *msg, int type, int to, float time, sizebuf_t *dst) MSG_WriteByte (dst, rec.lasttype | (rec.lastto << 3)); break; default: - //XXX SV_Stop (0); + while (sv.recorders) + SVR_RemoveUser (sv.recorders); Con_Printf ("bad demo message type:%d", type); return; } @@ -332,7 +334,8 @@ SVR_Init (void) } recorder_t * -SVR_AddUser (void (*writer)(sizebuf_t *), int (*frame)(void)) +SVR_AddUser (void (*write)(sizebuf_t *), int (*frame)(void), + void (*finish)(sizebuf_t *)) { recorder_t *r; @@ -350,8 +353,9 @@ SVR_AddUser (void (*writer)(sizebuf_t *), int (*frame)(void)) r->next = sv.recorders; sv.recorders = r; - r->writer = writer; + r->write = write; r->frame = frame; + r->finish = finish; return r; } @@ -360,12 +364,34 @@ void SVR_RemoveUser (recorder_t *r) { recorder_t **_r; + sizebuf_t msg;//, *dbuf; + + memset (&msg, 0, sizeof (msg)); + msg.data = msg_buffer; + msg.maxsize = sizeof (msg_buffer); + +// rec.dbuf->sz.cursize = 0; +// rec.dbuf->h = 0; +// rec.dbuf->bufsize = 0; + + MSG_WriteByte (&msg, 0); + MSG_WriteByte (&msg, dem_all); + MSG_WriteLong (&msg, 0); + r->finish (&msg); + if (msg.cursize > 6) { + 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; + r->write (&msg); + } for (_r = &sv.recorders; *_r; _r = &(*_r)->next) { if (*_r == r) { *_r = (*_r)->next; r->next = free_recorders; free_recorders = r; + break; } } } @@ -409,14 +435,12 @@ SVR_WritePacket (void) sizebuf_t msg; recorder_t *r; - write_datagram (); - memset (&msg, 0, sizeof (msg)); msg.data = msg_buffer; msg.maxsize = sizeof (msg_buffer); msg.allowoverflow = true; - frame = &rec.frames[rec.lastwritten & DEMO_FRAMES_MASK]; + frame = &rec.frames[rec.lastwritten++ & DEMO_FRAMES_MASK]; time = frame->time; rec.dbuf = &frame->buf; @@ -424,13 +448,10 @@ SVR_WritePacket (void) write_to_msg (0, 0, time, &msg); for (r = sv.recorders; r; r = r->next) - r->writer (&msg); + r->write (&msg); rec.dbuf = &rec.frames[rec.parsecount & DEMO_FRAMES_MASK].buf; rec.dbuf->sz.maxsize = MAXSIZE + rec.dbuf->bufsize; - - rec.parsecount++; - set_msgbuf (rec.dbuf, &rec.frames[rec.parsecount & DEMO_FRAMES_MASK].buf); } sizebuf_t * @@ -572,5 +593,10 @@ SV_SendDemoMessage (void) msg.allowoverflow = true; msg.overflowed = false; + write_datagram (); + SVR_WritePacket (); + + rec.parsecount++; + set_msgbuf (rec.dbuf, &rec.frames[rec.parsecount & DEMO_FRAMES_MASK].buf); }