bool CNetworkStringTable::ReadStringTable( CUtlBuffer& buf )
{
	DeleteAllStrings();

	int numstrings = buf.GetInt();
	for ( int i = 0 ; i < numstrings; i++ )
	{
		char stringname[4096];
		
		buf.GetString( stringname, sizeof( stringname ) );

		if ( buf.GetChar() == 1 )
		{
			int userDataSize = (int)buf.GetShort();
			Assert( userDataSize > 0 );
			byte *data = new byte[ userDataSize + 4 ];
			Assert( data );

			buf.Get( data, userDataSize );

			AddString( true, stringname, userDataSize, data );

			delete[] data;
			
		}
		else
		{
			AddString( true, stringname );
		}
	}

	return true;
}
bool CRunTimeKeyValuesStringTable::ReadStringTable( int numStrings, CUtlBuffer& buf )
{
	Assert( m_Strings.Count() == 0 );

	CUtlVector< int > offsets;
	offsets.EnsureCapacity( numStrings );

	offsets.CopyArray( (int *)( buf.PeekGet() ), numStrings );

	// Skip over data
	buf.SeekGet( CUtlBuffer::SEEK_HEAD, buf.TellGet() + numStrings * sizeof( int ) );

	int stringSize = buf.GetInt();
	
	// Read in the string table
	m_Strings.EnsureCapacity( numStrings );
	int i;
	for ( i = 0 ; i < numStrings; ++i )
	{
		m_Strings.AddToTail( (const char *)buf.PeekGet( offsets[ i ] ) );
	}

	buf.SeekGet( CUtlBuffer::SEEK_HEAD, buf.TellGet() + stringSize );

	return true;
}
Ejemplo n.º 3
0
void LoadBitString(int *pInts, int nInts, CUtlBuffer& buf)
{
	for (int i=0; i<nInts; i++) 
	{
		pInts[i] = buf.GetInt(); 
	}
}
bool BasicGameStats_t::ParseFromBuffer( CUtlBuffer& buf, int iBufferStatsVersion )
{
	bool bret = true;

	m_nSecondsToCompleteGame = buf.GetInt();
	if ( m_nSecondsToCompleteGame < 0 || m_nSecondsToCompleteGame > 10000000 )
	{
		bret = false;
	}

	m_Summary.ParseFromBuffer( buf, iBufferStatsVersion );
	int c = buf.GetInt();
	if ( c > 1024 || c < 0 )
	{
		bret = false;
	}

	for ( int i = 0; i < c; ++i )
	{
		char mapname[ 256 ];
		buf.GetString( mapname, sizeof( mapname ) );

		BasicGameStatsRecord_t *rec = FindOrAddRecordForMap( mapname );
		bool valid= rec->ParseFromBuffer( buf, iBufferStatsVersion );
		if ( !valid )
		{
			bret = false;
		}
	}

	if ( iBufferStatsVersion >= GAMESTATS_FILE_VERSION_OLD2 )
	{
		m_nHL2ChaptureUnlocked = (int)buf.GetChar();	
		m_bSteam = buf.GetChar() ? true : false;
	}
	if ( iBufferStatsVersion > GAMESTATS_FILE_VERSION_OLD2 )
	{
		m_bCyberCafe = buf.GetChar() ? true : false;
	}
	if ( iBufferStatsVersion > GAMESTATS_FILE_VERSION_OLD3 )
	{
		m_nDXLevel = (int)buf.GetShort();
	}
	return bret;
}
Ejemplo n.º 5
0
void CStaticPropMgr::UnserializeLeafList( CUtlBuffer& buf )
{
	int nCount = buf.GetInt();
	m_StaticPropLeaves.Purge();
	if ( nCount > 0 )
	{
		m_StaticPropLeaves.AddMultipleToTail( nCount );
		buf.Get( m_StaticPropLeaves.Base(), nCount * sizeof(StaticPropLeafLump_t) );
	}
}
Ejemplo n.º 6
0
bool AStar::Load(IFileSystem *filesystem, const char *Filename)
{
	CUtlBuffer buf;

	if(!filesystem->ReadFile(Filename, "MOD", buf))
	{
		return false;
	}

	buf.SeekGet(CUtlBuffer::SEEK_HEAD, 0);

	int SrcID, DestID;

	//////////////////////////////////////////////
	// Nodes
	int NodeTotal = buf.GetInt();

	for(int i = 0; i < NodeTotal; i++)
	{
		Vector origin;
		origin.x = buf.GetFloat();
		origin.y = buf.GetFloat();
		origin.z = buf.GetFloat();
		AddNode(new AStarNode(origin));
	}
	//////////////////////////////////////////////

	//////////////////////////////////////////////
	// Links
	int TotalNumLinks = buf.GetInt();

	for(int i = 0; i < TotalNumLinks; i++)
	{
		SrcID = buf.GetInt();
		DestID = buf.GetInt();
		Nodes[SrcID]->AddLink(Nodes[DestID]);
	}

	//////////////////////////////////////////////

	return true;
}
void CVradStaticPropMgr::UnserializeModelDict( CUtlBuffer& buf )
{
	int count = buf.GetInt();
	while ( --count >= 0 )
	{
		StaticPropDictLump_t lump;
		buf.Get( &lump, sizeof(StaticPropDictLump_t) );
		
		CreateCollisionModel( lump.m_Name );
	}
}
Ejemplo n.º 8
0
bool Unserialize( CUtlBuffer &buf, int &dest )
{
	if ( buf.IsText() )
	{
		int nRetVal = buf.Scanf( "%d", &dest );
		return (nRetVal == 1) && buf.IsValid();
	}

	dest = buf.GetInt( );
	return buf.IsValid();
}
bool BasicGameStatsRecord_t::ParseFromBuffer( CUtlBuffer &buf, int iBufferStatsVersion )
{
	bool bret = true;
	m_nCount = buf.GetInt();

	if ( m_nCount > 100000 || m_nCount < 0 )
	{
		bret = false;
	}

	m_nSeconds = buf.GetInt();
	// Note, don't put the buf.GetInt() in the macro since it'll get evaluated twice!!!
	m_nSeconds = MAX( m_nSeconds, 0 );

	m_nCommentary = buf.GetInt();
	if ( m_nCommentary < 0 || m_nCommentary > 100000 )
	{
		bret = false;
	}

	m_nHDR = buf.GetInt();
	if ( m_nHDR < 0 || m_nHDR > 100000 )
	{
		bret = false;
	}

	m_nCaptions = buf.GetInt();
	if ( m_nCaptions < 0 || m_nCaptions > 100000 )
	{
		bret = false;
	}

	for ( int i = 0; i < 3; ++i )
	{
		m_nSkill[ i ] = buf.GetInt();
		if ( m_nSkill[ i ] < 0 || m_nSkill[ i ]  > 100000 )
		{
			bret = false;
		}
	}

	if ( iBufferStatsVersion > GAMESTATS_FILE_VERSION_OLD )
	{
		m_bSteam = buf.GetChar() ? true : false;
	}
	if ( iBufferStatsVersion > GAMESTATS_FILE_VERSION_OLD2 )
	{
		m_bCyberCafe = buf.GetChar() ? true : false;
	}
	if ( iBufferStatsVersion > GAMESTATS_FILE_VERSION_OLD5 )
	{
		m_nDeaths = buf.GetInt();
	}

	return bret;
}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------
// Unserialize static prop model dictionary
//-----------------------------------------------------------------------------
void CStaticPropMgr::UnserializeModelDict( CUtlBuffer& buf )
{
	int count = buf.GetInt();
	while ( --count >= 0 )
	{
		StaticPropDictLump_t lump;
		buf.Get( &lump, sizeof(StaticPropDictLump_t) );
		
		StaticPropDict_t dict;
		dict.m_pModel = (model_t *)modelloader->GetModelForName(
			lump.m_Name, IModelLoader::FMODELLOADER_STATICPROP );
		m_StaticPropDict.AddToTail( dict );
	}
}
Ejemplo n.º 11
0
static void UnserializeSpriteDict( CUtlBuffer& buf )
{
	// Get origin offset for each model...
	int count = buf.GetInt();
	while ( --count >= 0 )
	{
		DetailSpriteDictLump_t lump;
		buf.Get( &lump, sizeof(DetailSpriteDictLump_t) );
		
		// For these sprites, x goes out the front, y right, z up
		int i = g_SpriteCenterOffset.AddToTail();
		g_SpriteCenterOffset[i].x = 0.0f;
		g_SpriteCenterOffset[i].y = lump.m_LR.x + lump.m_UL.x;
		g_SpriteCenterOffset[i].z = lump.m_LR.y + lump.m_UL.y;
		g_SpriteCenterOffset[i] *= 0.5f;
	}
}
Ejemplo n.º 12
0
bool Unserialize( CUtlBuffer &buf, CUtlBinaryBlock &dest )
{
	if ( !buf.IsText() )
	{
		int nLen = buf.GetInt( );
		dest.SetLength( nLen );
		if ( dest.Length() != 0 )
		{
			buf.Get( dest.Get(), dest.Length() );
		}

		if ( nLen != dest.Length() )
		{
			buf.SeekGet( CUtlBuffer::SEEK_CURRENT, nLen - dest.Length() );
			return false;
		}

		return buf.IsValid();
	}

	int nEndGet;
	int nByteCount = CountBinaryBytes( buf, &nEndGet );
	if ( nByteCount < 0 )
		return false;

	buf.EatWhiteSpace();
	int nDest = 0;
	dest.SetLength( nByteCount );
	while( buf.TellGet() < nEndGet )
	{
		char c1 = buf.GetChar();
		char c2 = buf.GetChar();

		unsigned char b1 = HexCharToInt( c1 );
		unsigned char b2 = HexCharToInt( c2 );
		if ( b1 == 0xFF || b2 == 0xFF )
			return false;

		dest[ nDest++ ] = b2 | ( b1 << 4 );
		buf.EatWhiteSpace();
	}

	return true;
}
Ejemplo n.º 13
0
void CStaticPropMgr::UnserializeModels( CUtlBuffer& buf )
{
	// Version check
	if ( Mod_GameLumpVersion( GAMELUMP_STATIC_PROPS ) < 4 )
	{
		Warning("Really old map format! Static props can't be loaded...\n");
		return;
	}

	int count = buf.GetInt();

	// Gotta preallocate the static props here so no rellocations take place
	// the leaf list stores pointers to these tricky little guys.
	m_StaticProps.AddMultipleToTail(count);
	for ( int i = 0; i < count; ++i )
	{
		StaticPropLump_t lump;
		buf.Get( &lump, sizeof(StaticPropLump_t) );
 		m_StaticProps[i].Init( i, lump, m_StaticPropDict[lump.m_PropType].m_pModel );

		// For distance-based fading, keep a list of the things that need
		// to be faded out. Not sure if this is the optimal way of doing it
		// but it's easy for now; we'll have to test later how large this list gets.
		// If it's <100 or so, we should be fine
		if (lump.m_Flags & STATIC_PROP_FLAG_FADES)
		{
			int idx = m_StaticPropFade.AddToTail();
			StaticPropFade_t& fade = m_StaticPropFade[idx];
			fade.m_Model = i;
			fade.m_MinDistSq = lump.m_FadeMinDist * lump.m_FadeMinDist;
			fade.m_MaxDistSq = lump.m_FadeMaxDist * lump.m_FadeMaxDist;
			if (fade.m_MaxDistSq != fade.m_MinDistSq)
				fade.m_FalloffFactor = 255.0f / (fade.m_MaxDistSq - fade.m_MinDistSq);
			else
				fade.m_FalloffFactor = 255.0f;
		}

		// Add the prop to the K-D tree for collision
		m_StaticProps[i].InsertPropIntoKDTree( );
	}
}
bool CNetworkStringTableContainer::ReadStringTables( CUtlBuffer& buf )
{
	int numTables = buf.GetInt();
	for ( int i = 0 ; i < numTables; i++ )
	{
		char tablename[ 256 ];
		buf.GetString( tablename, sizeof( tablename ) );

		// Find this table by name
		CNetworkStringTable *table = (CNetworkStringTable*)FindTable( tablename );
		Assert( table );

		// Now read the data for the table
		if ( !table->ReadStringTable( buf ) )
		{
			Host_Error( "Error reading string table %s\n", tablename );
		}

	}
	return true;
}
void CVradStaticPropMgr::UnserializeModels( CUtlBuffer& buf )
{
	int count = buf.GetInt();

	m_StaticProps.AddMultipleToTail(count);
	for ( int i = 0; i < count; ++i )
	{
		StaticPropLump_t lump;
		buf.Get( &lump, sizeof(StaticPropLump_t) );
		
		VectorCopy( lump.m_Origin, m_StaticProps[i].m_Origin );
		VectorCopy( lump.m_Angles, m_StaticProps[i].m_Angles );
		m_StaticProps[i].m_ModelIdx = lump.m_PropType;
		m_StaticProps[i].m_Handle = TREEDATA_INVALID_HANDLE;

		// Add the prop to the tree for collision, but only if it isn't
		// marked as not casting a shadow
		if ((lump.m_Flags & STATIC_PROP_NO_SHADOW) == 0)
			InsertPropIntoTree( i );
	}
}
Ejemplo n.º 16
0
//-----------------------------------------------------------------------------
// Unserialization
//-----------------------------------------------------------------------------
static void UnserializeModelDict( CUtlBuffer& buf )
{
	// Get origin offset for each model...
	int count = buf.GetInt();
	while ( --count >= 0 )
	{
		DetailObjectDictLump_t lump;
		buf.Get( &lump, sizeof(DetailObjectDictLump_t) );
		
		int i = g_ModelCenterOffset.AddToTail();

		CUtlBuffer mdlbuf;
		if (LoadStudioModel( lump.m_Name, mdlbuf ))
		{
			studiohdr_t* pHdr = (studiohdr_t*)mdlbuf.Base();
			VectorAdd( pHdr->hull_min, pHdr->hull_max, g_ModelCenterOffset[i] );
			g_ModelCenterOffset[i] *= 0.5f;
		}
		else
		{
			g_ModelCenterOffset[i].Init(0,0,0);
		}
	}
}
Ejemplo n.º 17
0
void VMPI_DistributeLightData()
{
	if ( !g_bUseMPI )
		return;

	if ( g_bMPIMaster )
	{
		const char *pVirtualFilename = "--plightdata--";
		
		CUtlBuffer lightFaceData;

		// write out the light data
		lightFaceData.EnsureCapacity( pdlightdata->Count() + (numfaces * (MAXLIGHTMAPS+sizeof(int))) );
		Q_memcpy( lightFaceData.PeekPut(), pdlightdata->Base(), pdlightdata->Count() );
		lightFaceData.SeekPut( CUtlBuffer::SEEK_HEAD, pdlightdata->Count() );

		// write out the relevant face info into the stream
		for ( int i = 0; i < numfaces; i++ )
		{
			for ( int j = 0; j < MAXLIGHTMAPS; j++ )
			{
				lightFaceData.PutChar(g_pFaces[i].styles[j]);
			}
			lightFaceData.PutInt(g_pFaces[i].lightofs);
		}
		VMPI_FileSystem_CreateVirtualFile( pVirtualFilename, lightFaceData.Base(), lightFaceData.TellMaxPut() );

		char cPacketID[2] = { VMPI_VRAD_PACKET_ID, VMPI_SUBPACKETID_PLIGHTDATA_RESULTS };
		VMPI_Send2Chunks( cPacketID, sizeof( cPacketID ), pVirtualFilename, strlen( pVirtualFilename ) + 1, VMPI_PERSISTENT );
	}
	else
	{
		VMPI_SetCurrentStage( "VMPI_DistributeLightData" );

		// Wait until we've received the filename from the master.
		while ( g_LightResultsFilename.Count() == 0 )
		{
			VMPI_DispatchNextMessage();
		}

		// Open 
		FileHandle_t fp = g_pFileSystem->Open( g_LightResultsFilename.Base(), "rb", VMPI_VIRTUAL_FILES_PATH_ID );
		if ( !fp )
			Error( "Can't open '%s' to read lighting info.", g_LightResultsFilename.Base() );

		int size = g_pFileSystem->Size( fp );
		int faceSize = (numfaces*(MAXLIGHTMAPS+sizeof(int)));

		if ( size > faceSize )
		{
			int lightSize = size - faceSize;
			CUtlBuffer faceData;
			pdlightdata->EnsureCount( lightSize );
			faceData.EnsureCapacity( faceSize );

			g_pFileSystem->Read( pdlightdata->Base(), lightSize, fp );
			g_pFileSystem->Read( faceData.Base(), faceSize, fp );
			g_pFileSystem->Close( fp );

			faceData.SeekPut( CUtlBuffer::SEEK_HEAD, faceSize );

			// write out the face data
			for ( int i = 0; i < numfaces; i++ )
			{
				for ( int j = 0; j < MAXLIGHTMAPS; j++ )
				{
					g_pFaces[i].styles[j] = faceData.GetChar();
				}
				g_pFaces[i].lightofs = faceData.GetInt();
			}
		}
	}
}
Ejemplo n.º 18
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : buf - 
//-----------------------------------------------------------------------------
void CSentence::CacheRestoreFromBuffer( CUtlBuffer& buf )
{
	Assert( !buf.IsText() );

	Reset();

	m_bIsCached = true;

	// determine format
	int version = buf.GetChar();
	if ( version != CACHED_SENTENCE_VERSION && version != CACHED_SENTENCE_VERSION_ALIGNED )
	{
		// Uh oh, version changed...
		m_bIsValid = false;
		return;
	}

	unsigned short pcount;
	if ( version == CACHED_SENTENCE_VERSION_ALIGNED )
	{
		buf.GetChar();
		buf.GetChar();
		buf.GetChar();
		pcount = buf.GetInt();
	}
	else
	{
		pcount = (unsigned short)buf.GetShort();
	}

	// phonemes
	CPhonemeTag pt;
	int i;
	if ( version == CACHED_SENTENCE_VERSION_ALIGNED )
	{
		for ( i = 0; i < pcount; ++i )
		{
			int code = buf.GetInt();
			float st = buf.GetFloat();
			float et = buf.GetFloat();

			pt.SetPhonemeCode( code );
			pt.SetStartTime( st );
			pt.SetEndTime( et );
			AddRuntimePhoneme( &pt );
		}
	}
	else
	{
		for ( i = 0; i < pcount; ++i )
		{
			unsigned short code = buf.GetShort();
			float st = buf.GetFloat();
			float et = buf.GetFloat();

			pt.SetPhonemeCode( code );
			pt.SetStartTime( st );
			pt.SetEndTime( et );
			AddRuntimePhoneme( &pt );
		}
	}

	// emphasis samples and voice duck
	int c;
	if ( version == CACHED_SENTENCE_VERSION_ALIGNED )
	{
		c = buf.GetInt();
		for ( i = 0; i < c; i++ )
		{
			CEmphasisSample sample;
			sample.SetSelected( false );
			sample.time = buf.GetFloat();
			sample.value = buf.GetFloat();
			m_EmphasisSamples.AddToTail( sample );
		}
		SetVoiceDuck( buf.GetInt() == 0 ? false : true );
	}
	else
	{
		c = buf.GetShort();
		for ( i = 0; i < c; i++ )
		{
			CEmphasisSample sample;
			sample.SetSelected( false );
			sample.time = buf.GetFloat();
			sample.value = (float)buf.GetShort() / 32767.0f;
			m_EmphasisSamples.AddToTail( sample );
		}
		SetVoiceDuck( buf.GetChar() == 0 ? false : true );
	}

	m_bIsValid = true;
}
Ejemplo n.º 19
0
bool CBaseGameStats::LoadFromFile( void )
{
	if ( filesystem->FileExists( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID ) )
	{
		char fullpath[ 512 ];
		filesystem->RelativePathToFullPath( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID, fullpath, sizeof( fullpath ) );
		StatsLog( "Loading stats from '%s'\n", fullpath );
	}
	
	CUtlBuffer buf; 
	if ( filesystem->ReadFile( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID, buf ) )
	{
		bool bRetVal = true;

		int version = buf.GetShort();
		if ( version > GAMESTATS_FILE_VERSION )
			return false; //file is beyond our comprehension

		// Set global parse version
		CBGSDriver.m_iLoadedVersion = version;

		buf.Get( CBGSDriver.m_szLoadedUserID, 16 );
		CBGSDriver.m_szLoadedUserID[ sizeof( CBGSDriver.m_szLoadedUserID ) - 1 ] = 0;

		if ( s_szPseudoUniqueID[ 0 ] != 0 )
		{			
			if ( Q_stricmp( CBGSDriver.m_szLoadedUserID, s_szPseudoUniqueID ) )
			{
				//UserID changed, blow away log!!!
				filesystem->RemoveFile( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID );
				filesystem->RemoveFile( GAMESTATS_LOG_FILE, GAMESTATS_PATHID );
				Warning( "Userid changed, clearing stats file\n" );
				CBGSDriver.m_szLoadedUserID[0] = '\0';
				CBGSDriver.m_iLoadedVersion = -1;
				gamestats->m_BasicStats.Clear();
				gamestats->LoadingEvent_PlayerIDDifferentThanLoadedStats();
				bRetVal = false;
			}
		
			if ( version <= GAMESTATS_FILE_VERSION_OLD5 )
			{
				gamestats->m_BasicStats.Clear();
				bRetVal = false;
			}
			else
			{
				// Peek ahead in buffer to see if we have the "no default stats" secret flag set.
				int iCheckForStandardStatsInFile = *( int * )buf.PeekGet();
				bool bValid = true;

				if ( iCheckForStandardStatsInFile != GAMESTATS_STANDARD_NOT_SAVED )
				{
					//the GAMESTATS_STANDARD_NOT_SAVED flag coincides with user completion time, rewind so the gamestats parser can grab it
					bValid = gamestats->m_BasicStats.ParseFromBuffer( buf, version );
				}
				else
				{
					// skip over the flag
					buf.GetInt();
				}

				if( !bValid )
				{
					m_BasicStats.Clear();
				}

				if( ( buf.TellPut() - buf.TellGet() ) != 0 ) //more data left, must be custom data
				{
					gamestats->LoadCustomDataFromBuffer( buf );
				}
			}
		}

		return bRetVal;
	}
	else
	{
		filesystem->RemoveFile( GAMESTATS_LOG_FILE, GAMESTATS_PATHID );
	}

	return false;	
}
Ejemplo n.º 20
0
bool KeyValues::ReadAsBinary(CUtlBuffer &buffer)
{
	if (buffer.IsText())
		return false;

	if (!buffer.IsValid())
		return false;

	RemoveEverything();
	Init();

	char token[KEYVALUES_TOKEN_SIZE];
	KeyValues *dat = this;
	types_t type = (types_t)buffer.GetUnsignedChar();

	while (true)
	{
		if (type == TYPE_NUMTYPES)
			break;

		dat->m_iDataType = type;

		buffer.GetString(token, KEYVALUES_TOKEN_SIZE - 1);
		token[KEYVALUES_TOKEN_SIZE - 1] = 0;

		dat->SetName(token);

		switch (type)
		{
			case TYPE_NONE:
			{
				dat->m_pSub = new KeyValues("");
				dat->m_pSub->ReadAsBinary(buffer);
				break;
			}

			case TYPE_STRING:
			{
				buffer.GetString(token, KEYVALUES_TOKEN_SIZE - 1);
				token[KEYVALUES_TOKEN_SIZE - 1] = 0;

				int len = Q_strlen(token);
				dat->m_sValue = new char[len + 1];
				Q_memcpy(dat->m_sValue, token, len + 1);

				break;
			}

			case TYPE_WSTRING:
			{
				Assert(!"TYPE_WSTRING");
				break;
			}

			case TYPE_INT:
			{
				dat->m_iValue = buffer.GetInt();
				break;
			}

			case TYPE_UINT64:
			{
				dat->m_sValue = new char[sizeof(uint64)];
				*((double *)dat->m_sValue) = buffer.GetDouble();
			}

			case TYPE_FLOAT:
			{
				dat->m_flValue = buffer.GetFloat();
				break;
			}

			case TYPE_COLOR:
			{
				dat->m_Color[0] = buffer.GetUnsignedChar();
				dat->m_Color[1] = buffer.GetUnsignedChar();
				dat->m_Color[2] = buffer.GetUnsignedChar();
				dat->m_Color[3] = buffer.GetUnsignedChar();
				break;
			}

			case TYPE_PTR:
			{
				dat->m_pValue = (void *)buffer.GetUnsignedInt();
			}

			default:
			{
				break;
			}
		}

		if (!buffer.IsValid())
			return false;

		type = (types_t)buffer.GetUnsignedChar();

		if (type == TYPE_NUMTYPES)
			break;

		dat->m_pPeer = new KeyValues("");
		dat = dat->m_pPeer;
	}

	return buffer.IsValid();
}