bool FChunkManifestGenerator::SaveAssetRegistry(const FString& SandboxPath, const TArray<FName>* IgnorePackageList)
{
    UE_LOG(LogChunkManifestGenerator, Display, TEXT("Saving asset registry."));


    TSet<FName> IgnorePackageSet;
    if (IgnorePackageList != nullptr)
    {
        for (const auto& IgnorePackage : *IgnorePackageList)
        {
            IgnorePackageSet.Add(IgnorePackage);
        }
    }


    // Create asset registry data
    FArrayWriter SerializedAssetRegistry;
    SerializedAssetRegistry.SetFilterEditorOnly(true);
    TMap<FName, FAssetData*> GeneratedAssetRegistryData;
    for (auto& AssetData : AssetRegistryData)
    {
        if (IgnorePackageSet.Contains(AssetData.PackageName))
        {
            continue;
        }

        // Add only assets that have actually been cooked and belong to any chunk
        if (AssetData.ChunkIDs.Num() > 0)
        {
            GeneratedAssetRegistryData.Add(AssetData.ObjectPath, &AssetData);
        }
    }
    AssetRegistry.SaveRegistryData(SerializedAssetRegistry, GeneratedAssetRegistryData);
    UE_LOG(LogChunkManifestGenerator, Display, TEXT("Generated asset registry num assets %d, size is %5.2fkb"), GeneratedAssetRegistryData.Num(), (float)SerializedAssetRegistry.Num() / 1024.f);

    // Save the generated registry for each platform
    for (auto Platform : Platforms)
    {
        FString PlatformSandboxPath = SandboxPath.Replace(TEXT("[Platform]"), *Platform->PlatformName());
        FFileHelper::SaveArrayToFile(SerializedAssetRegistry, *PlatformSandboxPath);
    }

    UE_LOG(LogChunkManifestGenerator, Display, TEXT("Done saving asset registry."));

    return true;
}
bool FChunkManifestGenerator::SaveAssetRegistry(const FString& SandboxPath, const TArray<FName>* IgnorePackageList)
{
	UE_LOG(LogChunkManifestGenerator, Display, TEXT("Saving asset registry."));


	TSet<FName> IgnorePackageSet;
	if (IgnorePackageList != nullptr)
	{
		for (const auto& IgnorePackage : *IgnorePackageList)
		{
			IgnorePackageSet.Add(IgnorePackage);
		}
	}
	

	// Create asset registry data
	TArray<FName> MapList;
	FArrayWriter SerializedAssetRegistry;
	SerializedAssetRegistry.SetFilterEditorOnly(true);
	TMap<FName, FAssetData*> GeneratedAssetRegistryData;
	for (auto& AssetData : AssetRegistryData)
	{
		if (IgnorePackageSet.Contains(AssetData.PackageName))
		{
			continue;
		}

		// Add only assets that have actually been cooked and belong to any chunk
		if (AssetData.ChunkIDs.Num() > 0)
		{
			GeneratedAssetRegistryData.Add(AssetData.PackageName, &AssetData);

			if (ContainsMap(AssetData.PackageName))
			{
				MapList.Add(AssetData.PackageName);
		}
	}
	}

	AssetRegistry.SaveRegistryData(SerializedAssetRegistry, GeneratedAssetRegistryData, &MapList);
	UE_LOG(LogChunkManifestGenerator, Display, TEXT("Generated asset registry num assets %d, size is %5.2fkb"), GeneratedAssetRegistryData.Num(), (float)SerializedAssetRegistry.Num() / 1024.f);

	auto CookerFileOrderString = CreateCookerFileOrderString(GeneratedAssetRegistryData, MapList);

	// Save the generated registry for each platform
	for (auto Platform : Platforms)
	{
		FString PlatformSandboxPath = SandboxPath.Replace(TEXT("[Platform]"), *Platform->PlatformName());
		FFileHelper::SaveArrayToFile(SerializedAssetRegistry, *PlatformSandboxPath);

		if (CookerFileOrderString.Len())
		{
			auto OpenOrderFilename = FString::Printf(TEXT("%sBuild/%s/FileOpenOrder/CookerOpenOrder.log"), *FPaths::GameDir(), *Platform->PlatformName());
			FFileHelper::SaveStringToFile(CookerFileOrderString, *OpenOrderFilename);
		}
	}

	UE_LOG(LogChunkManifestGenerator, Display, TEXT("Done saving asset registry."));

	return true;
}