Merge branch 'master' into blub/cmd_unset
[divverent/darkplaces.git] / sv_demo.c
1 #include "quakedef.h"
2 #include "sv_demo.h"
3
4 void SV_StartDemoRecording(client_t *client, const char *filename, int forcetrack)
5 {
6         char name[MAX_QPATH];
7
8         if(client->sv_demo_file != NULL)
9                 return; // we already have a demo
10
11         strlcpy(name, filename, sizeof(name));
12         FS_DefaultExtension(name, ".dem", sizeof(name));
13
14         Con_Printf("Recording demo for # %d (%s) to %s\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress, name);
15
16         client->sv_demo_file = FS_OpenRealFile(name, "wb", false);
17         if(!client->sv_demo_file)
18         {
19                 Con_Print("ERROR: couldn't open.\n");
20                 return;
21         }
22
23         FS_Printf(client->sv_demo_file, "%i\n", forcetrack);
24 }
25
26 void SV_WriteDemoMessage(client_t *client, sizebuf_t *sendbuffer, qboolean clienttoserver)
27 {
28         int len, i;
29         float f;
30         int temp;
31
32         if(client->sv_demo_file == NULL)
33                 return;
34         if(sendbuffer->cursize == 0)
35                 return;
36         
37         temp = sendbuffer->cursize | (clienttoserver ? DEMOMSG_CLIENT_TO_SERVER : 0);
38         len = LittleLong(temp);
39         FS_Write(client->sv_demo_file, &len, 4);
40         for(i = 0; i < 3; ++i)
41         {
42                 f = LittleFloat(client->edict->fields.server->v_angle[i]);
43                 FS_Write(client->sv_demo_file, &f, 4);
44         }
45         FS_Write(client->sv_demo_file, sendbuffer->data, sendbuffer->cursize);
46 }
47
48 void SV_StopDemoRecording(client_t *client)
49 {
50         sizebuf_t buf;
51         unsigned char bufdata[64];
52
53         if(client->sv_demo_file == NULL)
54                 return;
55         
56         buf.data = bufdata;
57         buf.maxsize = sizeof(bufdata);
58         SZ_Clear(&buf);
59         MSG_WriteByte(&buf, svc_disconnect);
60         SV_WriteDemoMessage(client, &buf, false);
61
62         FS_Close(client->sv_demo_file);
63         client->sv_demo_file = NULL;
64         Con_Printf("Stopped recording demo for # %d (%s)\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress);
65 }
66
67 void SV_WriteNetnameIntoDemo(client_t *client)
68 {
69         // This "pseudo packet" is written so a program can easily find out whose demo this is
70         sizebuf_t buf;
71         unsigned char bufdata[128];
72
73         if(client->sv_demo_file == NULL)
74                 return;
75
76         buf.data = bufdata;
77         buf.maxsize = sizeof(bufdata);
78         SZ_Clear(&buf);
79         MSG_WriteByte(&buf, svc_stufftext);
80         MSG_WriteUnterminatedString(&buf, "\n// this demo contains the point of view of: ");
81         MSG_WriteUnterminatedString(&buf, client->name);
82         MSG_WriteString(&buf, "\n");
83         SV_WriteDemoMessage(client, &buf, false);
84 }