本文整理汇总了C++中KeyValues::RecursiveSaveToFile方法的典型用法代码示例。如果您正苦于以下问题:C++ KeyValues::RecursiveSaveToFile方法的具体用法?C++ KeyValues::RecursiveSaveToFile怎么用?C++ KeyValues::RecursiveSaveToFile使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类KeyValues
的用法示例。
在下文中一共展示了KeyValues::RecursiveSaveToFile方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CreateMaterialPatch
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
const char *pNewKey, const char *pNewValue )
{
char oldVMTFile[ 512 ];
char newVMTFile[ 512 ];
AddNewTranslation( pOriginalMaterialName, pNewMaterialName );
sprintf( oldVMTFile, "materials/%s.vmt", pOriginalMaterialName );
sprintf( newVMTFile, "materials/%s.vmt", pNewMaterialName );
// printf( "Creating material patch file %s which points at %s\n", newVMTFile, oldVMTFile );
KeyValues *kv = new KeyValues( "patch" );
if ( !kv )
{
Error( "Couldn't allocate KeyValues for %s!!!", pNewMaterialName );
}
kv->SetString( "include", oldVMTFile );
KeyValues *section = kv->FindKey( "insert", true );
section->SetString( pNewKey, pNewValue );
// Write patched .vmt into a memory buffer
CUtlBuffer buf( 0, 0, true );
kv->RecursiveSaveToFile( buf, 0 );
// Add to pak file for this .bsp
AddBufferToPack( newVMTFile, (void*)buf.Base(), buf.TellPut(), true );
// Cleanup
kv->deleteThis();
}
示例2: CreateMaterialPatch
//-----------------------------------------------------------------------------
// A version which allows you to patch multiple key values
//-----------------------------------------------------------------------------
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
int nKeys, const MaterialPatchInfo_t *pInfo, MaterialPatchType_t nPatchType )
{
char pOldVMTFile[ 512 ];
char pNewVMTFile[ 512 ];
AddNewTranslation( pOriginalMaterialName, pNewMaterialName );
Q_snprintf( pOldVMTFile, 512, "materials/%s.vmt", pOriginalMaterialName );
Q_snprintf( pNewVMTFile, 512, "materials/%s.vmt", pNewMaterialName );
// printf( "Creating material patch file %s which points at %s\n", newVMTFile, oldVMTFile );
KeyValues *kv = new KeyValues( "patch" );
if ( !kv )
{
Error( "Couldn't allocate KeyValues for %s!!!", pNewMaterialName );
}
kv->SetString( "include", pOldVMTFile );
const char *pSectionName = (nPatchType == PATCH_INSERT) ? "insert" : "replace";
KeyValues *section = kv->FindKey( pSectionName, true );
if( nPatchType == PATCH_REPLACE )
{
char name[512];
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pOriginalMaterialName ) );
KeyValues *origkv = new KeyValues( "blah" );
if ( !origkv->LoadFromFile( g_pFileSystem, name ) )
{
origkv->deleteThis();
Assert( 0 );
return;
}
CreateMaterialPatchRecursive( origkv, section, nKeys, pInfo );
origkv->deleteThis();
}
else
{
for ( int i = 0; i < nKeys; ++i )
{
section->SetString( pInfo[i].m_pKey, pInfo[i].m_pValue );
}
}
// Write patched .vmt into a memory buffer
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
kv->RecursiveSaveToFile( buf, 0 );
// Add to pak file for this .bsp
AddBufferToPak( GetPakFile(), pNewVMTFile, (void*)buf.Base(), buf.TellPut(), true );
// Cleanup
kv->deleteThis();
}
示例3: UTIL_IncrementMapKey
void UTIL_IncrementMapKey( const char *pszCustomKey )
{
if ( !pszCustomKey )
return;
char szFilename[ _MAX_PATH ];
if ( !UTIL_GetMapLoadCountFileName( MAP_KEY_FILE, szFilename, _MAX_PATH ) )
return;
int iCount = 1;
KeyValues *kvMapLoadFile = new KeyValues( MAP_KEY_FILE );
if ( kvMapLoadFile )
{
kvMapLoadFile->LoadFromFile( g_pFullFileSystem, szFilename, "MOD" );
char mapname[MAX_MAP_NAME];
Q_FileBase( engine->GetLevelName(), mapname, sizeof( mapname) );
Q_strlower( mapname );
// Increment existing, or add a new one
KeyValues *pMapKey = kvMapLoadFile->FindKey( mapname );
if ( pMapKey )
{
iCount = pMapKey->GetInt( pszCustomKey, 0 ) + 1;
pMapKey->SetInt( pszCustomKey, iCount );
}
else
{
KeyValues *pNewKey = new KeyValues( mapname );
if ( pNewKey )
{
pNewKey->SetString( pszCustomKey, "1" );
kvMapLoadFile->AddSubKey( pNewKey );
}
}
// Write it out
// force create this directory incase it doesn't exist
filesystem->CreateDirHierarchy( MAP_KEY_FILE_DIR, "MOD");
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
kvMapLoadFile->RecursiveSaveToFile( buf, 0 );
g_pFullFileSystem->WriteFile( szFilename, "MOD", buf );
kvMapLoadFile->deleteThis();
}
if ( IsX360() )
{
#ifdef _X360
xboxsystem->FinishContainerWrites();
#endif
}
}
示例4: SaveLocationGrid
bool CASW_Location_Grid::SaveLocationGrid()
{
const char *filename = "resource/mission_grid.txt";
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
for ( int i = 0; i < m_Groups.Count(); i++ )
{
KeyValues *pKey = m_Groups[i]->GetKeyValuesForEditor();
pKey->RecursiveSaveToFile( buf, 0 );
pKey->deleteThis();
}
if ( !g_pFullFileSystem->WriteFile( filename, "GAME", buf ) )
{
Warning( "Failed to SaveLocationGrid %s\n", filename );
return false;
}
return true;
}
示例5: sizeof
CRC32_t IFaceposerModels::CFacePoserModel::GetBitmapCRC( int sequence )
{
CStudioHdr *hdr = m_pModel ? m_pModel->GetStudioHdr() : NULL;
if ( !hdr )
return (CRC32_t)-1;
if ( sequence < 0 || sequence >= hdr->GetNumSeq() )
return (CRC32_t)-1;
mstudioseqdesc_t &seqdesc = hdr->pSeqdesc( sequence );
CRC32_t crc;
CRC32_Init( &crc );
// For sequences, we'll checsum a bit of data
CRC32_ProcessBuffer( &crc, (void *)seqdesc.pszLabel(), Q_strlen( seqdesc.pszLabel() ) );
CRC32_ProcessBuffer( &crc, (void *)seqdesc.pszActivityName(), Q_strlen( seqdesc.pszActivityName() ) );
CRC32_ProcessBuffer( &crc, (void *)&seqdesc.flags, sizeof( seqdesc.flags ) );
//CRC32_ProcessBuffer( &crc, (void *)&seqdesc.numevents, sizeof( seqdesc.numevents ) );
CRC32_ProcessBuffer( &crc, (void *)&seqdesc.numblends, sizeof( seqdesc.numblends ) );
CRC32_ProcessBuffer( &crc, (void *)seqdesc.groupsize, sizeof( seqdesc.groupsize ) );
KeyValues *seqKeyValues = new KeyValues("");
if ( seqKeyValues->LoadFromBuffer( m_pModel->GetFileName( ), m_pModel->GetKeyValueText( sequence ) ) )
{
// Yuck, but I need it in a contiguous block of memory... oh well...
CUtlBuffer buf;
seqKeyValues->RecursiveSaveToFile( buf, 0 );
CRC32_ProcessBuffer( &crc, ( void * )buf.Base(), buf.TellPut() );
}
seqKeyValues->deleteThis();
CRC32_Final( &crc );
return crc;
}
示例6: ExportVMF
//.........这里部分代码省略.........
m_pRoom = m_pMapLayout->m_PlacedRooms[i];
AddRoomInstance( m_pRoom->m_pRoomTemplate, i );
}
}
else
{
// write out logical room solids
int iLogicalRooms = m_pMapLayout->m_LogicalRooms.Count();
m_pRoom = NULL;
for ( int i = 0 ; i < iLogicalRooms ; i++ )
{
// start logical room IDs at 5000 (assumes we'll never place 5000 real rooms)
m_iCurrentRoom = 5000 + i;
CRoomTemplate *pRoomTemplate = m_pMapLayout->m_LogicalRooms[i];
if ( !pRoomTemplate )
continue;
if ( !AddRoomTemplateSolids( pRoomTemplate ) )
return false;
}
// go through each CRoom and write out its world solids
int iRooms = m_pMapLayout->m_PlacedRooms.Count();
for ( m_iCurrentRoom = 0 ; m_iCurrentRoom<iRooms ; m_iCurrentRoom++)
{
m_pRoom = m_pMapLayout->m_PlacedRooms[m_iCurrentRoom];
if (!m_pRoom)
continue;
const CRoomTemplate *pRoomTemplate = m_pRoom->m_pRoomTemplate;
if (!pRoomTemplate)
continue;
if ( !AddRoomTemplateSolids( pRoomTemplate ) )
return false;
}
// write out logical room entities
m_pRoom = NULL;
for ( int i = 0 ; i < iLogicalRooms ; i++ )
{
// start logical room IDs at 5000 (assumes we'll never place 5000 real rooms)
m_iCurrentRoom = 5000 + i;
CRoomTemplate *pRoomTemplate = m_pMapLayout->m_LogicalRooms[i];
if ( !pRoomTemplate )
continue;
if ( !AddRoomTemplateEntities( pRoomTemplate ) )
return false;
}
// go through each CRoom and add its entities
for ( m_iCurrentRoom = 0 ; m_iCurrentRoom<iRooms ; m_iCurrentRoom++)
{
m_pRoom = m_pMapLayout->m_PlacedRooms[m_iCurrentRoom];
if (!m_pRoom)
continue;
const CRoomTemplate *pRoomTemplate = m_pRoom->m_pRoomTemplate;
if (!pRoomTemplate)
continue;
if ( !AddRoomTemplateEntities( pRoomTemplate ) )
return false;
}
}
// add some player starts to the map in the tile the user selected
if ( !bHasStartRoom )
{
m_pExportKeys->AddSubKey( GetPlayerStarts() );
}
m_pExportKeys->AddSubKey( GetGameRulesProxy() );
m_pExportKeys->AddSubKey( GetDefaultCamera() );
// save out the export keys
char filename[512];
Q_snprintf( filename, sizeof(filename), "maps\\%s", mapname );
Q_SetExtension( filename, "vmf", sizeof( filename ) );
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
for ( KeyValues *pKey = m_pExportKeys->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey() )
{
pKey->RecursiveSaveToFile( buf, 0 );
}
if ( !g_pFullFileSystem->WriteFile( filename, "GAME", buf ) )
{
Msg( "Failed to SaveToFile %s\n", filename );
return false;
}
// save the map layout there (so the game can get information about rooms during play)
Q_snprintf( filename, sizeof( filename ), "maps\\%s", mapname );
Q_SetExtension( filename, "layout", sizeof( filename ) );
if ( !m_pMapLayout->SaveMapLayout( filename ) )
{
Q_snprintf( m_szLastExporterError, sizeof(m_szLastExporterError), "Failed to save .layout file\n");
return false;
}
return true;
}
示例7: SaveMapLayout
bool CMapLayout::SaveMapLayout( const char *filename )
{
KeyValues *pLayoutKeys = new KeyValues( "Layout" );
if ( m_pGenerationOptions )
{
pLayoutKeys->AddSubKey( m_pGenerationOptions->MakeCopy() );
}
KeyValues *pMiscKeys = new KeyValues( "mapmisc" );
pMiscKeys->SetInt( "PlayerStartX", m_iPlayerStartTileX );
pMiscKeys->SetInt( "PlayerStartY", m_iPlayerStartTileY );
pLayoutKeys->AddSubKey( pMiscKeys );
// save out each room
int iRooms = m_PlacedRooms.Count();
for (int i=0;i<iRooms;i++)
{
CRoom *pRoom = m_PlacedRooms[i];
if (!pRoom)
continue;
pLayoutKeys->AddSubKey( pRoom->GetKeyValuesCopy() );
}
// save out logical rooms
iRooms = m_LogicalRooms.Count();
for (int i=0;i<iRooms;i++)
{
KeyValues *pRoomKeys = new KeyValues( "logical_room" );
if ( m_LogicalRooms[i]->m_pLevelTheme )
{
pRoomKeys->SetString( "theme", m_LogicalRooms[i]->m_pLevelTheme->m_szName );
}
pRoomKeys->SetString( "template", m_LogicalRooms[i]->GetFullName() );
pLayoutKeys->AddSubKey( pRoomKeys );
}
for ( int i = 0; i < m_InstanceSpawns.Count(); ++ i )
{
KeyValues *pNewInstanceSpawn = new KeyValues( "instance_spawn" );
m_InstanceSpawns[i].SaveToKeyValues( pNewInstanceSpawn );
pLayoutKeys->AddSubKey( pNewInstanceSpawn );
}
for ( int i = 0; i < m_Encounters.Count(); ++ i )
{
KeyValues *pEncounterKeys = new KeyValues( "npc_encounter" );
m_Encounters[i]->SaveToKeyValues( pEncounterKeys );
pLayoutKeys->AddSubKey( pEncounterKeys );
}
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
for ( KeyValues *pKey = pLayoutKeys->GetFirstSubKey(); pKey; pKey = pKey->GetNextKey() )
{
pKey->RecursiveSaveToFile( buf, 0 );
}
pLayoutKeys->deleteThis();
if ( !g_pFullFileSystem->WriteFile( filename, "GAME", buf ) )
{
Log_Warning( LOG_TilegenLayoutSystem, "Failed to SaveToFile %s\n", filename );
return false;
}
return true;
}
示例8: WriteSaveData
//=========================================================
//=========================================================
bool C_GameInstructor::WriteSaveData()
{
if ( engine->IsPlayingDemo() )
return false;
if ( !m_bDirtySaveData )
return true;
#ifdef _X360
float flPlatTime = Plat_FloatTime();
static ConVarRef host_write_last_time( "host_write_last_time" );
if ( host_write_last_time.IsValid() )
{
float flTimeSinceLastWrite = flPlatTime - host_write_last_time.GetFloat();
if ( flTimeSinceLastWrite < 3.5f )
{
// Prevent writing to the same storage device twice in less than 3 second succession for TCR success!
// This happens after leaving a game in splitscreen.
//DevMsg( "Waiting to write Game Instructor for splitscreen slot %d... (%.1f seconds remain)\n", m_nSplitScreenSlot, 3.5f - flTimeSinceLastWrite );
return false;
}
}
#endif
// Always mark as clean state to avoid re-entry on
// subsequent frames when storage device might be
// in a yet-unmounted state.
m_bDirtySaveData = false;
#ifdef _X360
DevMsg( "Write Game Instructor for splitscreen slot %d at time: %.1f\n", m_nSplitScreenSlot, flPlatTime );
if ( m_nSplitScreenSlot < 0 )
return false;
if ( m_nSplitScreenSlot >= (int) XBX_GetNumGameUsers() )
return false;
int iController = XBX_GetUserId( m_nSplitScreenSlot );
if ( iController < 0 || XBX_GetUserIsGuest( iController ) )
{
// Can't save data for guests
return false;
}
DWORD nStorageDevice = XBX_GetStorageDeviceId( iController );
if ( !XBX_DescribeStorageDevice( nStorageDevice ) )
return false;
#endif
// Build key value data to save
KeyValues *data = new KeyValues( "Game Instructor Counts" );
KeyValues::AutoDelete autoDelete(data);
for ( int i = 0; i < m_Lessons.Count(); ++i )
{
CBaseLesson *pLesson = m_Lessons[i];
int iDisplayCount = pLesson->GetDisplayCount();
int iSuccessCount = pLesson->GetSuccessCount();
if ( iDisplayCount || iSuccessCount )
{
// We've got some data worth saving
KeyValues *pKVData = new KeyValues( pLesson->GetName() );
if ( iDisplayCount )
pKVData->SetInt( "display", iDisplayCount );
if ( iSuccessCount )
pKVData->SetInt( "success", iSuccessCount );
data->AddSubKey( pKVData );
}
}
// Save it!
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
data->RecursiveSaveToFile( buf, 0 );
char szFilename[_MAX_PATH];
#ifdef _X360
if ( IsX360() )
{
XBX_MakeStorageContainerRoot( iController, XBX_USER_SETTINGS_CONTAINER_DRIVE, szFilename, sizeof( szFilename ) );
int nLen = strlen( szFilename );
Q_snprintf( szFilename + nLen, sizeof( szFilename ) - nLen, ":\\game_instructor_counts.txt" );
}
else
#endif
{
Q_snprintf( szFilename, sizeof( szFilename ), "save/game_instructor_counts.txt" );
filesystem->CreateDirHierarchy( "save", "MOD" );
}
//.........这里部分代码省略.........
示例9: SaveMedalStore
bool C_ASW_Medal_Store::SaveMedalStore()
{
if ( !m_bLoaded )
return false;
KeyValues *kv = new KeyValues( "CLIENTDAT" );
// output missions/campaigns/kills
kv->SetInt("MC", m_iMissionsCompleted);
kv->SetInt("CC", m_iCampaignsCompleted);
kv->SetInt("AK", m_iAliensKilled);
kv->SetInt("OMC", m_iOfflineMissionsCompleted);
kv->SetInt("OCC", m_iOfflineCampaignsCompleted);
kv->SetInt("OAK", m_iOfflineAliensKilled);
kv->SetInt( "LPL", m_iXP );
kv->SetInt( "LPP", m_iPromotion );
KeyValues *pSubSection = new KeyValues("NEWEQUIP");
char buffer[64];
if (pSubSection)
{
for (int i=0;i<m_NewEquipment.Count();i++)
{
pSubSection->SetInt( "EQUIP", m_NewEquipment[i]);
}
kv->AddSubKey(pSubSection);
}
// output player medals
pSubSection = new KeyValues("LP");
if (pSubSection)
{
for (int i=0;i<m_PlayerMedals.Count();i++)
{
Q_snprintf(buffer, sizeof(buffer), "M%d", i);
pSubSection->SetInt(buffer, m_PlayerMedals[i]);
}
kv->AddSubKey(pSubSection);
}
for (int k=0;k<ASW_NUM_MARINE_PROFILES;k++)
{
Q_snprintf(buffer, sizeof(buffer), "LA%d", k);
pSubSection = new KeyValues(buffer);
if (pSubSection)
{
for (int i=0;i<m_MarineMedals[k].Count();i++)
{
Q_snprintf(buffer, sizeof(buffer), "M%d", i);
pSubSection->SetInt(buffer, m_MarineMedals[k][i]);
}
kv->AddSubKey(pSubSection);
}
}
// offline medal store
pSubSection = new KeyValues("FP");
if (pSubSection)
{
for (int i=0;i<m_OfflinePlayerMedals.Count();i++)
{
Q_snprintf(buffer, sizeof(buffer), "M%d", i);
pSubSection->SetInt(buffer, m_OfflinePlayerMedals[i]);
}
kv->AddSubKey(pSubSection);
}
for (int k=0;k<ASW_NUM_MARINE_PROFILES;k++)
{
Q_snprintf(buffer, sizeof(buffer), "FA%d", k);
pSubSection = new KeyValues(buffer);
if (pSubSection)
{
for (int i=0;i<m_OfflineMarineMedals[k].Count();i++)
{
Q_snprintf(buffer, sizeof(buffer), "M%d", i);
pSubSection->SetInt(buffer, m_OfflineMarineMedals[k][i]);
}
kv->AddSubKey(pSubSection);
}
}
CUtlBuffer buf; //( 0, 0, CUtlBuffer::TEXT_BUFFER );
kv->RecursiveSaveToFile( buf, 0 );
// pad buffer with zeroes to make a multiple of 8
int nExtra = buf.TellPut() % 8;
while ( nExtra != 0 && nExtra < 8 )
{
buf.PutChar( 0 );
nExtra++;
}
UTIL_EncodeICE( (unsigned char*) buf.Base(), buf.TellPut(), g_ucMedalStoreEncryptionKey );
ISteamUser *pSteamUser = steamapicontext ? steamapicontext->SteamUser() : NULL;
if ( !pSteamUser )
return false;
//.........这里部分代码省略.........
示例10: WriteIndents
void KeyValues::RecursiveSaveToFile(IFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel)
{
WriteIndents(filesystem, f, pBuf, indentLevel);
INTERNALWRITE("\"", 1);
WriteConvertedString(filesystem, f, pBuf, GetName());
INTERNALWRITE("\"\n", 2);
WriteIndents(filesystem, f, pBuf, indentLevel);
INTERNALWRITE("{\n", 2);
for (KeyValues *dat = m_pSub; dat != NULL; dat = dat->m_pPeer)
{
if (dat->m_pSub)
{
dat->RecursiveSaveToFile(filesystem, f, pBuf, indentLevel + 1);
}
else
{
switch (dat->m_iDataType)
{
case TYPE_STRING:
{
if (dat->m_sValue && *(dat->m_sValue))
{
WriteIndents(filesystem, f, pBuf, indentLevel + 1);
INTERNALWRITE("\"", 1);
WriteConvertedString(filesystem, f, pBuf, dat->GetName());
INTERNALWRITE("\"\t\t\"", 4);
WriteConvertedString(filesystem, f, pBuf, dat->m_sValue);
INTERNALWRITE("\"\r\n", 3);
}
break;
}
#ifdef _WIN32
case TYPE_WSTRING:
{
if (dat->m_wsValue)
{
static char buf[KEYVALUES_TOKEN_SIZE];
assert(::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, NULL, 0, NULL, NULL) < KEYVALUES_TOKEN_SIZE);
int result = ::WideCharToMultiByte(CP_UTF8, 0, dat->m_wsValue, -1, buf, KEYVALUES_TOKEN_SIZE, NULL, NULL);
if (result)
{
WriteIndents(filesystem, f, pBuf, indentLevel + 1);
INTERNALWRITE("\"", 1);
INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName()));
INTERNALWRITE("\"\t\t\"", 4);
WriteConvertedString(filesystem, f, pBuf, buf);
INTERNALWRITE("\"\r\n", 3);
}
}
#endif
break;
}
case TYPE_INT:
{
WriteIndents(filesystem, f, pBuf, indentLevel + 1);
INTERNALWRITE("\"", 1);
INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName()));
INTERNALWRITE("\"\t\t\"", 4);
char buf[32];
Q_snprintf(buf, 32, "%d", dat->m_iValue);
INTERNALWRITE(buf, Q_strlen(buf));
INTERNALWRITE("\"\r\n", 3);
break;
}
case TYPE_UINT64:
{
WriteIndents(filesystem, f, pBuf, indentLevel + 1);
INTERNALWRITE("\"", 1);
INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName()));
INTERNALWRITE("\"\t\t\"", 4);
char buf[32];
Q_snprintf(buf, sizeof(buf), "0x%016I64X", *((uint64 *)dat->m_sValue));
INTERNALWRITE(buf, Q_strlen(buf));
INTERNALWRITE("\"\r\n", 3);
break;
}
case TYPE_FLOAT:
{
WriteIndents(filesystem, f, pBuf, indentLevel + 1);
INTERNALWRITE("\"", 1);
INTERNALWRITE(dat->GetName(), Q_strlen(dat->GetName()));
INTERNALWRITE("\"\t\t\"", 4);
char buf[48];
Q_snprintf(buf, 48, "%f", dat->m_flValue);
//.........这里部分代码省略.........