了解VDF文件——构建Steam游戏库的关键
对于Steam玩家和开发者,VDF(Valve Data Format)文件并不陌生。它是Steam游戏库中存储游戏信息的格式,包括游戏名称、封面、运行命令等。本文将介绍VDF文件的构成、读取和编辑。
一. VDF文件的组成
VDF文件采用类似于INI文件的格式,通过键值对来存储数据。在Steam游戏库中,VDF文件的默认路径为Steam\\userdata\\UserID\\config目录下的config.vdf文件,其中UserID为你的Steam账号ID。打开该文件,可以看到如下的结构:
\"UserLocalConfigStore\"
{
\"friends\"
{
\"FriendClientFlags\"
{
\"7656119xxxxxxxxxx\"
{
\"android\", \"friendsonly\", \"invites, mutualfriends\", \"pc\", \"psn\", \"restricted\", \"steamlink\", \"xb1\"
}
}
}
}
其中\"UserLocalConfigStore\"为根节点,包含一个名为“friends”的子节点,该节点下又包含一个名为“FriendClientFlags”的子节点。不同的节点通过大括号进行分隔,每个节点用双引号包裹。键值对之间采用英文逗号分隔,值可以是一个字符串、一个整数或一个子节点。
二. VDF文件的读取
在开发Steam相关的应用时,我们需要读取VDF文件中的数据。Steam API提供了读取VDF文件的函数。以C++为例,我们可以使用以下代码来读取config.vdf文件中的所有子节点:
std::string configPath = \"path/to/Steam/userdata/userid/config/config.vdf\";
KeyValues *root = new KeyValues(\"VDFRoot\");
std::ifstream configFile(configPath);
if (configFile.good())
{
std::string configData((std::istreambuf_iterator
root->LoadFromBuffer(\"\", configData.c_str());
}
KeyValues *friendsNode = root->FindKey(\"UserLocalConfigStore/friends\");
for (KeyValues *node = friendsNode->GetFirstTrueSubKey(); node != nullptr; node = node->GetNextTrueSubKey())
{
std::string friendID = node->GetName();
KeyValues *flagNode = node->FindKey(\"FriendClientFlags\", true);
if (flagNode != nullptr)
{
std::string flags = flagNode->GetString();
// do something
}
}
上述代码首先创建了一个名为“VDFRoot”的根节点,然后通过KeyValues::LoadFromBuffer函数将config.vdf文件中的数据加载进来。查找名为“friends”的节点并遍历其子节点。各个函数的详细用法可以参考Steamworks文档。
三. VDF文件的编辑
有时,我们需要修改VDF文件中的某些值,以适应特定的需求。Steam API也提供了修改VDF文件的函数,以下代码演示了如何往config.vdf文件中名为“UserLocalConfigStore/friends/7656119xxxxxxxxxx/FriendClientFlags”的节点中添加名为“test”的值:
std::string configPath = \"path/to/Steam/userdata/userid/config/config.vdf\";
KeyValues *root = new KeyValues(\"VDFRoot\");
std::ifstream configFile(configPath);
if (configFile.good())
{
std::string configData((std::istreambuf_iterator
root->LoadFromBuffer(\"\", configData.c_str());
}
KeyValues *flagNode = root->FindKey(\"UserLocalConfigStore/friends/7656119xxxxxxxxxx/FriendClientFlags\", true);
if (flagNode != nullptr)
{
flagNode->SetString(\"test\", \"test_value\");
std::ofstream outFile;
outFile.open(configPath, std::ios::out | std::ios::binary);
if (outFile.good())
{
std::string rawData;
root->RecursiveSaveToBuffer(rawData, 0, false, false);
outFile << rawData;
}
}
将config.vdf文件中名为“UserLocalConfigStore/friends/7656119xxxxxxxxxx/FriendClientFlags”的节点找到,并调用SetString函数,将名为“test”的键以及对应的值添加进去。最后调用KeyValues的RecursiveSaveToBuffer函数将修改后的数据保存回文件。
此外,VDF文件还有一些高级用法,例如使用全局变量和字符串替换来构建VDF模板等,在此不作赘述。感兴趣的读者可以去阅读Steamworks文档来学习更多。