bool FBuildPatchAppManifest::VerifyAgainstDirectory( const FString& VerifyDirectory, TArray < FString >& OutDatedFiles, FBuildPatchFloatDelegate ProgressDelegate, FBuildPatchBoolRetDelegate ShouldPauseDelegate, double& TimeSpentPaused )
{
	bool bAllCorrect = true;
	OutDatedFiles.Empty();
	TimeSpentPaused = 0;

	// Setup progress tracking
	double TotalBuildSizeDouble = GetBuildSize();
	double ProcessedBytes = 0;
	struct FLocalProgress
	{
		double CurrentBuildPercentage;
		double CurrentFileWeight;
		FBuildPatchFloatDelegate ProgressDelegate;
		void PerFileProgress( float Progress )
		{
			const double PercentComplete = CurrentBuildPercentage + ( Progress * CurrentFileWeight );
			ProgressDelegate.ExecuteIfBound( PercentComplete );
		}
	} LocalProgress;
	LocalProgress.CurrentBuildPercentage = 0;
	LocalProgress.ProgressDelegate = ProgressDelegate;

	// For all files in FileManifestList, check that they produce the correct SHA1 hash, adding any that don't to the list
	for( auto FileManifestIt = Data->FileManifestList.CreateConstIterator(); FileManifestIt && !FBuildPatchInstallError::HasFatalError(); ++FileManifestIt )
	{
		// Pause if necessary
		const double PrePauseTime = FPlatformTime::Seconds();
		double PostPauseTime = PrePauseTime;
		bool bShouldPause = ShouldPauseDelegate.IsBound() && ShouldPauseDelegate.Execute();
		while( bShouldPause )
		{
			FPlatformProcess::Sleep( 0.1f );
			bShouldPause = ShouldPauseDelegate.Execute();
			PostPauseTime = FPlatformTime::Seconds();
		}
		// Count up pause time
		TimeSpentPaused += PostPauseTime - PrePauseTime;
		// Get file details and construct
		const FFileManifestData& FileManifest = *FileManifestIt;
		FString FullFilename = VerifyDirectory / FileManifest.Filename;
		const int64 CurrentFileSize = FileManifest.GetFileSize();
		LocalProgress.CurrentFileWeight = CurrentFileSize / TotalBuildSizeDouble;
		const bool bSameFile = FBuildPatchUtils::VerifyFile(FullFilename, FileManifest.FileHash, FileManifest.FileHash, FBuildPatchFloatDelegate::CreateRaw(&LocalProgress, &FLocalProgress::PerFileProgress), ShouldPauseDelegate, TimeSpentPaused) != 0;
		ProcessedBytes += CurrentFileSize;
		LocalProgress.CurrentBuildPercentage = ProcessedBytes / TotalBuildSizeDouble;
		bAllCorrect &= bSameFile;
		if( !bSameFile )
		{
			OutDatedFiles.Add( FileManifest.Filename );
		}
	}

	return bAllCorrect && !FBuildPatchInstallError::HasFatalError();
}
Exemple #2
0
uint8 FBuildPatchUtils::VerifyFile(const FString& FileToVerify, const FSHAHashData& Hash1, const FSHAHashData& Hash2, FBuildPatchFloatDelegate ProgressDelegate, FBuildPatchBoolRetDelegate ShouldPauseDelegate, double& TimeSpentPaused)
{
	uint8 ReturnValue = 0;
	FArchive* FileReader = IFileManager::Get().CreateFileReader(*FileToVerify);
	ProgressDelegate.ExecuteIfBound(0.0f);
	if (FileReader != NULL)
	{
		FSHA1 HashState;
		FSHAHashData HashValue;
		const int64 FileSize = FileReader->TotalSize();
		uint8* FileReadBuffer = new uint8[FileBufferSize];
		while (!FileReader->AtEnd() && !FBuildPatchInstallError::HasFatalError())
		{
			// Pause if necessary
			const double PrePauseTime = FPlatformTime::Seconds();
			double PostPauseTime = PrePauseTime;
			bool bShouldPause = ShouldPauseDelegate.IsBound() && ShouldPauseDelegate.Execute();
			while (bShouldPause && !FBuildPatchInstallError::HasFatalError())
			{
				FPlatformProcess::Sleep(0.1f);
				bShouldPause = ShouldPauseDelegate.Execute();
				PostPauseTime = FPlatformTime::Seconds();
			}
			// Count up pause time
			TimeSpentPaused += PostPauseTime - PrePauseTime;
			// Read file and update hash state
			const int64 SizeLeft = FileSize - FileReader->Tell();
			const uint32 ReadLen = FMath::Min< int64 >(FileBufferSize, SizeLeft);
			FileReader->Serialize(FileReadBuffer, ReadLen);
			HashState.Update(FileReadBuffer, ReadLen);
			const double FileSizeTemp = FileSize;
			const float Progress = 1.0f - ((SizeLeft - ReadLen) / FileSizeTemp);
			ProgressDelegate.ExecuteIfBound(Progress);
		}
		delete[] FileReadBuffer;
		HashState.Final();
		HashState.GetHash(HashValue.Hash);
		ReturnValue = (HashValue == Hash1) ? 1 : (HashValue == Hash2) ? 2 : 0;
		if (ReturnValue == 0)
		{
			GLog->Logf(TEXT("BuildDataGenerator: Verify failed on %s"), *FPaths::GetCleanFilename(FileToVerify));
		}
		FileReader->Close();
		delete FileReader;
	}
	else
	{
		GLog->Logf(TEXT("BuildDataGenerator: ERROR VerifyFile cannot open %s"), *FileToVerify);
	}
	ProgressDelegate.ExecuteIfBound(1.0f);
	return ReturnValue;
}
bool FBuildPatchVerificationImpl::VerfiyFileSize(const FString& BuildFile, double& TimeSpentPaused)
{
	// Pause if necessary
	const double PrePauseTime = FPlatformTime::Seconds();
	double PostPauseTime = PrePauseTime;
	bool bShouldPause = ShouldPauseDelegate.IsBound() && ShouldPauseDelegate.Execute();
	while (bShouldPause && !FBuildPatchInstallError::HasFatalError())
	{
		FPlatformProcess::Sleep(0.1f);
		bShouldPause = ShouldPauseDelegate.Execute();
		PostPauseTime = FPlatformTime::Seconds();
	}
	// Count up pause time
	TimeSpentPaused += PostPauseTime - PrePauseTime;
	PerFileProgress(0.0f);
	int64 FileSize = IFileManager::Get().FileSize(*SelectFullFilePath(BuildFile));
	PerFileProgress(1.0f);
	return FileSize == Manifest->GetFileSize(BuildFile);
}