2018-12-14 13:44:01 -05:00
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Threading ;
2017-12-05 21:57:41 -05:00
using System.Threading.Tasks ;
2014-03-14 14:13:41 -04:00
using System.Reflection ;
2014-08-18 13:29:39 -04:00
using System.Linq ;
2017-12-05 21:57:41 -05:00
using System.Text ;
2014-03-14 14:13:41 -04:00
using AutomationTool ;
using UnrealBuildTool ;
2017-12-05 21:57:41 -05:00
using System.Collections.Concurrent ;
2017-08-31 12:08:38 -04:00
using Tools.DotNETCommon ;
2014-03-14 14:13:41 -04:00
/// <summary>
/// Helper command used for cooking.
/// </summary>
/// <remarks>
/// Command line parameters used by this command:
/// -clean
/// </remarks>
public partial class Project : CommandUtils
{
2016-07-08 14:59:19 -04:00
#region Cook Command
2014-03-14 14:13:41 -04:00
2016-07-08 14:59:19 -04:00
public static void Cook ( ProjectParams Params )
2014-03-14 14:13:41 -04:00
{
2014-09-18 18:55:01 -04:00
if ( ( ! Params . Cook & & ! ( Params . CookOnTheFly & & ! Params . SkipServer ) ) | | Params . SkipCook )
2014-03-14 14:13:41 -04:00
{
return ;
}
Params . ValidateAndLog ( ) ;
2018-09-04 14:32:41 -04:00
LogInformation ( "********** COOK COMMAND STARTED **********" ) ;
2014-09-18 18:55:01 -04:00
2014-03-14 14:13:41 -04:00
string UE4EditorExe = HostPlatform . Current . GetUE4ExePath ( Params . UE4Exe ) ;
if ( ! FileExists ( UE4EditorExe ) )
{
2014-05-06 15:34:31 -04:00
throw new AutomationException ( "Missing " + UE4EditorExe + " executable. Needs to be built first." ) ;
2014-03-14 14:13:41 -04:00
}
2014-09-18 18:55:01 -04:00
if ( Params . CookOnTheFly & & ! Params . SkipServer )
2014-03-14 14:13:41 -04:00
{
2014-12-17 10:00:26 -05:00
if ( Params . HasDLCName )
{
throw new AutomationException ( "Cook on the fly doesn't support cooking dlc" ) ;
}
2014-09-18 18:55:01 -04:00
if ( Params . ClientTargetPlatforms . Count > 0 )
2014-03-14 14:13:41 -04:00
{
2014-09-18 18:55:01 -04:00
var LogFolderOutsideOfSandbox = GetLogFolderOutsideOfSandbox ( ) ;
2019-01-14 12:15:37 -05:00
if ( ! CommandUtils . IsEngineInstalled ( ) )
2014-09-18 18:55:01 -04:00
{
// In the installed runs, this is the same folder as CmdEnv.LogFolder so delete only in not-installed
DeleteDirectory ( LogFolderOutsideOfSandbox ) ;
CreateDirectory ( LogFolderOutsideOfSandbox ) ;
}
2015-07-24 10:21:47 -04:00
String COTFCommandLine = Params . RunCommandline ;
if ( Params . IterativeCooking )
{
2017-03-26 15:18:02 -04:00
COTFCommandLine + = " -iterate -iteratehash" ;
2015-07-24 10:21:47 -04:00
}
2014-09-18 18:55:01 -04:00
var ServerLogFile = CombinePaths ( LogFolderOutsideOfSandbox , "Server.log" ) ;
Platform ClientPlatformInst = Params . ClientTargetPlatformInstances [ 0 ] ;
2016-07-19 19:13:01 -04:00
string TargetCook = ClientPlatformInst . GetCookPlatform ( false , false ) ; // cook on he fly doesn't support server cook platform...
2015-07-24 10:21:47 -04:00
ServerProcess = RunCookOnTheFlyServer ( Params . RawProjectPath , Params . NoClient ? "" : ServerLogFile , TargetCook , COTFCommandLine ) ;
2014-09-18 18:55:01 -04:00
if ( ServerProcess ! = null )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Waiting a few seconds for the server to start..." ) ;
2014-09-18 18:55:01 -04:00
Thread . Sleep ( 5000 ) ;
}
}
else
{
throw new AutomationException ( "Failed to run, client target platform not specified" ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-09-18 18:55:01 -04:00
else
2014-03-14 14:13:41 -04:00
{
2017-04-04 20:49:52 -04:00
var PlatformsToCook = new HashSet < string > ( ) ;
2016-07-08 14:59:19 -04:00
if ( ! Params . NoClient )
2014-03-14 14:13:41 -04:00
{
2014-09-18 18:55:01 -04:00
foreach ( var ClientPlatform in Params . ClientTargetPlatforms )
{
// Use the data platform, sometimes we will copy another platform's data
2016-07-19 19:13:01 -04:00
var DataPlatformDesc = Params . GetCookedDataPlatformForClientTarget ( ClientPlatform ) ;
string PlatformToCook = Platform . Platforms [ DataPlatformDesc ] . GetCookPlatform ( false , Params . Client ) ;
2016-07-08 14:59:19 -04:00
PlatformsToCook . Add ( PlatformToCook ) ;
}
2014-09-18 18:55:01 -04:00
}
if ( Params . DedicatedServer )
{
foreach ( var ServerPlatform in Params . ServerTargetPlatforms )
{
// Use the data platform, sometimes we will copy another platform's data
2016-07-19 19:13:01 -04:00
var DataPlatformDesc = Params . GetCookedDataPlatformForServerTarget ( ServerPlatform ) ;
string PlatformToCook = Platform . Platforms [ DataPlatformDesc ] . GetCookPlatform ( true , false ) ;
2016-07-08 14:59:19 -04:00
PlatformsToCook . Add ( PlatformToCook ) ;
}
2014-09-18 18:55:01 -04:00
}
if ( Params . Clean . HasValue & & Params . Clean . Value & & ! Params . IterativeCooking )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Cleaning cooked data." ) ;
2014-09-18 18:55:01 -04:00
CleanupCookedData ( PlatformsToCook . ToList ( ) , Params ) ;
}
// cook the set of maps, or the run map, or nothing
string [ ] Maps = null ;
if ( Params . HasMapsToCook )
{
Maps = Params . MapsToCook . ToArray ( ) ;
2015-02-04 16:18:11 -05:00
foreach ( var M in Maps )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "HasMapsToCook " + M . ToString ( ) ) ;
2015-02-04 16:18:11 -05:00
}
foreach ( var M in Params . MapsToCook )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Params.HasMapsToCook " + M . ToString ( ) ) ;
2015-02-04 16:18:11 -05:00
}
2014-09-18 18:55:01 -04:00
}
2017-01-27 23:32:44 -05:00
2014-09-18 18:55:01 -04:00
string [ ] Dirs = null ;
if ( Params . HasDirectoriesToCook )
{
Dirs = Params . DirectoriesToCook . ToArray ( ) ;
}
2014-10-27 19:33:51 -04:00
string InternationalizationPreset = null ;
if ( Params . HasInternationalizationPreset )
{
InternationalizationPreset = Params . InternationalizationPreset ;
}
2016-01-08 19:10:43 -05:00
string [ ] CulturesToCook = null ;
2014-09-18 18:55:01 -04:00
if ( Params . HasCulturesToCook )
{
2016-01-08 19:10:43 -05:00
CulturesToCook = Params . CulturesToCook . ToArray ( ) ;
2014-09-18 18:55:01 -04:00
}
2014-10-27 19:33:51 -04:00
try
2014-12-17 10:00:26 -05:00
{
2015-07-30 11:01:02 -04:00
var CommandletParams = IsBuildMachine ? "-buildmachine -fileopenlog" : "-fileopenlog" ;
2015-02-04 16:18:11 -05:00
if ( Params . UnversionedCookedContent )
{
CommandletParams + = " -unversioned" ;
}
2015-06-09 10:11:45 -04:00
if ( Params . FastCook )
{
CommandletParams + = " -FastCook" ;
}
2014-12-17 10:00:26 -05:00
if ( Params . Manifests )
{
CommandletParams + = " -manifests" ;
}
if ( Params . IterativeCooking )
{
2017-03-26 15:18:02 -04:00
CommandletParams + = " -iterate -iterateshash" ;
2014-12-17 10:00:26 -05:00
}
2018-06-07 22:39:07 -04:00
if ( Params . HasIterateSharedCookedBuild )
2016-11-21 20:27:58 -05:00
{
2017-06-14 08:40:01 -04:00
SharedCookedBuild . CopySharedCookedBuild ( Params ) ;
2017-03-26 15:18:02 -04:00
CommandletParams + = " -iteratesharedcookedbuild" ;
2016-11-21 20:27:58 -05:00
}
if ( Params . CookMapsOnly )
2015-02-04 16:18:11 -05:00
{
CommandletParams + = " -mapsonly" ;
}
if ( Params . CookAll )
{
CommandletParams + = " -cookall" ;
}
2014-12-15 11:35:52 -05:00
if ( Params . HasCreateReleaseVersion )
{
CommandletParams + = " -createreleaseversion=" + Params . CreateReleaseVersion ;
}
2015-07-06 10:03:34 -04:00
if ( Params . SkipCookingEditorContent )
{
CommandletParams + = " -skipeditorcontent" ;
}
if ( Params . NumCookersToSpawn ! = 0 )
{
CommandletParams + = " -numcookerstospawn=" + Params . NumCookersToSpawn ;
}
2016-09-09 20:13:41 -04:00
if ( Params . CookPartialGC )
{
CommandletParams + = " -partialgc" ;
}
2017-01-27 23:32:44 -05:00
if ( Params . HasMapIniSectionsToCook )
{
string MapIniSections = CombineCommandletParams ( Params . MapIniSectionsToCook . ToArray ( ) ) ;
CommandletParams + = " -MapIniSection=" + MapIniSections ;
}
if ( Params . HasDLCName )
2014-12-17 10:00:26 -05:00
{
2017-07-21 12:42:36 -04:00
CommandletParams + = " -dlcname=" + Params . DLCFile . GetFileNameWithoutExtension ( ) ;
2015-04-20 11:15:20 -04:00
if ( ! Params . DLCIncludeEngineContent )
{
CommandletParams + = " -errorOnEngineContentUse" ;
}
2014-12-17 10:00:26 -05:00
}
2017-04-10 11:00:33 -04:00
if ( ! String . IsNullOrEmpty ( Params . CookOutputDir ) )
{
CommandletParams + = " -outputdir=" + CommandUtils . MakePathSafeToUseWithCommandLine ( Params . CookOutputDir ) ;
}
2015-03-30 11:56:48 -04:00
// don't include the based on release version unless we are cooking dlc or creating a new release version
// in this case the based on release version is used in packaging
if ( Params . HasBasedOnReleaseVersion & & ( Params . HasDLCName | | Params . HasCreateReleaseVersion ) )
{
CommandletParams + = " -basedonreleaseversion=" + Params . BasedOnReleaseVersion ;
}
2015-02-13 15:35:16 -05:00
// if we are not going to pak but we specified compressed then compress in the cooker ;)
// otherwise compress the pak files
if ( ! Params . Pak & & ! Params . SkipPak & & Params . Compressed )
{
CommandletParams + = " -compressed" ;
}
2017-10-24 10:14:07 -04:00
2014-12-15 11:35:52 -05:00
if ( Params . HasAdditionalCookerOptions )
{
2014-12-17 10:00:26 -05:00
string FormatedAdditionalCookerParams = Params . AdditionalCookerOptions . TrimStart ( new char [ ] { '\"' , ' ' } ) . TrimEnd ( new char [ ] { '\"' , ' ' } ) ;
2015-03-30 11:56:48 -04:00
CommandletParams + = " " ;
2014-12-15 11:35:52 -05:00
CommandletParams + = FormatedAdditionalCookerParams ;
}
2015-04-02 14:54:35 -04:00
if ( ! Params . NoClient )
{
2015-04-02 18:38:41 -04:00
var MapsList = Maps = = null ? new List < string > ( ) : Maps . ToList ( ) ;
2015-04-02 14:54:35 -04:00
foreach ( var ClientPlatform in Params . ClientTargetPlatforms )
{
2016-07-19 19:13:01 -04:00
var DataPlatformDesc = Params . GetCookedDataPlatformForClientTarget ( ClientPlatform ) ;
CommandletParams + = ( Platform . Platforms [ DataPlatformDesc ] . GetCookExtraCommandLine ( Params ) ) ;
MapsList . AddRange ( ( Platform . Platforms [ ClientPlatform ] . GetCookExtraMaps ( ) ) ) ;
2015-04-02 14:54:35 -04:00
}
Maps = MapsList . ToArray ( ) ;
}
2017-10-24 10:14:07 -04:00
// Config overrides (-ini)
foreach ( string ConfigOverrideParam in Params . ConfigOverrideParams )
{
CommandletParams + = " -" ;
CommandletParams + = ConfigOverrideParam ;
}
2016-01-08 19:10:43 -05:00
CookCommandlet ( Params . RawProjectPath , Params . UE4Exe , Maps , Dirs , InternationalizationPreset , CulturesToCook , CombineCommandletParams ( PlatformsToCook . ToArray ( ) ) , CommandletParams ) ;
2017-05-16 13:13:20 -04:00
2017-06-14 08:40:01 -04:00
SharedCookedBuild . WaitForCopy ( ) ;
2014-12-17 10:00:26 -05:00
}
2014-09-18 18:55:01 -04:00
catch ( Exception Ex )
{
2015-06-09 10:11:45 -04:00
if ( Params . IgnoreCookErrors )
{
LogWarning ( "Ignoring cook failure." ) ;
}
else
{
2015-08-20 08:38:09 -04:00
throw new AutomationException ( ExitCode . Error_UnknownCookFailure , Ex , "Cook failed." ) ;
2015-06-09 10:11:45 -04:00
}
2014-03-14 14:13:41 -04:00
}
2015-08-11 17:11:41 -04:00
if ( Params . HasDiffCookedContentPath )
{
try
{
DiffCookedContent ( Params ) ;
}
catch ( Exception Ex )
{
2015-08-20 08:38:09 -04:00
throw new AutomationException ( ExitCode . Error_UnknownCookFailure , Ex , "Cook failed." ) ;
2015-08-11 17:11:41 -04:00
}
}
2014-03-14 14:13:41 -04:00
}
2015-08-11 17:11:41 -04:00
2018-09-04 14:32:41 -04:00
LogInformation ( "********** COOK COMMAND COMPLETED **********" ) ;
2014-03-14 14:13:41 -04:00
}
2016-05-16 16:20:52 -04:00
public struct FileInfo
{
public FileInfo ( string InFilename )
{
Filename = InFilename ;
FirstByteFailed = - 1 ;
BytesMismatch = 0 ;
File1Size = 0 ;
File2Size = 0 ;
}
public FileInfo ( string InFilename , long InFirstByteFailed , long InBytesMismatch , long InFile1Size , long InFile2Size )
{
Filename = InFilename ;
FirstByteFailed = InFirstByteFailed ;
BytesMismatch = InBytesMismatch ;
File1Size = InFile1Size ;
File2Size = InFile2Size ;
}
public string Filename ;
public long FirstByteFailed ;
public long BytesMismatch ;
public long File1Size ;
public long File2Size ;
} ;
2015-08-11 17:11:41 -04:00
private static void DiffCookedContent ( ProjectParams Params )
{
2016-07-19 19:13:01 -04:00
List < TargetPlatformDescriptor > PlatformsToCook = Params . ClientTargetPlatforms ;
2015-10-07 17:46:58 -04:00
string ProjectPath = Params . RawProjectPath . FullName ;
2015-08-11 17:11:41 -04:00
var CookedSandboxesPath = CombinePaths ( GetDirectoryName ( ProjectPath ) , "Saved" , "Cooked" ) ;
for ( int CookPlatformIndex = 0 ; CookPlatformIndex < PlatformsToCook . Count ; + + CookPlatformIndex )
{
// temporary directory to save the pak file to (pak file is usually not local and on network drive)
var TemporaryPakPath = CombinePaths ( GetDirectoryName ( ProjectPath ) , "Saved" , "Temp" , "LocalPKG" ) ;
// extracted files from pak file
var TemporaryFilesPath = CombinePaths ( GetDirectoryName ( ProjectPath ) , "Saved" , "Temp" , "LocalFiles" ) ;
try
{
Directory . Delete ( TemporaryPakPath , true ) ;
2015-11-12 12:38:50 -05:00
}
catch ( Exception Ex )
{
2016-05-16 16:20:52 -04:00
if ( ! ( Ex is System . IO . DirectoryNotFoundException ) )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Failed deleting temporary directories " + TemporaryPakPath + " continuing. " + Ex . GetType ( ) . ToString ( ) ) ;
2016-05-16 16:20:52 -04:00
}
2015-11-12 12:38:50 -05:00
}
try
{
2015-08-11 17:11:41 -04:00
Directory . Delete ( TemporaryFilesPath , true ) ;
}
2015-11-12 12:38:50 -05:00
catch ( Exception Ex )
2015-08-11 17:11:41 -04:00
{
2016-05-16 16:20:52 -04:00
if ( ! ( Ex is System . IO . DirectoryNotFoundException ) )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Failed deleting temporary directories " + TemporaryFilesPath + " continuing. " + Ex . GetType ( ) . ToString ( ) ) ;
2016-05-16 16:20:52 -04:00
}
2015-08-11 17:11:41 -04:00
}
2015-11-12 12:38:50 -05:00
2015-10-06 15:59:09 -04:00
try
2015-08-11 17:11:41 -04:00
{
2015-08-18 16:56:56 -04:00
2015-10-06 15:59:09 -04:00
Directory . CreateDirectory ( TemporaryPakPath ) ;
Directory . CreateDirectory ( TemporaryFilesPath ) ;
2015-08-11 17:11:41 -04:00
2016-07-19 19:13:01 -04:00
Platform CurrentPlatform = Platform . Platforms [ PlatformsToCook [ CookPlatformIndex ] ] ;
2015-08-11 17:11:41 -04:00
2015-10-06 15:59:09 -04:00
string SourceCookedContentPath = Params . DiffCookedContentPath ;
2015-08-11 17:11:41 -04:00
2015-10-06 15:59:09 -04:00
List < string > PakFiles = new List < string > ( ) ;
2016-07-19 19:13:01 -04:00
string CookPlatformString = CurrentPlatform . GetCookPlatform ( false , Params . Client ) ;
2015-11-17 14:50:21 -05:00
2015-10-06 15:59:09 -04:00
if ( Path . HasExtension ( SourceCookedContentPath ) & & ( ! SourceCookedContentPath . EndsWith ( ".pak" ) ) )
2015-08-18 16:56:56 -04:00
{
2015-10-06 15:59:09 -04:00
// must be a per platform pkg file try this
CurrentPlatform . ExtractPackage ( Params , Params . DiffCookedContentPath , TemporaryPakPath ) ;
// find the pak file
2015-11-12 12:38:50 -05:00
PakFiles . AddRange ( Directory . EnumerateFiles ( TemporaryPakPath , Params . ShortProjectName + "*.pak" , SearchOption . AllDirectories ) ) ;
PakFiles . AddRange ( Directory . EnumerateFiles ( TemporaryPakPath , "pakchunk*.pak" , SearchOption . AllDirectories ) ) ;
2015-08-18 16:56:56 -04:00
}
2015-11-17 14:50:21 -05:00
else if ( ! Path . HasExtension ( SourceCookedContentPath ) )
2015-08-11 17:11:41 -04:00
{
2015-10-06 15:59:09 -04:00
// try find the pak or pkg file
string SourceCookedContentPlatformPath = CombinePaths ( SourceCookedContentPath , CookPlatformString ) ;
2015-11-17 14:50:21 -05:00
foreach ( var PakName in Directory . EnumerateFiles ( SourceCookedContentPlatformPath , Params . ShortProjectName + "*.pak" , SearchOption . AllDirectories ) )
2015-08-11 17:11:41 -04:00
{
2015-10-06 15:59:09 -04:00
string TemporaryPakFilename = CombinePaths ( TemporaryPakPath , Path . GetFileName ( PakName ) ) ;
File . Copy ( PakName , TemporaryPakFilename ) ;
PakFiles . Add ( TemporaryPakFilename ) ;
}
2015-11-17 14:50:21 -05:00
foreach ( var PakName in Directory . EnumerateFiles ( SourceCookedContentPlatformPath , "pakchunk*.pak" , SearchOption . AllDirectories ) )
{
string TemporaryPakFilename = CombinePaths ( TemporaryPakPath , Path . GetFileName ( PakName ) ) ;
File . Copy ( PakName , TemporaryPakFilename ) ;
PakFiles . Add ( TemporaryPakFilename ) ;
}
2015-10-06 15:59:09 -04:00
if ( PakFiles . Count < = 0 )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "No Pak files found in " + SourceCookedContentPlatformPath + " :(" ) ;
2015-08-11 17:11:41 -04:00
}
}
2015-10-06 15:59:09 -04:00
else if ( SourceCookedContentPath . EndsWith ( ".pak" ) )
2015-08-11 17:11:41 -04:00
{
2015-10-06 15:59:09 -04:00
string TemporaryPakFilename = CombinePaths ( TemporaryPakPath , Path . GetFileName ( SourceCookedContentPath ) ) ;
File . Copy ( SourceCookedContentPath , TemporaryPakFilename ) ;
PakFiles . Add ( TemporaryPakFilename ) ;
2015-08-11 17:11:41 -04:00
}
2015-10-06 15:59:09 -04:00
string FullCookPath = CombinePaths ( CookedSandboxesPath , CookPlatformString ) ;
var UnrealPakExe = CombinePaths ( CmdEnv . LocalRoot , "Engine/Binaries/Win64/UnrealPak.exe" ) ;
foreach ( var Name in PakFiles )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Extracting pak " + Name + " for comparision to location " + TemporaryFilesPath ) ;
2015-10-06 15:59:09 -04:00
2017-12-05 21:57:41 -05:00
string UnrealPakParams = Name + " -Extract " + " " + TemporaryFilesPath + " -ExtractToMountPoint" ;
2015-11-12 12:38:50 -05:00
try
{
RunAndLog ( CmdEnv , UnrealPakExe , UnrealPakParams , Options : ERunOptions . Default | ERunOptions . UTF8Output | ERunOptions . LoggingOfRunDuration ) ;
}
catch ( Exception Ex )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Pak failed to extract because of " + Ex . GetType ( ) . ToString ( ) ) ;
2015-11-12 12:38:50 -05:00
}
2015-10-06 15:59:09 -04:00
}
2017-12-05 21:57:41 -05:00
string RootFailedContentDirectory = "\\\\epicgames.net\\root\\Developers\\Daniel.Lamb" ;
if ( Params . ShortProjectName = = "FortniteGame" )
{
RootFailedContentDirectory = "\\\\epicgames.net\\root\\Developers\\Hongyi.Yu" ;
}
2015-10-06 15:59:09 -04:00
2017-08-31 12:08:38 -04:00
string FailedContentDirectory = CombinePaths ( RootFailedContentDirectory , CommandUtils . P4Env . Branch + CommandUtils . P4Env . Changelist . ToString ( ) , Params . ShortProjectName , CookPlatformString ) ;
2015-10-06 15:59:09 -04:00
Directory . CreateDirectory ( FailedContentDirectory ) ;
// diff the content
2017-12-05 21:57:41 -05:00
ConcurrentBag < FileInfo > FileReport = new ConcurrentBag < FileInfo > ( ) ;
2016-05-16 16:20:52 -04:00
2015-10-06 15:59:09 -04:00
List < string > AllFiles = Directory . EnumerateFiles ( FullCookPath , "*.uasset" , System . IO . SearchOption . AllDirectories ) . ToList ( ) ;
2016-01-20 11:32:08 -05:00
AllFiles . AddRange ( Directory . EnumerateFiles ( FullCookPath , "*.umap" , System . IO . SearchOption . AllDirectories ) . ToList ( ) ) ;
2017-12-05 21:57:41 -05:00
Parallel . ForEach ( AllFiles , SourceFilename = >
2015-10-06 15:59:09 -04:00
{
2017-12-05 21:57:41 -05:00
StringBuilder LogStringBuilder = new StringBuilder ( ) ;
2015-10-06 15:59:09 -04:00
string RelativeFilename = SourceFilename . Remove ( 0 , FullCookPath . Length ) ;
string DestFilename = TemporaryFilesPath + RelativeFilename ;
2017-12-05 21:57:41 -05:00
LogStringBuilder . AppendLine ( "Comparing file " + RelativeFilename ) ;
2015-10-06 15:59:09 -04:00
byte [ ] SourceFile = null ;
try
{
SourceFile = File . ReadAllBytes ( SourceFilename ) ;
}
2017-12-05 21:57:41 -05:00
catch ( Exception Ex )
2015-10-06 15:59:09 -04:00
{
2017-12-05 21:57:41 -05:00
LogStringBuilder . AppendLine ( "Diff cooked content failed to load source file " + SourceFilename + " Exception " + Ex . ToString ( ) ) ;
2015-10-06 15:59:09 -04:00
}
byte [ ] DestFile = null ;
try
{
DestFile = File . ReadAllBytes ( DestFilename ) ;
}
2017-12-05 21:57:41 -05:00
catch ( Exception Ex )
2015-10-06 15:59:09 -04:00
{
2017-12-05 21:57:41 -05:00
LogStringBuilder . AppendLine ( "Diff cooked content failed to load target file " + DestFilename + " Exception " + Ex . ToString ( ) ) ;
2015-10-06 15:59:09 -04:00
}
2015-10-21 12:03:38 -04:00
if ( SourceFile = = null | | DestFile = = null )
2015-10-06 15:59:09 -04:00
{
2018-09-04 14:32:41 -04:00
LogInformation ( LogStringBuilder . ToString ( ) ) ;
2017-12-05 21:57:41 -05:00
LogError ( "Diff cooked content failed on file " + SourceFilename + " when comparing against " + DestFilename + " " + ( SourceFile = = null ? SourceFilename : DestFilename ) + " file is missing" ) ;
return ;
2015-10-21 12:03:38 -04:00
}
2016-05-16 16:20:52 -04:00
2017-12-05 21:57:41 -05:00
if ( SourceFile . LongLength = = DestFile . LongLength )
{
2016-05-16 16:20:52 -04:00
FileInfo DiffFileInfo = new FileInfo ( SourceFilename ) ;
DiffFileInfo . File1Size = DiffFileInfo . File2Size = SourceFile . LongLength ;
2017-12-05 21:57:41 -05:00
for ( long Index = 0 ; Index < SourceFile . LongLength ; + + Index )
2015-10-06 15:59:09 -04:00
{
if ( SourceFile [ Index ] ! = DestFile [ Index ] )
{
2017-12-05 21:57:41 -05:00
if ( DiffFileInfo . FirstByteFailed = = - 1 )
2016-05-16 16:20:52 -04:00
{
DiffFileInfo . FirstByteFailed = Index ;
}
DiffFileInfo . BytesMismatch + = 1 ;
2015-10-06 15:59:09 -04:00
}
}
2017-12-05 21:57:41 -05:00
if ( DiffFileInfo . BytesMismatch ! = 0 )
{
2016-05-16 16:20:52 -04:00
FileReport . Add ( DiffFileInfo ) ;
2017-12-05 21:57:41 -05:00
LogStringBuilder . AppendLine ( "Diff cooked content failed on file " + SourceFilename + " when comparing against " + DestFilename + " at offset " + DiffFileInfo . FirstByteFailed . ToString ( ) ) ;
string SavedSourceFilename = CombinePaths ( FailedContentDirectory , Path . GetFileName ( SourceFilename ) + "Source" ) ;
string SavedDestFilename = CombinePaths ( FailedContentDirectory , Path . GetFileName ( DestFilename ) + "Dest" ) ;
LogStringBuilder . AppendLine ( "Creating directory " + Path . GetDirectoryName ( SavedSourceFilename ) ) ;
try
{
Directory . CreateDirectory ( Path . GetDirectoryName ( SavedSourceFilename ) ) ;
}
catch ( Exception E )
{
LogStringBuilder . AppendLine ( "Failed to create directory " + Path . GetDirectoryName ( SavedSourceFilename ) + " Exception " + E . ToString ( ) ) ;
}
LogStringBuilder . AppendLine ( "Creating directory " + Path . GetDirectoryName ( SavedDestFilename ) ) ;
try
{
Directory . CreateDirectory ( Path . GetDirectoryName ( SavedDestFilename ) ) ;
}
catch ( Exception E )
{
LogStringBuilder . AppendLine ( "Failed to create directory " + Path . GetDirectoryName ( SavedDestFilename ) + " Exception " + E . ToString ( ) ) ;
}
bool bFailedToSaveSourceFile = ! Directory . Exists ( Path . GetDirectoryName ( SavedSourceFilename ) ) ;
bool bFailedToSaveDestFile = ! Directory . Exists ( Path . GetDirectoryName ( SavedDestFilename ) ) ;
if ( bFailedToSaveSourceFile | | bFailedToSaveDestFile )
{
2018-09-04 14:32:41 -04:00
LogInformation ( LogStringBuilder . ToString ( ) ) ;
2017-12-05 21:57:41 -05:00
if ( bFailedToSaveSourceFile )
{
LogError ( "Failed to save source file" + SavedSourceFilename ) ;
}
if ( bFailedToSaveDestFile )
{
LogError ( "Failed to save dest file" + SavedDestFilename ) ;
}
return ;
}
LogStringBuilder . AppendLine ( "Content temporarily saved to " + SavedSourceFilename + " and " + SavedDestFilename + " at offset " + DiffFileInfo . FirstByteFailed . ToString ( ) ) ;
File . Copy ( SourceFilename , SavedSourceFilename , true ) ;
File . Copy ( DestFilename , SavedDestFilename , true ) ;
}
else
{
LogStringBuilder . AppendLine ( "Content matches for " + SourceFilename + " and " + DestFilename ) ;
2016-05-16 16:20:52 -04:00
}
2015-10-06 15:59:09 -04:00
}
else
{
2017-12-05 21:57:41 -05:00
LogStringBuilder . AppendLine ( "Diff cooked content failed on file " + SourceFilename + " when comparing against " + DestFilename + " files are different sizes " + SourceFile . LongLength . ToString ( ) + " " + DestFile . LongLength . ToString ( ) ) ;
2016-05-16 16:20:52 -04:00
FileInfo DiffFileInfo = new FileInfo ( SourceFilename ) ;
DiffFileInfo . File1Size = SourceFile . LongLength ;
DiffFileInfo . File2Size = DestFile . LongLength ;
FileReport . Add ( DiffFileInfo ) ;
2015-10-06 15:59:09 -04:00
}
2017-12-05 21:57:41 -05:00
2018-09-04 14:32:41 -04:00
LogInformation ( LogStringBuilder . ToString ( ) ) ;
2017-12-05 21:57:41 -05:00
} ) ;
2016-05-16 16:20:52 -04:00
2018-09-04 14:32:41 -04:00
LogInformation ( "Mismatching files:" ) ;
2016-05-16 16:20:52 -04:00
foreach ( var Report in FileReport )
{
if ( Report . FirstByteFailed = = - 1 )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "File " + Report . Filename + " size mismatch: " + Report . File1Size + " VS " + Report . File2Size ) ;
2016-05-16 16:20:52 -04:00
}
else
{
2018-09-04 14:32:41 -04:00
LogInformation ( "File " + Report . Filename + " bytes mismatch: " + Report . BytesMismatch + " first byte failed at: " + Report . FirstByteFailed + " file size: " + Report . File1Size ) ;
2016-05-16 16:20:52 -04:00
}
}
2015-10-06 15:59:09 -04:00
}
catch ( Exception Ex )
{
2018-09-04 14:32:41 -04:00
LogInformation ( "Exception " + Ex . ToString ( ) ) ;
2015-10-06 15:59:09 -04:00
continue ;
}
2015-08-11 17:11:41 -04:00
}
}
2014-03-14 14:13:41 -04:00
private static void CleanupCookedData ( List < string > PlatformsToCook , ProjectParams Params )
2014-08-18 13:29:39 -04:00
{
2015-09-26 14:41:15 -04:00
var ProjectPath = Params . RawProjectPath . FullName ;
2014-05-29 16:43:14 -04:00
var CookedSandboxesPath = CombinePaths ( GetDirectoryName ( ProjectPath ) , "Saved" , "Cooked" ) ;
2014-03-14 14:13:41 -04:00
var CleanDirs = new string [ PlatformsToCook . Count ] ;
for ( int DirIndex = 0 ; DirIndex < CleanDirs . Length ; + + DirIndex )
{
2014-05-29 16:43:14 -04:00
CleanDirs [ DirIndex ] = CombinePaths ( CookedSandboxesPath , PlatformsToCook [ DirIndex ] ) ;
2014-03-14 14:13:41 -04:00
}
const bool bQuiet = true ;
2017-03-14 15:48:33 -04:00
foreach ( string CleanDir in CleanDirs )
{
DeleteDirectory ( bQuiet , CleanDir ) ;
}
2014-03-14 14:13:41 -04:00
}
#endregion
}