| 391 | } |
| 392 | |
| 393 | static bool TryExtractAccountMetadataAppId(const std::string& path, |
| 394 | uint32_t accountId, |
| 395 | uint32_t& appId) { |
| 396 | std::string prefix = std::to_string(accountId) + "/" + |
| 397 | std::to_string(CloudIntercept::kAccountScopeAppId) + "/blobs/"; |
| 398 | if (path.rfind(prefix, 0) != 0) return false; |
| 399 | |
| 400 | std::string name = path.substr(prefix.size()); |
| 401 | const char* dirs[] = { "UserGameStats/", "Playtime/" }; |
| 402 | for (const char* dir : dirs) { |
| 403 | size_t dirLen = strlen(dir); |
| 404 | if (name.rfind(dir, 0) != 0) continue; |
| 405 | std::string leaf = name.substr(dirLen); |
| 406 | const std::string ext = ".bin"; |
| 407 | if (leaf.size() <= ext.size() || leaf.substr(leaf.size() - ext.size()) != ext) return false; |
| 408 | if (!ParseU32(leaf.substr(0, leaf.size() - ext.size()), appId)) return false; |
| 409 | return appId != CloudIntercept::kAccountScopeAppId; |
| 410 | } |
| 411 | return false; |
| 412 | } |
| 413 | |
| 414 | static void EnumerateLocalAccountMetadataAppIds(const std::filesystem::path& accountRootPath, |
| 415 | std::unordered_set<uint32_t>& appIds) { |
no test coverage detected