Example #1
0
/*
==================
CL_ParseClientdata

Server information pertaining to this client only
==================
*/
void CL_ParseClientdata (int bits)
{
	int		i, j;
	
	if (bits & SU_VIEWHEIGHT)
		cl.viewheight = MSG_ReadChar ();
	else
		cl.viewheight = DEFAULT_VIEWHEIGHT;

	if (bits & SU_IDEALPITCH)
		cl.idealpitch = MSG_ReadChar ();
	else
		cl.idealpitch = 0;
	
	VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
	for (i=0 ; i<3 ; i++)
	{
		if (bits & (SU_PUNCH1<<i) )
			cl.punchangle[i] = MSG_ReadChar();
		else
			cl.punchangle[i] = 0;
		if (bits & (SU_VELOCITY1<<i) )
			cl.mvelocity[0][i] = MSG_ReadChar()*16;
		else
			cl.mvelocity[0][i] = 0;
	}

// [always sent]	if (bits & SU_ITEMS)
		i = MSG_ReadLong ();

	if (cl.items != i)
	{	// set flash times
		Sbar_Changed ();
		for (j=0 ; j<32 ; j++)
			if ( (i & (1<<j)) && !(cl.items & (1<<j)))
				cl.item_gettime[j] = cl.time;
		cl.items = i;
	}
		
	cl.onground = (bits & SU_ONGROUND) != 0;
	cl.inwater = (bits & SU_INWATER) != 0;

	if (bits & SU_WEAPONFRAME)
		cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
	else
		cl.stats[STAT_WEAPONFRAME] = 0;

	if (bits & SU_ARMOR)
		i = MSG_ReadByte ();
	else
		i = 0;
	if (cl.stats[STAT_ARMOR] != i)
	{
		cl.stats[STAT_ARMOR] = i;
		Sbar_Changed ();
	}

	if (bits & SU_WEAPON)
		i = MSG_ReadByte ();
	else
		i = 0;
	if (cl.stats[STAT_WEAPON] != i)
	{
		cl.stats[STAT_WEAPON] = i;
		Sbar_Changed ();
	}
	
	i = MSG_ReadShort ();
	if (cl.stats[STAT_HEALTH] != i)
	{
		cl.stats[STAT_HEALTH] = i;
		Sbar_Changed ();
	}

	i = MSG_ReadByte ();
	if (cl.stats[STAT_AMMO] != i)
	{
		cl.stats[STAT_AMMO] = i;
		Sbar_Changed ();
	}

	for (i=0 ; i<4 ; i++)
	{
		j = MSG_ReadByte ();
		if (cl.stats[STAT_SHELLS+i] != j)
		{
			cl.stats[STAT_SHELLS+i] = j;
			Sbar_Changed ();
		}
	}

	i = MSG_ReadByte ();

	if (standard_quake)
	{
		if (cl.stats[STAT_ACTIVEWEAPON] != i)
		{
			cl.stats[STAT_ACTIVEWEAPON] = i;
			Sbar_Changed ();
		}
	}
	else
	{
		if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
		{
			cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
			Sbar_Changed ();
		}
	}
}
Example #2
0
/*
* CL_ParseGetServersResponseMessage
* Handle a reply from getservers message to master server
*/
static void CL_ParseGetServersResponseMessage( msg_t *msg, qboolean extended )
{
	const char *header;
	char adrString[64];
	qbyte addr[16];
	unsigned short port;
	netadr_t adr;

	MSG_BeginReading( msg );
	MSG_ReadLong( msg ); // skip the -1

	//jump over the command name
	header = ( extended ? "getserversExtResponse" : "getserversResponse" );
	if( !MSG_SkipData( msg, strlen( header ) ) )
	{
		Com_Printf( "Invalid master packet ( missing %s )\n", header );
		return;
	}

	while( msg->readcount + 7 <= msg->cursize )
	{
		char prefix = MSG_ReadChar( msg );

		switch( prefix )
		{
		case '\\':
			MSG_ReadData( msg, addr, 4 );
			port = ShortSwap( MSG_ReadShort( msg ) ); // both endians need this swapped.
			Q_snprintfz( adrString, sizeof( adrString ), "%u.%u.%u.%u:%u", addr[0], addr[1], addr[2], addr[3], port );
			break;

		case '/':
			if( extended )
			{
				MSG_ReadData( msg, addr, 16 );
				port = ShortSwap( MSG_ReadShort( msg ) ); // both endians need this swapped.
				Q_snprintfz( adrString, sizeof( adrString ), "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%hu",
								addr[ 0], addr[ 1], addr[ 2], addr[ 3], addr[ 4], addr[ 5], addr[ 6], addr[ 7],
								addr[ 8], addr[ 9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15],
								port );
			}
			else
			{
				Com_Printf( "Invalid master packet ( IPv6 prefix in a non-extended response )\n" );
				return;
			}

			break;

		default:
			Com_Printf( "Invalid master packet ( missing separator )\n" );
			return;
		}

		if( port == 0 )  // last server seen
			return;

		Com_DPrintf( "%s\n", adrString );
		if( !NET_StringToAddress( adrString, &adr ) )
		{
			Com_Printf( "Bad address: %s\n", adrString );
			continue;
		}

		CL_AddServerToList( &masterList, adrString, 0 );
	}
}
float MSG_ReadAngle() {
   return(MSG_ReadChar() * (360.0/256));
}
Example #4
0
/*
=================
CL_ParseTEnt
=================
*/
qboolean CL_ParseTEnt (qboolean parse_only)
{
	int			type, rnd, colorStart, colorLength, cnt;
	vec3_t		pos, dir;
	dlight_t	*dl;
	byte		*colorByte;
	float		ExploColor[3];

	type = MSG_ReadByte ();
	switch (type)
	{
	
	case TE_WIZSPIKE:			// spike hitting wall
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
		{
			R_RunParticleEffect (pos, vec3_origin, 20, 30);
		#ifdef HEXEN2_SUPPORT
			if (!hexen2)
		#endif
				S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
		}
		break;

	case TE_KNIGHTSPIKE:			// spike hitting wall
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
		{
			R_RunParticleEffect (pos, vec3_origin, 226, 20);
		#ifdef HEXEN2_SUPPORT
			if (!hexen2)
		#endif
				S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
		}
		break;

	case TE_SPIKE:				// spike hitting wall
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
	// joe: they put the ventillator's wind effect to "10" in Nehahra. sigh.
		if (!parse_only)
		{
			if (nehahra)
				R_RunParticleEffect (pos, vec3_origin, 0, 9);
			else
				R_RunParticleEffect (pos, vec3_origin, 0, 10);

			if (rand() % 5)
			{
				S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
			}
			else
			{
				rnd = rand() & 3;
				if (rnd == 1)
					S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
				else if (rnd == 2)
					S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
				else
					S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
			}
		}
		break;

	case TE_SUPERSPIKE:			// super spike hitting wall
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
		{
			R_RunParticleEffect (pos, vec3_origin, 0, 20);

			if (rand() % 5)
			{
				S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
			}
			else
			{
				rnd = rand() & 3;
				if (rnd == 1)
					S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
				else if (rnd == 2)
					S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
				else
					S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
			}
		}
		break;

		// DP105 version
		/* 
	case TE_BLOOD:	// blood puff
		MSG_ReadVector(pos);
		dir[0] = MSG_ReadChar ();
		dir[1] = MSG_ReadChar ();
		dir[2] = MSG_ReadChar ();
		count = MSG_ReadByte (); // amount of particles
		if (!parse_only)
			R_BloodPuff(pos, dir, count);
		break;
		*/

	case TE_BLOOD:	// blood puff hitting flesh
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		dir[0] = MSG_ReadChar ();
		dir[1] = MSG_ReadChar ();
		dir[2] = MSG_ReadChar ();
		cnt = MSG_ReadByte (); // amount of particles
		if (!parse_only)
		{
			if (!qmb_initialized || !gl_part_blood.value)		// JDH: fix for Marcher/Bastion
			{
				VectorScale (dir, 0.1f, dir);		// 0.1 and 2 (below) come from standard SpawnBlood
			}
			R_RunParticleEffect (pos, dir, 73, cnt*2);
		}
		break;

/*	case TE_CUSTOMFLASH:
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		radius = (MSG_ReadByte() + 1) * 8;
		velspeed = (MSG_ReadByte() + 1) / 256.0;
		color[0] = MSG_ReadByte() * (2.0f / 255.0f);
		color[1] = MSG_ReadByte() * (2.0f / 255.0f);
		color[2] = MSG_ReadByte() * (2.0f / 255.0f);
	//	Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
	//	CL_AllocDlight(NULL, &tempmatrix, radius, color[0], color[1], color[2], radius / velspeed, velspeed, 0, -1, true, 1, 0.25, 1, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
		if (!parse_only)
			CL_NewDlight (0, pos, radius, );
		break;
*/
	case TE_GUNSHOT:			// bullet hitting wall
		cnt = (cl.protocol == PROTOCOL_VERSION_QW) ? MSG_ReadByte () : 1;
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
		{
			/*if (nehahra)
				R_SparkShower (pos, vec3_origin, 15, 0);
			else*/
				R_RunParticleEffect (pos, vec3_origin, 0, 21*cnt);
		}
		break;

	case TE_EXPLOSION:			// rocket explosion
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
		{
			if (r_explosiontype.value == 3)
				R_RunParticleEffect (pos, vec3_origin, 225, 50);
			else
				R_ParticleExplosion (pos);

			if (r_explosionlight.value)
			{
				SetCommonExploStuff;
//				dl->type = SetDlightColor (r_explosionlightcolor.value, lt_explosion, true);
				SetDlightColor (dl, r_explosionlightcolor.value, lt_explosion, true);
			}

			S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
		}
		break;

	case TE_TAREXPLOSION:			// tarbaby explosion
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
		{
			R_BlobExplosion (pos);

			S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
		}
		break;

	case TE_LIGHTNING1:				// lightning bolts
		CL_ParseBeam ("progs/bolt.mdl", parse_only);
		break;

	case TE_LIGHTNING2:				// lightning bolts
		CL_ParseBeam ("progs/bolt2.mdl", parse_only);
		break;

	case TE_LIGHTNING3:				// lightning bolts
		CL_ParseBeam ("progs/bolt3.mdl", parse_only);
		break;

	// nehahra support
	case TE_LIGHTNING4NEH:                             // lightning bolts
		CL_ParseBeam (MSG_ReadString(), parse_only);
		break;

// PGM 01/21/97 
	case TE_BEAM:				// grappling hook beam
		if (cl.protocol == PROTOCOL_VERSION_QW)
		{
			// temp ent #13 in QW is TE_LIGHTNINGBLOOD
			pos[0] = MSG_ReadCoord ();
			pos[1] = MSG_ReadCoord ();
			pos[2] = MSG_ReadCoord ();
			if (!parse_only)
				R_RunParticleEffect (pos, vec3_origin, 225, 50);
		}
		else
			CL_ParseBeam ("progs/beam.mdl", parse_only);
		break;
// PGM 01/21/97

	case TE_LAVASPLASH:	
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
			R_LavaSplash (pos);
		break;

	case TE_TELEPORT:
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		if (!parse_only)
			R_TeleportSplash (pos);
		break;

	case TE_EXPLOSION2:			// color mapped explosion
		if (cl.protocol == PROTOCOL_VERSION_QW)
		{
			// JDH: temp ent #12 in QW is TE_BLOOD
			cnt = MSG_ReadByte ();
			pos[0] = MSG_ReadCoord ();
			pos[1] = MSG_ReadCoord ();
			pos[2] = MSG_ReadCoord ();
			if (!parse_only)
				R_RunParticleEffect (pos, vec3_origin, 73, 20*cnt);
			break;
		}
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		colorStart = MSG_ReadByte ();
		colorLength = MSG_ReadByte ();

		if (!parse_only)
		{
			if (r_explosiontype.value == 3)
				R_RunParticleEffect (pos, vec3_origin, 225, 50);
			else
				R_ColorMappedExplosion (pos, colorStart, colorLength);

			if (r_explosionlight.value)
			{
				SetCommonExploStuff;
	//#ifdef GLQUAKE
				colorByte = (byte *)&d_8to24table[colorStart];
				/*ExploColor[0] = ((float)colorByte[0]) / (2.0 * 255.0);
				ExploColor[1] = ((float)colorByte[1]) / (2.0 * 255.0);
				ExploColor[2] = ((float)colorByte[2]) / (2.0 * 255.0);
				dl->type = lt_explosion2;*/
				dl->color[0] = ((float)colorByte[0]) / (2.0 * 255.0);
				dl->color[1] = ((float)colorByte[1]) / (2.0 * 255.0);
				dl->color[2] = ((float)colorByte[2]) / (2.0 * 255.0);	
	//#endif
			}

			S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
		}
		break;

	// nehahra support
	case TE_SMOKE:                      // rocket explosion
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		MSG_ReadByte();		//R_Smoke(pos, MSG_ReadByte());
	case TE_EXPLOSION3:
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		ExploColor[0] = MSG_ReadCoord () / 2.0;
		ExploColor[1] = MSG_ReadCoord () / 2.0;
		ExploColor[2] = MSG_ReadCoord () / 2.0;

		if (!parse_only)
		{
			if (r_explosiontype.value == 3)
				R_RunParticleEffect (pos, vec3_origin, 225, 50);
			else
				R_ParticleExplosion (pos);

			if (r_explosionlight.value)
			{
				SetCommonExploStuff;
//				dl->type = lt_explosion3;
				VectorCopy (ExploColor, dl->color);
			}

			S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
		}
		break;

#ifdef HEXEN2_SUPPORT
	case TE_STREAM_CHAIN:
	case TE_STREAM_SUNSTAFF1:
	case TE_STREAM_SUNSTAFF2:
	case TE_STREAM_LIGHTNING:
	case TE_STREAM_LIGHTNING_SMALL:
	case TE_STREAM_COLORBEAM:
	case TE_STREAM_ICECHUNKS:
	case TE_STREAM_GAZE:
	case TE_STREAM_FAMINE:
		CL_ParseStream (type, parse_only);
		break;

#endif
	
	default:
		if (!parse_only)
			Sys_Error ("CL_ParseTEnt: bad type");
		return false;
	}

	return true;
}
Example #5
0
/*
===================
SV_ReadClientMessage

Returns false if the client should be killed
===================
*/
qboolean SV_ReadClientMessage (void)
{
	int		ret;
	int		cmd;
	char		*s;
	
	do
	{
nextmsg:
		ret = NET_GetMessage (host_client->netconnection);
		if (ret == -1)
		{
			Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
			return false;
		}
		if (!ret)
			return true;
					
		MSG_BeginReading ();
		
		while (1)
		{
			if (!host_client->active)
				return false;	// a command caused an error

			if (msg_badread)
			{
				Sys_Printf ("SV_ReadClientMessage: badread\n");
				return false;
			}	
	
			cmd = MSG_ReadChar ();
			
			switch (cmd)
			{
			case -1:
				goto nextmsg;		// end of message
				
			default:
				Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
				return false;
							
			case clc_nop:
//				Sys_Printf ("clc_nop\n");
				break;
				
			case clc_stringcmd:	
				s = MSG_ReadString ();
				if (host_client->privileged)
					ret = 2;
				else
					ret = 0;
				if (Q_strncasecmp(s, "status", 6) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "god", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "notarget", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "fly", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "name", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "noclip", 6) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "say", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "say_team", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "tell", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "color", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "kill", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "pause", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "spawn", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "begin", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "prespawn", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "kick", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "ping", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "give", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "ban", 3) == 0)
					ret = 1;
				if (ret == 2)
					Cbuf_InsertText (s);
				else if (ret == 1)
					Cmd_ExecuteString (s, src_client);
				else
					Con_DPrintf("%s tried to %s\n", host_client->name, s);
				break;
				
			case clc_disconnect:
//				Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
				return false;
			
			case clc_move:
				SV_ReadClientMove (&host_client->cmd);
				break;
			}
		}
	} while (ret == 1);
	
	return true;
}
Example #6
0
/*
===================
SV_ReadClientMessage

Returns false if the client should be killed
===================
*/
qboolean SV_ReadClientMessage (void)
{
	int		ret;
	int		cmd;
	char		*s;
	
	do
	{
nextmsg:
		ret = NET_GetMessage (host_client->netconnection);
		if (ret == -1)
		{
			Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
			return false;
		}
		if (!ret)
			return true;
					
		MSG_BeginReading (net_message);
		
		while (1)
		{
			if (!host_client->active)
				return false;	// a command caused an error

			if (net_message->badread)
			{
				Sys_Printf ("SV_ReadClientMessage: badread\n");
				return false;
			}	
	
			cmd = MSG_ReadChar (net_message);
			
			switch (cmd)
			{
			case -1:
				goto nextmsg;		// end of message
				
			default:
				Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
				return false;
							
			case clc_nop:
//				Sys_Printf ("SV_ReadClientMessage: clc_nop\n");
				break;
				
			case clc_stringcmd:	
				s = MSG_ReadString (net_message);

				ret = 0;

				if (nehahra)
				{
					if (strncasecmp(s, "max", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "monster", 7) == 0)
						ret = 1;
					else if (strncasecmp(s, "scrag", 5) == 0)
						ret = 1;
					else if (strncasecmp(s, "wraith", 6) == 0)
						ret = 1;
					else if (strncasecmp(s, "gimme", 5) == 0)
						ret = 1;
				}
				else
				{
					if (strncasecmp(s, "god", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "notarget", 8) == 0)
						ret = 1;
					else if (strncasecmp(s, "fly", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "noclip", 6) == 0)
						ret = 1;
					else if (strncasecmp(s, "give", 4) == 0)
						ret = 1;
				}

				if (strncasecmp(s, "status", 6) == 0)
					ret = 1;
				else if (strncasecmp(s, "freezeall", 9) == 0)
					ret = 1;
				else if (strncasecmp(s, "name", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "say", 3) == 0)
					ret = 1;
				else if (strncasecmp(s, "say_team", 8) == 0)
					ret = 1;
				else if (strncasecmp(s, "tell", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "color", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "kill", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "pause", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "spawn", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "begin", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "prespawn", 8) == 0)
					ret = 1;
				else if (strncasecmp(s, "kick", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "ping", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "ban", 3) == 0)
					ret = 1;
				else if (strncasecmp(s, "qcexec", 6) == 0)
					ret = 1; // qcexec command for qc testing

				if (ret == 1)
					Cmd_ExecuteString (s, src_client);
				else
					Con_DPrintf("%s tried to %s\n", host_client->name, s);
				break;
				
			case clc_disconnect:
//				Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
				return false;
			
			case clc_move:
				SV_ReadClientMove (&host_client->cmd);
				break;
			}
		}
	} while (ret == 1);
	
	return true;
}