]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - sv_demo.c
fix offset/reliefmapping by using the proper miplevel - NOTE: this makes use of a...
[xonotic/darkplaces.git] / sv_demo.c
1 #include "quakedef.h"
2 #include "sv_demo.h"
3
4 extern cvar_t sv_autodemo_perclient_discardable;
5
6 void SV_StartDemoRecording(client_t *client, const char *filename, int forcetrack)
7 {
8         char name[MAX_QPATH];
9         prvm_eval_t *val;
10
11         if(client->sv_demo_file != NULL)
12                 return; // we already have a demo
13
14         strlcpy(name, filename, sizeof(name));
15         FS_DefaultExtension(name, ".dem", sizeof(name));
16
17         Con_Printf("Recording demo for # %d (%s) to %s\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress, name);
18
19         // Reset discardable flag for every new demo.
20         if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.discardabledemo)))
21                 val->_float = 0;
22
23         client->sv_demo_file = FS_OpenRealFile(name, "wb", false);
24         if(!client->sv_demo_file)
25         {
26                 Con_Print("ERROR: couldn't open.\n");
27                 return;
28         }
29
30         FS_Printf(client->sv_demo_file, "%i\n", forcetrack);
31 }
32
33 void SV_WriteDemoMessage(client_t *client, sizebuf_t *sendbuffer, qboolean clienttoserver)
34 {
35         int len, i;
36         float f;
37         int temp;
38
39         if(client->sv_demo_file == NULL)
40                 return;
41         if(sendbuffer->cursize == 0)
42                 return;
43         
44         temp = sendbuffer->cursize | (clienttoserver ? DEMOMSG_CLIENT_TO_SERVER : 0);
45         len = LittleLong(temp);
46         FS_Write(client->sv_demo_file, &len, 4);
47         for(i = 0; i < 3; ++i)
48         {
49                 f = LittleFloat(client->edict->fields.server->v_angle[i]);
50                 FS_Write(client->sv_demo_file, &f, 4);
51         }
52         FS_Write(client->sv_demo_file, sendbuffer->data, sendbuffer->cursize);
53 }
54
55 void SV_StopDemoRecording(client_t *client)
56 {
57         sizebuf_t buf;
58         unsigned char bufdata[64];
59         prvm_eval_t *val;
60
61         if(client->sv_demo_file == NULL)
62                 return;
63         
64         buf.data = bufdata;
65         buf.maxsize = sizeof(bufdata);
66         SZ_Clear(&buf);
67         MSG_WriteByte(&buf, svc_disconnect);
68         SV_WriteDemoMessage(client, &buf, false);
69
70         if (sv_autodemo_perclient_discardable.integer && (val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.discardabledemo)) && val->_float)
71         {
72                 FS_RemoveOnClose(client->sv_demo_file);
73                 Con_Printf("Stopped recording discardable demo for # %d (%s)\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress);
74         }
75         else
76                 Con_Printf("Stopped recording demo for # %d (%s)\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress);
77
78         FS_Close(client->sv_demo_file);
79         client->sv_demo_file = NULL;
80 }
81
82 void SV_WriteNetnameIntoDemo(client_t *client)
83 {
84         // This "pseudo packet" is written so a program can easily find out whose demo this is
85         sizebuf_t buf;
86         unsigned char bufdata[128];
87
88         if(client->sv_demo_file == NULL)
89                 return;
90
91         buf.data = bufdata;
92         buf.maxsize = sizeof(bufdata);
93         SZ_Clear(&buf);
94         MSG_WriteByte(&buf, svc_stufftext);
95         MSG_WriteUnterminatedString(&buf, "\n// this demo contains the point of view of: ");
96         MSG_WriteUnterminatedString(&buf, client->name);
97         MSG_WriteString(&buf, "\n");
98         SV_WriteDemoMessage(client, &buf, false);
99 }