You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden ========================== MAJOR FEATURES + CHANGES ========================== Change 2716841 on 2015/10/05 by Mike.Beach (WIP) Cleaning up how we setup script assets for replacement on cook (aligning more with the Blueprint conversion tool). #codereview Maciej.Mroz Change 2719089 on 2015/10/07 by Maciej.Mroz ToValidCPPIdentifierChars handles propertly '?' char. #codereview Dan.Oconnor Change 2719361 on 2015/10/07 by Maciej.Mroz Generated native code for AnimBPGC - some preliminary changes. Refactor: UAnimBlueprintGeneratedClass is not accessed directly in runtime. It is accessed via UAnimClassInterface interface. Properties USkeletalMeshComponent::AnimBlueprintGeneratedClass and UInterpTrackFloatAnimBPParam::AnimBlueprintClass were changed into "TSubclassOf<UAnimInstance> AnimClass" The UDynamicClass also can deliver the IAnimClassInterface interface. See UAnimClassData, IAnimClassInterface::GetFromClass and UDynamicClass::AnimClassImplementation. #codereview Lina.Halper, Thomas.Sarkanen Change 2719383 on 2015/10/07 by Maciej.Mroz Debug-only code removed Change 2720528 on 2015/10/07 by Dan.Oconnor Fix for determinsitc cooking of async tasks and load asset nodes #codereview Mike.Beach, Maciej.Mroz Change 2721273 on 2015/10/08 by Maciej.Mroz Blueprint Compiler Cpp Backend - Anim Blueprints can be converted - Various fixes/improvements Change 2721310 on 2015/10/08 by Maciej.Mroz refactor (cl#2719361) - no "auto" keyword Change 2721727 on 2015/10/08 by Mike.Beach (WIP) Setup the cook commandlet so it handles converted assets, replacing them with generated classes. - Refactored the conversion manifest (using a map over an array) - Centralized destination paths into a helper struct (for the manifest) - Generating an Editor module that automatically hooks into the cook process when enabled - Loading and applying native replacments for the cook Change 2723276 on 2015/10/09 by Michael.Schoell Blueprints duplicated for PIE will no longer register as dependencies to other Blueprint. #jira UE-16695 - Editor freezes then crashes while attempting to save during PIE #jira UE-21614 - [CrashReport] Crash while saving during PIE - FKismetEditorUtilities::CompileBlueprint() kismet2.cpp:736 Change 2724345 on 2015/10/11 by Ben.Cosh Blueprint profiler at first pass, this includes the ability to instrument specific blueprints with realtime editor stat display. #UEBP-21 - Profiling data capture and storage #UEBP-13 - Performance capture landing page #Branch UE4 #Proj BlueprintProfiler, BlueprintGraph, EditorStyle, Kismet, UnrealEd, CoreUObject, Engine Change 2724613 on 2015/10/12 by Ben.Cosh Incremental update for blueprint profiler to fix the way some of the reported stats cascade through events and branches and additionally some missed bits of code are refactored/removed. #Branch UE4 #Proj BlueprintProfiler #info Whilst looking into this I spotted the reason why the stats seem so erratic, There appears to be an issue with FText's use of EXPERIMENTAL_TEXT_FAST_DECIMAL_FORMAT which I have reported, but ideally disable this locally until a fix is integrated. Change 2724723 on 2015/10/12 by Maciej.Mroz Constructor of a dynamic class creates CDO. #codereview Robert.Manuszewski Change 2725108 on 2015/10/12 by Mike.Beach [UE-21891] Minor fix to the array shuffle() function; now processes the last entry like all the others. Change 2726358 on 2015/10/13 by Maciej.Mroz UDataTable is properly saved even if its RowStruct is null. https://udn.unrealengine.com/questions/264064/crash-using-hotreload-in-custom-datatable-cdo-clas.html Change 2727395 on 2015/10/13 by Mike.Beach (WIP) Second pass on the Blueprint conversion pipeline; setting it up for more optimal (speedier) performance. * Using stubs for replacements (rather than loading dynamic replacement). * Giving the cook commandlet more control (so a conversion could be ran directly). * Now logging replacements by old object path (to account for UPackage replacement queries). * Fix for [UE-21947], unshelved from CL 2724944 (by Maciej.Mroz). #codereview Maciej.Mroz Change 2727484 on 2015/10/13 by Mike.Beach [UE-22008] Fixing up comment/tooltip typo for UActorComponent::bAutoActivate. Change 2727527 on 2015/10/13 by Mike.Beach Downgrading an inactionable EdGraph warning, while adding more info so we could possibly determine what's happening. Change 2727702 on 2015/10/13 by Dan.Oconnor Fix for crash in UDelegateProperty::GetCPPType when called on a function with no OwnerClass (events) Change 2727968 on 2015/10/14 by Maciej.Mroz Since ConstructorHelpers::FClassFinder is usually static, the loaded class should be in root set, to prevent the pointer stored in ConstructorHelpers::FClassFinder from being obsolete. FindOrLoadClass behaves now like FindOrLoadObject. #codereview Robert.Manuszewski, Nick.Whiting Change 2728139 on 2015/10/14 by Phillip.Kavan
506 lines
21 KiB
C#
506 lines
21 KiB
C#
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Reflection;
|
|
using System.Linq;
|
|
using AutomationTool;
|
|
using UnrealBuildTool;
|
|
|
|
/// <summary>
|
|
/// Helper command used for cooking.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Command line parameters used by this command:
|
|
/// -clean
|
|
/// </remarks>
|
|
public partial class Project : CommandUtils
|
|
{
|
|
#region Cook Command
|
|
|
|
public static void Cook(ProjectParams Params)
|
|
{
|
|
if ((!Params.Cook && !(Params.CookOnTheFly && !Params.SkipServer)) || Params.SkipCook)
|
|
{
|
|
return;
|
|
}
|
|
Params.ValidateAndLog();
|
|
|
|
Log("********** COOK COMMAND STARTED **********");
|
|
|
|
string UE4EditorExe = HostPlatform.Current.GetUE4ExePath(Params.UE4Exe);
|
|
if (!FileExists(UE4EditorExe))
|
|
{
|
|
throw new AutomationException("Missing " + UE4EditorExe + " executable. Needs to be built first.");
|
|
}
|
|
|
|
if (Params.CookOnTheFly && !Params.SkipServer)
|
|
{
|
|
if (Params.HasDLCName)
|
|
{
|
|
throw new AutomationException("Cook on the fly doesn't support cooking dlc");
|
|
}
|
|
if (Params.ClientTargetPlatforms.Count > 0)
|
|
{
|
|
var LogFolderOutsideOfSandbox = GetLogFolderOutsideOfSandbox();
|
|
if (!GlobalCommandLine.Installed)
|
|
{
|
|
// In the installed runs, this is the same folder as CmdEnv.LogFolder so delete only in not-installed
|
|
DeleteDirectory(LogFolderOutsideOfSandbox);
|
|
CreateDirectory(LogFolderOutsideOfSandbox);
|
|
}
|
|
|
|
String COTFCommandLine = Params.RunCommandline;
|
|
if (Params.IterativeCooking)
|
|
{
|
|
COTFCommandLine += " -iterate";
|
|
}
|
|
if (Params.UseDebugParamForEditorExe)
|
|
{
|
|
COTFCommandLine += " -debug";
|
|
}
|
|
|
|
var ServerLogFile = CombinePaths(LogFolderOutsideOfSandbox, "Server.log");
|
|
Platform ClientPlatformInst = Params.ClientTargetPlatformInstances[0];
|
|
string TargetCook = ClientPlatformInst.GetCookPlatform(false, Params.HasDedicatedServerAndClient, Params.CookFlavor);
|
|
ServerProcess = RunCookOnTheFlyServer(Params.RawProjectPath, Params.NoClient ? "" : ServerLogFile, TargetCook, COTFCommandLine);
|
|
|
|
if (ServerProcess != null)
|
|
{
|
|
Log("Waiting a few seconds for the server to start...");
|
|
Thread.Sleep(5000);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new AutomationException("Failed to run, client target platform not specified");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var PlatformsToCook = new HashSet<string>();
|
|
|
|
if (!Params.NoClient)
|
|
{
|
|
foreach (var ClientPlatform in Params.ClientTargetPlatforms)
|
|
{
|
|
// Use the data platform, sometimes we will copy another platform's data
|
|
var DataPlatform = Params.GetCookedDataPlatformForClientTarget(ClientPlatform);
|
|
PlatformsToCook.Add(Params.GetTargetPlatformInstance(DataPlatform).GetCookPlatform(false, Params.Client, Params.CookFlavor));
|
|
}
|
|
}
|
|
if (Params.DedicatedServer)
|
|
{
|
|
foreach (var ServerPlatform in Params.ServerTargetPlatforms)
|
|
{
|
|
// Use the data platform, sometimes we will copy another platform's data
|
|
var DataPlatform = Params.GetCookedDataPlatformForServerTarget(ServerPlatform);
|
|
PlatformsToCook.Add(Params.GetTargetPlatformInstance(DataPlatform).GetCookPlatform(true, false, Params.CookFlavor));
|
|
}
|
|
}
|
|
|
|
if (Params.Clean.HasValue && Params.Clean.Value && !Params.IterativeCooking)
|
|
{
|
|
Log("Cleaning cooked data.");
|
|
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();
|
|
foreach (var M in Maps)
|
|
{
|
|
Log("HasMapsToCook " + M.ToString());
|
|
}
|
|
foreach (var M in Params.MapsToCook)
|
|
{
|
|
Log("Params.HasMapsToCook " + M.ToString());
|
|
}
|
|
}
|
|
|
|
string[] Dirs = null;
|
|
if (Params.HasDirectoriesToCook)
|
|
{
|
|
Dirs = Params.DirectoriesToCook.ToArray();
|
|
}
|
|
|
|
string InternationalizationPreset = null;
|
|
if (Params.HasInternationalizationPreset)
|
|
{
|
|
InternationalizationPreset = Params.InternationalizationPreset;
|
|
}
|
|
|
|
string[] Cultures = null;
|
|
if (Params.HasCulturesToCook)
|
|
{
|
|
Cultures = Params.CulturesToCook.ToArray();
|
|
}
|
|
|
|
try
|
|
{
|
|
var CommandletParams = IsBuildMachine ? "-buildmachine -fileopenlog" : "-fileopenlog";
|
|
if (Params.UnversionedCookedContent)
|
|
{
|
|
CommandletParams += " -unversioned";
|
|
}
|
|
if (Params.FastCook)
|
|
{
|
|
CommandletParams += " -FastCook";
|
|
}
|
|
if (Params.UseDebugParamForEditorExe)
|
|
{
|
|
CommandletParams += " -debug";
|
|
}
|
|
if (Params.Manifests)
|
|
{
|
|
CommandletParams += " -manifests";
|
|
}
|
|
if (Params.IterativeCooking)
|
|
{
|
|
CommandletParams += " -iterate";
|
|
}
|
|
if (Params.CookMapsOnly)
|
|
{
|
|
CommandletParams += " -mapsonly";
|
|
}
|
|
if (Params.NewCook)
|
|
{
|
|
CommandletParams += " -newcook";
|
|
}
|
|
if (Params.OldCook)
|
|
{
|
|
CommandletParams += " -oldcook";
|
|
}
|
|
if (Params.CookAll)
|
|
{
|
|
CommandletParams += " -cookall";
|
|
}
|
|
if (Params.CookMapsOnly)
|
|
{
|
|
CommandletParams += " -mapsonly";
|
|
}
|
|
if (Params.HasCreateReleaseVersion)
|
|
{
|
|
CommandletParams += " -createreleaseversion=" + Params.CreateReleaseVersion;
|
|
}
|
|
if ( Params.SkipCookingEditorContent)
|
|
{
|
|
CommandletParams += " -skipeditorcontent";
|
|
}
|
|
if ( Params.NumCookersToSpawn != 0)
|
|
{
|
|
CommandletParams += " -numcookerstospawn=" + Params.NumCookersToSpawn;
|
|
|
|
}
|
|
if (Params.HasDLCName)
|
|
{
|
|
CommandletParams += " -dlcname=" + Params.DLCName;
|
|
if ( !Params.DLCIncludeEngineContent )
|
|
{
|
|
CommandletParams += " -errorOnEngineContentUse";
|
|
}
|
|
}
|
|
// 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;
|
|
}
|
|
// 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";
|
|
}
|
|
// we provide the option for users to run a conversion on certain (script) assets, translating them
|
|
// into native source code... the cooker needs to
|
|
if (Params.RunAssetNativization)
|
|
{
|
|
string GeneratedPluginName = "NativizedScript";
|
|
string ProjectDir = Params.RawProjectPath.Directory.ToString();
|
|
string GeneratedPluginDirectory = Path.GetFullPath(CommandUtils.CombinePaths(ProjectDir, "Intermediate", "Plugins", GeneratedPluginName));
|
|
string PluginDescFilename = GeneratedPluginName + ".uplugin";
|
|
string GeneratedPluginPath = Path.GetFullPath(CommandUtils.CombinePaths(GeneratedPluginDirectory, PluginDescFilename));
|
|
|
|
CommandletParams += " -NativizeAssets -NativizedAssetPlugin=\"" + GeneratedPluginPath + "\"";
|
|
|
|
// fill out this, so as to coordinate with build automation
|
|
// (the builder now needs to compile in the generated assets)
|
|
Params.NativizedScriptPlugin = new FileReference(GeneratedPluginPath);
|
|
}
|
|
if (Params.HasAdditionalCookerOptions)
|
|
{
|
|
string FormatedAdditionalCookerParams = Params.AdditionalCookerOptions.TrimStart(new char[] { '\"', ' ' }).TrimEnd(new char[] { '\"', ' ' });
|
|
CommandletParams += " ";
|
|
CommandletParams += FormatedAdditionalCookerParams;
|
|
}
|
|
|
|
if (!Params.NoClient)
|
|
{
|
|
var MapsList = Maps == null ? new List<string>() : Maps.ToList();
|
|
foreach (var ClientPlatform in Params.ClientTargetPlatforms)
|
|
{
|
|
var DataPlatform = Params.GetCookedDataPlatformForClientTarget(ClientPlatform);
|
|
CommandletParams += (Params.GetTargetPlatformInstance(DataPlatform).GetCookExtraCommandLine(Params));
|
|
MapsList.AddRange((Params.GetTargetPlatformInstance(ClientPlatform).GetCookExtraMaps()));
|
|
}
|
|
Maps = MapsList.ToArray();
|
|
}
|
|
|
|
CookCommandlet(Params.RawProjectPath, Params.UE4Exe, Maps, Dirs, InternationalizationPreset, Cultures, CombineCommandletParams(PlatformsToCook.ToArray()), CommandletParams);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
if (Params.IgnoreCookErrors)
|
|
{
|
|
LogWarning("Ignoring cook failure.");
|
|
}
|
|
else
|
|
{
|
|
// Delete cooked data (if any) as it may be incomplete / corrupted.
|
|
Log("Cook failed. Deleting cooked data.");
|
|
CleanupCookedData(PlatformsToCook.ToList(), Params);
|
|
throw new AutomationException(ExitCode.Error_UnknownCookFailure, Ex, "Cook failed.");
|
|
}
|
|
}
|
|
|
|
if (Params.HasDiffCookedContentPath)
|
|
{
|
|
try
|
|
{
|
|
DiffCookedContent(Params);
|
|
}
|
|
catch ( Exception Ex )
|
|
{
|
|
// Delete cooked data (if any) as it may be incomplete / corrupted.
|
|
Log("Cook failed. Deleting cooked data.");
|
|
CleanupCookedData(PlatformsToCook.ToList(), Params);
|
|
throw new AutomationException(ExitCode.Error_UnknownCookFailure, Ex, "Cook failed.");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
Log("********** COOK COMMAND COMPLETED **********");
|
|
}
|
|
|
|
private static void DiffCookedContent( ProjectParams Params)
|
|
{
|
|
List<UnrealTargetPlatform> PlatformsToCook = Params.ClientTargetPlatforms;
|
|
string ProjectPath = Params.RawProjectPath.FullName;
|
|
|
|
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);
|
|
}
|
|
catch(Exception Ex)
|
|
{
|
|
Log("Failed deleting temporary directories "+TemporaryPakPath+" continuing. "+ Ex.GetType().ToString());
|
|
}
|
|
try
|
|
{
|
|
Directory.Delete(TemporaryFilesPath, true);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
Log("Failed deleting temporary directories " + TemporaryFilesPath + " continuing. " + Ex.GetType().ToString());
|
|
}
|
|
|
|
try
|
|
{
|
|
|
|
Directory.CreateDirectory(TemporaryPakPath);
|
|
Directory.CreateDirectory(TemporaryFilesPath);
|
|
|
|
Platform CurrentPlatform = Params.GetTargetPlatformInstance(PlatformsToCook[CookPlatformIndex]);
|
|
|
|
string SourceCookedContentPath = Params.DiffCookedContentPath;
|
|
|
|
List<string> PakFiles = new List<string>();
|
|
|
|
string CookPlatformString = CurrentPlatform.GetCookPlatform(false, Params.HasDedicatedServerAndClient, Params.CookFlavor);
|
|
|
|
if (Path.HasExtension(SourceCookedContentPath) && (!SourceCookedContentPath.EndsWith(".pak")))
|
|
{
|
|
// must be a per platform pkg file try this
|
|
CurrentPlatform.ExtractPackage(Params, Params.DiffCookedContentPath, TemporaryPakPath);
|
|
|
|
// find the pak file
|
|
PakFiles.AddRange( Directory.EnumerateFiles(TemporaryPakPath, Params.ShortProjectName+"*.pak", SearchOption.AllDirectories));
|
|
PakFiles.AddRange( Directory.EnumerateFiles(TemporaryPakPath, "pakchunk*.pak", SearchOption.AllDirectories));
|
|
}
|
|
else if (!Path.HasExtension(SourceCookedContentPath))
|
|
{
|
|
// try find the pak or pkg file
|
|
string SourceCookedContentPlatformPath = CombinePaths(SourceCookedContentPath, CookPlatformString);
|
|
|
|
foreach (var PakName in Directory.EnumerateFiles(SourceCookedContentPlatformPath, Params.ShortProjectName + "*.pak", SearchOption.AllDirectories))
|
|
{
|
|
string TemporaryPakFilename = CombinePaths(TemporaryPakPath, Path.GetFileName(PakName));
|
|
File.Copy(PakName, TemporaryPakFilename);
|
|
PakFiles.Add(TemporaryPakFilename);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
if ( PakFiles.Count <= 0 )
|
|
{
|
|
Log("No Pak files found in " + SourceCookedContentPlatformPath +" :(");
|
|
}
|
|
}
|
|
else if (SourceCookedContentPath.EndsWith(".pak"))
|
|
{
|
|
string TemporaryPakFilename = CombinePaths(TemporaryPakPath, Path.GetFileName(SourceCookedContentPath));
|
|
File.Copy(SourceCookedContentPath, TemporaryPakFilename);
|
|
PakFiles.Add(TemporaryPakFilename);
|
|
}
|
|
|
|
|
|
string FullCookPath = CombinePaths(CookedSandboxesPath, CookPlatformString);
|
|
|
|
var UnrealPakExe = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UnrealPak.exe");
|
|
|
|
|
|
foreach (var Name in PakFiles)
|
|
{
|
|
Log("Extracting pak " + Name + " for comparision to location " + TemporaryFilesPath);
|
|
|
|
string UnrealPakParams = Name + " -Extract " + " " + TemporaryFilesPath;
|
|
try
|
|
{
|
|
RunAndLog(CmdEnv, UnrealPakExe, UnrealPakParams, Options: ERunOptions.Default | ERunOptions.UTF8Output | ERunOptions.LoggingOfRunDuration);
|
|
}
|
|
catch(Exception Ex)
|
|
{
|
|
Log("Pak failed to extract because of " + Ex.GetType().ToString());
|
|
}
|
|
}
|
|
|
|
const string RootFailedContentDirectory = "\\\\epicgames.net\\root\\Developers\\Daniel.Lamb";
|
|
|
|
string FailedContentDirectory = CombinePaths(RootFailedContentDirectory, CommandUtils.P4Env.BuildRootP4 + CommandUtils.P4Env.ChangelistString, Params.ShortProjectName, CookPlatformString);
|
|
|
|
Directory.CreateDirectory(FailedContentDirectory);
|
|
|
|
// diff the content
|
|
List<string> AllFiles = Directory.EnumerateFiles(FullCookPath, "*.uasset", System.IO.SearchOption.AllDirectories).ToList();
|
|
AllFiles.AddRange(Directory.EnumerateFiles(FullCookPath, "*.map", System.IO.SearchOption.AllDirectories).ToList());
|
|
foreach (string SourceFilename in AllFiles)
|
|
{
|
|
// Filename.StartsWith( CookedSandboxesPath );
|
|
string RelativeFilename = SourceFilename.Remove(0, FullCookPath.Length);
|
|
|
|
string DestFilename = TemporaryFilesPath + RelativeFilename;
|
|
|
|
|
|
byte[] SourceFile = null;
|
|
try
|
|
{
|
|
SourceFile = File.ReadAllBytes(SourceFilename);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
Log("Diff cooked content failed to load file " + SourceFilename);
|
|
}
|
|
|
|
byte[] DestFile = null;
|
|
try
|
|
{
|
|
DestFile = File.ReadAllBytes(DestFilename);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
Log("Diff cooked content failed to load file " + DestFilename );
|
|
}
|
|
|
|
if (SourceFile == null || DestFile == null)
|
|
{
|
|
Log("Diff cooked content failed on file " + SourceFilename + " when comparing against " + DestFilename + " " + (SourceFile==null?SourceFilename:DestFilename) + " file is missing");
|
|
}
|
|
else if (SourceFile.LongLength == DestFile.LongLength)
|
|
{
|
|
for (long Index = 0; Index < SourceFile.LongLength; ++Index)
|
|
{
|
|
if (SourceFile[Index] != DestFile[Index])
|
|
{
|
|
Log("Diff cooked content failed on file " + SourceFilename + " when comparing against " + DestFilename + " at offset " + Index.ToString());
|
|
string SavedSourceFilename = CombinePaths(FailedContentDirectory, Path.GetFileName(SourceFilename) + "Source");
|
|
string SavedDestFilename = CombinePaths(FailedContentDirectory, Path.GetFileName(DestFilename) + "Dest");
|
|
|
|
Log("Creating directory " + Path.GetDirectoryName(SavedSourceFilename));
|
|
|
|
try
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(SavedSourceFilename));
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
Log("Failed to create directory " + Path.GetDirectoryName(SavedSourceFilename) + " Exception " + E.ToString());
|
|
}
|
|
Log("Creating directory " + Path.GetDirectoryName(SavedDestFilename));
|
|
try
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(SavedDestFilename));
|
|
}
|
|
catch(Exception E)
|
|
{
|
|
Log("Failed to create directory " + Path.GetDirectoryName(SavedDestFilename) + " Exception " + E.ToString());
|
|
}
|
|
File.Copy(SourceFilename, SavedSourceFilename);
|
|
File.Copy(DestFilename, SavedDestFilename);
|
|
Log("Content temporarily saved to " + SavedSourceFilename + " and " + SavedDestFilename + " at offset " + Index.ToString());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log("Diff cooked content failed on file " + SourceFilename + " when comparing against " + DestFilename + " files are different sizes " + SourceFile.LongLength.ToString() + " " + DestFile.LongLength.ToString());
|
|
}
|
|
}
|
|
}
|
|
catch ( Exception Ex )
|
|
{
|
|
Log("Exception " + Ex.ToString());
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void CleanupCookedData(List<string> PlatformsToCook, ProjectParams Params)
|
|
{
|
|
var ProjectPath = Params.RawProjectPath.FullName;
|
|
var CookedSandboxesPath = CombinePaths(GetDirectoryName(ProjectPath), "Saved", "Cooked");
|
|
var CleanDirs = new string[PlatformsToCook.Count];
|
|
for (int DirIndex = 0; DirIndex < CleanDirs.Length; ++DirIndex)
|
|
{
|
|
CleanDirs[DirIndex] = CombinePaths(CookedSandboxesPath, PlatformsToCook[DirIndex]);
|
|
}
|
|
|
|
const bool bQuiet = true;
|
|
DeleteDirectory(bQuiet, CleanDirs);
|
|
}
|
|
|
|
#endregion
|
|
}
|