1 /*
2 Copyright (C) 2003-2006 Andrey Nazarov
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #define MVD_REC_NUM_FRAMES	2
22 #define MVD_REC_FRAMES_MASK ( MVD_REC_NUM_FRAMES - 1 )
23 
24 typedef enum {
25 	MVD_UNINITIALIZED,
26 	MVD_CHALLENGING,
27 	MVD_CONNECTING,
28 	MVD_CONNECTED,
29 	MVD_PRIMED,
30 	MVD_BUFFERING,
31 	MVD_ACTIVE
32 } mvdState_t;
33 
34 #define LAYOUT_MSEC		3000
35 #define LAYOUT_TIMEOUT	90		/* in frames */
36 
37 typedef enum {
38 	SBOARD_NONE,		/* no layout at all */
39 	SBOARD_FOLLOW,		/* layout of player being followed */
40 	SBOARD_CLIENTS,		/* MVD clients list */
41 	SBOARD_SCORES		/* current scores */
42 } scoreboard_t;
43 
44 #define FLOOD_SAMPLES	16
45 #define	FLOOD_MASK		( FLOOD_SAMPLES - 1 )
46 
47 typedef struct {
48     player_state_t ps;
49     int ping;
50     int clientNum;
51 /* =================== */
52 
53     qboolean admin;
54 	qboolean following;
55 	qboolean savedFollowing;
56 	qboolean connected;
57     int lastServerPacket;
58 	int followClientNum;
59 	int savedClientNum;
60 	int pmflags;
61 	client_t *cl;
62 	float fov;
63 	scoreboard_t scoreboard;
64 	int layoutTime;
65 	int floodSamples[FLOOD_SAMPLES];
66 	int floodHead;
67 	int floodTime;
68 	usercmd_t lastcmd;
69 	short delta_angles[3];
70 } mvdClient_t;
71 
72 typedef struct {
73 	char layout[MAX_STRING_CHARS];			/* private layout */
74 	char *configstrings[MAX_CONFIGSTRINGS];	/* private configstrings */
75 } mvdPlayer_t;
76 
77 typedef enum {
78 	MFF_ACTIVE			= ( 1 << 0 ),
79 	MFF_VALID			= ( 1 << 1 ),
80 	MFF_GAMESTATE		= ( 1 << 2 ),
81 	MFF_RELIABLE		= ( 1 << 3 )
82 } mvdFrameFlags_t;
83 
84 typedef struct {
85 	mvdFrameFlags_t	flags;
86 
87 	int				serverFrame;
88 	int				deltaPacketNum;
89 	int				serverPacketNum;
90 	int				gamestateSequence;
91 
92 	byte			portalbytes[MAX_MAP_AREAS/8];
93 	int				numPortalBytes;
94 
95 	/* indices into circular buffers */
96 	int				firstEntityState;
97 	int				numEntityStates;
98 
99 	int				firstPlayerState;
100 	int				numPlayerStates;
101 
102 	int				firstMessageByte;
103 	int				numMessageBytes;
104 
105 	int				firstReliableMessageByte;
106 	int				numReliableMessageBytes;
107 } mvdFrame_t;
108 
109 #define MAX_GAMESTATES	16
110 #define GAMESTATE_MASK	( MAX_GAMESTATES - 1 )
111 
112 typedef struct mvdConfigstring_s {
113 	struct mvdConfigstring_s *next;
114 	int index;
115 	char string[1];
116 } mvdConfigstring_t;
117 
118 typedef struct {
119 	entity_state_t s;
120 	qboolean	linked;
121 	int			num_clusters;
122 	int			clusternums[MAX_ENT_CLUSTERS];
123 	cnode_t		*headnode;
124 	int			areanum, areanum2;
125 } entityStateEx_t;
126 
127 typedef struct {
128 	int serverPacketNum;
129 	char mapname[MAX_QPATH];
130 	char fullname[MAX_QPATH];
131 	int maxclients;
132 	cm_t cm;
133 	vec3_t spawnOrigin;
134 	vec3_t spawnAngles;
135 	qboolean spawnSet;
136 	mvdConfigstring_t *headCS, *tailCS;
137 	entityStateEx_t *baselines[SV_BASELINES_CHUNKS];
138 } mvdGamestate_t;
139 
140 typedef struct mvd_s {
141 	mvdState_t		state;
142 	int				realtime;
143 
144 	/* demo related variables */
145 	fileHandle_t	demofile;
146 	qboolean	demoplayback;
147 	qboolean	demorecording;
148 	qboolean	demowaiting;
149 	qboolean	demobackwards;
150 	int			demofileSize;
151 	int			demofileFrameOffset;
152 	int         demofilePercent;
153 	char		demopath[MAX_QPATH];
154 
155 	/* connection variables */
156 	netadr_t	serverAddress;
157 	int			serverProtocol;
158 	int			connectCount;
159 	int			connectTime;
160 	int			challenge;
161 	int			quakePort;
162 	netchan_t	*netchan;
163 	int			servercount;
164 	int			sendtime;
165 	int			timeoutcount;
166 	int			clientNum;
167     usercmd_t   cmd;
168 
169 	/* delta decoder variables */
170 	int		        maxEntityStates;
171 	int		        nextEntityStates;
172 	entityStateEx_t	*entityStates;  /* [maxEntityStates] */
173 
174 	int		        maxPlayerStates;
175 	int		        nextPlayerStates;
176 	playerStateEx_t	*playerStates;  /* [maxPlayerStates] */
177 
178 	int			lastServerFrame;		/* last valid frame number received */
179 	mvdFrame_t	*frames;		        /* [frameBackup] */
180 	int			frameBackup;
181 	int			packetNums[UPDATE_BACKUP]; /* for converting from serverFrames
182                                               to packetNums */
183 
184 	int		serverPacketNum;	/* number of the last packet recevied */
185 	int		validPacketNum;		/* number of the last packet with a valid frame */
186 	int		activePacketNum;    /* frame displayed to clients */
187     int     prevPacketNum;      /* previous frame displayed */
188 
189 	int		maxMessageBytes;
190 	int		nextMessageBytes;
191 	byte	*messageBytes;		/* [maxMessageBytes] */
192 
193 	int		maxReliableMessageBytes;
194 	int		nextReliableMessageBytes;
195 	byte	*reliableMessageBytes;		/* [maxReliableMessageBytes] */
196 
197 	int		lastReliableMessageBytes;
198 
199 	mvdGamestate_t gamestates[MAX_GAMESTATES];
200 	int		activeGamestateSequence;
201 	int		gamestateSequence;
202 	mvdGamestate_t *nextGS;		/* partial gamestate being currently parsed */
203 
204 	/* game data */
205 	char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]; /* latest configstrings */
206 	mvdClient_t *clients;	/* [svs.maxclients] */
207 
208 	/* derived data */
209 	mvdPlayer_t *players;	/* [maxPlayers] */
210 	int		maxPlayers;
211 	int		lastLayoutPacket;
212 } mvd_t;
213 
214 typedef struct {
215 	listElem_t	elem;
216 	int			sequence;
217 	int			size;
218 	int			numFrames;
219 	time_t		time;
220 	qboolean	completed;
221 	char		*filename;
222 	char		*fullpath;
223 } mvdCacheEntry_t;
224 
225 extern list_t		rec_cache;
226 
227 extern mvd_t			mvd;
228 
229 extern cmdbuf_t	mvd_buffer;
230 extern byte		mvd_buffer_text[MAX_STRING_CHARS];
231 
232 extern	game_export_t	mvd_ge;
233 
234 extern cvar_t	*mvd_nodelta;
235 extern cvar_t	*mvd_wait_clients;
236 extern cvar_t	*mvd_cache_megs;
237 extern cvar_t	*mvd_shownet;
238 extern cvar_t	*mvd_buffer_size;
239 extern cvar_t	*mvd_debug;
240 extern cvar_t	*mvd_buffer_size;
241 extern cvar_t	*mvd_pause;
242 extern cvar_t	*mvd_noblend;
243 extern cvar_t	*mvd_nogun;
244 extern cvar_t	*mvd_motd;
245 extern cvar_t	*mvd_custom_fov;
246 extern cvar_t	*mvd_nextserver;
247 extern cvar_t	*mvd_timeout;
248 extern cvar_t	*mvd_admin_password;
249 extern cvar_t	*mvd_flood_msgs;
250 extern cvar_t	*mvd_flood_persecond;
251 extern cvar_t	*mvd_flood_waitdelay;
252 extern cvar_t	*mvd_autoscores;
253 extern cvar_t	*mvd_safecmd;
254 
255 #define MVD_Mallocz( size )     Z_TagMallocz( size, TAG_MVD )
256 #define MVD_CopyString( s )		Z_TagCopyString( s, TAG_MVD )
257 
258 qboolean MVD_PlayerIsActive( int playerNum );
259 
260 const char *MVD_Play_g( const char *partial, int state );
261 void MVD_Play_f( void );
262 void MVD_Connect_f( void );
263 void MVD_Disconnect_f( void );
264 void MVD_Disconnect( void );
265 
266 qboolean MVD_ReadNextMessage( fileHandle_t f );
267 qboolean MVD_ParseNextMessage( void );
268 void MVD_ParseMessage( void );
269 
270 void MVD_ClientCommand( const char *string );
271 
272 void MVD_ForwardToServer_f( void );
273 
274 void MVD_StreamedStop_f( void );
275 void MVD_StreamedRecord_f( void );
276 
277 void MVD_BackwardsDown_f( void );
278 void MVD_BackwardsUp_f( void );
279 
280 void MVD_Jump_f( void );
281 
282 void MVD_Register( void );
283 void MVD_RecBeginFrame( void );
284 void MVD_RecEndFrame( void );
285 void MVD_RecStop( void );
286 void MVD_RecMulticast( const vec3_t origin, multicast_t to );
287 void MVD_RecUnicast( int clientNum );
288 void MVD_RecConfigstring( int index, const char *string );
289 void MVD_ListCache( qboolean fromConsole );
290 
291 void MVD_Multicast( qboolean unbuffered, vec3_t origin, multicast_t to );
292 void MVD_TransitionGamestate( int sequence );
293 void MVD_GameSpawnEntities( char *mapname, char *entstring, char *spawnpoint );
294 
295 void MVD_ExecuteString( const char *line );
296 
297 void MVD_ClientFrame( int msec );
298 
299 void MVD_UpdateFollower( mvdClient_t *client, playerStateEx_t *src );
300 
301 
302 
303