/*
=====================
CL_ParseStatic
=====================
*/
void CL_ParseStatic (int version) //johnfitz -- added a parameter
{
	entity_t *ent;
	int		i;

	i = cl.num_statics;
	if (i >= MAX_STATIC_ENTITIES)
		Host_Error ("Too many static entities");

	ent = &cl_static_entities[i];
	cl.num_statics++;
	CL_ParseBaseline (ent, version); //johnfitz -- added second parameter

// copy it to the current state

	ent->model = cl.model_precache[ent->baseline.modelindex];
	ent->lerpflags |= LERP_RESETANIM; //johnfitz -- lerping
	ent->frame = ent->baseline.frame;

	ent->colormap = vid.colormap;
	ent->skinnum = ent->baseline.skin;
	ent->effects = ent->baseline.effects;
	ent->alpha = ent->baseline.alpha; //johnfitz -- alpha

	VectorCopy (ent->baseline.origin, ent->origin);
	VectorCopy (ent->baseline.angles, ent->angles);
	R_AddEfrags (ent);
}
/*
=====================
CL_ParseStatic
=====================
*/
static void CL_ParseStatic (void)
{
	entity_t *ent;
	int		i;

	i = cl.num_statics;
	if (i >= MAX_STATIC_ENTITIES)
		Host_Error ("Too many static entities");
	ent = &cl_static_entities[i];
	cl.num_statics++;
	CL_ParseBaseline (ent);

// copy it to the current state
	ent->model = cl.model_precache[ent->baseline.modelindex];
	ent->frame = ent->baseline.frame;
	ent->colormap = vid.colormap;
	ent->skinnum = ent->baseline.skin;
	ent->scale = ent->baseline.scale;
	ent->effects = ent->baseline.effects;
	ent->drawflags = ent->baseline.drawflags;
	ent->abslight = ent->baseline.abslight;

	VectorCopy (ent->baseline.origin, ent->origin);
	VectorCopy (ent->baseline.angles, ent->angles);
	R_AddEfrags (ent);
}
Example #3
0
/*
=====================
CL_ParseStatic
=====================
*/
void
CL_ParseStatic(unsigned int bits)
{
    entity_t *ent;
    int i;

    i = cl.num_statics;
    if (i >= MAX_STATIC_ENTITIES)
	Host_Error("Too many static entities");
    ent = &cl_static_entities[i];
    cl.num_statics++;
    CL_ParseBaseline(ent, bits);

// copy it to the current state
    ent->model = cl.model_precache[ent->baseline.modelindex];
    ent->frame = ent->baseline.frame;
    ent->colormap = vid.colormap;
    ent->skinnum = ent->baseline.skinnum;
    ent->effects = ent->baseline.effects;

    /* Initilise frames for model lerp */
    ent->currentframe = ent->baseline.frame;
    ent->previousframe = ent->baseline.frame;
    ent->currentframetime = cl.time;
    ent->previousframetime = cl.time;

    /* Initialise movelerp data */
    ent->previousorigintime = cl.time;
    ent->currentorigintime = cl.time;
    VectorCopy(ent->baseline.origin, ent->previousorigin);
    VectorCopy(ent->baseline.origin, ent->currentorigin);
    VectorCopy(ent->baseline.angles, ent->previousangles);
    VectorCopy(ent->baseline.angles, ent->currentangles);

    VectorCopy(ent->baseline.origin, ent->origin);
    VectorCopy(ent->baseline.angles, ent->angles);
    R_AddEfrags(ent);
}
Example #4
0
/*
=====================
CL_ParseServerMessage
=====================
*/
void
CL_ParseServerMessage(void)
{
    unsigned int bits;
    int i, cmd, prevcmd;
    int playernum, version, stylenum, signon, statnum;
    int stopsound, entitynum, channel;
    byte colors;
    player_info_t *player;
    lightstyle_t *style;
    const char *stylemap, *name;

//
// if recording demos, copy the message out
//
    if (cl_shownet.value == 1)
	Con_Printf("%i ", net_message.cursize);
    else if (cl_shownet.value == 2)
	Con_Printf("------------------\n");

    cl.onground = false;	// unless the server says otherwise
//
// parse the message
//
    prevcmd = svc_bad;
    MSG_BeginReading();

    while (1) {
	if (msg_badread)
	    Host_Error("%s: Bad server message", __func__);

	cmd = MSG_ReadByte();

	if (cmd == -1) {
	    SHOWNET("END OF MESSAGE");
	    return;		// end of message
	}
	// if the high bit of the command byte is set, it is a fast update
	if (cmd & 128) {
	    SHOWNET("fast update");
	    CL_ParseUpdate(cmd & 127);
	    continue;
	}

	SHOWNET(svc_strings[cmd]);

	// other commands
	switch (cmd) {
	case svc_nop:
	    break;

	case svc_time:
	    cl.mtime[1] = cl.mtime[0];
	    cl.mtime[0] = MSG_ReadFloat();
	    break;

	case svc_clientdata:
	    CL_ParseClientdata();
	    break;

	case svc_version:
	    version = MSG_ReadLong();
	    if (!Protocol_Known(version))
		Host_Error("%s: Server returned unknown protocol version %i",
			   __func__, version);
	    cl.protocol = version;
	    break;

	case svc_disconnect:
	    Host_EndGame("Server disconnected\n");

	case svc_print:
	    Con_Printf("%s", MSG_ReadString());
	    break;

	case svc_centerprint:
	    SCR_CenterPrint(MSG_ReadString());
	    break;

	case svc_stufftext:
	    Cbuf_AddText("%s", MSG_ReadString());
	    break;

	case svc_damage:
	    V_ParseDamage();
	    break;

	case svc_serverinfo:
	    CL_ParseServerInfo();
	    vid.recalc_refdef = true;	// leave intermission full screen
	    break;

	case svc_setangle:
	    for (i = 0; i < 3; i++)
		cl.viewangles[i] = MSG_ReadAngle();
	    break;

	case svc_setview:
	    cl.viewentity = MSG_ReadShort();
	    break;

	case svc_lightstyle:
	    stylenum = MSG_ReadByte();
	    if (stylenum >= MAX_LIGHTSTYLES)
		Sys_Error("svc_lightstyle > MAX_LIGHTSTYLES");
	    stylemap = MSG_ReadString();
	    style = cl_lightstyle + stylenum;
	    snprintf(style->map, MAX_STYLESTRING, "%s", stylemap);
	    style->length = strlen(style->map);
	    break;

	case svc_sound:
	    CL_ParseStartSoundPacket();
	    break;

	case svc_stopsound:
	    stopsound = MSG_ReadShort(); /* 3-bit channel encoded in lsb */
	    entitynum = stopsound >> 3;
	    channel = stopsound & 7;
	    S_StopSound(entitynum, channel);
	    break;

	case svc_updatename:
	    Sbar_Changed();
	    playernum = MSG_ReadByte();
	    if (playernum >= cl.maxclients)
		Host_Error("%s: svc_updatename > MAX_SCOREBOARD", __func__);
	    name = MSG_ReadString();
	    player = cl.players + playernum;
	    snprintf(player->name, MAX_SCOREBOARDNAME, "%s", name);
	    break;

	case svc_updatefrags:
	    Sbar_Changed();
	    playernum = MSG_ReadByte();
	    if (playernum >= cl.maxclients)
		Host_Error("%s: svc_updatefrags > MAX_SCOREBOARD", __func__);
	    player = cl.players + playernum;
	    player->frags = MSG_ReadShort();
	    break;

	case svc_updatecolors:
	    Sbar_Changed();
	    playernum = MSG_ReadByte();
	    if (playernum >= cl.maxclients)
		Host_Error("%s: svc_updatecolors > MAX_SCOREBOARD", __func__);
	    colors = MSG_ReadByte();
	    player = cl.players + playernum;
	    player->topcolor = (colors & 0xf0) >> 4;
	    player->bottomcolor = colors & 0x0f;
	    /* FIXME - is this the right check for current player? */
	    if (playernum == cl.viewentity)
		cl_color.value = colors;
	    CL_NewTranslation(playernum);
	    break;

	case svc_particle:
	    R_ParseParticleEffect();
	    break;

	case svc_spawnbaseline:
	    entitynum = MSG_ReadShort();
	    // must use CL_EntityNum() to force cl.num_entities up
	    CL_ParseBaseline(CL_EntityNum(entitynum), 0);
	    break;

	case svc_fitz_spawnbaseline2:
	    /* FIXME - check here that protocol is FITZ? => Host_Error() */
	    entitynum = MSG_ReadShort();
	    bits = MSG_ReadByte();
	    // must use CL_EntityNum() to force cl.num_entities up
	    CL_ParseBaseline(CL_EntityNum(entitynum), bits);
	    break;

	case svc_spawnstatic:
	    CL_ParseStatic(0);
	    break;

	case svc_fitz_spawnstatic2:
	    /* FIXME - check here that protocol is FITZ? => Host_Error() */
	    bits = MSG_ReadByte();
	    CL_ParseStatic(bits);
	    break;

	case svc_temp_entity:
	    CL_ParseTEnt();
	    break;

	case svc_setpause:
	    cl.paused = MSG_ReadByte();
	    if (cl.paused)
		CDAudio_Pause();
	    else
		CDAudio_Resume();
	    break;

	case svc_signonnum:
	    signon = MSG_ReadByte();
	    if (signon <= cls.signon)
		Host_Error("Received signon %d when at %d", signon, cls.signon);
	    cls.signon = signon;
	    CL_SignonReply();
	    break;

	case svc_killedmonster:
	    cl.stats[STAT_MONSTERS]++;
	    break;

	case svc_foundsecret:
	    cl.stats[STAT_SECRETS]++;
	    break;

	case svc_updatestat:
	    statnum = MSG_ReadByte();
	    if (statnum < 0 || statnum >= MAX_CL_STATS)
		Sys_Error("svc_updatestat: %d is invalid", statnum);
	    cl.stats[statnum] = MSG_ReadLong();
	    break;

	case svc_spawnstaticsound:
	    CL_ParseStaticSound();
	    break;

	case svc_fitz_spawnstaticsound2:
	    /* FIXME - check here that protocol is FITZ? => Host_Error() */
	    CL_ParseFitzStaticSound2();
	    break;

	case svc_cdtrack:
	    cl.cdtrack = MSG_ReadByte();
	    cl.looptrack = MSG_ReadByte();
	    if ((cls.demoplayback || cls.demorecording)
		&& (cls.forcetrack != -1))
		CDAudio_Play((byte)cls.forcetrack, true);
	    else
		CDAudio_Play((byte)cl.cdtrack, true);
	    break;

	case svc_intermission:
	    cl.intermission = 1;
	    cl.completed_time = cl.time;
	    vid.recalc_refdef = true;	// go to full screen
	    break;

	case svc_finale:
	    cl.intermission = 2;
	    cl.completed_time = cl.time;
	    vid.recalc_refdef = true;	// go to full screen
	    SCR_CenterPrint(MSG_ReadString());
	    break;

	case svc_cutscene:
	    cl.intermission = 3;
	    cl.completed_time = cl.time;
	    vid.recalc_refdef = true;	// go to full screen
	    SCR_CenterPrint(MSG_ReadString());
	    break;

	case svc_sellscreen:
	    Cmd_ExecuteString("help", src_command);
	    break;

	/* Various FITZ protocol messages - FIXME - !protocol => Host_Error */
	case svc_fitz_skybox:
	    MSG_ReadString(); // FIXME - TODO
	    break;

	case svc_fitz_bf:
	    Cmd_ExecuteString("bf", src_command);
	    break;

	case svc_fitz_fog:
	    /* FIXME - TODO */
	    MSG_ReadByte(); // density
	    MSG_ReadByte(); // red
	    MSG_ReadByte(); // green
	    MSG_ReadByte(); // blue
	    MSG_ReadShort(); // time
	    break;

	default:
	    Host_Error("%s: Illegible server message. Previous was %s",
		       __func__, svc_strings[prevcmd]);
	}
	prevcmd = cmd;
    }
}
Example #5
0
void CL_ParseServerMessage (void)
{
	int			cmd;
	int			i;
	
//
// if recording demos, copy the message out
//
	if (cl_shownet.value == 1)
		Con_Printf ("%i ",net_message.cursize);
	else if (cl_shownet.value == 2)
		Con_Printf ("------------------\n");
	
	cl.onground = false;	// unless the server says otherwise	
//
// parse the message
//
	MSG_BeginReading ();
	
	while (1)
	{
		if (msg_badread)
			Host_Error ("CL_ParseServerMessage: Bad server message");

		cmd = MSG_ReadByte ();

		if (cmd == -1)
		{
			SHOWNET("END OF MESSAGE");
			return;		// end of message
		}

	// if the high bit of the command byte is set, it is a fast update
		if (cmd & 128)
		{
			SHOWNET("fast update");
			CL_ParseUpdate (cmd&127);
			continue;
		}

		SHOWNET(svc_strings[cmd]);
	
	// other commands
		switch (cmd)
		{
		default:
			Host_Error ("CL_ParseServerMessage: Illegible server message\n");
			break;
			
		case svc_nop:
//			Con_Printf ("svc_nop\n");
			break;
			
		case svc_time:
			cl.mtime[1] = cl.mtime[0];
			cl.mtime[0] = MSG_ReadFloat ();			
			break;
			
		case svc_clientdata:
			i = MSG_ReadShort ();
			CL_ParseClientdata (i);
			break;
		
		case svc_version:
			i = MSG_ReadLong ();
			if (i != PROTOCOL_VERSION)
				Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
			break;
			
		case svc_disconnect:
			Host_EndGame ("Server disconnected\n");

		case svc_print:
			Con_Printf ("%s", MSG_ReadString ());
			break;
			
		case svc_centerprint:
			SCR_CenterPrint (MSG_ReadString ());
			break;
			
		case svc_stufftext:
			Cbuf_AddText (MSG_ReadString ());
			break;
			
		case svc_damage:
			V_ParseDamage ();
			break;
			
		case svc_serverinfo:
			CL_ParseServerInfo ();
			vid.recalc_refdef = true;	// leave intermission full screen
			break;
			
		case svc_setangle:
			for (i=0 ; i<3 ; i++)
				cl.viewangles[i] = MSG_ReadAngle ();
			break;
			
		case svc_setview:
			cl.viewentity = MSG_ReadShort ();
			break;
					
		case svc_lightstyle:
			i = MSG_ReadByte ();
			if (i >= MAX_LIGHTSTYLES)
				Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
			Q_strcpy (cl_lightstyle[i].map,  MSG_ReadString());
			cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
			break;
			
		case svc_sound:
			CL_ParseStartSoundPacket();
			break;
			
		case svc_stopsound:
			i = MSG_ReadShort();
			S_StopSound(i>>3, i&7);
			break;
		
		case svc_updatename:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
			strcpy (cl.scores[i].name, MSG_ReadString ());
			break;
			
		case svc_updatefrags:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
			cl.scores[i].frags = MSG_ReadShort ();
			break;			

		case svc_updatecolors:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
			cl.scores[i].colors = MSG_ReadByte ();
			CL_NewTranslation (i);
			break;
			
		case svc_particle:
			R_ParseParticleEffect ();
			break;

		case svc_spawnbaseline:
			i = MSG_ReadShort ();
			// must use CL_EntityNum() to force cl.num_entities up
			CL_ParseBaseline (CL_EntityNum(i));
			break;
		case svc_spawnstatic:
			CL_ParseStatic ();
			break;			
		case svc_temp_entity:
			CL_ParseTEnt ();
			break;

		case svc_setpause:
			{
				cl.paused = MSG_ReadByte ();

				if (cl.paused)
				{
					CDAudio_Pause ();
#ifdef _WIN32
					VID_HandlePause (true);
#endif
				}
				else
				{
					CDAudio_Resume ();
#ifdef _WIN32
					VID_HandlePause (false);
#endif
				}
			}
			break;
			
		case svc_signonnum:
			i = MSG_ReadByte ();
			if (i <= cls.signon)
				Host_Error ("Received signon %i when at %i", i, cls.signon);
			cls.signon = i;
			CL_SignonReply ();
			break;

		case svc_killedmonster:
			cl.stats[STAT_MONSTERS]++;
			break;

		case svc_foundsecret:
			cl.stats[STAT_SECRETS]++;
			break;

		case svc_updatestat:
			i = MSG_ReadByte ();
			if (i < 0 || i >= MAX_CL_STATS)
				Sys_Error ("svc_updatestat: %i is invalid", i);
			cl.stats[i] = MSG_ReadLong ();;
			break;
			
		case svc_spawnstaticsound:
			CL_ParseStaticSound ();
			break;

		case svc_cdtrack:
			cl.cdtrack = MSG_ReadByte ();
			cl.looptrack = MSG_ReadByte ();
			if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
				CDAudio_Play ((byte)cls.forcetrack, true);
			else
				CDAudio_Play ((byte)cl.cdtrack, true);
			break;

		case svc_intermission:
			cl.intermission = 1;
			cl.completed_time = (int) cl.time;
			vid.recalc_refdef = true;	// go to full screen
			break;

		case svc_finale:
			cl.intermission = 2;
			cl.completed_time = (int) cl.time;
			vid.recalc_refdef = true;	// go to full screen
			SCR_CenterPrint (MSG_ReadString ());			
			break;

		case svc_cutscene:
			cl.intermission = 3;
			cl.completed_time = (int) cl.time;
			vid.recalc_refdef = true;	// go to full screen
			SCR_CenterPrint (MSG_ReadString ());			
			break;

		case svc_sellscreen:
			Cmd_ExecuteString2 ("help", src_command);
			break;
		}
	}
}
Example #6
0
/*
=====================
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage( sizebuf_t *msg )
{
	char	*s;
	int	i, j, cmd;
	int	param1, param2;
	int	bufStart;

	cls_message_debug.parsing = true;		// begin parsing
	starting_count = BF_GetNumBytesRead( msg );	// updates each frame
	
	// parse the message
	while( 1 )
	{
		if( BF_CheckOverflow( msg ))
		{
			Host_Error( "CL_ParseServerMessage: overflow!\n" );
			return;
		}

		// mark start position
		bufStart = BF_GetNumBytesRead( msg );

		// end of message
		if( BF_GetNumBitsLeft( msg ) < 8 )
			break;		

		cmd = BF_ReadByte( msg );

		// record command for debugging spew on parse problem
		CL_Parse_RecordCommand( cmd, bufStart );

		// other commands
		switch( cmd )
		{
		case svc_bad:
			Host_Error( "svc_bad\n" );
			break;
		case svc_nop:
			// this does nothing
			break;
		case svc_disconnect:
			MsgDev( D_INFO, "Disconnected from server\n" );
			CL_Drop ();
			Host_AbortCurrentFrame ();
			break;
		case svc_changing:
			if( BF_ReadOneBit( msg ))
			{
				cls.changelevel = true;
				S_StopAllSounds();

				if( cls.demoplayback )
				{
					SCR_BeginLoadingPlaque( cl.background );
					cls.changedemo = true;
				}
			}
			else MsgDev( D_INFO, "Server disconnected, reconnecting\n" );

			CL_ClearState ();
			CL_InitEdicts (); // re-arrange edicts

			if( cls.demoplayback )
			{
				cl.background = (cls.demonum != -1) ? true : false;
				cls.state = ca_connected;
			}
			else cls.state = ca_connecting;
			cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
			break;
		case svc_setview:
			cl.refdef.viewentity = BF_ReadWord( msg );
			break;
		case svc_sound:
			CL_ParseSoundPacket( msg, false );
			break;
		case svc_time:
			// shuffle timestamps
			cl.mtime[1] = cl.mtime[0];
			cl.mtime[0] = BF_ReadFloat( msg );			
			break;
		case svc_print:
			i = BF_ReadByte( msg );
			MsgDev( D_INFO, "^6%s", BF_ReadString( msg ));
			if( i == PRINT_CHAT ) S_StartLocalSound( "common/menu2.wav", VOL_NORM, false );
			break;
		case svc_stufftext:
			CL_ParseStuffText( msg );
			break;
		case svc_lightstyle:
			CL_ParseLightStyle( msg );
			break;
		case svc_setangle:
			CL_ParseSetAngle( msg );
			break;
		case svc_serverdata:
			Cbuf_Execute(); // make sure any stuffed commands are done
			CL_ParseServerData( msg );
			break;
		case svc_addangle:
			CL_ParseAddAngle( msg );
			break;
		case svc_clientdata:
			CL_ParseClientData( msg );
			break;
		case svc_packetentities:
			CL_ParsePacketEntities( msg, false );
			break;
		case svc_deltapacketentities:
			CL_ParsePacketEntities( msg, true );
			break;
		case svc_updatepings:
			CL_UpdateUserPings( msg );
			break;
		case svc_usermessage:
			CL_RegisterUserMessage( msg );
			break;
		case svc_particle:
			CL_ParseParticles( msg );
			break;
		case svc_restoresound:
			CL_ParseRestoreSoundPacket( msg );
			break;
		case svc_spawnstatic:
			CL_ParseStaticEntity( msg );
			break;
		case svc_ambientsound:
			CL_ParseSoundPacket( msg, true );
			break;
		case svc_crosshairangle:
			CL_ParseCrosshairAngle( msg );
			break;
		case svc_spawnbaseline:
			CL_ParseBaseline( msg );
			break;
		case svc_temp_entity:
			CL_ParseTempEntity( msg );
			break;
		case svc_setpause:
			cl.refdef.paused = ( BF_ReadOneBit( msg ) != 0 );
			break;
		case svc_deltamovevars:
			CL_ParseMovevars( msg );
			break;
		case svc_customization:
			CL_ParseCustomization( msg );
			break;
		case svc_centerprint:
			CL_CenterPrint( BF_ReadString( msg ), 0.25f );
			break;
		case svc_event:
			CL_ParseEvent( msg );
			break;
		case svc_event_reliable:
			CL_ParseReliableEvent( msg );
			break;
		case svc_updateuserinfo:
			CL_UpdateUserinfo( msg );
			break;
		case svc_intermission:
			cl.refdef.intermission = true;
			break;
		case svc_modelindex:
			CL_PrecacheModel( msg );
			break;
		case svc_soundindex:
			CL_PrecacheSound( msg );
			break;
		case svc_soundfade:
			CL_ParseSoundFade( msg );
			break;
		case svc_cdtrack:
			param1 = BF_ReadByte( msg );
			param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
			param2 = BF_ReadByte( msg );
			param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
			S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0 );
			break;
		case svc_serverinfo:
			CL_ServerInfo( msg );
			break;
		case svc_eventindex:
			CL_PrecacheEvent( msg );
			break;
		case svc_deltatable:
			Delta_ParseTableField( msg );
			break;
		case svc_weaponanim:
			param1 = BF_ReadByte( msg );	// iAnim
			param2 = BF_ReadByte( msg );	// body
			CL_WeaponAnim( param1, param2 );
			break;
		case svc_bspdecal:
			CL_ParseStaticDecal( msg );
			break;
		case svc_roomtype:
			param1 = BF_ReadShort( msg );
			Cvar_SetFloat( "room_type", param1 );
			break;
		case svc_chokecount:
			i = BF_ReadByte( msg );
			j = cls.netchan.incoming_acknowledged - 1;
			for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
			{
				if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
				{
					cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
					i--;
				}
			}
			break;
		case svc_resourcelist:
			CL_ParseResourceList( msg );
			break;
		case svc_director:
			CL_ParseDirector( msg );
			break;
		case svc_studiodecal:
			CL_ParseStudioDecal( msg );
			break;
		case svc_querycvarvalue:
			CL_ParseCvarValue( msg );
			break;
		case svc_querycvarvalue2:
			CL_ParseCvarValue2( msg );
			break;
		default:
			CL_ParseUserMessage( msg, cmd );
			break;
		}
	}

	cls_message_debug.parsing = false;	// done

	// we don't know if it is ok to save a demo message until
	// after we have parsed the frame
	if( !cls.demoplayback )
	{
		if( cls.demorecording && !cls.demowaiting )
		{
			CL_WriteDemoMessage( false, starting_count, msg );
		}
		else if( cls.state != ca_active )
		{
			CL_WriteDemoMessage( true, starting_count, msg );
		}
	}
}
Example #7
0
void CLNQ_ParseServerMessage (void)
{
	int		cmd;
	int		i;
	qbool	message_with_datagram;		// hack to fix glitches when receiving a packet
											// without a datagram

	nq_player_teleported = false;		// OMG, it's a hack!
	message_with_datagram = false;
	cl_entframecount++;

	if (cl_shownet.value == 1)
		Com_Printf ("%i ", net_message.cursize);
	else if (cl_shownet.value == 2)
		Com_Printf ("------------------\n");
	
	cl.onground = false;	// unless the server says otherwise	

//
// parse the message
//
	//MSG_BeginReading ();
	
	while (1)
	{
		if (msg_badread)
			Host_Error ("CL_ParseServerMessage: Bad server message");

		cmd = MSG_ReadByte ();

		if (cmd == -1)
		{
			SHOWNET("END OF MESSAGE");
			if (!message_with_datagram) {
				cl_entframecount--;
			}
			else
			{
				VectorCopy (nq_mviewangles[0], nq_mviewangles[1]);
				VectorCopy (nq_mviewangles_temp, nq_mviewangles[0]);
			}
			return;		// end of message
		}

	// if the high bit of the command byte is set, it is a fast update
		if (cmd & 128)
		{
			SHOWNET("fast update");
			NQD_ParseUpdate (cmd&127);
			continue;
		}

		if (cmd < num_svc_strings)
			SHOWNET(svc_strings[cmd]);
	
	// other commands
		switch (cmd)
		{
		default:
			Host_Error ("CL_ParseServerMessage: Illegible server message");
			break;

		case svc_nop:
			break;

		case nq_svc_time:
			nq_mtime[1] = nq_mtime[0];
			nq_mtime[0] = MSG_ReadFloat ();
			cl.servertime = nq_mtime[0];
			message_with_datagram = true;
			break;

		case nq_svc_clientdata:
			i = MSG_ReadShort ();
			NQD_ParseClientdata (i);
			break;

		case nq_svc_version:
			i = MSG_ReadLong ();
			if (i != NQ_PROTOCOL_VERSION)
				Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, NQ_PROTOCOL_VERSION);
			break;

		case svc_disconnect:
			Com_Printf ("\n======== End of demo ========\n\n");
			CL_NextDemo ();
			Host_EndGame ();
			Host_Abort ();
			break;

		case svc_print:
			NQD_ParsePrint ();
			break;
			
		case svc_centerprint:
			SCR_CenterPrint (MSG_ReadString ());
			break;

		case svc_stufftext:
			NQD_ParseStufftext ();
			break;

		case svc_damage:
			V_ParseDamage ();
			break;

		case svc_serverdata:
			NQD_ParseServerData ();
			break;

		case svc_setangle:
			for (i=0 ; i<3 ; i++)
				nq_last_fixangle[i] = cl.simangles[i] = cl.viewangles[i] = MSG_ReadAngle ();
			break;

		case svc_setview:
			nq_viewentity = MSG_ReadShort ();
			if (nq_viewentity <= nq_maxclients)
				cl.playernum = nq_viewentity - 1;
			else	{
				// just let cl.playernum stay where it was
			}
			break;

		case svc_lightstyle:
			i = MSG_ReadByte ();
			if (i >= MAX_LIGHTSTYLES)
				Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
			strlcpy (cl_lightstyle[i].map,  MSG_ReadString(), sizeof(cl_lightstyle[0].map));
			cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
			break;

		case svc_sound:
			NQD_ParseStartSoundPacket();
			break;

		case svc_stopsound:
			i = MSG_ReadShort();
			S_StopSound(i>>3, i&7);
			break;

		case nq_svc_updatename:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= nq_maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatename > NQ_MAX_CLIENTS");
			strlcpy (cl.players[i].name, MSG_ReadString(), sizeof(cl.players[i].name));
			break;

		case svc_updatefrags:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= nq_maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatefrags > NQ_MAX_CLIENTS");
			cl.players[i].frags = MSG_ReadShort();
			break;

		case nq_svc_updatecolors:
			NQD_ParseUpdatecolors ();
			break;
			
		case nq_svc_particle:
			CL_ParseParticleEffect ();
			break;

		case svc_spawnbaseline:
			i = MSG_ReadShort ();
			if (i >= NQ_MAX_EDICTS)
				Host_Error ("svc_spawnbaseline: ent > MAX_EDICTS");
			NQD_BumpEntityCount (i);
			CL_ParseBaseline (&cl_entities[i].baseline);
			break;
		case svc_spawnstatic:
			CL_ParseStatic ();
			break;
		case svc_temp_entity:
			CL_ParseTEnt ();
			break;

		case svc_setpause:
			if (MSG_ReadByte() != 0)
				cl.paused |= PAUSED_SERVER;
			else
				cl.paused &= ~PAUSED_SERVER;

			if (cl.paused)
				CDAudio_Pause ();
			else
				CDAudio_Resume ();
			break;

		case nq_svc_signonnum:
			i = MSG_ReadByte ();
			if (i <= nq_signon)
				Host_Error ("Received signon %i when at %i", i, nq_signon);
			nq_signon = i;
			CLNQ_SignonReply ();
			break;

		case svc_killedmonster:
			cl.stats[STAT_MONSTERS]++;
			break;

		case svc_foundsecret:
			cl.stats[STAT_SECRETS]++;
			break;

		case svc_updatestat:
			i = MSG_ReadByte ();
			if (i < 0 || i >= MAX_CL_STATS)
				Sys_Error ("svc_updatestat: %i is invalid", i);
			cl.stats[i] = MSG_ReadLong ();;
			break;

		case svc_spawnstaticsound:
			CL_ParseStaticSound ();
			break;

		case svc_cdtrack:
			cl.cdtrack = MSG_ReadByte ();
			MSG_ReadByte();		// loop track (unused)
			if (nq_forcecdtrack != -1)
				CDAudio_Play ((byte)nq_forcecdtrack, true);
			else
				CDAudio_Play ((byte)cl.cdtrack, true);
			break;

		case svc_intermission:
			cl.intermission = 1;
			cl.completed_time = cl.time;
			VectorCopy (nq_last_fixangle, cl.simangles);
			break;

		case svc_finale:
			cl.intermission = 2;
			cl.completed_time = cl.time;
			SCR_CenterPrint (MSG_ReadString ());
			VectorCopy (nq_last_fixangle, cl.simangles);
			break;

		case nq_svc_cutscene:
			cl.intermission = 3;
			cl.completed_time = cl.time;
			SCR_CenterPrint (MSG_ReadString ());
			VectorCopy (nq_last_fixangle, cl.simangles);
			break;

		case svc_sellscreen:
			break;
		}
	}

}
Example #8
0
/*
* CL_ParseServerMessage
*/
void CL_ParseServerMessage( msg_t *msg )
{
	int cmd;

	if( cl_shownet->integer == 1 )
	{
		Com_Printf( "%i ", msg->cursize );
	}
	else if( cl_shownet->integer >= 2 )
	{
		Com_Printf( "------------------\n" );
	}

	// parse the message
	while( 1 )
	{
		if( msg->readcount > msg->cursize )
		{
			Com_Error( ERR_DROP, "CL_ParseServerMessage: Bad server message" );
			break;
		}

		cmd = MSG_ReadByte( msg );
		if( cl_debug_serverCmd->integer & 4 )
		{
			if( cmd == -1 )
				Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, "EOF" );
			else
				Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, !svc_strings[cmd] ? "bad" : svc_strings[cmd] );
		}

		if( cmd == -1 )
		{
			SHOWNET( msg, "END OF MESSAGE" );
			break;
		}

		if( cl_shownet->integer >= 2 )
		{
			if( !svc_strings[cmd] )
				Com_Printf( "%3i:BAD CMD %i\n", msg->readcount-1, cmd );
			else
				SHOWNET( msg, svc_strings[cmd] );
		}

		// other commands
		switch( cmd )
		{
		default:
			Com_Error( ERR_DROP, "CL_ParseServerMessage: Illegible server message" );
			break;

		case svc_nop:
			// Com_Printf( "svc_nop\n" );
			break;

		case svc_servercmd:
			if( !cls.reliable )
			{
				int cmdNum = MSG_ReadLong( msg );
				if( cmdNum < 0 )
				{
					Com_Error( ERR_DROP, "CL_ParseServerMessage: Invalid cmdNum value received: %i\n",
						cmdNum );
					return;
				}
				if( cmdNum <= cls.lastExecutedServerCommand )
				{
					MSG_ReadString( msg ); // read but ignore
					break;
				}
				cls.lastExecutedServerCommand = cmdNum;
			}
			// fall through
		case svc_servercs: // configstrings from demo files. they don't have acknowledge
			CL_ParseServerCommand( msg );	
			break;

		case svc_serverdata:
			if( cls.state == CA_HANDSHAKE )
			{
				Cbuf_Execute(); // make sure any stuffed commands are done
				CL_ParseServerData( msg );
			}
			else
			{
				return; // ignore rest of the packet (serverdata is always sent alone)
			}
			break;

		case svc_spawnbaseline:
			CL_ParseBaseline( msg );
			break;

		case svc_download:
			CL_ParseDownload( msg );
			break;

		case svc_clcack:
			if( cls.reliable )
			{
				Com_Error( ERR_DROP, "CL_ParseServerMessage: clack message for reliable client\n" );
				return;
			}
			cls.reliableAcknowledge = (unsigned)MSG_ReadLong( msg );
			cls.ucmdAcknowledged = (unsigned)MSG_ReadLong( msg );
			if( cl_debug_serverCmd->integer & 4 )
				Com_Printf( "svc_clcack:reliable cmd ack:%i ucmdack:%i\n", cls.reliableAcknowledge, cls.ucmdAcknowledged );
			break;

		case svc_frame:
			CL_ParseFrame( msg );
			break;

		case svc_demoinfo:
			assert( cls.demo.playing );
			{
				size_t meta_data_maxsize;

				MSG_ReadLong( msg );
				MSG_ReadLong( msg );
				cls.demo.meta_data_realsize = (size_t)MSG_ReadLong( msg );
				meta_data_maxsize = (size_t)MSG_ReadLong( msg );

				// sanity check
				if( cls.demo.meta_data_realsize > meta_data_maxsize ) {
					cls.demo.meta_data_realsize = meta_data_maxsize;
				}
				if( cls.demo.meta_data_realsize > sizeof( cls.demo.meta_data ) ) {
					cls.demo.meta_data_realsize = sizeof( cls.demo.meta_data );
				}

				MSG_ReadData( msg, cls.demo.meta_data, cls.demo.meta_data_realsize );
				MSG_SkipData( msg, meta_data_maxsize - cls.demo.meta_data_realsize );
			}
			break;

		case svc_playerinfo:
		case svc_packetentities:
		case svc_match:
			Com_Error( ERR_DROP, "Out of place frame data" );
			break;

		case svc_extension:
			if( 1 )
			{
				int ext, len;

				ext = MSG_ReadByte( msg );		// extension id
				MSG_ReadByte( msg );			// version number
				len = MSG_ReadShort( msg );		// command length

				switch( ext )
				{
				default:
					// unsupported
					MSG_SkipData( msg, len );
					break;
				}
			}
			break;
		}
	}

	CL_AddNetgraph();

	//
	// if recording demos, copy the message out
	//
	//
	// we don't know if it is ok to save a demo message until
	// after we have parsed the frame
	//
	if( cls.demo.recording && !cls.demo.waiting )
		CL_WriteDemoMessage( msg );
}
/*
=====================
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage (void)
{
	int			cmd;
	int			i;
	const char		*str; //johnfitz
	int			total, j, lastcmd; //johnfitz

//
// if recording demos, copy the message out
//
	if (cl_shownet.value == 1)
		Con_Printf ("%i ",net_message.cursize);
	else if (cl_shownet.value == 2)
		Con_Printf ("------------------\n");

	cl.onground = false;	// unless the server says otherwise
//
// parse the message
//
	MSG_BeginReading ();

	lastcmd = 0;
	while (1)
	{
		if (msg_badread)
			Host_Error ("CL_ParseServerMessage: Bad server message");

		cmd = MSG_ReadByte ();

		if (cmd == -1)
		{
			SHOWNET("END OF MESSAGE");
			return;		// end of message
		}

	// if the high bit of the command byte is set, it is a fast update
		if (cmd & U_SIGNAL) //johnfitz -- was 128, changed for clarity
		{
			SHOWNET("fast update");
			CL_ParseUpdate (cmd&127);
			continue;
		}

		SHOWNET(svc_strings[cmd]);

	// other commands
		switch (cmd)
		{
		default:
			Host_Error ("Illegible server message, previous was %s\n", svc_strings[lastcmd]); //johnfitz -- added svc_strings[lastcmd]
			break;

		case svc_nop:
		//	Con_Printf ("svc_nop\n");
			break;

		case svc_time:
			cl.mtime[1] = cl.mtime[0];
			cl.mtime[0] = MSG_ReadFloat ();
			break;

		case svc_clientdata:
			CL_ParseClientdata (); //johnfitz -- removed bits parameter, we will read this inside CL_ParseClientdata()
			break;

		case svc_version:
			i = MSG_ReadLong ();
			//johnfitz -- support multiple protocols
			if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE)
				Host_Error ("Server returned version %i, not %i or %i\n", i, PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE);
			cl.protocol = i;
			//johnfitz
			break;

		case svc_disconnect:
			Host_EndGame ("Server disconnected\n");

		case svc_print:
			Con_Printf ("%s", MSG_ReadString ());
			break;

		case svc_centerprint:
			//johnfitz -- log centerprints to console
			str = MSG_ReadString ();
			SCR_CenterPrint (str);
			Con_LogCenterPrint (str);
			//johnfitz
			break;

		case svc_stufftext:
			cls.stufftext_frame = host_framecount;	// allow full frame update
								// in demo playback -- Pa3PyX
			Cbuf_AddText (MSG_ReadString ());
			break;

		case svc_damage:
			V_ParseDamage ();
			break;

		case svc_serverinfo:
			CL_ParseServerInfo ();
			vid.recalc_refdef = true;	// leave intermission full screen
			break;

		case svc_setangle:
			for (i=0 ; i<3 ; i++)
				cl.viewangles[i] = MSG_ReadAngle ();
			break;

		case svc_setview:
			cl.viewentity = MSG_ReadShort ();
			break;

		case svc_lightstyle:
			i = MSG_ReadByte ();
			if (i >= MAX_LIGHTSTYLES)
				Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
			q_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING);
			cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
			//johnfitz -- save extra info
			if (cl_lightstyle[i].length)
			{
				total = 0;
				cl_lightstyle[i].peak = 'a';
				for (j=0; j<cl_lightstyle[i].length; j++)
				{
					total += cl_lightstyle[i].map[j] - 'a';
					cl_lightstyle[i].peak = q_max(cl_lightstyle[i].peak, cl_lightstyle[i].map[j]);
				}
				cl_lightstyle[i].average = total / cl_lightstyle[i].length + 'a';
			}
			else
				cl_lightstyle[i].average = cl_lightstyle[i].peak = 'm';
			//johnfitz
			break;

		case svc_sound:
			CL_ParseStartSoundPacket();
			break;

		case svc_stopsound:
			i = MSG_ReadShort();
			S_StopSound(i>>3, i&7);
			break;

		case svc_updatename:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
			q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME);
			break;

		case svc_updatefrags:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
			cl.scores[i].frags = MSG_ReadShort ();
			break;

		case svc_updatecolors:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
			cl.scores[i].colors = MSG_ReadByte ();
			CL_NewTranslation (i);
			break;

		case svc_particle:
			R_ParseParticleEffect ();
			break;

		case svc_spawnbaseline:
			i = MSG_ReadShort ();
			// must use CL_EntityNum() to force cl.num_entities up
			CL_ParseBaseline (CL_EntityNum(i), 1); // johnfitz -- added second parameter
			break;

		case svc_spawnstatic:
			CL_ParseStatic (1); //johnfitz -- added parameter
			break;

		case svc_temp_entity:
			CL_ParseTEnt ();
			break;

		case svc_setpause:
			cl.paused = MSG_ReadByte ();
			if (cl.paused)
			{
				CDAudio_Pause ();
				BGM_Pause ();
			}
			else
			{
				CDAudio_Resume ();
				BGM_Resume ();
			}
			break;

		case svc_signonnum:
			i = MSG_ReadByte ();
			if (i <= cls.signon)
				Host_Error ("Received signon %i when at %i", i, cls.signon);
			cls.signon = i;
			//johnfitz -- if signonnum==2, signon packet has been fully parsed, so check for excessive static ents and efrags
			if (i == 2)
			{
				if (cl.num_statics > 128)
					Con_Warning ("%i static entities exceeds standard limit of 128.\n", cl.num_statics);
				R_CheckEfrags ();
			}
			//johnfitz
			CL_SignonReply ();
			break;

		case svc_killedmonster:
			cl.stats[STAT_MONSTERS]++;
			break;

		case svc_foundsecret:
			cl.stats[STAT_SECRETS]++;
			break;

		case svc_updatestat:
			i = MSG_ReadByte ();
			if (i < 0 || i >= MAX_CL_STATS)
				Sys_Error ("svc_updatestat: %i is invalid", i);
			cl.stats[i] = MSG_ReadLong ();;
			break;

		case svc_spawnstaticsound:
			CL_ParseStaticSound (1); //johnfitz -- added parameter
			break;

		case svc_cdtrack:
			cl.cdtrack = MSG_ReadByte ();
			cl.looptrack = MSG_ReadByte ();
			if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
				BGM_PlayCDtrack ((byte)cls.forcetrack, true);
			else
				BGM_PlayCDtrack ((byte)cl.cdtrack, true);
			break;

		case svc_intermission:
			cl.intermission = 1;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			break;

		case svc_finale:
			cl.intermission = 2;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			//johnfitz -- log centerprints to console
			str = MSG_ReadString ();
			SCR_CenterPrint (str);
			Con_LogCenterPrint (str);
			//johnfitz
			break;

		case svc_cutscene:
			cl.intermission = 3;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			//johnfitz -- log centerprints to console
			str = MSG_ReadString ();
			SCR_CenterPrint (str);
			Con_LogCenterPrint (str);
			//johnfitz
			break;

		case svc_sellscreen:
			Cmd_ExecuteString ("help", src_command);
			break;

		//johnfitz -- new svc types
		case svc_skybox:
			Sky_LoadSkyBox (MSG_ReadString());
			break;

		case svc_bf:
			Cmd_ExecuteString ("bf", src_command);
			break;

		case svc_fog:
			Fog_ParseServerMessage ();
			break;

		case svc_spawnbaseline2: //PROTOCOL_FITZQUAKE
			i = MSG_ReadShort ();
			// must use CL_EntityNum() to force cl.num_entities up
			CL_ParseBaseline (CL_EntityNum(i), 2);
			break;

		case svc_spawnstatic2: //PROTOCOL_FITZQUAKE
			CL_ParseStatic (2);
			break;

		case svc_spawnstaticsound2: //PROTOCOL_FITZQUAKE
			CL_ParseStaticSound (2);
			break;
		//johnfitz
		}

		lastcmd = cmd; //johnfitz
	}
}
/*
=====================
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage (void)
{
	int		cmd;
	int		i, j, k;
	int		EntityCount = 0;
	int		EntitySize = 0;
	int		before;
	static		double lasttime;
	static		qboolean packet_loss = false;
	entity_t	*ent;
	short		RemovePlace, OrigPlace, NewPlace, AddedIndex;
	int		sc1, sc2;
	byte		test;
	float		compangles[2][3];
	vec3_t		deltaangles;

//
// if recording demos, copy the message out
//
	if (net_message.cursize > LastServerMessageSize)
	{
		LastServerMessageSize = net_message.cursize;
	}
	if (cl_shownet.integer == 1)
	{
		Con_Printf ("Time: %2.2f Pck: %i ", realtime - lasttime, net_message.cursize);
		lasttime = realtime;
	}
	else if (cl_shownet.integer == 2)
		Con_Printf ("------------------\n");

	cl.onground = false;	// unless the server says otherwise
//
// parse the message
//
	MSG_BeginReading ();

	while (1)
	{
		if (msg_badread)
			Host_Error ("%s: Bad server message", __thisfunc__);

		cmd = MSG_ReadByte ();

		if (cmd == -1)
		{
			if (cl_shownet.integer == 1)
				Con_Printf ("Ent: %i (%i bytes)",EntityCount,EntitySize);

			SHOWNET("END OF MESSAGE");
			return;		// end of message
		}

	// if the high bit of the command byte is set, it is a fast update
		if (cmd & 128)
		{
			before = msg_readcount;
			SHOWNET("fast update");
			if (packet_loss)
				CL_ParseUpdate2 (cmd&127);
			else
				CL_ParseUpdate (cmd&127);

			EntityCount++;
			EntitySize += msg_readcount - before + 1;
			continue;
		}

		if (cmd < NUM_SVC_STRINGS)	// else, it'll hit the illegible message below
		{
			SHOWNET(svc_strings[cmd]);
		}

	// other commands
		switch (cmd)
		{
		default:
		//	CL_DumpPacket ();
			Host_Error ("%s: Illegible server message %d", __thisfunc__, cmd);
			break;

		case svc_nop:
//			Con_Printf ("svc_nop\n");
			break;

		case svc_time:
			cl.mtime[1] = cl.mtime[0];
			cl.mtime[0] = MSG_ReadFloat ();
			break;

		case svc_clientdata:
			i = MSG_ReadShort ();
			CL_ParseClientdata (i);
			break;

		case svc_version:
			cl_protocol = MSG_ReadLong ();
			switch (cl_protocol)
			{
			case PROTOCOL_RAVEN_111:
			case PROTOCOL_RAVEN_112:
			case PROTOCOL_UQE_113:
				Con_Printf ("Server using protocol %i\n", cl_protocol);
				break;
			default:
				Host_Error ("%s: Server is protocol %i instead of %i or %i",
						__thisfunc__, cl_protocol,
						PROTOCOL_RAVEN_112, PROTOCOL_UQE_113);
			}
			break;

		case svc_disconnect:
			Host_EndGame ("Server disconnected\n");
			break;

		case svc_print:
			if (intro_playing)
				MSG_ReadString ();
			else
				Con_Printf ("%s", MSG_ReadString ());
			break;

		case svc_centerprint:
			SCR_CenterPrint (MSG_ReadString ());
			break;

		case svc_stufftext:
			stufftext_frame = host_framecount;	// allow full frame update
								// on stuff messages. Pa3PyX
			Cbuf_AddText (MSG_ReadString ());
			break;

		case svc_damage:
			V_ParseDamage ();
			break;

		case svc_serverinfo:
			CL_ParseServerInfo ();
			vid.recalc_refdef = true;	// leave intermission full screen
			break;

		case svc_setangle:
			for (i = 0; i < 3; i++)
				cl.viewangles[i] = MSG_ReadAngle ();
			break;

		case svc_setangle_interpolate:
			compangles[0][0] = MSG_ReadAngle();
			compangles[0][1] = MSG_ReadAngle();
			compangles[0][2] = MSG_ReadAngle();
			for (i = 0; i < 3; i++)
			{
				compangles[1][i] = cl.viewangles[i];
				for (j = 0; j < 2; j++)
				{//standardize both old and new angles to +-180
					if (compangles[j][i] >= 360)
						compangles[j][i] -= 360*((int)(compangles[j][i]/360));
					else if (compangles[j][i] <= 360)
						compangles[j][i] += 360*(1+(int)(-compangles[j][i]/360));
					if (compangles[j][i] > 180)
						compangles[j][i] = -360 + compangles[j][i];
					else if (compangles[j][i] < -180)
						compangles[j][i] = 360 + compangles[j][i];
				}
				//get delta
				deltaangles[i] = compangles[0][i] - compangles[1][i];
				//cap delta to <=180,>=-180
				if (deltaangles[i] > 180)
					deltaangles[i] += -360;
				else if (deltaangles[i] < -180)
					deltaangles[i] += 360;
				//add the delta
				cl.viewangles[i]+=(deltaangles[i]/8);//8 step interpolation
				//cap newangles to +-180
				if (cl.viewangles[i] >= 360)
					cl.viewangles[i] -= 360*((int)(cl.viewangles[i]/360));
				else if (cl.viewangles[i] <= 360)
					cl.viewangles[i] += 360*(1+(int)(-cl.viewangles[i]/360));
				if (cl.viewangles[i] > 180)
					cl.viewangles[i] += -360;
				else if (cl.viewangles[i] < -180)
					cl.viewangles[i] += 360;
			}
			break;

		case svc_setview:
			cl.viewentity = MSG_ReadShort ();
			break;

		case svc_lightstyle:
			i = MSG_ReadByte ();
			if (i >= MAX_LIGHTSTYLES)
				Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
			q_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING);
			cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
			break;

		case svc_sound:
			CL_ParseStartSoundPacket();
			break;

		case svc_sound_update_pos:
		{//FIXME: put a field on the entity that lists the channels
			//it should update when it moves- if a certain flag
			//is on the ent, this update_channels field could
			//be set automatically by each sound and stopSound
			//called for this ent?
			vec3_t	pos;
			int	channel, ent_num;

			channel = MSG_ReadShort ();

			ent_num = channel >> 3;
			channel &= 7;

			if (ent_num > MAX_EDICTS)
				Host_Error ("svc_sound_update_pos: ent = %i", ent_num);

			for (i = 0; i < 3; i++)
				pos[i] = MSG_ReadCoord ();

			S_UpdateSoundPos (ent_num, channel, pos);
		}
			break;

		case svc_stopsound:
			i = MSG_ReadShort();
			S_StopSound(i>>3, i&7);
			break;

		case svc_updatename:
			Sbar_Changed();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("%s: svc_updatename > MAX_CLIENTS", __thisfunc__);
			q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME);
			break;

		case svc_updateclass:
			Sbar_Changed();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("%s: svc_updateclass > MAX_CLIENTS", __thisfunc__);
			cl.scores[i].playerclass = (float)MSG_ReadByte();
			CL_NewTranslation(i); // update the color
			break;

		case svc_updatefrags:
			Sbar_Changed();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("%s: svc_updatefrags > MAX_CLIENTS", __thisfunc__);
			cl.scores[i].frags = MSG_ReadShort ();
			break;

		case svc_update_kingofhill:
			sv_kingofhill = MSG_ReadShort() - 1;
			break;

		case svc_updatecolors:
			Sbar_Changed();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("%s: svc_updatecolors > MAX_CLIENTS", __thisfunc__);
			cl.scores[i].colors = MSG_ReadByte ();
			CL_NewTranslation (i);
			break;

		case svc_particle:
			R_ParseParticleEffect ();
			break;

		case svc_particle2:
			R_ParseParticleEffect2 ();
			break;
		case svc_particle3:
			R_ParseParticleEffect3 ();
			break;
		case svc_particle4:
			R_ParseParticleEffect4 ();
			break;

		case svc_spawnbaseline:
			i = MSG_ReadShort ();
			// must use CL_EntityNum() to force cl.num_entities up
			CL_ParseBaseline (CL_EntityNum(i));
			break;
		case svc_spawnstatic:
			CL_ParseStatic ();
			break;

		case svc_raineffect:
			CL_ParseRainEffect();
			break;

		case svc_temp_entity:
			CL_ParseTEnt ();
			break;

		case svc_setpause:
			cl.paused = MSG_ReadByte ();
			if (cl.paused)
			{
				CDAudio_Pause ();
				VID_HandlePause (true);
			}
			else
			{
				CDAudio_Resume ();
				VID_HandlePause (false);
			}
			break;

		case svc_signonnum:
			i = MSG_ReadByte ();
			if (i <= cls.signon)
				Host_Error ("Received signon %i when at %i", i, cls.signon);
			cls.signon = i;
			CL_SignonReply ();
			break;

		case svc_killedmonster:
			cl.stats[STAT_MONSTERS]++;
			break;

		case svc_foundsecret:
			cl.stats[STAT_SECRETS]++;
			break;

		case svc_updatestat:
			i = MSG_ReadByte ();
			if (i < 0 || i >= MAX_CL_STATS)
				Sys_Error ("svc_updatestat: %i is invalid", i);
			cl.stats[i] = MSG_ReadLong ();
			break;

		case svc_spawnstaticsound:
			CL_ParseStaticSound ();
			break;

		case svc_cdtrack:
			cl.cdtrack = MSG_ReadByte ();
			cl.looptrack = MSG_ReadByte ();
			if (q_strcasecmp(bgmtype.string,"cd") == 0)
			{
				if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
					CDAudio_Play ((byte)cls.forcetrack, true);
				else
					CDAudio_Play ((byte)cl.cdtrack, true);
			}
			else
				CDAudio_Stop();
			break;

		case svc_midi_name:
			q_strlcpy (cl.midi_name, MSG_ReadString(), sizeof(cl.midi_name));
			if (q_strcasecmp(bgmtype.string,"midi") == 0)
				MIDI_Play(cl.midi_name);
			else
				MIDI_Stop();
			break;

		case svc_toggle_statbar:
			break;

		case svc_intermission:
			cl.intermission = MSG_ReadByte();
			if (oem.integer && cl.intermission == 1)
				cl.intermission = 9;
			// skip intermissions while recording demos in single
			// player games, but stop recording at ending scenes.
			// skip intermissions when playing demos.
			if (cls.demorecording)
			{
				// 5: finale for the demo version
				// 6, 7, 8: eidolon end-1 to end-3
				// 9: finale for the bundle version
				// 10: praevus ending
				if (sv.active && svs.maxclients == 1 &&
				    (cl.intermission < 5 || cl.intermission > 10))
				{
					cl.intermission = 0;
					demohack = true;
					Cbuf_AddText("+attack\n");	// HACK !..
					break;
				}

				CL_Stop_f ();
			}
			else if (cls.demoplayback)
			{
				cl.intermission = 0;
				break;
			}

			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			break;

/*		case svc_finale:
			cl.intermission = 2;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			SCR_CenterPrint (MSG_ReadString ());
			break;

		case svc_cutscene:
			cl.intermission = 3;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			SCR_CenterPrint (MSG_ReadString ());
			break;

		case svc_sellscreen:
			Cmd_ExecuteString ("help", src_command);
			break;
*/
		case svc_set_view_flags:
			cl.viewent.drawflags |= MSG_ReadByte();
			break;

		case svc_clear_view_flags:
			cl.viewent.drawflags &= ~MSG_ReadByte();
			break;

		case svc_start_effect:
			CL_ParseEffect();
			break;
		case svc_end_effect:
			CL_EndEffect();
			break;

		case svc_plaque:
			CL_Plaque();
			break;

		case svc_particle_explosion:
			CL_ParticleExplosion();
			break;

		case svc_set_view_tint:
			i = MSG_ReadByte();
			cl.viewent.colorshade = i;
			break;

		case svc_reference:
			packet_loss = false;
			cl.last_frame = cl.current_frame;
			cl.last_sequence = cl.current_sequence;
			cl.current_frame = MSG_ReadByte();
			cl.current_sequence = MSG_ReadByte();
			if (cl.need_build == 2)
			{
//				Con_Printf("CL: NB2 CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame);
				cl.frames[0].count = cl.frames[1].count = cl.frames[2].count = 0;
				cl.need_build = 1;
				cl.reference_frame = cl.current_frame;
			}
			else if (cl.last_sequence != cl.current_sequence)
			{
//				Con_Printf("CL: Sequence CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame);
				if (cl.reference_frame >= 1 && cl.reference_frame <= MAX_FRAMES)
				{
					RemovePlace = OrigPlace = NewPlace = AddedIndex = 0;
					for (i = 0; i < cl.num_entities; i++)
					{
						if (RemovePlace >= cl.NumToRemove || cl.RemoveList[RemovePlace] != i)
						{
							if (NewPlace < cl.frames[1].count &&
								cl.frames[1].states[NewPlace].index == i)
							{
								cl.frames[2].states[AddedIndex] = cl.frames[1].states[NewPlace];
								AddedIndex++;
								cl.frames[2].count++;
							}
							else if (OrigPlace < cl.frames[0].count &&
								     cl.frames[0].states[OrigPlace].index == i)
							{
								cl.frames[2].states[AddedIndex] = cl.frames[0].states[OrigPlace];
								AddedIndex++;
								cl.frames[2].count++;
							}
						}
						else
							RemovePlace++;

						if (cl.frames[0].states[OrigPlace].index == i)
							OrigPlace++;
						if (cl.frames[1].states[NewPlace].index == i)
							NewPlace++;
					}
					cl.frames[0] = cl.frames[2];
				}
				cl.frames[1].count = cl.frames[2].count = 0;
				cl.need_build = 1;
				cl.reference_frame = cl.current_frame;
			}
			else
			{
//				Con_Printf("CL: Normal CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame);
				cl.need_build = 0;
			}

			for (i = 1, ent = cl_entities+1; i < cl.num_entities; i++, ent++)
			{
				ent->baseline.flags &= ~BE_ON;
			}

			for (i = 0; i < cl.frames[0].count; i++)
			{
				ent = CL_EntityNum (cl.frames[0].states[i].index);
				ent->model = cl.model_precache[cl.frames[0].states[i].modelindex];
				ent->baseline.flags |= BE_ON;
			}
			break;

		case svc_clear_edicts:
			j = MSG_ReadByte();
			if (cl.need_build)
			{
				cl.NumToRemove = j;
			}
			for (i = 0; i < j; i++)
			{
				k = MSG_ReadShort();
				if (cl.need_build)
					cl.RemoveList[i] = k;
				ent = CL_EntityNum (k);
				ent->baseline.flags &= ~BE_ON;
			}
			break;

		case svc_update_inv:
			sc1 = sc2 = 0;

			test = MSG_ReadByte();
			if (test & 1)
				sc1 |= ((int)MSG_ReadByte());
			if (test & 2)
				sc1 |= ((int)MSG_ReadByte())<<8;
			if (test & 4)
				sc1 |= ((int)MSG_ReadByte())<<16;
			if (test & 8)
				sc1 |= ((int)MSG_ReadByte())<<24;
			if (test & 16)
				sc2 |= ((int)MSG_ReadByte());
			if (test & 32)
				sc2 |= ((int)MSG_ReadByte())<<8;
			if (test & 64)
				sc2 |= ((int)MSG_ReadByte())<<16;
			if (test & 128)
				sc2 |= ((int)MSG_ReadByte())<<24;

			if (sc1 & SC1_HEALTH)
				cl.v.health = MSG_ReadShort();
			if (sc1 & SC1_LEVEL)
				cl.v.level = MSG_ReadByte();
			if (sc1 & SC1_INTELLIGENCE)
				cl.v.intelligence = MSG_ReadByte();
			if (sc1 & SC1_WISDOM)
				cl.v.wisdom = MSG_ReadByte();
			if (sc1 & SC1_STRENGTH)
				cl.v.strength = MSG_ReadByte();
			if (sc1 & SC1_DEXTERITY)
				cl.v.dexterity = MSG_ReadByte();
			if (sc1 & SC1_WEAPON)
				cl.v.weapon = MSG_ReadByte();
			if (sc1 & SC1_BLUEMANA)
				cl.v.bluemana = MSG_ReadByte();
			if (sc1 & SC1_GREENMANA)
				cl.v.greenmana = MSG_ReadByte();
			if (sc1 & SC1_EXPERIENCE)
				cl.v.experience = MSG_ReadLong();
			if (sc1 & SC1_CNT_TORCH)
				cl.v.cnt_torch = MSG_ReadByte();
			if (sc1 & SC1_CNT_H_BOOST)
				cl.v.cnt_h_boost = MSG_ReadByte();
			if (sc1 & SC1_CNT_SH_BOOST)
				cl.v.cnt_sh_boost = MSG_ReadByte();
			if (sc1 & SC1_CNT_MANA_BOOST)
				cl.v.cnt_mana_boost = MSG_ReadByte();
			if (sc1 & SC1_CNT_TELEPORT)
				cl.v.cnt_teleport = MSG_ReadByte();
			if (sc1 & SC1_CNT_TOME)
				cl.v.cnt_tome = MSG_ReadByte();
			if (sc1 & SC1_CNT_SUMMON)
				cl.v.cnt_summon = MSG_ReadByte();
			if (sc1 & SC1_CNT_INVISIBILITY)
				cl.v.cnt_invisibility = MSG_ReadByte();
			if (sc1 & SC1_CNT_GLYPH)
				cl.v.cnt_glyph = MSG_ReadByte();
			if (sc1 & SC1_CNT_HASTE)
				cl.v.cnt_haste = MSG_ReadByte();
			if (sc1 & SC1_CNT_BLAST)
				cl.v.cnt_blast = MSG_ReadByte();
			if (sc1 & SC1_CNT_POLYMORPH)
				cl.v.cnt_polymorph = MSG_ReadByte();
			if (sc1 & SC1_CNT_FLIGHT)
				cl.v.cnt_flight = MSG_ReadByte();
			if (sc1 & SC1_CNT_CUBEOFFORCE)
				cl.v.cnt_cubeofforce = MSG_ReadByte();
			if (sc1 & SC1_CNT_INVINCIBILITY)
				cl.v.cnt_invincibility = MSG_ReadByte();
			if (sc1 & SC1_ARTIFACT_ACTIVE)
				cl.v.artifact_active = MSG_ReadFloat();
			if (sc1 & SC1_ARTIFACT_LOW)
				cl.v.artifact_low = MSG_ReadFloat();
			if (sc1 & SC1_MOVETYPE)
				cl.v.movetype = MSG_ReadByte();
			if (sc1 & SC1_CAMERAMODE)
				cl.v.cameramode = MSG_ReadByte();
			if (sc1 & SC1_HASTED)
				cl.v.hasted = MSG_ReadFloat();
			if (sc1 & SC1_INVENTORY)
				cl.v.inventory = MSG_ReadByte();
			if (sc1 & SC1_RINGS_ACTIVE)
				cl.v.rings_active = MSG_ReadFloat();

			if (sc2 & SC2_RINGS_LOW)
				cl.v.rings_low = MSG_ReadFloat();
			if (sc2 & SC2_AMULET)
				cl.v.armor_amulet = MSG_ReadByte();
			if (sc2 & SC2_BRACER)
				cl.v.armor_bracer = MSG_ReadByte();
			if (sc2 & SC2_BREASTPLATE)
				cl.v.armor_breastplate = MSG_ReadByte();
			if (sc2 & SC2_HELMET)
				cl.v.armor_helmet = MSG_ReadByte();
			if (sc2 & SC2_FLIGHT_T)
				cl.v.ring_flight = MSG_ReadByte();
			if (sc2 & SC2_WATER_T)
				cl.v.ring_water = MSG_ReadByte();
			if (sc2 & SC2_TURNING_T)
				cl.v.ring_turning = MSG_ReadByte();
			if (sc2 & SC2_REGEN_T)
				cl.v.ring_regeneration = MSG_ReadByte();
			if (sc2 & SC2_HASTE_T)
				cl.v.haste_time = MSG_ReadFloat();
			if (sc2 & SC2_TOME_T)
				cl.v.tome_time = MSG_ReadFloat();
			if (sc2 & SC2_PUZZLE1)
				q_snprintf(cl.puzzle_pieces[0], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_PUZZLE2)
				q_snprintf(cl.puzzle_pieces[1], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_PUZZLE3)
				q_snprintf(cl.puzzle_pieces[2], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_PUZZLE4)
				q_snprintf(cl.puzzle_pieces[3], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_PUZZLE5)
				q_snprintf(cl.puzzle_pieces[4], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_PUZZLE6)
				q_snprintf(cl.puzzle_pieces[5], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_PUZZLE7)
				q_snprintf(cl.puzzle_pieces[6], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_PUZZLE8)
				q_snprintf(cl.puzzle_pieces[7], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
			if (sc2 & SC2_MAXHEALTH)
				cl.v.max_health = MSG_ReadShort();
			if (sc2 & SC2_MAXMANA)
				cl.v.max_mana = MSG_ReadByte();
			if (sc2 & SC2_FLAGS)
				cl.v.flags = MSG_ReadFloat();

			// SC2_OBJ, SC2_OBJ2: mission pack objectives
			// With protocol 18 (PROTOCOL_RAVEN_111), these
			// bits get set somehow (?!): let's avoid them.
			if (cl_protocol > PROTOCOL_RAVEN_111)
			{
				if (sc2 & SC2_OBJ)
					cl.info_mask = MSG_ReadLong();
				if (sc2 & SC2_OBJ2)
					cl.info_mask2 = MSG_ReadLong();
			}

			if ((sc1 & SC1_STAT_BAR) || (sc2 & SC2_STAT_BAR))
				Sbar_Changed();

			if ((sc1 & SC1_INV) || (sc2 & SC2_INV))
				SB_InvChanged();
			break;

		case svc_mod_name:
		case svc_skybox:
			MSG_ReadString();
			Con_DPrintf ("Ignored server msg %d (%s)\n", cmd, svc_strings[cmd]);
			break;
		}
	}
}
Example #11
0
/*
=====================
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage( msg_t *msg ) {
	int			cmd;

	if ( cl_shownet->integer == 1 ) {
		Com_Printf ("%i ",msg->cursize);
	} else if ( cl_shownet->integer >= 2 ) {
		Com_Printf ("------------------\n");
	}

	MSG_Bitstream(msg);

	// get the reliable sequence acknowledge number
	clc.reliableAcknowledge = MSG_ReadLong( msg );
	// 
	if ( clc.reliableAcknowledge < clc.reliableSequence - MAX_RELIABLE_COMMANDS ) {
		clc.reliableAcknowledge = clc.reliableSequence;
	}

	//
	// parse the message
	//
	while ( 1 ) {
		if ( msg->readcount > msg->cursize ) {
			Com_Error (ERR_DROP,"CL_ParseServerMessage: read past end of server message");
			break;
		}

		cmd = MSG_ReadByte( msg );

		if (cmd == svc_EOF) {
			SHOWNET( msg, "END OF MESSAGE" );
			break;
		}

		if ( cl_shownet->integer >= 2 ) {
			if ( (cmd < 0) || (!svc_strings[cmd]) ) {
				Com_Printf( "%3i:BAD CMD %i\n", msg->readcount-1, cmd );
			} else {
				SHOWNET( msg, svc_strings[cmd] );
			}
		}
	
	// other commands
		switch ( cmd ) {
		default:
			Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message");
			break;			
		case svc_nop:
			break;
		case svc_serverCommand:
			CL_ParseCommandString( msg );
			break;
		case svc_gamestate:
			CL_ParseGamestate( msg );
			break;
		case svc_baseline:
			CL_ParseBaseline( msg );
			break;
		case svc_snapshot:
			CL_ParseSnapshot( msg );
			break;
		case svc_download:
			CL_ParseDownload( msg );
			break;
		case svc_voipSpeex:
#ifdef USE_VOIP
			CL_ParseVoip( msg, qtrue );
#endif
			break;
		case svc_voipOpus:
#ifdef USE_VOIP
			CL_ParseVoip( msg, !clc.voipEnabled );
#endif
			break;
		}
	}
}