1 /*
2 ===========================================================================
3 
4 Return to Castle Wolfenstein single player GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”).
8 
9 RTCW SP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 RTCW SP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with RTCW SP Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 // cl_parse.c  -- parse a message received from the server
30 
31 #include "client.h"
32 
33 char *svc_strings[256] = {
34 	"svc_bad",
35 
36 	"svc_nop",
37 	"svc_gamestate",
38 	"svc_configstring",
39 	"svc_baseline",
40 	"svc_serverCommand",
41 	"svc_download",
42 	"svc_snapshot",
43 	"svc_EOF",
44 	"svc_voipSpeex",
45 	"svc_voipOpus",
46 };
47 
SHOWNET(msg_t * msg,char * s)48 void SHOWNET( msg_t *msg, char *s ) {
49 	if ( cl_shownet->integer >= 2 ) {
50 		Com_Printf( "%3i %3i:%s\n", msg->readcount - 1, msg->cursize, s );
51 	}
52 }
53 
54 
55 /*
56 =========================================================================
57 
58 MESSAGE PARSING
59 
60 =========================================================================
61 */
62 
63 /*
64 ==================
65 CL_DeltaEntity
66 
67 Parses deltas from the given base and adds the resulting entity
68 to the current frame
69 ==================
70 */
CL_DeltaEntity(msg_t * msg,clSnapshot_t * frame,int newnum,entityState_t * old,qboolean unchanged)71 void CL_DeltaEntity( msg_t *msg, clSnapshot_t *frame, int newnum, entityState_t *old,
72 					 qboolean unchanged ) {
73 	entityState_t   *state;
74 
75 	// save the parsed entity state into the big circular buffer so
76 	// it can be used as the source for a later delta
77 	state = &cl.parseEntities[cl.parseEntitiesNum & ( MAX_PARSE_ENTITIES - 1 )];
78 
79 	if ( unchanged ) {
80 		*state = *old;
81 	} else {
82 		MSG_ReadDeltaEntity( msg, old, state, newnum );
83 	}
84 
85 	if ( state->number == ( MAX_GENTITIES - 1 ) ) {
86 		return;     // entity was delta removed
87 	}
88 	cl.parseEntitiesNum++;
89 	frame->numEntities++;
90 }
91 
92 /*
93 ==================
94 CL_ParsePacketEntities
95 
96 ==================
97 */
CL_ParsePacketEntities(msg_t * msg,clSnapshot_t * oldframe,clSnapshot_t * newframe)98 void CL_ParsePacketEntities( msg_t *msg, clSnapshot_t *oldframe, clSnapshot_t *newframe ) {
99 	int newnum;
100 	entityState_t   *oldstate;
101 	int oldindex, oldnum;
102 
103 	newframe->parseEntitiesNum = cl.parseEntitiesNum;
104 	newframe->numEntities = 0;
105 
106 	// delta from the entities present in oldframe
107 	oldindex = 0;
108 	oldstate = NULL;
109 	if ( !oldframe ) {
110 		oldnum = 99999;
111 	} else {
112 		if ( oldindex >= oldframe->numEntities ) {
113 			oldnum = 99999;
114 		} else {
115 			oldstate = &cl.parseEntities[
116 				( oldframe->parseEntitiesNum + oldindex ) & ( MAX_PARSE_ENTITIES - 1 )];
117 			oldnum = oldstate->number;
118 		}
119 	}
120 
121 	while ( 1 ) {
122 		// read the entity index number
123 		newnum = MSG_ReadBits( msg, GENTITYNUM_BITS );
124 
125 		if ( newnum == ( MAX_GENTITIES - 1 ) ) {
126 			break;
127 		}
128 
129 		if ( msg->readcount > msg->cursize ) {
130 			Com_Error( ERR_DROP,"CL_ParsePacketEntities: end of message" );
131 		}
132 
133 		while ( oldnum < newnum ) {
134 			// one or more entities from the old packet are unchanged
135 			if ( cl_shownet->integer == 3 ) {
136 				Com_Printf( "%3i:  unchanged: %i\n", msg->readcount, oldnum );
137 			}
138 			CL_DeltaEntity( msg, newframe, oldnum, oldstate, qtrue );
139 
140 			oldindex++;
141 
142 			if ( oldindex >= oldframe->numEntities ) {
143 				oldnum = 99999;
144 			} else {
145 				oldstate = &cl.parseEntities[
146 					( oldframe->parseEntitiesNum + oldindex ) & ( MAX_PARSE_ENTITIES - 1 )];
147 				oldnum = oldstate->number;
148 			}
149 		}
150 		if ( oldnum == newnum ) {
151 			// delta from previous state
152 			if ( cl_shownet->integer == 3 ) {
153 				Com_Printf( "%3i:  delta: %i\n", msg->readcount, newnum );
154 			}
155 			CL_DeltaEntity( msg, newframe, newnum, oldstate, qfalse );
156 
157 			oldindex++;
158 
159 			if ( oldindex >= oldframe->numEntities ) {
160 				oldnum = 99999;
161 			} else {
162 				oldstate = &cl.parseEntities[
163 					( oldframe->parseEntitiesNum + oldindex ) & ( MAX_PARSE_ENTITIES - 1 )];
164 				oldnum = oldstate->number;
165 			}
166 			continue;
167 		}
168 
169 		if ( oldnum > newnum ) {
170 			// delta from baseline
171 			if ( cl_shownet->integer == 3 ) {
172 				Com_Printf( "%3i:  baseline: %i\n", msg->readcount, newnum );
173 			}
174 			CL_DeltaEntity( msg, newframe, newnum, &cl.entityBaselines[newnum], qfalse );
175 			continue;
176 		}
177 
178 	}
179 
180 	// any remaining entities in the old frame are copied over
181 	while ( oldnum != 99999 ) {
182 		// one or more entities from the old packet are unchanged
183 		if ( cl_shownet->integer == 3 ) {
184 			Com_Printf( "%3i:  unchanged: %i\n", msg->readcount, oldnum );
185 		}
186 		CL_DeltaEntity( msg, newframe, oldnum, oldstate, qtrue );
187 
188 		oldindex++;
189 
190 		if ( oldindex >= oldframe->numEntities ) {
191 			oldnum = 99999;
192 		} else {
193 			oldstate = &cl.parseEntities[
194 				( oldframe->parseEntitiesNum + oldindex ) & ( MAX_PARSE_ENTITIES - 1 )];
195 			oldnum = oldstate->number;
196 		}
197 	}
198 }
199 
200 
201 /*
202 ================
203 CL_ParseSnapshot
204 
205 If the snapshot is parsed properly, it will be copied to
206 cl.snap and saved in cl.snapshots[].  If the snapshot is invalid
207 for any reason, no changes to the state will be made at all.
208 ================
209 */
CL_ParseSnapshot(msg_t * msg)210 void CL_ParseSnapshot( msg_t *msg ) {
211 	int len;
212 	clSnapshot_t    *old;
213 	clSnapshot_t newSnap;
214 	int deltaNum;
215 	int oldMessageNum;
216 	int i, packetNum;
217 
218 	// get the reliable sequence acknowledge number
219 	// NOTE: now sent with all server to client messages
220 	//clc.reliableAcknowledge = MSG_ReadLong( msg );
221 
222 	// read in the new snapshot to a temporary buffer
223 	// we will only copy to cl.snap if it is valid
224 	memset( &newSnap, 0, sizeof( newSnap ) );
225 
226 	// we will have read any new server commands in this
227 	// message before we got to svc_snapshot
228 	newSnap.serverCommandNum = clc.serverCommandSequence;
229 
230 	newSnap.serverTime = MSG_ReadLong( msg );
231 
232 	// if we were just unpaused, we can only *now* really let the
233 	// change come into effect or the client hangs.
234 	cl_paused->modified = 0;
235 
236 	newSnap.messageNum = clc.serverMessageSequence;
237 
238 	deltaNum = MSG_ReadByte( msg );
239 	if ( !deltaNum ) {
240 		newSnap.deltaNum = -1;
241 	} else {
242 		newSnap.deltaNum = newSnap.messageNum - deltaNum;
243 	}
244 	newSnap.snapFlags = MSG_ReadByte( msg );
245 
246 	// If the frame is delta compressed from data that we
247 	// no longer have available, we must suck up the rest of
248 	// the frame, but not use it, then ask for a non-compressed
249 	// message
250 	if ( newSnap.deltaNum <= 0 ) {
251 		newSnap.valid = qtrue;      // uncompressed frame
252 		old = NULL;
253 		clc.demowaiting = qfalse;   // we can start recording now
254 	} else {
255 		old = &cl.snapshots[newSnap.deltaNum & PACKET_MASK];
256 		if ( !old->valid ) {
257 			// should never happen
258 			Com_Printf( "Delta from invalid frame (not supposed to happen!).\n" );
259 		} else if ( old->messageNum != newSnap.deltaNum ) {
260 			// The frame that the server did the delta from
261 			// is too old, so we can't reconstruct it properly.
262 			Com_DPrintf( "Delta frame too old.\n" );
263 		} else if ( cl.parseEntitiesNum - old->parseEntitiesNum > MAX_PARSE_ENTITIES - MAX_SNAPSHOT_ENTITIES ) {
264 			Com_DPrintf( "Delta parseEntitiesNum too old.\n" );
265 		} else {
266 			newSnap.valid = qtrue;  // valid delta parse
267 		}
268 	}
269 
270 	// read areamask
271 	len = MSG_ReadByte( msg );
272 
273 	if ( len > sizeof( newSnap.areamask ) ) {
274 		Com_Error( ERR_DROP,"CL_ParseSnapshot: Invalid size %d for areamask.", len );
275 		return;
276 	}
277 
278 	MSG_ReadData( msg, &newSnap.areamask, len );
279 
280 	// read playerinfo
281 	SHOWNET( msg, "playerstate" );
282 	if ( old ) {
283 		MSG_ReadDeltaPlayerstate( msg, &old->ps, &newSnap.ps );
284 	} else {
285 		MSG_ReadDeltaPlayerstate( msg, NULL, &newSnap.ps );
286 	}
287 
288 	// read packet entities
289 	SHOWNET( msg, "packet entities" );
290 	CL_ParsePacketEntities( msg, old, &newSnap );
291 
292 	// if not valid, dump the entire thing now that it has
293 	// been properly read
294 	if ( !newSnap.valid ) {
295 		return;
296 	}
297 
298 	// clear the valid flags of any snapshots between the last
299 	// received and this one, so if there was a dropped packet
300 	// it won't look like something valid to delta from next
301 	// time we wrap around in the buffer
302 	oldMessageNum = cl.snap.messageNum + 1;
303 
304 	if ( newSnap.messageNum - oldMessageNum >= PACKET_BACKUP ) {
305 		oldMessageNum = newSnap.messageNum - ( PACKET_BACKUP - 1 );
306 	}
307 	for ( ; oldMessageNum < newSnap.messageNum ; oldMessageNum++ ) {
308 		cl.snapshots[oldMessageNum & PACKET_MASK].valid = qfalse;
309 	}
310 
311 	// copy to the current good spot
312 	cl.snap = newSnap;
313 	cl.snap.ping = 999;
314 	// calculate ping time
315 	for ( i = 0 ; i < PACKET_BACKUP ; i++ ) {
316 		packetNum = ( clc.netchan.outgoingSequence - 1 - i ) & PACKET_MASK;
317 		if ( cl.snap.ps.commandTime >= cl.outPackets[ packetNum ].p_serverTime ) {
318 			cl.snap.ping = cls.realtime - cl.outPackets[ packetNum ].p_realtime;
319 			break;
320 		}
321 	}
322 	// save the frame off in the backup array for later delta comparisons
323 	cl.snapshots[cl.snap.messageNum & PACKET_MASK] = cl.snap;
324 
325 	if ( cl_shownet->integer == 3 ) {
326 		Com_Printf( "   snapshot:%i  delta:%i  ping:%i\n", cl.snap.messageNum,
327 					cl.snap.deltaNum, cl.snap.ping );
328 	}
329 
330 	cl.newSnapshots = qtrue;
331 }
332 
333 
334 //=====================================================================
335 
336 int cl_connectedToPureServer;
337 int cl_connectedToCheatServer;
338 
339 /*
340 ==================
341 CL_SystemInfoChanged
342 
343 The systeminfo configstring has been changed, so parse
344 new information out of it.  This will happen at every
345 gamestate, and possibly during gameplay.
346 ==================
347 */
CL_SystemInfoChanged(void)348 void CL_SystemInfoChanged( void ) {
349 	char	*systemInfo;
350 	const char	*s, *t;
351 	char	key[BIG_INFO_KEY];
352 	char	value[BIG_INFO_VALUE];
353 	qboolean	gameSet;
354 
355 	systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ];
356 	cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) );
357 
358 #ifdef USE_VOIP
359 #ifdef LEGACY_PROTOCOL
360 	if(clc.compat)
361 		clc.voipEnabled = qfalse;
362 	else
363 #endif
364 	{
365 		s = Info_ValueForKey( systemInfo, "sv_voipProtocol" );
366 		clc.voipEnabled = !Q_stricmp(s, "opus");
367 	}
368 #endif
369 
370 	// don't set any vars when playing a demo
371 	if ( clc.demoplaying ) {
372 		return;
373 	}
374 
375 	s = Info_ValueForKey( systemInfo, "sv_cheats" );
376 	cl_connectedToCheatServer = atoi( s );
377 	if ( !cl_connectedToCheatServer ) {
378 		Cvar_SetCheatState();
379 	}
380 
381 	// check pure server string
382 	s = Info_ValueForKey( systemInfo, "sv_paks" );
383 	t = Info_ValueForKey( systemInfo, "sv_pakNames" );
384 	FS_PureServerSetLoadedPaks( s, t );
385 
386 	s = Info_ValueForKey( systemInfo, "sv_referencedPaks" );
387 	t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" );
388 	FS_PureServerSetReferencedPaks( s, t );
389 
390 	gameSet = qfalse;
391 	// scan through all the variables in the systeminfo and locally set cvars to match
392 	s = systemInfo;
393 	while ( s ) {
394 		int cvar_flags;
395 
396 		Info_NextPair( &s, key, value );
397 		if ( !key[0] ) {
398 			break;
399 		}
400 
401 		// ehw!
402 		if (!Q_stricmp(key, "fs_game"))
403 		{
404 			if(FS_InvalidGameDir(value))
405 			{
406 				Com_Printf(S_COLOR_YELLOW "WARNING: Server sent invalid fs_game value %s\n", value);
407 				continue;
408 			}
409 
410 			gameSet = qtrue;
411 		}
412 
413 		if((cvar_flags = Cvar_Flags(key)) == CVAR_NONEXISTENT)
414 			Cvar_Get(key, value, CVAR_SERVER_CREATED | CVAR_ROM);
415 		else
416 		{
417 			// If this cvar may not be modified by a server discard the value.
418 			if(!(cvar_flags & (CVAR_SYSTEMINFO | CVAR_SERVER_CREATED | CVAR_USER_CREATED)))
419 			{
420 #ifndef STANDALONE
421 				if(Q_stricmp(key, "g_synchronousClients") && Q_stricmp(key, "pmove_fixed") &&
422 				   Q_stricmp(key, "pmove_msec"))
423 #endif
424 				{
425 					Com_DPrintf(S_COLOR_YELLOW "WARNING: server is not allowed to set %s=%s\n", key, value);
426 					continue;
427 				}
428 			}
429 
430 			Cvar_SetSafe(key, value);
431 		}
432 	}
433 	// if game folder should not be set and it is set at the client side
434 	if ( !gameSet && *Cvar_VariableString("fs_game") ) {
435 		Cvar_Set( "fs_game", "" );
436 	}
437 	cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" );
438 }
439 
440 /*
441 ==================
442 CL_ParseServerInfo
443 ==================
444 */
CL_ParseServerInfo(void)445 static void CL_ParseServerInfo(void)
446 {
447 	const char *serverInfo;
448 
449 	serverInfo = cl.gameState.stringData
450 		+ cl.gameState.stringOffsets[ CS_SERVERINFO ];
451 
452 	clc.sv_allowDownload = atoi(Info_ValueForKey(serverInfo,
453 		"sv_allowDownload"));
454 	Q_strncpyz(clc.sv_dlURL,
455 		Info_ValueForKey(serverInfo, "sv_dlURL"),
456 		sizeof(clc.sv_dlURL));
457 }
458 
459 /*
460 ==================
461 CL_ParseGamestate
462 ==================
463 */
CL_ParseGamestate(msg_t * msg)464 void CL_ParseGamestate( msg_t *msg ) {
465 	int i;
466 	entityState_t   *es;
467 	int newnum;
468 	entityState_t nullstate;
469 	int cmd;
470 	char            *s;
471 	char oldGame[MAX_QPATH];
472 
473 	Con_Close();
474 
475 	clc.connectPacketCount = 0;
476 
477 	// wipe local client state
478 	CL_ClearState();
479 
480 	// a gamestate always marks a server command sequence
481 	clc.serverCommandSequence = MSG_ReadLong( msg );
482 
483 	// parse all the configstrings and baselines
484 	cl.gameState.dataCount = 1; // leave a 0 at the beginning for uninitialized configstrings
485 	while ( 1 ) {
486 		cmd = MSG_ReadByte( msg );
487 
488 		if ( cmd == svc_EOF ) {
489 			break;
490 		}
491 
492 		if ( cmd == svc_configstring ) {
493 			int len;
494 
495 			i = MSG_ReadShort( msg );
496 			if ( i < 0 || i >= MAX_CONFIGSTRINGS ) {
497 				Com_Error( ERR_DROP, "configstring > MAX_CONFIGSTRINGS" );
498 			}
499 			s = MSG_ReadBigString( msg );
500 			len = strlen( s );
501 
502 			if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) {
503 				Com_Error( ERR_DROP, "MAX_GAMESTATE_CHARS exceeded" );
504 			}
505 
506 			// append it to the gameState string buffer
507 			cl.gameState.stringOffsets[ i ] = cl.gameState.dataCount;
508 			memcpy( cl.gameState.stringData + cl.gameState.dataCount, s, len + 1 );
509 			cl.gameState.dataCount += len + 1;
510 		} else if ( cmd == svc_baseline ) {
511 			newnum = MSG_ReadBits( msg, GENTITYNUM_BITS );
512 			if ( newnum < 0 || newnum >= MAX_GENTITIES ) {
513 				Com_Error( ERR_DROP, "Baseline number out of range: %i", newnum );
514 			}
515 			memset( &nullstate, 0, sizeof( nullstate ) );
516 			es = &cl.entityBaselines[ newnum ];
517 			MSG_ReadDeltaEntity( msg, &nullstate, es, newnum );
518 		} else {
519 			Com_Error( ERR_DROP, "CL_ParseGamestate: bad command byte" );
520 		}
521 	}
522 
523 	clc.clientNum = MSG_ReadLong( msg );
524 	// read the checksum feed
525 	clc.checksumFeed = MSG_ReadLong( msg );
526 
527 	// save old gamedir
528 	Cvar_VariableStringBuffer("fs_game", oldGame, sizeof(oldGame));
529 
530 	// parse useful values out of CS_SERVERINFO
531 	CL_ParseServerInfo();
532 
533 	// parse serverId and other cvars
534 	CL_SystemInfoChanged();
535 
536 	// stop recording now so the demo won't have an unnecessary level load at the end.
537 	if(cl_autoRecordDemo->integer && clc.demorecording)
538 		CL_StopRecord_f();
539 
540 	// reinitialize the filesystem if the game directory has changed
541 	if(!cl_oldGameSet && (Cvar_Flags("fs_game") & CVAR_MODIFIED))
542 	{
543 		cl_oldGameSet = qtrue;
544 		Q_strncpyz(cl_oldGame, oldGame, sizeof(cl_oldGame));
545 	}
546 
547 	FS_ConditionalRestart(clc.checksumFeed, qfalse);
548 
549 	// This used to call CL_StartHunkUsers, but now we enter the download state before loading the
550 	// cgame
551 	CL_InitDownloads();
552 
553 	// make sure the game starts
554 	Cvar_Set( "cl_paused", "0" );
555 }
556 
557 
558 //=====================================================================
559 
560 /*
561 =====================
562 CL_ParseDownload
563 
564 A download message has been received from the server
565 =====================
566 */
CL_ParseDownload(msg_t * msg)567 void CL_ParseDownload( msg_t *msg ) {
568 	int size;
569 	unsigned char data[MAX_MSGLEN];
570 	uint16_t block;
571 
572 	if (!*clc.downloadTempName) {
573 		Com_Printf("Server sending download, but no download was requested\n");
574 		CL_AddReliableCommand("stopdl", qfalse);
575 		return;
576 	}
577 
578 	// read the data
579 	block = MSG_ReadShort( msg );
580 
581 	if( !block && !clc.downloadBlock ) {
582 		// block zero is special, contains file size
583 		clc.downloadSize = MSG_ReadLong( msg );
584 
585 		Cvar_SetValue( "cl_downloadSize", clc.downloadSize );
586 
587 		if ( clc.downloadSize < 0 ) {
588 			Com_Error( ERR_DROP, "%s", MSG_ReadString( msg ) );
589 			return;
590 		}
591 	}
592 
593 	size = MSG_ReadShort( msg );
594 	if ( size < 0 || size > sizeof( data ) ) {
595 		Com_Error( ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk", size );
596 		return;
597 	}
598 
599 	MSG_ReadData( msg, data, size );
600 
601 	if( ( clc.downloadBlock & 0xFFFF ) != block ) {
602 		Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", (clc.downloadBlock & 0xFFFF), block);
603 		return;
604 	}
605 
606 	// open the file if not opened yet
607 	if ( !clc.download ) {
608 		clc.download = FS_SV_FOpenFileWrite( clc.downloadTempName );
609 
610 		if ( !clc.download ) {
611 			Com_Printf( "Could not create %s\n", clc.downloadTempName );
612 			CL_AddReliableCommand("stopdl", qfalse);
613 			CL_NextDownload();
614 			return;
615 		}
616 	}
617 
618 	if ( size ) {
619 		FS_Write( data, size, clc.download );
620 	}
621 
622 	CL_AddReliableCommand(va("nextdl %d", clc.downloadBlock), qfalse);
623 	clc.downloadBlock++;
624 
625 	clc.downloadCount += size;
626 
627 	// So UI gets access to it
628 	Cvar_SetValue( "cl_downloadCount", clc.downloadCount );
629 
630 	if ( !size ) { // A zero length block means EOF
631 		if ( clc.download ) {
632 			FS_FCloseFile( clc.download );
633 			clc.download = 0;
634 
635 			// rename the file
636 			FS_SV_Rename( clc.downloadTempName, clc.downloadName, qfalse );
637 		}
638 
639 		// send intentions now
640 		// We need this because without it, we would hold the last nextdl and then start
641 		// loading right away.  If we take a while to load, the server is happily trying
642 		// to send us that last block over and over.
643 		// Write it twice to help make sure we acknowledge the download
644 		CL_WritePacket();
645 		CL_WritePacket();
646 
647 		// get another file if needed
648 		CL_NextDownload();
649 	}
650 }
651 
652 #ifdef USE_VOIP
653 static
CL_ShouldIgnoreVoipSender(int sender)654 qboolean CL_ShouldIgnoreVoipSender(int sender)
655 {
656 	if (!cl_voip->integer)
657 		return qtrue;  // VoIP is disabled.
658 	else if ((sender == clc.clientNum) && (!clc.demoplaying))
659 		return qtrue;  // ignore own voice (unless playing back a demo).
660 	else if (clc.voipMuteAll)
661 		return qtrue;  // all channels are muted with extreme prejudice.
662 	else if (clc.voipIgnore[sender])
663 		return qtrue;  // just ignoring this guy.
664 	else if (clc.voipGain[sender] == 0.0f)
665 		return qtrue;  // too quiet to play.
666 
667 	return qfalse;
668 }
669 
670 /*
671 =====================
672 CL_PlayVoip
673 
674 Play raw data
675 =====================
676 */
677 
CL_PlayVoip(int sender,int samplecnt,const byte * data,int flags)678 static void CL_PlayVoip(int sender, int samplecnt, const byte *data, int flags)
679 {
680 	if(flags & VOIP_DIRECT)
681 	{
682 		S_RawSamples(sender + 1, samplecnt, 48000, 2, 1,
683 	             data, clc.voipGain[sender], -1);
684 	}
685 
686 	if(flags & VOIP_SPATIAL)
687 	{
688 		S_RawSamples(sender + MAX_CLIENTS + 1, samplecnt, 48000, 2, 1,
689 	             data, 1.0f, sender);
690 	}
691 }
692 
693 /*
694 =====================
695 CL_ParseVoip
696 
697 A VoIP message has been received from the server
698 =====================
699 */
700 static
CL_ParseVoip(msg_t * msg,qboolean ignoreData)701 void CL_ParseVoip ( msg_t *msg, qboolean ignoreData ) {
702 	static short decoded[VOIP_MAX_PACKET_SAMPLES*4]; // !!! FIXME: don't hard code
703 
704 	const int sender = MSG_ReadShort(msg);
705 	const int generation = MSG_ReadByte(msg);
706 	const int sequence = MSG_ReadLong(msg);
707 	const int frames = MSG_ReadByte(msg);
708 	const int packetsize = MSG_ReadShort(msg);
709 	const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
710 	unsigned char encoded[4000];
711 	int	numSamples;
712 	int seqdiff;
713 	int written = 0;
714 	int i;
715 
716 	Com_DPrintf("VoIP: %d-byte packet from client %d\n", packetsize, sender);
717 
718 	if (sender < 0)
719 		return;   // short/invalid packet, bail.
720 	else if (generation < 0)
721 		return;   // short/invalid packet, bail.
722 	else if (sequence < 0)
723 		return;   // short/invalid packet, bail.
724 	else if (frames < 0)
725 		return;   // short/invalid packet, bail.
726 	else if (packetsize < 0)
727 		return;   // short/invalid packet, bail.
728 
729 	if (packetsize > sizeof (encoded)) {  // overlarge packet?
730 		int bytesleft = packetsize;
731 		while (bytesleft) {
732 			int br = bytesleft;
733 			if (br > sizeof (encoded))
734 				br = sizeof (encoded);
735 			MSG_ReadData(msg, encoded, br);
736 			bytesleft -= br;
737 		}
738 		return;   // overlarge packet, bail.
739 	}
740 
741 	MSG_ReadData(msg, encoded, packetsize);
742 
743 	if (ignoreData) {
744 		return; // just ignore legacy speex voip data
745 	} else if (!clc.voipCodecInitialized) {
746 		return;   // can't handle VoIP without libopus!
747 	} else if (sender >= MAX_CLIENTS) {
748 		return;   // bogus sender.
749 	} else if (CL_ShouldIgnoreVoipSender(sender)) {
750 		return;   // Channel is muted, bail.
751 	}
752 
753 	// !!! FIXME: make sure data is narrowband? Does decoder handle this?
754 
755 	Com_DPrintf("VoIP: packet accepted!\n");
756 
757 	seqdiff = sequence - clc.voipIncomingSequence[sender];
758 
759 	// This is a new "generation" ... a new recording started, reset the bits.
760 	if (generation != clc.voipIncomingGeneration[sender]) {
761 		Com_DPrintf("VoIP: new generation %d!\n", generation);
762 		opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
763 		clc.voipIncomingGeneration[sender] = generation;
764 		seqdiff = 0;
765 	} else if (seqdiff < 0) {   // we're ahead of the sequence?!
766 		// This shouldn't happen unless the packet is corrupted or something.
767 		Com_DPrintf("VoIP: misordered sequence! %d < %d!\n",
768 		            sequence, clc.voipIncomingSequence[sender]);
769 		// reset the decoder just in case.
770 		opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
771 		seqdiff = 0;
772 	} else if (seqdiff * VOIP_MAX_PACKET_SAMPLES*2 >= sizeof (decoded)) { // dropped more than we can handle?
773 		// just start over.
774 		Com_DPrintf("VoIP: Dropped way too many (%d) frames from client #%d\n",
775 		            seqdiff, sender);
776 		opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
777 		seqdiff = 0;
778 	}
779 
780 	if (seqdiff != 0) {
781 		Com_DPrintf("VoIP: Dropped %d frames from client #%d\n",
782 		            seqdiff, sender);
783 		// tell opus that we're missing frames...
784 		for (i = 0; i < seqdiff; i++) {
785 			assert((written + VOIP_MAX_PACKET_SAMPLES) * 2 < sizeof (decoded));
786 			numSamples = opus_decode(clc.opusDecoder[sender], NULL, 0, decoded + written, VOIP_MAX_PACKET_SAMPLES, 0);
787 			if ( numSamples <= 0 ) {
788 				Com_DPrintf("VoIP: Error decoding frame %d from client #%d\n", i, sender);
789 				continue;
790 			}
791 			written += numSamples;
792 		}
793 	}
794 
795 	numSamples = opus_decode(clc.opusDecoder[sender], encoded, packetsize, decoded + written, ARRAY_LEN(decoded) - written, 0);
796 
797 	if ( numSamples <= 0 ) {
798 		Com_DPrintf("VoIP: Error decoding voip data from client #%d\n", sender);
799 		numSamples = 0;
800 	}
801 
802 	#if 0
803 	static FILE *encio = NULL;
804 	if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb");
805 	if (encio != NULL) { fwrite(encoded, packetsize, 1, encio); fflush(encio); }
806 	static FILE *decio = NULL;
807 	if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb");
808 	if (decio != NULL) { fwrite(decoded+written, numSamples*2, 1, decio); fflush(decio); }
809 	#endif
810 
811 	written += numSamples;
812 
813 	Com_DPrintf("VoIP: playback %d bytes, %d samples, %d frames\n",
814 			written * 2, written, frames);
815 
816 	if(written > 0)
817 		CL_PlayVoip(sender, written, (const byte *) decoded, flags);
818 
819 	clc.voipIncomingSequence[sender] = sequence + frames;
820 }
821 #endif
822 
823 /*
824 =====================
825 CL_ParseCommandString
826 
827 Command strings are just saved off until cgame asks for them
828 when it transitions a snapshot
829 =====================
830 */
CL_ParseCommandString(msg_t * msg)831 void CL_ParseCommandString( msg_t *msg ) {
832 	char    *s;
833 	int seq;
834 	int index;
835 
836 	seq = MSG_ReadLong( msg );
837 	s = MSG_ReadString( msg );
838 
839 	// see if we have already executed stored it off
840 	if ( clc.serverCommandSequence >= seq ) {
841 		return;
842 	}
843 	clc.serverCommandSequence = seq;
844 
845 	index = seq & ( MAX_RELIABLE_COMMANDS - 1 );
846 	Q_strncpyz( clc.serverCommands[ index ], s, sizeof( clc.serverCommands[ index ] ) );
847 }
848 
849 
850 /*
851 =====================
852 CL_ParseServerMessage
853 =====================
854 */
CL_ParseServerMessage(msg_t * msg)855 void CL_ParseServerMessage( msg_t *msg ) {
856 	int cmd;
857 
858 	if ( cl_shownet->integer == 1 ) {
859 		Com_Printf( "%i ",msg->cursize );
860 	} else if ( cl_shownet->integer >= 2 ) {
861 		Com_Printf( "------------------\n" );
862 	}
863 
864 	MSG_Bitstream( msg );
865 
866 	// get the reliable sequence acknowledge number
867 	clc.reliableAcknowledge = MSG_ReadLong( msg );
868 	//
869 	if ( clc.reliableAcknowledge < clc.reliableSequence - MAX_RELIABLE_COMMANDS ) {
870 		clc.reliableAcknowledge = clc.reliableSequence;
871 	}
872 
873 	//
874 	// parse the message
875 	//
876 	while ( 1 ) {
877 		if ( msg->readcount > msg->cursize ) {
878 			Com_Error( ERR_DROP,"CL_ParseServerMessage: read past end of server message" );
879 			break;
880 		}
881 
882 		cmd = MSG_ReadByte( msg );
883 
884 		if ( cmd == svc_EOF ) {
885 			SHOWNET( msg, "END OF MESSAGE" );
886 			break;
887 		}
888 
889 		if ( cl_shownet->integer >= 2 ) {
890 			if ( (cmd < 0) || (!svc_strings[cmd]) ) {
891 				Com_Printf( "%3i:BAD CMD %i\n", msg->readcount - 1, cmd );
892 			} else {
893 				SHOWNET( msg, svc_strings[cmd] );
894 			}
895 		}
896 
897 		// other commands
898 		switch ( cmd ) {
899 		default:
900 			Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message");
901 			break;
902 		case svc_nop:
903 			break;
904 		case svc_serverCommand:
905 			CL_ParseCommandString( msg );
906 			break;
907 		case svc_gamestate:
908 			CL_ParseGamestate( msg );
909 			break;
910 		case svc_snapshot:
911 			CL_ParseSnapshot( msg );
912 			break;
913 		case svc_download:
914 			CL_ParseDownload( msg );
915 			break;
916 		case svc_voipSpeex:
917 #ifdef USE_VOIP
918 			CL_ParseVoip( msg, qtrue );
919 #endif
920 			break;
921 		case svc_voipOpus:
922 #ifdef USE_VOIP
923 			CL_ParseVoip( msg, !clc.voipEnabled );
924 #endif
925 			break;
926 		}
927 	}
928 }
929