Files
UnrealEngineUWP/Engine/Source/Programs/AutomationTool/AutomationUtils/ProjectParams.cs
Ben Marsh 496e06c3d5 Copying //UE4/Orion-Staging to //UE4/Dev-Main (//UE4/Orion-Staging @ 2979119, //Orion/Dev-General @2976565)
#lockdown Nick.Penwarden
==========================
MAJOR FEATURES + CHANGES
==========================

Change 2976484 on 2016/05/12 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: nick.atamas
	Added queueing to HUD Alerts so they don't clobber each other.
	Added input visualization so that keys show up in game.
	SRichTextBlock/UOrionRichTextBlock now have a MinDesiredWidth

	#test PIE

	#ROBOMERGE-SOURCE: CL 2976474 in //Orion/Release-0.26/... via CL 2976481 via CL 2976482 via CL 2976483
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2976256 on 2016/05/12 by Zak.Middleton

	#ue4 - Fix for shipping build.

	#tests compiled

Change 2976205 on 2016/05/12 by Zak.Middleton

	#ue4 - (Merge 2957866) Add MaxDepenetration for characters against geometry and pawns.

	#tests MP PIE PlayGo
	(Merging CL 2957866 using Framework->DevGeneral)

Change 2976166 on 2016/05/12 by Daniel.Lamb

	Cooking optimziation to unsolicited markup saves 150 seconds paragon cook time.
	#test Cook paragon

Change 2976161 on 2016/05/12 by Zak.Middleton

	#ue4 - Make sure LastUpdateLocation, Rotation, and Velocity are updated on client and server error corrections. ForcePositionUpdate should call PerformMovement regardless of velocity (there may be root motion or gravity effects).

	#tests PIE MP w/ real-world networking

Change 2976092 on 2016/05/12 by Mieszko.Zielinski

	Modified adding dynamic subtrees to BT component so that we get a log info if it fails #UE4

	#test golden path

Change 2976001 on 2016/05/12 by Robert.Manuszewski

	Don't log to memory on dedicated servers

	#jira UE-30693
	#test Cooked dedicated server and client

Change 2975855 on 2016/05/12 by Lukasz.Furman

	fixed behavior tree serialization spawning duplicates of task services
	#tests BT editor

Change 2975706 on 2016/05/12 by Daniel.Lamb

	Fixed redirect collector stats.
	#test Compile

Change 2975636 on 2016/05/12 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge DUI @ CL 2975557

	#RB:none
	#Tests:none

	[CodeReviewed]: matt.schembari, kerrington.smith, tony.oliva, jaymee.stanford, mona.huang, alex.conner, jacob.lawyer, paul.shank

	#ROBOMERGE-SOURCE: CL 2975635 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2975592 on 2016/05/12 by Zak.Middleton

	#ue4 - Add stat for SetHitResultFromShapeAndFaceIndex().

	#tests PIE

Change 2975589 on 2016/05/12 by Zak.Middleton

	#ue4 - Avoid filling temp variable unless in Editor builds. It's only used later in the function in Editor builds.

	#tests PIE

Change 2975588 on 2016/05/12 by Zak.Middleton

	#ue4 - Minor tweak to avoid array read each loop iteration.

	#tests PIE

Change 2975587 on 2016/05/12 by Zak.Middleton

	#ue4 - Add "IsPlayerController()" function to AController. Variable already existed, just wasn't exposed.

	#tests PIE

Change 2975504 on 2016/05/12 by Daniel.Lamb

	Remove new stats system because it broke build.
	#test cook paragon

Change 2975500 on 2016/05/12 by Daniel.Lamb

	Enable redirect timers so I can get stats from build machines.
	#test cook paragon.

Change 2975367 on 2016/05/12 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: david.nikdel
	#OGF #CatalogService #OSS #Localization
	- Flush the cached offers/items in CatalogServiceMcp when the culture changes since they contain localized text
	- Flush the cached virtual catalog offers/items in McpCatalogHelper when the culture changes since they contain localized text
	- Replaced SetForceCatalogRefresh with ClearCache per CR with SamZ (will require Launcher fixup)

	[CodeReviewed]: Sam.Zamani, Matt.Kuhlenschmidt
	#RB: Sam.Zamani
	#TESTS: storefront w/ language change

	#ROBOMERGE-SOURCE: CL 2975366 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2975209 on 2016/05/12 by Simon.Tovey

	Fixed initialization order warning.

	#tests none

Change 2975200 on 2016/05/12 by Simon.Tovey

	Translucency GPU time stats for automation.

	Refactored separate translucency gpu timer to more general helper class and used it to also time regular translucency.
	Feeding both of these into a stat to help art identify poorly performing VFX for more detailed investigation.
	There are occasional spikes when the GPU is starved but overall the data out seems good.

	#tests GoldenPath, Editor, Auto downsampling works, new stat produces reasonable data.

Change 2974984 on 2016/05/11 by Mieszko.Zielinski

	Fixed a bug in graph-a-star heuristics' calculation #UE4

	#test golden path

Change 2974916 on 2016/05/11 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 26 @ CL 2974578

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2974915 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2974869 on 2016/05/11 by Ben.Marsh

	BuildGraph: Add a MergeTelemetryWithPrefix="..." parameter to the <Command> task which allows merging the telemetry data from a child UAT run, adding a given prefix to all the key names.

	#tests none

Change 2974673 on 2016/05/11 by Mieszko.Zielinski

	Fix to BT not stopping if "StopTree" called while BT was waiting for a task to latently abort #UE4

	(change by ?ukasz.Furman)
	#test golden path

Change 2974581 on 2016/05/11 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: matt.kuhlenschmidt
	Merged CL 2974565 from Release-.26 -> Main:

	Fixed loc region not saving in shipping builds
	Partially fixed store not refreshing when changing regions. Real money currency items are pending additional fixes

	#ROBOMERGE-SOURCE: CL 2974578 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2974444 on 2016/05/11 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: richard.fawcett
	Reimplement support for specifying BuildPatchTool version used in chunking

	This is now possible after Ben Marsh's fix to BuildGraph with CL 2974407.

	#tests none

	#ROBOMERGE-SOURCE: CL 2974441 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2974408 on 2016/05/11 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: ben.marsh
	BuildGraph: Fix support for variable expansion in user-defined enum types. Enums in the schema are now represented as the union of valid values and a regex matching a balanced property expansion string, which still validates/autocompletes cleanly in Visual Studio.

	#tests none
	[CodeReviewed] Richard.Fawcett

	#ROBOMERGE-SOURCE: CL 2974407 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2974392 on 2016/05/11 by Daniel.Lamb

	Optimizing resolve string asset reference resolution.
	Added timing stats (disabled by default).
	#test Cook paragon.

Change 2974349 on 2016/05/11 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: richard.fawcett
	Back out changelist 2974298. An issue with the BuildGraph system has prevented this change from working on the build farm.

	#tests none

	#ROBOMERGE-SOURCE: CL 2974347 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2974299 on 2016/05/11 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: richard.fawcett
	Add support for chunking builds with the pre-release version of BuildPatchTool.

	#tests None. This code will be tested by creating a build on the build farm immediately after submission.

	#ROBOMERGE-SOURCE: CL 2974298 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2974277 on 2016/05/11 by Lina.Halper

	Fix up of retargeting when it skips replacing nested reference

	#tests: retargeting anim BP

Change 2974210 on 2016/05/11 by Bart.Bressler

	Merging Oodle changes from Dev-Networking

	Change 2939167 on 2016/04/10 by John.Barrett

		Updated packet bit termination code, so that both UNetConnection's and the PacketHandler use a termination bit (required for both PacketHandler/UNetconnection, as HandlerComponent's such as Oodle, are byte-aligned and do not preserve packet bit size).

		Added new 'stat packet' stats group, for tracking reserved packet bits.

		Added '-NoPacketHandler' commandline parameter, for disabling the PacketHandler and all HandlerComponent's (including stateless handshake) - restoring netcode to pre-PacketHandler state.

		Removed PacketHandler 'packet overhead' method of packet bit size calculation - replaced with termination bit. Still partially used for reserving bits within packets (but renamed to avoid conflict with other 'PacketOverhead' variable).

		Refactored/consolidated some PacketHandler code. Added more stringent bounds checking on packet sizes.

	Change 2939168 on 2016/04/10 by John.Barrett

		Updated Oodle to support new packet bit-termination code.

		Added Oodle protocol support for selective packet compression (packets can now be sent uncompressed - game code will require a hook for this) - required for new bit-based netcode (Oodle outputs byte-aligned data, allowing compressed data to exceed size of uncompressed data - and thus, maximum packet size if not sent uncompressed - in rare edge cases).

		Added '-CompressionTest' commandline parameter to Oodle dictionary generation commandlet, which reserves a portion of captured packets, for determining the compression savings percentage.

		Added '-OodleDebugDump' commandline parameter, which disables normal dictionary generation, and converts packet captures into a .bin file, which is compatible with the Oodle 'example_packet.cpp' code.

		Added temporary security bandaids to Oodle code, based on report that Luigi Auriemma put together, which deals with potential weaknesses in the Oodle API

		Added 'stat oodle' stats for tracking failed attempts at compressing packets.

	Change 2942964 on 2016/04/10 by Ryan.Gerleve

		Fix broken indentation/formatting

	Change 2958260 on 2016/04/27 by Bart.bRessler

		Add branch name and changelist to oodle packet capture filenames.

	Change 2964360 on 2016/05/03 by John.Barrett

		Updated Oodle to support using a dictionary and capturing packets at the same time.

		The dictionary is now always loaded, if specified, and whenever -OodleCapturing is on the commandline, packets are captured alongside the active dictionary.

		Added several debug commands, to aid with testing compression performance (not QA-ready; only works with 1 player on a server):

		"Oodle Compression On/Off" - enables/disables packet compression (but still decompresses received compressed packets)

		"Oodle Dictionary Unload/Load" - unloads/loads the dictionary files, to allow releasing the files for dictionary generation, and reloading the new dictionary.

		"Oodle Capture On/Off" - Enables/Disables packet capturing at runtime - requires '-OodleCapturing' on commandline.

		"Oodle ResetStats" - resets the 'stat oodle' stat counters.

		The NetcodeUnitTest plugin should be enabled, so that these commands can automatically execute on the server as well, as needed.

	Change 2964553 on 2016/05/03 by Bart.Bressler

		Add process ID to oodle capture filenames

	Change 2966247 on 2016/05/04 by John.Pollard

		Oodle 2.1.5 SDK

	Change 2968761 on 2016/05/06 by Bart.Bressler

		- Added changelist number as parameter to most command line tasks to filter captures by their changelist number (use "all" to get everything)
		- Moved a bunch of the file searching/processing code outside of the tasks themselves so that the tasks all just operate to an array of capture files, this makes it easier to create new command line options
		- When looking for capture files, we will now recursively search subdirectories

	Change 2970529 on 2016/05/09 by Bart.Bressler

		Add an optional "CapturePercentage" command line parameter that has a percentage chance of generating capture files per connection

	Change 2970874 on 2016/05/09 by Bart.Bressler

		- Turn on OODLE_DEV_SHIPPING in the Orion server shipping config so that captures can be generated in shipping builds
		- Link to version 215 of oodle

	Change 2971233 on 2016/05/09 by Bart.Bressler

		Update Oodle DLLs in Orion

	Change 2971362 on 2016/05/09 by Bart.Bressler

		Create script for building an oodle dictionary out of capture files in an arbitrary location

	Change 2972176 on 2016/05/10 by Bart.Bressler

		Update oodle references to version 215 in OodleHandlerComponent.Build.cs

	#tests used solo vs. ai to test oodle captures and using them

Change 2974035 on 2016/05/11 by Simon.Tovey

	Adding fx.ParticleCollisionIgnoreInvisibleTime to replace hard coded time.

	This is the time a PSC needs to be invisible for to have all it's collisions ignored.
	This is potentially the cause of a bug Tim et al are seeing.

	#tests Editor, Can be used to repro/fix the issue.

Change 2973985 on 2016/05/11 by Lina.Halper

	Retargeting fix with editor saving issue

	#tests: retargeting

Change 2973695 on 2016/05/11 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 26 @ CL 2973469

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2973694 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2973679 on 2016/05/11 by Graeme.Thornton

	UAT parameter -signedpak now no longer implies -pak

	#tests win64 cooked client. checked that pak generation works as expected through project launcher

Change 2973588 on 2016/05/11 by Simon.Tovey

	OR-21033 - Get physical material from particle collision event exposed in Cascade / Blueprint

	Particles can now receive collision events selectively based upon the phyisics material of the hit.

	Physics material is passed through the event and can be accessed in BPs.
	The Event Receiver Spawn node also now has an array of Allowed and Banned phys materials.

	#tests Editor and game. Coudln't test cooked as having unrelated crashes in cooked games. Shouldn't be any cooked/uncooked issues here.

Change 2973394 on 2016/05/11 by bruce.nesbit

	Fixed couple of shadow vars

	#tests compiled

Change 2973335 on 2016/05/11 by Andrew.Grant

	Warning fix
	#tests compiled

Change 2973308 on 2016/05/10 by Dmitry.Rekman

	Add "unplayable condition" reporting.

	- The server will report an unplayable condition by creating a local file (under Saved).
	- An external script can possibly notice this and, applying its own logic on % of servers reporting it, profile or shutdown the whole machine.
	- Report file is to be deleted by an external script.

	#tests Compiled and ran Linux server, subjected it to various hitches.

Change 2973235 on 2016/05/10 by Zak.Middleton

	#ue4 - Removed allocs after initial spawn from client saved move processing in character movement.

	#tests PIE multiplayer w/ Bots

Change 2973157 on 2016/05/10 by Olaf.Piesche

	Merging CL 2973112 from //UE4/Dev-Rendering->//Orion/Dev-General

	Providing particle source and target for beam emitters

	#tests editor game PC

Change 2972715 on 2016/05/10 by Jason.Bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 26 @ CL 2972681

	#RB: none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2972712 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2972678 on 2016/05/10 by Mieszko.Zielinski

	Fixed babysitter bot not avoiding enemy towers when pathfinding back to base #Orion

	#jira OR-18590
	#test golden path

Change 2972595 on 2016/05/10 by Lina.Halper

	Animation Retargeting fix for blendspaces

	#code review: Benn.Gallagher, Martin.Wilson

	#tests: retargeting anim BP

Change 2972282 on 2016/05/10 by Daniel.Lamb

	Optimized string asset reference resolution slightly to help get back missing 10 minutes from paragon cook.
	#test cook paragon.

Change 2972260 on 2016/05/10 by Laurent.Delayen

	Fixed crash in UCharacterMovementComponent::HasRootMotionSources().

	#tests Chains pull not crashing anymore.

Change 2972241 on 2016/05/10 by Frank.Fella

	UMG - Fixes for material animation copied from 4.12.

	#RB Matt K.
	#TESTS Struct materials can now be animated and animated materials are named nicely.

Change 2971643 on 2016/05/09 by Dmitry.Rekman

	Add reporting of "zero load" frame times (OR-21035).

	- Added a thread that does nothing but sleeps and counts how often it missed the target FPS.
	- Added an analytics event ServerZeroLoadFrameTimeDistribution that is sent at the end of the match.
	- Server only.

	#tests Compiled and ran Linux server on a compatible content, played few matches in a row.

Change 2971544 on 2016/05/09 by Ben.Marsh

	EC: Use a full path to the telemetry file, to account for UAT switching directories.

Change 2971532 on 2016/05/09 by Wes.Hunt

	Alter the cook stats hierarchical profile data to reflect the latest cook changes.
	#tests none

Change 2971527 on 2016/05/09 by Ben.Marsh

	UAT: Move telemetry object into CommandUtils, so we can add stats from anywhere.

	#tests none

Change 2971461 on 2016/05/09 by David.Ratti

	Fix issues with mesh swap skins:
	-Front end intro animations not playing
	-In game spawn animations not playing
	-Some attachment weirdness (twinblast)

	#tests golden path

Change 2971460 on 2016/05/09 by David.Ratti

	Fallback to Target actor if there is no instigating actor in the GAmeplayCue parameters when determining if we should play "local only" effects

	#tests pie

Change 2971364 on 2016/05/09 by Ben.Marsh

	EC: Add support for adding custom telemetry data from UAT scripts, which gets piped through to the trends panel in EC.

	#tests none

Change 2971245 on 2016/05/09 by Dmitry.Rekman

	Add a "hitchhunter" log message to catch hitches while sleeping.

	#tests Compiled and ran Linux server on a compatible content.

Change 2971196 on 2016/05/09 by jason.bestimt

	#ORION_MAIN - Merge 25.2 @ CL 2971139

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2971168 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

	#ROBOMERGE-SAYS: Beep boop! I couldn't merge this change. Please do it yourself, human.
	//Orion/Dev-General/OrionGame/Content/Characters/Heroes/Coil/Audio/Body/Pixie_Cranking_Loop_Cue.uasset - can't branch exclusive file already opened
	#CodeReview: david.nikdel, jason.bestimt

Change 2971113 on 2016/05/09 by Dmitry.Rekman

	UdpMessaging: Fixed broken filters for when to enable UDP transport.

	- Redoing MaxP's change from Dev-Sequencer (CL 2963357).
	- Reduces number of threads spawned by the server.

	#tests Compiled Linux server, ran it on a compatible content.

Change 2971040 on 2016/05/09 by jason.bestimt

	#ORION_MAIN - Merge 25.2 @ CL 2970990

	#RB:none
	#Tests:none

	[CodeReviewed]: jon.lietz

	#ROBOMERGE-SOURCE: CL 2971027 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

	#ROBOMERGE-SAYS: Beep boop! I couldn't merge this change. Please do it yourself, human.
	#CodeReview: david.nikdel, jason.bestimt

Change 2970555 on 2016/05/09 by Ben.Marsh

	BuildGraph: Only show warnings and errors for the SavePackage log during cooks. Prevents redundant display of information that's already in the Cook log.

	#tests preflight here: https://ec-01.epicgames.net/commander/link/jobDetails/jobs/6443796

Change 2970507 on 2016/05/09 by David.Ratti

	Support for linking passive abilities to a key binded ability. E.g., allow a passive ability to be unlocked and leveled up in step with a key binded ability.

	Cleaned up the TryLevel/CanLevelUp code a bit: moved to Orion Ability System Component

	#tests pie

Change 2970414 on 2016/05/09 by Graeme.Thornton

	Don't take a copy of the child tags array when doing UGameplayTagsManager::FindTagNode, just take a const&

	#tests win64 client golden path

Change 2969729 on 2016/05/06 by Mieszko.Zielinski

	Fixed a dumb mistake in a conditional expresion in UNavigationQueryFilter::GetQueryFilter #UE4

	#test golden path

Change 2969675 on 2016/05/06 by Mieszko.Zielinski

	Implemented "meta navigation filter" that can fetch a filter class based on given agent #UE4

	Added NavFilter_AIControllerDefault that fetched DefaultNavigationFilter from AIController
	Reverted hack-feature that supplied same functionality to EQS

	#test golden path

Change 2969652 on 2016/05/06 by Michael.Noland

	HLOD: Changed UI gating code so that whether or not a LOD Actor is valid is based on the presence of at least two static mesh components, rather than at least two actors (to improve handling when including BPs)
	- Repurposed HasValidSubActors for this check, and introduced HasAnySubActors() for the existing uses as this better matches the intent of how the function was used
	#tests Added a single BP containing 7 mesh components to a new ALODActor and verified that it allowed a proxy to be generated

Change 2969651 on 2016/05/06 by Michael.Noland

	Simplygon: Added time taken for simplygon mesh reduction to the log message
	#tests Simplified a LOD cluster and inspected the log

Change 2969604 on 2016/05/06 by Uriel.Doyon

	Changed default value to true for UParticleModuleVectorFieldLocal::bUseFixDT.
	#tests confirmed that default value has changed for old assets, while allowing override.

Change 2969418 on 2016/05/06 by jason.bestimt

	#ROBOMERGE-AUTHOR: andrew.grant
	Fixed unconverted char string being passed as part of build info
	#tests ran & verified patch check passes

	#ROBOMERGE-SOURCE: CL 2969417 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2968817 on 2016/05/06 by jason.bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 25.2 @ CL 2968572

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2968813 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2968383 on 2016/05/05 by Mieszko.Zielinski

	Added "default navigation filter" to AIController #UE4

	Also, made EQS take advantage of that

	#test golden path

Change 2968225 on 2016/05/05 by John.Pollard

	Add sanity checks and more info to help track down possible memory corruption

	#tests Networking, replication

Change 2967903 on 2016/05/05 by jason.bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 25.2 @ CL 2967827

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2967902 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2967899 on 2016/05/05 by Lina.Halper

	Merged change of 2956152

	Remove invalid ensure - this didn't work if you have composite inside.

	#tests: none

Change 2967870 on 2016/05/05 by Andrew.Grant

	Fix for OR-20731 (gamever crashes client)
	#tests gamever at console with -game

Change 2967606 on 2016/05/05 by Wes.Hunt

	Tweaked output log message for HTTP module shutdown.
	#tests none

Change 2967359 on 2016/05/05 by Wes.Hunt

	HttpManager will log outstanding requests on shutdown so people can debug shutdown issues and ensure their requests get flushed properly. Also changed default LogHttp logging level to display so these messages can be shown by default without using warning level.

	#tests ran editor build and queued up an event using the console command, then quit immediately. the log indeed showed that HttpManager had to wait at least 0.5 seconds for the request to complete.

Change 2966987 on 2016/05/05 by Dmitry.Rekman

	Fix editor build.

	#tests Compiled Win64 editor.

Change 2966977 on 2016/05/05 by Dmitry.Rekman

	Added collecting and reporting periodic server frame time distribution.

	- Added generic FHistogram class and necessary analytic events.
	- Also added reporting hostname (OR-20842).

	#tests Built Linux server and ran a few matches on a compatible content.

Change 2966920 on 2016/05/04 by jason.bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 25.2 @ CL 2966805

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2966919 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2966778 on 2016/05/04 by Michael.Noland

	Rendering: Fixed shadow variable warning in GPUProfiler
	#tests Compiled and tested GPUProfiler command

Change 2966769 on 2016/05/04 by Mieszko.Zielinski

	Fixed GraphAStar not resetting the output path before fillinf it with results #UE4

	#test golden path

Change 2966704 on 2016/05/04 by Michael.Noland

	Rendering: Added triangle and draw call summaries to ProfileGPU output, broken up by asset and material
	- This is controlled by r.ProfileGPU.PrintAssetSummary, which defaults to 1, but you really need r.ShowMaterialDrawEvents 1 enabled as well for a complete picture
	- It can also output a summary line for speciifc asset names using a comma separated list in r.ProfileGPU.AssetSummaryCallOuts (e.g., "LOD,HeroName")
	#tests Used ProfileGPU a number of times

Change 2966696 on 2016/05/04 by Michael.Noland

	Engine: Embedded FPS chart preamble/postamble/row .html files into ChartCreation.cpp to permanently solve packaging woes
	#tests Tested FPS charts in an uncooked and cooked build
	#jira OR-19713

Change 2966336 on 2016/05/04 by Lukasz.Furman

	fixed jungle minions unable to reach spawn locations when camp resets
	#jira OR-20700
	#tests jungle camp POC

Change 2965948 on 2016/05/04 by David.Ratti

	Changes to how passive abilities activate
	-Passives now continually try to activate by default rather than only on spawn

	Support for Status.Immortal
	-Prevents death, fies AbilityTriggerEvent.ImmortalProc when this happens.
	-Clamps health to 1.

	Fixed bug in muriel passive where ShieldHealthRegen would be left in the world where muriel died.

	Fixed bunch of crap in GA_OnSpawn that was causing desync on client at start of match

	#tests multi pie

Change 2965870 on 2016/05/04 by Ryan.Gerleve

	Duplicated fix from Release-4.12 by marc.audy, CL 2960819:

	Owned components are once again referenced by their Owning actor for GC purposes
	#jira UE-29131

	#tests golden path

Change 2965798 on 2016/05/04 by jason.bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 25.2 @ CL 2965789

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2965796 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2965220 on 2016/05/03 by Dmitry.Rekman

	Log instance id and system id (OR-20782).

	- These ids get reported in multiple analytics events, having them logged is helpful for quickly mapping events to the log file.

	#tests Compiled Linux server, ran on compatible client.

Change 2964907 on 2016/05/03 by Jason.Bestimt

	#ORION_DG - Merge MAIN @ CL 2964858

	#RB:none
	#Tests:none

Change 2964530 on 2016/05/03 by Laurent.Delayen

	Renamed GetSlotRootMotionWeight to GetSlotNodeGlobalWeight and made it double buffered to it's safe to access anytime.
	Added GetSlotMontageGlobalWeight() to get the Global Weight of a montage being played on a Slot. (Also double buffered).
	Added GetInstanceMachineWeight() to get Global Weight of a State Machine in the AnimGraph. (Also double buffered)
	Added FAnimInstanceProxy::GetStateMachineIndexAndDescription to avoid searching through the AnimNodeProperties twice.

	#tests Chains full feature system in PIE.

Change 2964498 on 2016/05/03 by Frank.Fella

	DecalComponent - Fix visibility so that it behaves like other scene components with regard to the editor visibility, component visibility, and actor hidden in game flags.

	#RB Andrew Rodham
	#TESTS Visibility for decals works like other scene components in the editor, and their visibility can now be animated properly by sequencer.

Change 2964428 on 2016/05/03 by Benn.Gallagher

	Fixed stale clothing chunk/section references after container realloc in editor
	#tests editor

Change 2964316 on 2016/05/03 by bruce.nesbit

	Banner revisions

	Banners now use components for various banner items
	Banners can now be enabled when killing  a hero.

	#tests PIE+Game

Change 2964187 on 2016/05/03 by Jon.Lietz

	Speeding up the tag count check in UAbilitySystemComponent::RegisterAndCallGameplayTagEvent()

	- Remove the call to GetAggregatedStackCount and creating a FGameplayEffectQuery every time we call RegisterAndCallGameplayTagEvent
	- Added GetTagCount to the UAbilitySystemComponent that will call GetTagCount on the GameplayTagCountContainer

	#RB DanY
	#tests JIP shadow pad still works.

Change 2964136 on 2016/05/03 by Laurent.Delayen

	Fix crash while switching tabs using Persona.

	#tests not crashing anymore.

Change 2964083 on 2016/05/03 by jason.bestimt

	#ROBOMERGE-AUTHOR: jason.bestimt
	#ORION_MAIN - Merge 25.2 @ CL 2963929

	[CodeReviewed]: andrew.grant

	HTTP Manager has larger stack size (1024)

	#RB:none
	#Tests:none

	#ROBOMERGE-SOURCE: CL 2964080 in //Orion/Main/...
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2963771 on 2016/05/02 by Nick.Atamas

	Setting a desired size scale invalidates layout and volatility.

	#test none

Change 2963555 on 2016/05/02 by Rob.Cannaday

	Fix PS4 Orion players being able to whisper chat with non-Orion players
	#jira OR-20626
	#tests chat with launcher, fortnite

Change 2963387 on 2016/05/02 by Laurent.Delayen

	Added GatherDebugData to FABRIK node.

	#tests showdebug animation works on Chains now.

Change 2963331 on 2016/05/02 by Jon.Lietz

	fixing compile error, dont need the clamp just the ternary on the EventType and pass down the tag count or 1.

	#RB none
	#tests compiles

Change 2963106 on 2016/05/02 by Rob.Cannaday

	Increase HTTP thread's stack size to 128k
	We discovered a stack overflow when the stack size was 64kb in LavasoftTcpService64.dll (Ad-Aware's Lavasoft Web Companion)
	#tests log in

Change 2963047 on 2016/05/02 by Jon.Lietz

	OR-20206 for JIP we need to call the bound function if we already have the tag on reconnect.

	- adding a new function in UAbilitySystemComponent, RegisterAndCallGameplayTagEvent this will bind the passed in delegate and if the ability system has that tag already will execute the delegate.

	#RB Dave.Ratti
	#test shadow pad, slow, stun and root still trigger and trigger for JIP players.

Change 2962836 on 2016/05/02 by jason.bestimt

	#ROBOMERGE-AUTHOR: andrew.grant
	[NULL MERGE]
	Duplicating 2961899 - Fix minimal code builds for Linux not overwriting files
	[CodeReviewed] Ben.Marsh

	#ROBOMERGE-SOURCE: CL 2962812 in //Orion/Release-0.24.2/... via CL 2962830 via CL 2962833 via CL 2962834 via CL 2962835
	#ROBOMERGE-BOT: ORION (Main -> Dev-General)

Change 2962570 on 2016/05/02 by Jason.Bestimt

	#ORION_MAIN - Merge MAIN @ CL 2962544

	#RB:none
	#Tests:none

Change 2962552 on 2016/05/02 by Ben.Marsh

	Avoid output of warnings containing the string "error:" (and causing the EC post processor to fail the build) if posting build info has a human-readable error message instead. Output should probably be changed to parse out/sanitize the actual failure message if it's meant to retry and succeed, but this will stop failures caused by multiple builds being posted with the same build version.

	#tests none

Change 2962506 on 2016/05/02 by Ben.Marsh

	Add a version string to identify a given build (FApp::GetBuildVersion()/BUILD_VERSION) which is distinct from the engine version. Defaults to <Escaped Branch Name>-CL-<Changelist>, but can be overriden by specifying a -Build=... argument to UpdateLocalVersion or the "Build" attribute to the SetVersion BuildGraph task.

	#tests Preflighted Win64 client/server build (P:\Builds\Orion\++Orion+Dev-General-CL-2962228-PF-2945494-6398155-PF-2945494-6398155) and loaded into Agora. Checked that version strings appear correctly in generated executables.

Change 2962228 on 2016/04/30 by Dmitry.Rekman

	Move processing HTTP requests into separate thread (OR-20723).

	- First iteration of the implementation, pending implementing feedback.
	- Adds a separate thread for CurlHttp where actual processing is performed.
	- Coded by RobC, post-processed by me.

	#tests Compiled Linux server and Windows client, ran them on compatible content, played a match.

Change 2961899 on 2016/04/29 by Ben.Marsh

	BuildGraph: Fix minimal Linux server builds not overwriting the existing executables, by adding an "Overwrite" parameter into the staging task. Windows exe-only patches already happen to bypass this bug by deleting the Binaries/Win64 directory (designed to remove any configurations that weren't built this time), but could still fail if changes had been made to some other staged binaries.

	#tests preflighted code-only build against DG CL 2960870 and compared output (P:\Builds\Orion\++Orion+Dev-General-CL-2961878-PF-2961895-6393603)

Change 2961587 on 2016/04/29 by Daniel.Lamb

	Redirector doesn't fire callback if it fails to be loaded.

	#test Cook orion.

Change 2961458 on 2016/04/29 by Wes.Hunt

	Cooker Stats improvements. Also removed some old UBT telemetry that was not being used.
	#tests many cooks of orion

Change 2961136 on 2016/04/29 by Daniel.Lamb

	Readded caching of platform data into postload of materials.
	#test Cook paragon.

[CL 2979220 by Ben Marsh in Main branch]
2016-05-16 16:20:52 -04:00

2311 lines
88 KiB
C#

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnrealBuildTool;
using System.IO;
using System.Reflection;
namespace AutomationTool
{
[Help("targetplatform=PlatformName", "target platform for building, cooking and deployment (also -Platform)")]
[Help("servertargetplatform=PlatformName", "target platform for building, cooking and deployment of the dedicated server (also -ServerPlatform)")]
public class ProjectParams
{
#region Constructors
/// <summary>
/// Gets a parameter from the command line if it hasn't been specified in the constructor.
/// If the command line is not available, default value will be used.
/// </summary>
/// <param name="Command">Command to parse the command line for. Can be null.</param>
/// <param name="SpecifiedValue">Value specified in the constructor (or not)</param>
/// <param name="Default">Default value.</param>
/// <param name="ParamNames">Command line parameter names to parse.</param>
/// <returns>Parameter value.</returns>
bool GetParamValueIfNotSpecified(CommandUtils Command, bool? SpecifiedValue, bool Default, params string[] ParamNames)
{
if (SpecifiedValue.HasValue)
{
return SpecifiedValue.Value;
}
else if (Command != null)
{
foreach (var Param in ParamNames)
{
if (Command.ParseParam(Param))
{
return true;
}
}
}
return Default;
}
/// <summary>
/// Gets optional parameter from the command line if it hasn't been specified in the constructor.
/// If the command line is not available or the command has not been specified in the command line, default value will be used.
/// </summary>
/// <param name="Command">Command to parse the command line for. Can be null.</param>
/// <param name="SpecifiedValue">Value specified in the constructor (or not)</param>
/// <param name="Default">Default value.</param>
/// <param name="TrueParam">Name of a parameter that sets the value to 'true', for example: -clean</param>
/// <param name="FalseParam">Name of a parameter that sets the value to 'false', for example: -noclean</param>
/// <returns>Parameter value or default value if the paramater has not been specified</returns>
bool? GetOptionalParamValueIfNotSpecified(CommandUtils Command, bool? SpecifiedValue, bool? Default, string TrueParam, string FalseParam)
{
if (SpecifiedValue.HasValue)
{
return SpecifiedValue.Value;
}
else if (Command != null)
{
bool? Value = null;
if (!String.IsNullOrEmpty(TrueParam) && Command.ParseParam(TrueParam))
{
Value = true;
}
else if (!String.IsNullOrEmpty(FalseParam) && Command.ParseParam(FalseParam))
{
Value = false;
}
if (Value.HasValue)
{
return Value;
}
}
return Default;
}
/// <summary>
/// Gets a parameter value from the command line if it hasn't been specified in the constructor.
/// If the command line is not available, default value will be used.
/// </summary>
/// <param name="Command">Command to parse the command line for. Can be null.</param>
/// <param name="SpecifiedValue">Value specified in the constructor (or not)</param>
/// <param name="ParamName">Command line parameter name to parse.</param>
/// <param name="Default">Default value</param>
/// <param name="bTrimQuotes">If set, the leading and trailing quotes will be removed, e.g. instead of "/home/User Name" it will return /home/User Name</param>
/// <returns>Parameter value.</returns>
string ParseParamValueIfNotSpecified(CommandUtils Command, string SpecifiedValue, string ParamName, string Default = "", bool bTrimQuotes = false)
{
string Result = Default;
if (SpecifiedValue != null)
{
Result = SpecifiedValue;
}
else if (Command != null)
{
Result = Command.ParseParamValue(ParamName, Default);
}
return bTrimQuotes ? Result.Trim( new char[]{'\"'} ) : Result;
}
/// <summary>
/// Sets up platforms
/// </summary>
/// <param name="DependentPlatformMap">Set with a mapping from source->destination if specified on command line</param>
/// <param name="Command">The command line to parse</param>
/// <param name="OverrideTargetPlatforms">If passed use this always</param>
/// <param name="DefaultTargetPlatforms">Use this if nothing is passed on command line</param>
/// <param name="AllowPlatformParams">Allow raw -platform options</param>
/// <param name="PlatformParamNames">Possible -parameters to check for</param>
/// <returns>List of platforms parsed from the command line</returns>
private List<UnrealTargetPlatform> SetupTargetPlatforms(ref Dictionary<UnrealTargetPlatform,UnrealTargetPlatform> DependentPlatformMap, CommandUtils Command, List<UnrealTargetPlatform> OverrideTargetPlatforms, List<UnrealTargetPlatform> DefaultTargetPlatforms, bool AllowPlatformParams, params string[] PlatformParamNames)
{
List<UnrealTargetPlatform> TargetPlatforms = null;
if (CommandUtils.IsNullOrEmpty(OverrideTargetPlatforms))
{
if (Command != null)
{
// Parse the command line, we support the following params:
// -'PlatformParamNames[n]'=Platform_1+Platform_2+...+Platform_k
// or (if AllowPlatformParams is true)
// -Platform_1 -Platform_2 ... -Platform_k
string CmdLinePlatform = null;
foreach (var ParamName in PlatformParamNames)
{
CmdLinePlatform = Command.ParseParamValue(ParamName);
if (!String.IsNullOrEmpty(CmdLinePlatform))
{
break;
}
}
if (!String.IsNullOrEmpty(CmdLinePlatform))
{
// Get all platforms from the param value: Platform_1+Platform_2+...+Platform_k
TargetPlatforms = new List<UnrealTargetPlatform>();
var Platforms = new List<string>(CmdLinePlatform.Split('+'));
foreach (var PlatformName in Platforms)
{
// Look for dependent platforms, Source_1.Dependent_1+Source_2.Dependent_2+Standalone_3
var SubPlatforms = new List<string>(PlatformName.Split('.'));
foreach (var SubPlatformName in SubPlatforms)
{
UnrealTargetPlatform NewPlatform = (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), SubPlatformName, true);
TargetPlatforms.Add(NewPlatform);
if (SubPlatformName != SubPlatforms[0])
{
// We're a dependent platform so add ourselves to the map, pointing to the first element in the list
DependentPlatformMap.Add(NewPlatform, (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), SubPlatforms[0], true));
}
}
}
}
else if (AllowPlatformParams)
{
// Look up platform names in the command line: -Platform_1 -Platform_2 ... -Platform_k
TargetPlatforms = new List<UnrealTargetPlatform>();
foreach (UnrealTargetPlatform Plat in Enum.GetValues(typeof(UnrealTargetPlatform)))
{
if (Plat != UnrealTargetPlatform.Unknown)
{
if (Command.ParseParam(Plat.ToString()))
{
TargetPlatforms.Add(Plat);
}
}
}
}
}
}
else
{
TargetPlatforms = OverrideTargetPlatforms;
}
if (CommandUtils.IsNullOrEmpty(TargetPlatforms))
{
// Revert to single default platform - the current platform we're running
TargetPlatforms = DefaultTargetPlatforms;
}
return TargetPlatforms;
}
public ProjectParams(ProjectParams InParams)
{
//
//// Use this.Name with properties and fields!
//
this.RawProjectPath = InParams.RawProjectPath;
this.MapsToCook = InParams.MapsToCook;
this.DirectoriesToCook = InParams.DirectoriesToCook;
this.InternationalizationPreset = InParams.InternationalizationPreset;
this.CulturesToCook = InParams.CulturesToCook;
this.BasedOnReleaseVersion = InParams.BasedOnReleaseVersion;
this.CreateReleaseVersion = InParams.CreateReleaseVersion;
this.GeneratePatch = InParams.GeneratePatch;
this.DLCName = InParams.DLCName;
this.DLCIncludeEngineContent = InParams.DLCIncludeEngineContent;
this.DiffCookedContentPath = InParams.DiffCookedContentPath;
this.NewCook = InParams.NewCook;
this.OldCook = InParams.OldCook;
this.AdditionalCookerOptions = InParams.AdditionalCookerOptions;
this.ClientCookedTargets = InParams.ClientCookedTargets;
this.ServerCookedTargets = InParams.ServerCookedTargets;
this.EditorTargets = InParams.EditorTargets;
this.ProgramTargets = InParams.ProgramTargets;
this.ClientTargetPlatforms = InParams.ClientTargetPlatforms;
this.ClientDependentPlatformMap = InParams.ClientDependentPlatformMap;
this.ServerTargetPlatforms = InParams.ServerTargetPlatforms;
this.ServerDependentPlatformMap = InParams.ServerDependentPlatformMap;
this.Build = InParams.Build;
this.Run = InParams.Run;
this.Cook = InParams.Cook;
this.IterativeCooking = InParams.IterativeCooking;
this.CookAll = InParams.CookAll;
this.CookMapsOnly = InParams.CookMapsOnly;
this.CookFlavor = InParams.CookFlavor;
this.SkipCook = InParams.SkipCook;
this.SkipCookOnTheFly = InParams.SkipCookOnTheFly;
this.Prebuilt = InParams.Prebuilt;
this.RunTimeoutSeconds = InParams.RunTimeoutSeconds;
this.Clean = InParams.Clean;
this.Pak = InParams.Pak;
this.SignPak = InParams.SignPak;
this.SignedPak = InParams.SignedPak;
this.SkipPak = InParams.SkipPak;
this.NoXGE = InParams.NoXGE;
this.CookOnTheFly = InParams.CookOnTheFly;
this.CookOnTheFlyStreaming = InParams.CookOnTheFlyStreaming;
this.UnversionedCookedContent = InParams.UnversionedCookedContent;
this.SkipCookingEditorContent = InParams.SkipCookingEditorContent;
this.NumCookersToSpawn = InParams.NumCookersToSpawn;
this.FileServer = InParams.FileServer;
this.DedicatedServer = InParams.DedicatedServer;
this.Client = InParams.Client;
this.NoClient = InParams.NoClient;
this.LogWindow = InParams.LogWindow;
this.Stage = InParams.Stage;
this.SkipStage = InParams.SkipStage;
this.StageDirectoryParam = InParams.StageDirectoryParam;
this.Manifests = InParams.Manifests;
this.CreateChunkInstall = InParams.CreateChunkInstall;
this.UE4Exe = InParams.UE4Exe;
this.NoDebugInfo = InParams.NoDebugInfo;
this.NoCleanStage = InParams.NoCleanStage;
this.MapToRun = InParams.MapToRun;
this.AdditionalServerMapParams = InParams.AdditionalServerMapParams;
this.Foreign = InParams.Foreign;
this.ForeignCode = InParams.ForeignCode;
this.StageCommandline = InParams.StageCommandline;
this.BundleName = InParams.BundleName;
this.RunCommandline = InParams.RunCommandline;
this.Package = InParams.Package;
this.Deploy = InParams.Deploy;
this.IterativeDeploy = InParams.IterativeDeploy;
this.IgnoreCookErrors = InParams.IgnoreCookErrors;
this.FastCook = InParams.FastCook;
this.Device = InParams.Device;
this.DeviceName = InParams.DeviceName;
this.ServerDevice = InParams.ServerDevice;
this.NullRHI = InParams.NullRHI;
this.FakeClient = InParams.FakeClient;
this.EditorTest = InParams.EditorTest;
this.RunAutomationTests = InParams.RunAutomationTests;
this.RunAutomationTest = InParams.RunAutomationTest;
this.CrashIndex = InParams.CrashIndex;
this.Port = InParams.Port;
this.SkipServer = InParams.SkipServer;
this.Unattended = InParams.Unattended;
this.ServerDeviceAddress = InParams.ServerDeviceAddress;
this.DeviceUsername = InParams.DeviceUsername;
this.DevicePassword = InParams.DevicePassword;
this.CrashReporter = InParams.CrashReporter;
this.ClientConfigsToBuild = InParams.ClientConfigsToBuild;
this.ServerConfigsToBuild = InParams.ServerConfigsToBuild;
this.NumClients = InParams.NumClients;
this.Compressed = InParams.Compressed;
this.UseDebugParamForEditorExe = InParams.UseDebugParamForEditorExe;
this.bUsesSteam = InParams.bUsesSteam;
this.bUsesCEF3 = InParams.bUsesCEF3;
this.bUsesSlate = InParams.bUsesSlate;
this.bUsesSlateEditorStyle = InParams.bUsesSlateEditorStyle;
this.bDebugBuildsActuallyUseDebugCRT = InParams.bDebugBuildsActuallyUseDebugCRT;
this.Archive = InParams.Archive;
this.ArchiveDirectoryParam = InParams.ArchiveDirectoryParam;
this.ArchiveMetaData = InParams.ArchiveMetaData;
this.CreateAppBundle = InParams.CreateAppBundle;
this.Distribution = InParams.Distribution;
this.Prereqs = InParams.Prereqs;
this.NoBootstrapExe = InParams.NoBootstrapExe;
this.Prebuilt = InParams.Prebuilt;
this.RunTimeoutSeconds = InParams.RunTimeoutSeconds;
this.bIsCodeBasedProject = InParams.bIsCodeBasedProject;
this.bCodeSign = InParams.bCodeSign;
this.UploadSymbols = InParams.UploadSymbols;
this.TitleID = InParams.TitleID;
this.bTreatNonShippingBinariesAsDebugFiles = InParams.bTreatNonShippingBinariesAsDebugFiles;
this.RunAssetNativization = InParams.RunAssetNativization;
}
/// <summary>
/// Constructor. Be sure to use this.ParamName to set the actual property name as parameter names and property names
/// overlap here.
/// If a parameter value is not set, it will be parsed from the command line; if the command is null, the default value will be used.
/// </summary>
public ProjectParams(
FileReference RawProjectPath,
CommandUtils Command = null,
string Device = null,
string MapToRun = null,
string AdditionalServerMapParams = null,
ParamList<string> Port = null,
string RunCommandline = null,
string StageCommandline = null,
string BundleName = null,
string StageDirectoryParam = null,
string UE4Exe = null,
string SignPak = null,
List<UnrealTargetConfiguration> ClientConfigsToBuild = null,
List<UnrealTargetConfiguration> ServerConfigsToBuild = null,
ParamList<string> MapsToCook = null,
ParamList<string> DirectoriesToCook = null,
string InternationalizationPreset = null,
ParamList<string> CulturesToCook = null,
ParamList<string> ClientCookedTargets = null,
ParamList<string> EditorTargets = null,
ParamList<string> ServerCookedTargets = null,
List<UnrealTargetPlatform> ClientTargetPlatforms = null,
Dictionary<UnrealTargetPlatform, UnrealTargetPlatform> ClientDependentPlatformMap = null,
List<UnrealTargetPlatform> ServerTargetPlatforms = null,
Dictionary<UnrealTargetPlatform, UnrealTargetPlatform> ServerDependentPlatformMap = null,
bool? Build = null,
bool? Cook = null,
string CookFlavor = null,
bool? Run = null,
bool? SkipServer = null,
bool? Clean = null,
bool? Compressed = null,
bool? UseDebugParamForEditorExe = null,
bool? IterativeCooking = null,
bool? CookAll = null,
bool? CookMapsOnly = null,
bool? CookOnTheFly = null,
bool? CookOnTheFlyStreaming = null,
bool? UnversionedCookedContent = null,
bool? SkipCookingEditorContent = null,
int? NumCookersToSpawn = null,
string AdditionalCookerOptions = null,
string BasedOnReleaseVersion = null,
string CreateReleaseVersion = null,
string CreateReleaseVersionBasePath = null,
string BasedOnReleaseVersionBasePath = null,
bool? GeneratePatch = null,
string DLCName = null,
string DiffCookedContentPath = null,
bool? DLCIncludeEngineContent = null,
bool? NewCook = null,
bool? OldCook = null,
bool? CrashReporter = null,
bool? DedicatedServer = null,
bool? Client = null,
bool? Deploy = null,
bool? FileServer = null,
bool? Foreign = null,
bool? ForeignCode = null,
bool? LogWindow = null,
bool? NoCleanStage = null,
bool? NoClient = null,
bool? NoDebugInfo = null,
bool? NoXGE = null,
bool? Package = null,
bool? Pak = null,
bool? Prereqs = null,
bool? NoBootstrapExe = null,
bool? SignedPak = null,
bool? NullRHI = null,
bool? FakeClient = null,
bool? EditorTest = null,
bool? RunAutomationTests = null,
string RunAutomationTest = null,
int? CrashIndex = null,
bool? SkipCook = null,
bool? SkipCookOnTheFly = null,
bool? SkipPak = null,
bool? SkipStage = null,
bool? Stage = null,
bool? Manifests = null,
bool? CreateChunkInstall = null,
bool? Unattended = null,
int? NumClients = null,
bool? Archive = null,
string ArchiveDirectoryParam = null,
bool? ArchiveMetaData = null,
bool? CreateAppBundle = null,
ParamList<string> ProgramTargets = null,
bool? Distribution = null,
bool? Prebuilt = null,
int? RunTimeoutSeconds = null,
string SpecifiedArchitecture = null,
bool? IterativeDeploy = null,
bool? FastCook = null,
bool? IgnoreCookErrors = null,
bool? RunAssetNativization = null,
bool? CodeSign = null,
bool? TreatNonShippingBinariesAsDebugFiles = null,
bool? UploadSymbols = null,
string Provision = null,
string Certificate = null,
ParamList<string> InMapsToRebuildLightMaps = null,
ParamList<string> TitleID = null
)
{
//
//// Use this.Name with properties and fields!
//
this.RawProjectPath = RawProjectPath;
if (DirectoriesToCook != null)
{
this.DirectoriesToCook = DirectoriesToCook;
}
this.InternationalizationPreset = ParseParamValueIfNotSpecified(Command, InternationalizationPreset, "i18npreset");
// If not specified in parameters, check commandline.
if (CulturesToCook == null)
{
if (Command != null)
{
var CookCulturesString = Command.ParseParamValue("CookCultures");
if (CookCulturesString != null)
{
this.CulturesToCook = new ParamList<string>(CookCulturesString.Split(','));
}
}
}
else
{
this.CulturesToCook = CulturesToCook;
}
if (ClientCookedTargets != null)
{
this.ClientCookedTargets = ClientCookedTargets;
}
if (ServerCookedTargets != null)
{
this.ServerCookedTargets = ServerCookedTargets;
}
if (EditorTargets != null)
{
this.EditorTargets = EditorTargets;
}
if (ProgramTargets != null)
{
this.ProgramTargets = ProgramTargets;
}
// Parse command line params for client platforms "-TargetPlatform=Win64+Mac", "-Platform=Win64+Mac" and also "-Win64", "-Mac" etc.
if (ClientDependentPlatformMap != null)
{
this.ClientDependentPlatformMap = ClientDependentPlatformMap;
}
this.ClientTargetPlatforms = SetupTargetPlatforms(ref this.ClientDependentPlatformMap, Command, ClientTargetPlatforms, new ParamList<UnrealTargetPlatform>() { HostPlatform.Current.HostEditorPlatform }, true, "TargetPlatform", "Platform");
// Parse command line params for server platforms "-ServerTargetPlatform=Win64+Mac", "-ServerPlatform=Win64+Mac". "-Win64" etc is not allowed here
if (ServerDependentPlatformMap != null)
{
this.ServerDependentPlatformMap = ServerDependentPlatformMap;
}
this.ServerTargetPlatforms = SetupTargetPlatforms(ref this.ServerDependentPlatformMap, Command, ServerTargetPlatforms, this.ClientTargetPlatforms, false, "ServerTargetPlatform", "ServerPlatform");
this.Build = GetParamValueIfNotSpecified(Command, Build, this.Build, "build");
this.Run = GetParamValueIfNotSpecified(Command, Run, this.Run, "run");
this.Cook = GetParamValueIfNotSpecified(Command, Cook, this.Cook, "cook");
this.CookFlavor = ParseParamValueIfNotSpecified(Command, CookFlavor, "cookflavor", String.Empty);
this.NewCook = GetParamValueIfNotSpecified(Command, NewCook, this.NewCook, "NewCook");
this.OldCook = GetParamValueIfNotSpecified(Command, OldCook, this.OldCook, "OldCook");
this.CreateReleaseVersionBasePath = ParseParamValueIfNotSpecified(Command, CreateReleaseVersionBasePath, "createreleaseversionroot", String.Empty);
this.BasedOnReleaseVersionBasePath = ParseParamValueIfNotSpecified(Command, BasedOnReleaseVersionBasePath, "basedonreleaseversionroot", String.Empty);
this.CreateReleaseVersion = ParseParamValueIfNotSpecified(Command, CreateReleaseVersion, "createreleaseversion", String.Empty);
this.BasedOnReleaseVersion = ParseParamValueIfNotSpecified(Command, BasedOnReleaseVersion, "basedonreleaseversion", String.Empty);
this.GeneratePatch = GetParamValueIfNotSpecified(Command, GeneratePatch, this.GeneratePatch, "GeneratePatch");
this.AdditionalCookerOptions = ParseParamValueIfNotSpecified(Command, AdditionalCookerOptions, "AdditionalCookerOptions", String.Empty);
this.DLCName = ParseParamValueIfNotSpecified(Command, DLCName, "DLCName", String.Empty);
this.DiffCookedContentPath = ParseParamValueIfNotSpecified(Command, DiffCookedContentPath, "DiffCookedContentPath", String.Empty);
this.DLCIncludeEngineContent = GetParamValueIfNotSpecified(Command, DLCIncludeEngineContent, this.DLCIncludeEngineContent, "DLCIncludeEngineContent");
this.SkipCook = GetParamValueIfNotSpecified(Command, SkipCook, this.SkipCook, "skipcook");
if (this.SkipCook)
{
this.Cook = true;
}
this.Clean = GetOptionalParamValueIfNotSpecified(Command, Clean, this.Clean, "clean", null);
this.SignPak = ParseParamValueIfNotSpecified(Command, SignPak, "signpak", String.Empty);
this.SignedPak = !String.IsNullOrEmpty(this.SignPak) || GetParamValueIfNotSpecified(Command, SignedPak, this.SignedPak, "signedpak");
if (string.IsNullOrEmpty(this.SignPak))
{
this.SignPak = Path.Combine(RawProjectPath.Directory.FullName, @"Build\NoRedist\Keys.txt");
if (!File.Exists(this.SignPak))
{
this.SignPak = null;
}
}
this.Pak = GetParamValueIfNotSpecified(Command, Pak, this.Pak, "pak");
this.SkipPak = GetParamValueIfNotSpecified(Command, SkipPak, this.SkipPak, "skippak");
if (this.SkipPak)
{
this.Pak = true;
}
this.NoXGE = GetParamValueIfNotSpecified(Command, NoXGE, this.NoXGE, "noxge");
this.CookOnTheFly = GetParamValueIfNotSpecified(Command, CookOnTheFly, this.CookOnTheFly, "cookonthefly");
if (this.CookOnTheFly && this.SkipCook)
{
this.Cook = false;
}
this.CookOnTheFlyStreaming = GetParamValueIfNotSpecified(Command, CookOnTheFlyStreaming, this.CookOnTheFlyStreaming, "cookontheflystreaming");
this.UnversionedCookedContent = GetParamValueIfNotSpecified(Command, UnversionedCookedContent, this.UnversionedCookedContent, "UnversionedCookedContent");
this.SkipCookingEditorContent = GetParamValueIfNotSpecified(Command, SkipCookingEditorContent, this.SkipCookingEditorContent, "SkipCookingEditorContent");
if (NumCookersToSpawn.HasValue)
{
this.NumCookersToSpawn = NumCookersToSpawn.Value;
}
else if (Command != null)
{
this.NumCookersToSpawn = Command.ParseParamInt("NumCookersToSpawn");
}
this.Compressed = GetParamValueIfNotSpecified(Command, Compressed, this.Compressed, "compressed");
this.UseDebugParamForEditorExe = GetParamValueIfNotSpecified(Command, UseDebugParamForEditorExe, this.UseDebugParamForEditorExe, "UseDebugParamForEditorExe");
this.IterativeCooking = GetParamValueIfNotSpecified(Command, IterativeCooking, this.IterativeCooking, new string[] { "iterativecooking", "iterate" } );
this.SkipCookOnTheFly = GetParamValueIfNotSpecified(Command, SkipCookOnTheFly, this.SkipCookOnTheFly, "skipcookonthefly");
this.CookAll = GetParamValueIfNotSpecified(Command, CookAll, this.CookAll, "CookAll");
this.CookMapsOnly = GetParamValueIfNotSpecified(Command, CookMapsOnly, this.CookMapsOnly, "CookMapsOnly");
this.FileServer = GetParamValueIfNotSpecified(Command, FileServer, this.FileServer, "fileserver");
this.DedicatedServer = GetParamValueIfNotSpecified(Command, DedicatedServer, this.DedicatedServer, "dedicatedserver", "server");
this.Client = GetParamValueIfNotSpecified(Command, Client, this.Client, "client");
/*if( this.Client )
{
this.DedicatedServer = true;
}*/
this.NoClient = GetParamValueIfNotSpecified(Command, NoClient, this.NoClient, "noclient");
this.LogWindow = GetParamValueIfNotSpecified(Command, LogWindow, this.LogWindow, "logwindow");
this.Stage = GetParamValueIfNotSpecified(Command, Stage, this.Stage, "stage");
this.SkipStage = GetParamValueIfNotSpecified(Command, SkipStage, this.SkipStage, "skipstage");
if (this.SkipStage)
{
this.Stage = true;
}
this.StageDirectoryParam = ParseParamValueIfNotSpecified(Command, StageDirectoryParam, "stagingdirectory", String.Empty, true);
this.bCodeSign = GetParamValueIfNotSpecified(Command, CodeSign, CommandUtils.IsBuildMachine, "CodeSign");
this.bTreatNonShippingBinariesAsDebugFiles = GetParamValueIfNotSpecified(Command, TreatNonShippingBinariesAsDebugFiles, false, "TreatNonShippingBinariesAsDebugFiles");
this.Manifests = GetParamValueIfNotSpecified(Command, Manifests, this.Manifests, "manifests");
this.CreateChunkInstall = GetParamValueIfNotSpecified(Command, CreateChunkInstall, this.CreateChunkInstall, "createchunkinstall");
this.ChunkInstallDirectory = ParseParamValueIfNotSpecified(Command, ChunkInstallDirectory, "chunkinstalldirectory", String.Empty, true);
this.ChunkInstallVersionString = ParseParamValueIfNotSpecified(Command, ChunkInstallVersionString, "chunkinstallversion", String.Empty, true);
this.Archive = GetParamValueIfNotSpecified(Command, Archive, this.Archive, "archive");
this.ArchiveDirectoryParam = ParseParamValueIfNotSpecified(Command, ArchiveDirectoryParam, "archivedirectory", String.Empty, true);
this.ArchiveMetaData = GetParamValueIfNotSpecified(Command, ArchiveMetaData, this.ArchiveMetaData, "archivemetadata");
this.CreateAppBundle = GetParamValueIfNotSpecified(Command, CreateAppBundle, true, "createappbundle");
this.Distribution = GetParamValueIfNotSpecified(Command, Distribution, this.Distribution, "distribution");
this.Prereqs = GetParamValueIfNotSpecified(Command, Prereqs, this.Prereqs, "prereqs");
this.NoBootstrapExe = GetParamValueIfNotSpecified(Command, NoBootstrapExe, this.NoBootstrapExe, "nobootstrapexe");
this.Prebuilt = GetParamValueIfNotSpecified(Command, Prebuilt, this.Prebuilt, "prebuilt");
if (this.Prebuilt)
{
this.SkipCook = true;
/*this.SkipPak = true;
this.SkipStage = true;
this.Pak = true;
this.Stage = true;*/
this.Cook = true;
this.Archive = true;
this.Deploy = true;
this.Run = true;
//this.StageDirectoryParam = this.PrebuiltDir;
}
this.NoDebugInfo = GetParamValueIfNotSpecified(Command, NoDebugInfo, this.NoDebugInfo, "nodebuginfo");
this.NoCleanStage = GetParamValueIfNotSpecified(Command, NoCleanStage, this.NoCleanStage, "nocleanstage");
this.MapToRun = ParseParamValueIfNotSpecified(Command, MapToRun, "map", String.Empty);
this.AdditionalServerMapParams = ParseParamValueIfNotSpecified(Command, AdditionalServerMapParams, "AdditionalServerMapParams", String.Empty);
this.Foreign = GetParamValueIfNotSpecified(Command, Foreign, this.Foreign, "foreign");
this.ForeignCode = GetParamValueIfNotSpecified(Command, ForeignCode, this.ForeignCode, "foreigncode");
this.StageCommandline = ParseParamValueIfNotSpecified(Command, StageCommandline, "cmdline");
this.BundleName = ParseParamValueIfNotSpecified(Command, BundleName, "bundlename");
this.RunCommandline = ParseParamValueIfNotSpecified(Command, RunCommandline, "addcmdline");
this.RunCommandline = this.RunCommandline.Replace('\'', '\"'); // replace any single quotes with double quotes
this.Package = GetParamValueIfNotSpecified(Command, Package, this.Package, "package");
this.Deploy = GetParamValueIfNotSpecified(Command, Deploy, this.Deploy, "deploy");
this.IterativeDeploy = GetParamValueIfNotSpecified(Command, IterativeDeploy, this.IterativeDeploy, new string[] {"iterativedeploy", "iterate" } );
this.FastCook = GetParamValueIfNotSpecified(Command, FastCook, this.FastCook, "FastCook");
this.IgnoreCookErrors = GetParamValueIfNotSpecified(Command, IgnoreCookErrors, this.IgnoreCookErrors, "IgnoreCookErrors");
this.RunAssetNativization = GetParamValueIfNotSpecified(Command, RunAssetNativization, this.RunAssetNativization, "nativizeAssets");
this.UploadSymbols = GetParamValueIfNotSpecified(Command, UploadSymbols, this.UploadSymbols, "uploadsymbols");
this.Device = ParseParamValueIfNotSpecified(Command, Device, "device", String.Empty).Trim(new char[] { '\"' });
// strip the platform prefix the specified device.
if (this.Device.Contains("@"))
{
this.DeviceName = this.Device.Substring(this.Device.IndexOf("@") + 1);
}
else
{
this.DeviceName = this.Device;
}
this.Provision = ParseParamValueIfNotSpecified(Command, Provision, "provision", String.Empty, true);
this.Certificate = ParseParamValueIfNotSpecified(Command, Certificate, "certificate", String.Empty, true);
this.ServerDevice = ParseParamValueIfNotSpecified(Command, ServerDevice, "serverdevice", this.Device);
this.NullRHI = GetParamValueIfNotSpecified(Command, NullRHI, this.NullRHI, "nullrhi");
this.FakeClient = GetParamValueIfNotSpecified(Command, FakeClient, this.FakeClient, "fakeclient");
this.EditorTest = GetParamValueIfNotSpecified(Command, EditorTest, this.EditorTest, "editortest");
this.RunAutomationTest = ParseParamValueIfNotSpecified(Command, RunAutomationTest, "RunAutomationTest");
this.RunAutomationTests = this.RunAutomationTest != "" || GetParamValueIfNotSpecified(Command, RunAutomationTests, this.RunAutomationTests, "RunAutomationTests");
this.SkipServer = GetParamValueIfNotSpecified(Command, SkipServer, this.SkipServer, "skipserver");
this.UE4Exe = ParseParamValueIfNotSpecified(Command, UE4Exe, "ue4exe", "UE4Editor-Cmd.exe");
this.Unattended = GetParamValueIfNotSpecified(Command, Unattended, this.Unattended, "unattended");
this.DeviceUsername = ParseParamValueIfNotSpecified(Command, DeviceUsername, "deviceuser", String.Empty);
this.DevicePassword = ParseParamValueIfNotSpecified(Command, DevicePassword, "devicepass", String.Empty);
this.CrashReporter = GetParamValueIfNotSpecified(Command, CrashReporter, this.CrashReporter, "crashreporter");
this.SpecifiedArchitecture = ParseParamValueIfNotSpecified(Command, SpecifiedArchitecture, "specifiedarchitecture", String.Empty);
if (ClientConfigsToBuild == null)
{
if (Command != null)
{
var ClientConfig = Command.ParseParamValue("clientconfig");
if (ClientConfig != null)
{
this.ClientConfigsToBuild = new List<UnrealTargetConfiguration>();
var Configs = new ParamList<string>(ClientConfig.Split('+'));
foreach (var ConfigName in Configs)
{
this.ClientConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
}
}
}
}
else
{
this.ClientConfigsToBuild = ClientConfigsToBuild;
}
if (Port == null)
{
if( Command != null )
{
this.Port = new ParamList<string>();
var PortString = Command.ParseParamValue("port");
if (String.IsNullOrEmpty(PortString) == false)
{
var Ports = new ParamList<string>(PortString.Split('+'));
foreach (var P in Ports)
{
this.Port.Add(P);
}
}
}
}
else
{
this.Port = Port;
}
if (MapsToCook == null)
{
if (Command != null)
{
this.MapsToCook = new ParamList<string>();
var MapsString = Command.ParseParamValue("MapsToCook");
if (String.IsNullOrEmpty(MapsString) == false)
{
var MapNames = new ParamList<string>(MapsString.Split('+'));
foreach ( var M in MapNames )
{
this.MapsToCook.Add( M );
}
}
}
}
else
{
this.MapsToCook = MapsToCook;
}
if (String.IsNullOrEmpty(this.MapToRun) == false)
{
this.MapsToCook.Add(this.MapToRun);
}
if (InMapsToRebuildLightMaps == null)
{
if (Command != null)
{
this.MapsToRebuildLightMaps = new ParamList<string>();
var MapsString = Command.ParseParamValue("MapsToRebuildLightMaps");
if (String.IsNullOrEmpty(MapsString) == false)
{
var MapNames = new ParamList<string>(MapsString.Split('+'));
foreach (var M in MapNames)
{
this.MapsToRebuildLightMaps.Add(M);
}
}
}
}
else
{
this.MapsToRebuildLightMaps = InMapsToRebuildLightMaps;
}
if (TitleID == null)
{
if (Command != null)
{
this.TitleID = new ParamList<string>();
var TitleString = Command.ParseParamValue("TitleID");
if (String.IsNullOrEmpty(TitleString) == false)
{
var TitleIDs = new ParamList<string>(TitleString.Split('+'));
foreach (var T in TitleIDs)
{
this.TitleID.Add(T);
}
}
}
}
else
{
this.TitleID = TitleID;
}
if (ServerConfigsToBuild == null)
{
if (Command != null)
{
var ServerConfig = Command.ParseParamValue("serverconfig");
if (ServerConfig != null && ServerConfigsToBuild == null)
{
this.ServerConfigsToBuild = new List<UnrealTargetConfiguration>();
var Configs = new ParamList<string>(ServerConfig.Split('+'));
foreach (var ConfigName in Configs)
{
this.ServerConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
}
}
}
}
else
{
this.ServerConfigsToBuild = ServerConfigsToBuild;
}
if (NumClients.HasValue)
{
this.NumClients = NumClients.Value;
}
else if (Command != null)
{
this.NumClients = Command.ParseParamInt("numclients");
}
if (CrashIndex.HasValue)
{
this.CrashIndex = CrashIndex.Value;
}
else if (Command != null)
{
this.CrashIndex = Command.ParseParamInt("CrashIndex");
}
if (RunTimeoutSeconds.HasValue)
{
this.RunTimeoutSeconds = RunTimeoutSeconds.Value;
}
else if (Command != null)
{
this.RunTimeoutSeconds = Command.ParseParamInt("runtimeoutseconds");
}
AutodetectSettings(false);
ValidateAndLog();
}
#endregion
#region Shared
/// <summary>
/// Shared: Full path to the .uproject file
/// </summary>
public FileReference RawProjectPath { private set; get; }
/// <summary>
/// Shared: The current project is a foreign project, commandline: -foreign
/// </summary>
[Help("foreign", "Generate a foreign uproject from blankproject and use that")]
public bool Foreign { private set; get; }
/// <summary>
/// Shared: The current project is a foreign project, commandline: -foreign
/// </summary>
[Help("foreigncode", "Generate a foreign code uproject from platformergame and use that")]
public bool ForeignCode { private set; get; }
/// <summary>
/// Shared: true if we should build crash reporter
/// </summary>
[Help("CrashReporter", "true if we should build crash reporter")]
public bool CrashReporter { private set; get; }
/// <summary>
/// Shared: Determines if the build is going to use cooked data, commandline: -cook, -cookonthefly
/// </summary>
[Help("cook, -cookonthefly", "Determines if the build is going to use cooked data")]
public bool Cook { private set; get; }
/// <summary>
/// Shared: Determines if the build is going to use special sub-target platform, commandline: -cookflavor=ATC
/// </summary>
[Help( "cookflavor", "Determines if the build is going to use special sub-target platform" )]
public string CookFlavor { private set; get; }
/// <summary>
/// Shared: Determines if the build is going to use cooked data, commandline: -cook, -cookonthefly
/// </summary>
[Help("skipcook", "use a cooked build, but we assume the cooked data is up to date and where it belongs, implies -cook")]
public bool SkipCook { private set; get; }
/// <summary>
/// Shared: In a cookonthefly build, used solely to pass information to the package step. This is necessary because you can't set cookonthefly and cook at the same time, and skipcook sets cook.
/// </summary>
[Help("skipcookonthefly", "in a cookonthefly build, used solely to pass information to the package step")]
public bool SkipCookOnTheFly { private set; get; }
/// <summary>
/// Shared: Determines if the intermediate folders will be wiped before building, commandline: -clean
/// </summary>
[Help("clean", "wipe intermediate folders before building")]
public bool? Clean { private set; get; }
/// <summary>
/// Shared: Assumes no user is sitting at the console, so for example kills clients automatically, commandline: -Unattended
/// </summary>
[Help("unattended", "assumes no operator is present, always terminates without waiting for something.")]
public bool Unattended { private set; get; }
/// <summary>
/// Shared: Sets platforms to build for non-dedicated servers. commandline: -TargetPlatform
/// </summary>
public List<UnrealTargetPlatform> ClientTargetPlatforms = new List<UnrealTargetPlatform>();
/// <summary>
/// Shared: Dictionary that maps client dependent platforms to "source" platforms that it should copy data from. commandline: -TargetPlatform=source.dependent
/// </summary>
public Dictionary<UnrealTargetPlatform, UnrealTargetPlatform> ClientDependentPlatformMap = new Dictionary<UnrealTargetPlatform, UnrealTargetPlatform>();
/// <summary>
/// Shared: Sets platforms to build for dedicated servers. commandline: -ServerTargetPlatform
/// </summary>
public List<UnrealTargetPlatform> ServerTargetPlatforms = new List<UnrealTargetPlatform>();
/// <summary>
/// Shared: Dictionary that maps server dependent platforms to "source" platforms that it should copy data from: -ServerTargetPlatform=source.dependent
/// </summary>
public Dictionary<UnrealTargetPlatform, UnrealTargetPlatform> ServerDependentPlatformMap = new Dictionary<UnrealTargetPlatform, UnrealTargetPlatform>();
/// <summary>
/// Shared: True if pak file should be generated.
/// </summary>
[Help("pak", "generate a pak file")]
public bool Pak { private set; get; }
/// <summary>
///
/// </summary>
public bool UsePak(Platform PlatformToCheck)
{
return Pak || PlatformToCheck.RequiresPak(this) == Platform.PakType.Always;
}
private string SignPakInternal { get; set; }
/// <summary>
/// Shared: Encryption keys used for signing the pak file.
/// </summary>
[Help("signpak=keys", "sign the generated pak file with the specified key, i.e. -signpak=C:\\Encryption.keys. Also implies -signedpak.")]
public string SignPak
{
private set
{
if (string.IsNullOrEmpty(value) || value.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
{
SignPakInternal = value;
}
else
{
SignPakInternal = Path.GetFullPath(value);
}
}
get
{
return SignPakInternal;
}
}
/// <summary>
/// Shared: the game will use only signed content.
/// </summary>
[Help("signed", "the game should expect to use a signed pak file.")]
public bool SignedPak { private set; get; }
/// <summary>
/// Shared: true if this build is staged, command line: -stage
/// </summary>
[Help("skippak", "use a pak file, but assume it is already built, implies pak")]
public bool SkipPak { private set; get; }
/// <summary>
/// Shared: true if this build is staged, command line: -stage
/// </summary>
[Help("stage", "put this build in a stage directory")]
public bool Stage { private set; get; }
/// <summary>
/// Shared: true if this build is staged, command line: -stage
/// </summary>
[Help("skipstage", "uses a stage directory, but assumes everything is already there, implies -stage")]
public bool SkipStage { private set; get; }
/// <summary>
/// Shared: true if this build is using streaming install manifests, command line: -manifests
/// </summary>
[Help("manifests", "generate streaming install manifests when cooking data")]
public bool Manifests { private set; get; }
/// <summary>
/// Shared: true if this build chunk install streaming install data, command line: -createchunkinstalldata
/// </summary>
[Help("createchunkinstall", "generate streaming install data from manifest when cooking data, requires -stage & -manifests")]
public bool CreateChunkInstall { private set; get; }
/// <summary>
/// Shared: Directory to use for built chunk install data, command line: -chunkinstalldirectory=
/// </summary>
public string ChunkInstallDirectory { set; get; }
/// <summary>
/// Shared: Version string to use for built chunk install data, command line: -chunkinstallversion=
/// </summary>
public string ChunkInstallVersionString { set; get; }
/// <summary>
/// Shared: Directory to copy the client to, command line: -stagingdirectory=
/// </summary>
public string BaseStageDirectory
{
get
{
if( !String.IsNullOrEmpty(StageDirectoryParam ) )
{
return Path.GetFullPath( StageDirectoryParam );
}
if ( HasDLCName )
{
return Path.GetFullPath( CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Plugins", DLCName, "Saved", "StagedBuilds" ) );
}
// default return the project saved\stagedbuilds directory
return Path.GetFullPath( CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Saved", "StagedBuilds") );
}
}
[Help("stagingdirectory=Path", "Directory to copy the builds to, i.e. -stagingdirectory=C:\\Stage")]
public string StageDirectoryParam;
[Help("ue4exe=ExecutableName", "Name of the UE4 Editor executable, i.e. -ue4exe=UE4Editor.exe")]
public string UE4Exe;
/// <summary>
/// Shared: true if this build is archived, command line: -archive
/// </summary>
[Help("archive", "put this build in an archive directory")]
public bool Archive { private set; get; }
/// <summary>
/// Shared: Directory to archive the client to, command line: -archivedirectory=
/// </summary>
public string BaseArchiveDirectory
{
get
{
return Path.GetFullPath(String.IsNullOrEmpty(ArchiveDirectoryParam) ? CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "ArchivedBuilds") : ArchiveDirectoryParam);
}
}
[Help("archivedirectory=Path", "Directory to archive the builds to, i.e. -archivedirectory=C:\\Archive")]
public string ArchiveDirectoryParam;
/// <summary>
/// Whether the project should use non monolithic staging
/// </summary>
[Help("archivemetadata", "Archive extra metadata files in addition to the build (e.g. build.properties)")]
public bool ArchiveMetaData;
/// <summary>
/// When archiving for Mac, set this to true to package it in a .app bundle instead of normal loose files
/// </summary>
[Help("createappbundle", "When archiving for Mac, set this to true to package it in a .app bundle instead of normal loose files")]
public bool CreateAppBundle;
/// <summary>
/// Determines if Blueprint assets should be substituted with auto-generated code.
/// </summary>
[Help("nativizeAssets", "Runs a \"nativization\" pass on Blueprint assets, converting then into C++ (replacing the assets with the generated source).")]
public bool RunAssetNativization;
/// <summary>
/// Shared: Ref to an auto-generated plugin file that should be incorporated into the project's build
/// </summary>
public List<FileReference> BlueprintPluginPaths = new List<FileReference>();
#endregion
#region Build
/// <summary>
/// Build: True if build step should be executed, command: -build
/// </summary>
[Help("build", "True if build step should be executed")]
public bool Build { private set; get; }
/// <summary>
/// Build: True if XGE should NOT be used for building.
/// </summary>
[Help("noxge", "True if XGE should NOT be used for building")]
public bool NoXGE { private set; get; }
/// <summary>
/// Build: List of maps to cook.
/// </summary>
private ParamList<string> EditorTargetsList = null;
public ParamList<string> EditorTargets
{
set { EditorTargetsList = value; }
get
{
if (EditorTargetsList == null)
{
// Lazy auto-initialization
AutodetectSettings(false);
}
return EditorTargetsList;
}
}
/// <summary>
/// Build: List of maps to cook.
/// </summary>
private ParamList<string> ProgramTargetsList = null;
public ParamList<string> ProgramTargets
{
set { ProgramTargetsList = value; }
get
{
if (ProgramTargetsList == null)
{
// Lazy auto-initialization
AutodetectSettings(false);
}
return ProgramTargetsList;
}
}
/// <summary>
/// Build: List of client configurations
/// </summary>
public List<UnrealTargetConfiguration> ClientConfigsToBuild = new List<UnrealTargetConfiguration>() { UnrealTargetConfiguration.Development };
///<summary>
/// Build: List of Server configurations
/// </summary>
public List<UnrealTargetConfiguration> ServerConfigsToBuild = new List<UnrealTargetConfiguration>() { UnrealTargetConfiguration.Development };
/// <summary>
/// Build: List of client cooked build targets.
/// </summary>
private ParamList<string> ClientCookedTargetsList = null;
public ParamList<string> ClientCookedTargets
{
set { ClientCookedTargetsList = value; }
get
{
if (ClientCookedTargetsList == null)
{
// Lazy auto-initialization
AutodetectSettings(false);
}
return ClientCookedTargetsList;
}
}
/// <summary>
/// Build: List of Server cooked build targets.
/// </summary>
private ParamList<string> ServerCookedTargetsList = null;
public ParamList<string> ServerCookedTargets
{
set { ServerCookedTargetsList = value; }
get
{
if (ServerCookedTargetsList == null)
{
// Lazy auto-initialization
AutodetectSettings(false);
}
return ServerCookedTargetsList;
}
}
#endregion
#region Cook
/// <summary>
/// Cook: List of maps to cook.
/// </summary>
public ParamList<string> MapsToCook = new ParamList<string>();
/// <summary>
/// Cook: List of directories to cook.
/// </summary>
public ParamList<string> DirectoriesToCook = new ParamList<string>();
/// <summary>
/// Cook: Internationalization preset to cook.
/// </summary>
public string InternationalizationPreset;
/// <summary>
/// Cook: Create a cooked release version. Also, the version. e.g. 1.0
/// </summary>
public string CreateReleaseVersion;
/// <summary>
/// Cook: Use new cooker (temporary cooker option until it's enabled permanently)
/// </summary>
public bool NewCook { private set; get; }
/// <summary>
/// Cook: Use old cooker (temporary cooker options until new cook replaces it)
/// </summary>
public bool OldCook { private set; get; }
/// <summary>
/// Cook: Base this cook of a already released version of the cooked data
/// </summary>
public string BasedOnReleaseVersion;
/// <summary>
/// Cook: Path to the root of the directory where we store released versions of the game for a given version
/// </summary>
public string BasedOnReleaseVersionBasePath;
/// <summary>
/// Cook: Path to the root of the directory to create a new released version of the game.
/// </summary>
public string CreateReleaseVersionBasePath;
/// <summary>
/// Are we generating a patch, generate a patch from a previously released version of the game (use CreateReleaseVersion to create a release).
/// this requires BasedOnReleaseVersion
/// see also CreateReleaseVersion, BasedOnReleaseVersion
/// </summary>
public bool GeneratePatch;
/// <summary>
/// Name of dlc to cook and package (if this paramter is supplied cooks the dlc and packages it into the dlc directory)
/// </summary>
public string DLCName;
/// <summary>
/// Enable cooking of engine content when cooking dlc
/// not included in original release but is referenced by current cook
/// </summary>
public bool DLCIncludeEngineContent;
/// <summary>
/// After cook completes diff the cooked content against another cooked content directory.
/// report all errors to the log
/// </summary>
public string DiffCookedContentPath;
/// <summary>
/// Cook: Additional cooker options to include on the cooker commandline
/// </summary>
public string AdditionalCookerOptions;
/// <summary>
/// Cook: List of cultures to cook.
/// </summary>
public ParamList<string> CulturesToCook;
/// <summary>
/// Compress packages during cook.
/// </summary>
public bool Compressed;
/// <summary>
/// put -debug on the editorexe commandline
/// </summary>
public bool UseDebugParamForEditorExe;
/// <summary>
/// Cook: Do not include a version number in the cooked content
/// </summary>
public bool UnversionedCookedContent = true;
/// <summary>
/// Cook: Uses the iterative cooking, command line: -iterativecooking or -iterate
/// </summary>
[Help( "iterativecooking", "Uses the iterative cooking, command line: -iterativecooking or -iterate" )]
public bool IterativeCooking;
/// <summary>
/// Cook: Only cook maps (and referenced content) instead of cooking everything only affects -cookall flag
/// </summary>
[Help("CookMapsOnly", "Cook only maps this only affects usage of -cookall the flag")]
public bool CookMapsOnly;
/// <summary>
/// Cook: Only cook maps (and referenced content) instead of cooking everything only affects cookall flag
/// </summary>
[Help("CookAll", "Cook all the things in the content directory for this project")]
public bool CookAll;
/// <summary>
/// Cook: Skip cooking editor content
/// </summary>
[Help("SkipCookingEditorContent", "Skips content under /Engine/Editor when cooking")]
public bool SkipCookingEditorContent;
/// <summary>
/// Cook: number of additional cookers to spawn while cooking
/// </summary>
public int NumCookersToSpawn;
/// <summary>
/// Cook: Uses the iterative deploy, command line: -iterativedeploy or -iterate
/// </summary>
[Help("iterativecooking", "Uses the iterative cooking, command line: -iterativedeploy or -iterate")]
public bool IterativeDeploy;
[Help("FastCook", "Uses fast cook path if supported by target")]
public bool FastCook;
/// <summary>
/// Cook: Ignores cook errors and continues with packaging etc.
/// </summary>
[Help("IgnoreCookErrors", "Ignores cook errors and continues with packaging etc")]
public bool IgnoreCookErrors { private set; get; }
#endregion
#region Stage
/// <summary>
/// Stage: Commanndline: -nodebuginfo
/// </summary>
[Help("nodebuginfo", "do not copy debug files to the stage")]
public bool NoDebugInfo { private set; get; }
/// <summary>
/// true if the staging directory is to be cleaned: -cleanstage (also true if -clean is specified)
/// </summary>
[Help("nocleanstage", "skip cleaning the stage directory")]
public bool NoCleanStage { set { bNoCleanStage = value; } get { return SkipStage || bNoCleanStage; } }
private bool bNoCleanStage;
/// <summary>
/// Stage: If non-empty, the contents will be put into the stage
/// </summary>
[Help("cmdline", "command line to put into the stage in UE4CommandLine.txt")]
public string StageCommandline;
/// <summary>
/// Stage: If non-empty, the contents will be used for the bundle name
/// </summary>
[Help("bundlename", "string to use as the bundle name when deploying to mobile device")]
public string BundleName;
/// <summary>
/// Whether the project uses Steam (todo: substitute with more generic functionality)
/// </summary>
public bool bUsesSteam;
/// <summary>
/// Whether the project uses CEF3
/// </summary>
public bool bUsesCEF3;
/// <summary>
/// Whether the project uses visual Slate UI (as opposed to the low level windowing/messaging which is alway used)
/// </summary>
public bool bUsesSlate = true;
/// <summary>
/// Hack for legacy game styling isses. No new project should ever set this to true
/// Whether the project uses the Slate editor style in game.
/// </summary>
public bool bUsesSlateEditorStyle = false;
/// <summary>
/// By default we use the Release C++ Runtime (CRT), even when compiling Debug builds. This is because the Debug C++
/// Runtime isn't very useful when debugging Unreal Engine projects, and linking against the Debug CRT libraries forces
/// our third party library dependencies to also be compiled using the Debug CRT (and often perform more slowly.) Often
/// it can be inconvenient to require a separate copy of the debug versions of third party static libraries simply
/// so that you can debug your program's code.
/// </summary>
public bool bDebugBuildsActuallyUseDebugCRT = false;
/// <summary>
/// On Windows, adds an executable to the root of the staging directory which checks for prerequisites being
/// installed and launches the game with a path to the .uproject file.
/// </summary>
public bool NoBootstrapExe { get; set; }
/// <summary>
/// By default we don't code sign unless it is required or requested
/// </summary>
public bool bCodeSign = false;
/// <summary>
/// Provision to use
/// </summary>
public string Provision = null;
/// <summary>
/// Certificate to use
/// </summary>
public string Certificate = null;
/// <summary>
/// TitleID to package
/// </summary>
public ParamList<string> TitleID = new ParamList<string>();
/// <summary>
/// If true, non-shipping binaries will be considered DebugUFS files and will appear on the debugfiles manifest
/// </summary>
public bool bTreatNonShippingBinariesAsDebugFiles = false;
#endregion
#region Run
/// <summary>
/// Run: True if the Run step should be executed, command: -run
/// </summary>
[Help("run", "run the game after it is built (including server, if -server)")]
public bool Run { private set; get; }
/// <summary>
/// Run: The client runs with cooked data provided by cook on the fly server, command line: -cookonthefly
/// </summary>
[Help("cookonthefly", "run the client with cooked data provided by cook on the fly server")]
public bool CookOnTheFly { private set; get; }
/// <summary>
/// Run: The client should run in streaming mode when connecting to cook on the fly server
/// </summary>
[Help("Cookontheflystreaming", "run the client in streaming cook on the fly mode (don't cache files locally instead force reget from server each file load)")]
public bool CookOnTheFlyStreaming { private set; get; }
/// <summary>
/// Run: The client runs with cooked data provided by UnrealFileServer, command line: -fileserver
/// </summary>
[Help("fileserver", "run the client with cooked data provided by UnrealFileServer")]
public bool FileServer { private set; get; }
/// <summary>
/// Run: The client connects to dedicated server to get data, command line: -dedicatedserver
/// </summary>
[Help("dedicatedserver", "build, cook and run both a client and a server (also -server)")]
public bool DedicatedServer { private set; get; }
/// <summary>
/// Run: Uses a client target configuration, also implies -dedicatedserver, command line: -client
/// </summary>
[Help( "client", "build, cook and run a client and a server, uses client target configuration" )]
public bool Client { private set; get; }
/// <summary>
/// Run: Whether the client should start or not, command line (to disable): -noclient
/// </summary>
[Help("noclient", "do not run the client, just run the server")]
public bool NoClient { private set; get; }
/// <summary>
/// Run: Client should create its own log window, command line: -logwindow
/// </summary>
[Help("logwindow", "create a log window for the client")]
public bool LogWindow { private set; get; }
/// <summary>
/// Run: Map to run the game with.
/// </summary>
[Help("map", "map to run the game with")]
public string MapToRun;
/// <summary>
/// Run: Additional server map params.
/// </summary>
[Help("AdditionalServerMapParams", "Additional server map params, i.e ?param=value")]
public string AdditionalServerMapParams;
/// <summary>
/// Run: The target device to run the game on. Comes in the form platform@devicename.
/// </summary>
[Help("device", "Device to run the game on")]
public string Device;
/// <summary>
/// Run: The target device to run the game on. No platform prefix.
/// </summary>
[Help("device", "Device name without the platform prefix to run the game on")]
public string DeviceName;
/// <summary>
/// Run: the target device to run the server on
/// </summary>
[Help("serverdevice", "Device to run the server on")]
public string ServerDevice;
/// <summary>
/// Run: The indicated server has already been started
/// </summary>
[Help("skipserver", "Skip starting the server")]
public bool SkipServer;
/// <summary>
/// Run: The indicated server has already been started
/// </summary>
[Help("numclients=n", "Start extra clients, n should be 2 or more")]
public int NumClients;
/// <summary>
/// Run: Additional command line arguments to pass to the program
/// </summary>
[Help("addcmdline", "Additional command line arguments for the program")]
public string RunCommandline;
/// <summary>
/// Run:adds -nullrhi to the client commandline
/// </summary>
[Help("nullrhi", "add -nullrhi to the client commandlines")]
public bool NullRHI;
/// <summary>
/// Run:adds ?fake to the server URL
/// </summary>
[Help("fakeclient", "adds ?fake to the server URL")]
public bool FakeClient;
/// <summary>
/// Run:adds ?fake to the server URL
/// </summary>
[Help("editortest", "rather than running a client, run the editor instead")]
public bool EditorTest;
/// <summary>
/// Run:when running -editortest or a client, run all automation tests, not compatible with -server
/// </summary>
[Help("RunAutomationTests", "when running -editortest or a client, run all automation tests, not compatible with -server")]
public bool RunAutomationTests;
/// <summary>
/// Run:when running -editortest or a client, run all automation tests, not compatible with -server
/// </summary>
[Help("RunAutomationTests", "when running -editortest or a client, run a specific automation tests, not compatible with -server")]
public string RunAutomationTest;
/// <summary>
/// Run: Adds commands like debug crash, debug rendercrash, etc based on index
/// </summary>
[Help("Crash=index", "when running -editortest or a client, adds commands like debug crash, debug rendercrash, etc based on index")]
public int CrashIndex;
public ParamList<string> Port;
/// <summary>
/// Run: Linux username for unattended key genereation
/// </summary>
[Help("deviceuser", "Linux username for unattended key genereation")]
public string DeviceUsername;
/// <summary>
/// Run: Linux password for unattended key genereation
/// </summary>
[Help("devicepass", "Linux password for unattended key genereation")]
public string DevicePassword;
/// <summary>
/// Run: Sever device IP address
/// </summary>
public string ServerDeviceAddress;
#endregion
#region Package
[Help("package", "package the project for the target platform")]
public bool Package { get; set; }
[Help("distribution", "package for distribution the project")]
public bool Distribution { get; set; }
[Help("prereqs", "stage prerequisites along with the project")]
public bool Prereqs { get; set; }
[Help("Prebuilt", "this is a prebuilt cooked and packaged build")]
public bool Prebuilt { get; private set; }
[Help("RunTimeoutSeconds", "timeout to wait after we lunch the game")]
public int RunTimeoutSeconds;
[Help("SpecifiedArchitecture", "Determine a specific Minimum OS")]
public string SpecifiedArchitecture;
[Help("UploadSymbols", "upload symbols while packaging")]
public bool UploadSymbols { get; set; }
#endregion
#region Deploy
[Help("deploy", "deploy the project for the target platform")]
public bool Deploy { get; set; }
#endregion
#region Misc
[Help("MapsToRebuildLightMaps", "List of maps that need light maps rebuilding")]
public ParamList<string> MapsToRebuildLightMaps = new ParamList<string>();
[Help("IgnoreLightMapErrors", "Whether Light Map errors should be treated as critical")]
public bool IgnoreLightMapErrors { get; set; }
#endregion
#region Initialization
private Dictionary<TargetRules.TargetType, SingleTargetProperties> DetectedTargets;
private Dictionary<UnrealTargetPlatform, ConfigCacheIni> LoadedEngineConfigs;
private Dictionary<UnrealTargetPlatform, ConfigCacheIni> LoadedGameConfigs;
private void AutodetectSettings(bool bReset)
{
if (bReset)
{
EditorTargetsList = null;
ClientCookedTargetsList = null;
ServerCookedTargetsList = null;
ProgramTargetsList = null;
ProjectBinariesPath = null;
ProjectGameExePath = null;
}
var Properties = ProjectUtils.GetProjectProperties(RawProjectPath, ClientTargetPlatforms, RunAssetNativization);
bUsesSteam = Properties.bUsesSteam;
bUsesCEF3 = Properties.bUsesCEF3;
bUsesSlate = Properties.bUsesSlate;
bUsesSlateEditorStyle = Properties.bUsesSlateEditorStyle;
bDebugBuildsActuallyUseDebugCRT = Properties.bDebugBuildsActuallyUseDebugCRT;
bIsCodeBasedProject = Properties.bIsCodeBasedProject;
DetectedTargets = Properties.Targets;
LoadedEngineConfigs = Properties.EngineConfigs;
LoadedGameConfigs = Properties.GameConfigs;
var GameTarget = String.Empty;
var EditorTarget = String.Empty;
var ServerTarget = String.Empty;
var ProgramTarget = String.Empty;
var ProjectType = TargetRules.TargetType.Game;
if (!bIsCodeBasedProject)
{
GameTarget = "UE4Game";
EditorTarget = "UE4Editor";
ServerTarget = "UE4Server";
}
else if (!CommandUtils.CmdEnv.HasCapabilityToCompile)
{
var ShortName = ProjectUtils.GetShortProjectName(RawProjectPath);
GameTarget = ShortName;
EditorTarget = ShortName + "Editor";
ServerTarget = ShortName + "Server";
}
else if (!CommandUtils.IsNullOrEmpty(Properties.Targets))
{
SingleTargetProperties TargetData;
var GameTargetType = TargetRules.TargetType.Game;
if( Client )
{
if( HasClientTargetDetected )
{
GameTargetType = TargetRules.TargetType.Client;
}
else
{
throw new AutomationException( "Client target not found!" );
}
}
var ValidGameTargetTypes = new TargetRules.TargetType[]
{
GameTargetType,
TargetRules.TargetType.Program
};
foreach (var ValidTarget in ValidGameTargetTypes)
{
if (DetectedTargets.TryGetValue(ValidTarget, out TargetData))
{
GameTarget = TargetData.TargetName;
bDebugBuildsActuallyUseDebugCRT = TargetData.Rules.bDebugBuildsActuallyUseDebugCRT;
bUsesSlate = TargetData.Rules.bUsesSlate;
bUsesSlateEditorStyle = TargetData.Rules.bUsesSlateEditorStyle;
bUsesSteam = TargetData.Rules.bUsesSteam;
bUsesCEF3 = TargetData.Rules.bUsesCEF3;
ProjectType = ValidTarget;
break;
}
}
if (DetectedTargets.TryGetValue(TargetRules.TargetType.Editor, out TargetData))
{
EditorTarget = TargetData.TargetName;
}
if (DetectedTargets.TryGetValue(TargetRules.TargetType.Server, out TargetData))
{
ServerTarget = TargetData.TargetName;
}
if (DetectedTargets.TryGetValue(TargetRules.TargetType.Program, out TargetData))
{
ProgramTarget = TargetData.TargetName;
}
}
else if (!CommandUtils.IsNullOrEmpty(Properties.Programs))
{
SingleTargetProperties TargetData = Properties.Programs[0];
bDebugBuildsActuallyUseDebugCRT = TargetData.Rules.bDebugBuildsActuallyUseDebugCRT;
bUsesSlate = TargetData.Rules.bUsesSlate;
bUsesSlateEditorStyle = TargetData.Rules.bUsesSlateEditorStyle;
bUsesSteam = TargetData.Rules.bUsesSteam;
bUsesCEF3 = TargetData.Rules.bUsesCEF3;
ProjectType = TargetRules.TargetType.Program;
ProgramTarget = TargetData.TargetName;
GameTarget = TargetData.TargetName;
}
else if (!this.Build)
{
var ShortName = ProjectUtils.GetShortProjectName(RawProjectPath);
GameTarget = ShortName;
EditorTarget = ShortName + "Editor";
ServerTarget = ShortName + "Server";
}
else
{
throw new AutomationException("{0} does not look like uproject file but no targets have been found!", RawProjectPath);
}
IsProgramTarget = ProjectType == TargetRules.TargetType.Program;
if (String.IsNullOrEmpty(EditorTarget) && ProjectType != TargetRules.TargetType.Program && CommandUtils.IsNullOrEmpty(EditorTargetsList))
{
if (Properties.bWasGenerated)
{
EditorTarget = "UE4Editor";
}
else
{
throw new AutomationException("Editor target not found!");
}
}
if (String.IsNullOrEmpty(GameTarget) && Run && !NoClient && (Cook || CookOnTheFly) && CommandUtils.IsNullOrEmpty(ClientCookedTargetsList))
{
throw new AutomationException("Game target not found. Game target is required with -cook or -cookonthefly");
}
if (EditorTargetsList == null)
{
if (!GlobalCommandLine.NoCompileEditor && (ProjectType != TargetRules.TargetType.Program) && !String.IsNullOrEmpty(EditorTarget))
{
EditorTargetsList = new ParamList<string>(EditorTarget);
}
else
{
EditorTargetsList = new ParamList<string>();
}
}
if (ProgramTargetsList == null)
{
if (ProjectType == TargetRules.TargetType.Program)
{
ProgramTargetsList = new ParamList<string>(ProgramTarget);
}
else
{
ProgramTargetsList = new ParamList<string>();
}
}
if (ClientCookedTargetsList == null && !NoClient && (Cook || CookOnTheFly || Prebuilt))
{
if (String.IsNullOrEmpty(GameTarget))
{
throw new AutomationException("Game target not found. Game target is required with -cook or -cookonthefly");
}
else
{
ClientCookedTargetsList = new ParamList<string>(GameTarget);
}
}
else if (ClientCookedTargetsList == null)
{
ClientCookedTargetsList = new ParamList<string>();
}
if (ServerCookedTargetsList == null && DedicatedServer && (Cook || CookOnTheFly))
{
if (String.IsNullOrEmpty(ServerTarget))
{
throw new AutomationException("Server target not found. Server target is required with -server and -cook or -cookonthefly");
}
ServerCookedTargetsList = new ParamList<string>(ServerTarget);
}
else if (ServerCookedTargetsList == null)
{
ServerCookedTargetsList = new ParamList<string>();
}
if (String.IsNullOrEmpty(ProjectBinariesPath) || String.IsNullOrEmpty(ProjectGameExePath))
{
if ( ClientTargetPlatforms.Count > 0 )
{
var ProjectClientBinariesPath = ProjectUtils.GetClientProjectBinariesRootPath(RawProjectPath, ProjectType, Properties.bIsCodeBasedProject);
ProjectBinariesPath = ProjectUtils.GetProjectClientBinariesFolder(ProjectClientBinariesPath, ClientTargetPlatforms[0]);
ProjectGameExePath = CommandUtils.CombinePaths(ProjectBinariesPath, GameTarget + Platform.GetExeExtension(ClientTargetPlatforms[0]));
}
}
// for the moment, allow the commandline to override the ini if set. This will keep us from breaking licensee packaging scripts until we have
// the full solution for per-platform packaging settings.
if (!Manifests)
{
ConfigCacheIni GameIni = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.Unknown, "Game", RawProjectPath.Directory);
String IniPath = "/Script/UnrealEd.ProjectPackagingSettings";
bool bSetting = false;
if (!GameIni.GetBool(IniPath, "bGenerateChunks", out bSetting))
{
Manifests = bSetting;
}
}
}
#endregion
#region Utilities
public bool HasEditorTargets
{
get { return !CommandUtils.IsNullOrEmpty(EditorTargets); }
}
public bool HasCookedTargets
{
get { return !CommandUtils.IsNullOrEmpty(ClientCookedTargets) || !CommandUtils.IsNullOrEmpty(ServerCookedTargets); }
}
public bool HasServerCookedTargets
{
get { return !CommandUtils.IsNullOrEmpty(ServerCookedTargets); }
}
public bool HasClientCookedTargets
{
get { return !CommandUtils.IsNullOrEmpty(ClientCookedTargets); }
}
public bool HasProgramTargets
{
get { return !CommandUtils.IsNullOrEmpty(ProgramTargets); }
}
public bool HasMapsToCook
{
get { return !CommandUtils.IsNullOrEmpty(MapsToCook); }
}
public bool HasDirectoriesToCook
{
get { return !CommandUtils.IsNullOrEmpty(DirectoriesToCook); }
}
public bool HasInternationalizationPreset
{
get { return !String.IsNullOrEmpty(InternationalizationPreset); }
}
public bool HasBasedOnReleaseVersion
{
get { return !String.IsNullOrEmpty(BasedOnReleaseVersion); }
}
public bool HasAdditionalCookerOptions
{
get { return !String.IsNullOrEmpty(AdditionalCookerOptions); }
}
public bool HasDLCName
{
get { return !String.IsNullOrEmpty(DLCName); }
}
public bool HasDiffCookedContentPath
{
get { return !String.IsNullOrEmpty(DiffCookedContentPath); }
}
public bool HasCreateReleaseVersion
{
get { return !String.IsNullOrEmpty(CreateReleaseVersion); }
}
public bool HasCulturesToCook
{
get { return CulturesToCook != null; }
}
public bool HasGameTargetDetected
{
get { return ProjectTargets.ContainsKey(TargetRules.TargetType.Game); }
}
public bool HasClientTargetDetected
{
get { return ProjectTargets.ContainsKey( TargetRules.TargetType.Client ); }
}
public bool HasDedicatedServerAndClient
{
get { return Client && DedicatedServer; }
}
/// <summary>
/// Project name (name of the uproject file without extension or directory name where the project is localed)
/// </summary>
public string ShortProjectName
{
get { return ProjectUtils.GetShortProjectName(RawProjectPath); }
}
/// <summary>
/// True if this project contains source code.
/// </summary>
public bool IsCodeBasedProject
{
get
{
return bIsCodeBasedProject;
}
}
private bool bIsCodeBasedProject;
public FileReference CodeBasedUprojectPath
{
get { return IsCodeBasedProject ? RawProjectPath : null; }
}
/// <summary>
/// True if this project is a program.
/// </summary>
public bool IsProgramTarget { get; private set; }
/// <summary>
/// Path where the project's game (or program) binaries are built.
/// </summary>
public string ProjectBinariesFolder
{
get
{
if (String.IsNullOrEmpty(ProjectBinariesPath))
{
AutodetectSettings(false);
}
return ProjectBinariesPath;
}
}
private string ProjectBinariesPath;
/// <summary>
/// Get the path to the directory of the version we are basing a diff or a patch on.
/// </summary>
public String GetBasedOnReleaseVersionPath(DeploymentContext SC)
{
String BasePath = BasedOnReleaseVersionBasePath;
String Platform = SC.StageTargetPlatform.GetCookPlatform(SC.DedicatedServer, false, CookFlavor);
if (String.IsNullOrEmpty(BasePath))
{
BasePath = CommandUtils.CombinePaths(SC.ProjectRoot, "Releases", BasedOnReleaseVersion, Platform);
}
else
{
BasePath = CommandUtils.CombinePaths(BasePath, BasedOnReleaseVersion, Platform);
}
/*if ( TitleID != null && TitleID.Count == 1 )
{
BasePath = CommandUtils.CombinePaths( BasePath, TitleID[0]);
}*/
return BasePath;
}
/// <summary>
/// Get the path to the target directory for creating a new release version
/// </summary>
/// <param name="SC"></param>
/// <returns></returns>
public String GetCreateReleaseVersionPath(DeploymentContext SC)
{
String BasePath = CreateReleaseVersionBasePath;
String Platform = SC.StageTargetPlatform.GetCookPlatform(SC.DedicatedServer, false, CookFlavor);
if (String.IsNullOrEmpty(BasePath))
{
BasePath = CommandUtils.CombinePaths(SC.ProjectRoot, "Releases", CreateReleaseVersion, Platform);
}
else
{
BasePath = CommandUtils.CombinePaths(BasePath, CreateReleaseVersion, Platform);
}
/*if (TitleID != null && TitleID.Count == 1)
{
BasePath = CommandUtils.CombinePaths(BasePath, TitleID[0]);
}*/
return BasePath;
}
/// <summary>
/// True if we are generating a patch
/// </summary>
public bool IsGeneratingPatch
{
get { return GeneratePatch; }
}
/// <summary>
/// Filename of the target game exe (or program exe).
/// </summary>
public string ProjectGameExeFilename
{
get
{
if (String.IsNullOrEmpty(ProjectGameExePath))
{
AutodetectSettings(false);
}
return ProjectGameExePath;
}
}
private string ProjectGameExePath;
public Platform GetTargetPlatformInstance(UnrealTargetPlatform TargetPlatformType)
{
return Platform.Platforms[TargetPlatformType];
}
public List<Platform> ClientTargetPlatformInstances
{
get
{
List<Platform> ClientPlatformInstances = new List<Platform>();
foreach ( var ClientPlatform in ClientTargetPlatforms )
{
ClientPlatformInstances.Add(Platform.Platforms[ClientPlatform]);
}
return ClientPlatformInstances;
}
}
public UnrealTargetPlatform GetCookedDataPlatformForClientTarget(UnrealTargetPlatform TargetPlatformType)
{
if (ClientDependentPlatformMap.ContainsKey(TargetPlatformType))
{
return ClientDependentPlatformMap[TargetPlatformType];
}
return TargetPlatformType;
}
public List<Platform> ServerTargetPlatformInstances
{
get
{
List<Platform> ServerPlatformInstances = new List<Platform>();
foreach (var ServerPlatform in ServerTargetPlatforms)
{
ServerPlatformInstances.Add(Platform.Platforms[ServerPlatform]);
}
return ServerPlatformInstances;
}
}
public UnrealTargetPlatform GetCookedDataPlatformForServerTarget(UnrealTargetPlatform TargetPlatformType)
{
if (ServerDependentPlatformMap.ContainsKey(TargetPlatformType))
{
return ServerDependentPlatformMap[TargetPlatformType];
}
return TargetPlatformType;
}
/// <summary>
/// All auto-detected targets for this project
/// </summary>
public Dictionary<TargetRules.TargetType, SingleTargetProperties> ProjectTargets
{
get
{
if (DetectedTargets == null)
{
AutodetectSettings(false);
}
return DetectedTargets;
}
}
/// <summary>
/// List of all Engine ini files for this project
/// </summary>
public Dictionary<UnrealTargetPlatform, ConfigCacheIni> EngineConfigs
{
get
{
if (LoadedEngineConfigs == null)
{
AutodetectSettings(false);
}
return LoadedEngineConfigs;
}
}
/// <summary>
/// List of all Game ini files for this project
/// </summary>
public Dictionary<UnrealTargetPlatform, ConfigCacheIni> GameConfigs
{
get
{
if (LoadedGameConfigs == null)
{
AutodetectSettings(false);
}
return LoadedGameConfigs;
}
}
public void Validate()
{
if (RawProjectPath == null)
{
throw new AutomationException("RawProjectPath can't be empty.");
}
if (!RawProjectPath.HasExtension(".uproject"))
{
throw new AutomationException("RawProjectPath {0} must end with .uproject", RawProjectPath);
}
if (!CommandUtils.FileExists_NoExceptions(RawProjectPath.FullName))
{
throw new AutomationException("RawProjectPath {0} file must exist", RawProjectPath);
}
if (FileServer && !Cook)
{
throw new AutomationException("Only cooked builds can use a fileserver be staged, use -cook");
}
if (Stage && !Cook && !CookOnTheFly && !IsProgramTarget)
{
throw new AutomationException("Only cooked builds or programs can be staged, use -cook or -cookonthefly.");
}
if (Manifests && !Cook && !Stage && !Pak)
{
throw new AutomationException("Only staged pakd and cooked builds can generate streaming install manifests");
}
if (Pak && !Stage)
{
throw new AutomationException("Only staged builds can be paked, use -stage or -skipstage.");
}
if (Deploy && !Stage)
{
throw new AutomationException("Only staged builds can be deployed, use -stage or -skipstage.");
}
if ((Pak || Stage || Cook || CookOnTheFly || FileServer || DedicatedServer) && EditorTest)
{
throw new AutomationException("None of pak, stage, cook, CookOnTheFly or DedicatedServer can be used with EditorTest");
}
if (DedicatedServer && RunAutomationTests)
{
throw new AutomationException("DedicatedServer cannot be used with RunAutomationTests");
}
if ((CookOnTheFly || FileServer) && DedicatedServer)
{
throw new AutomationException("Don't use either -cookonthefly or -fileserver with -server.");
}
if (NoClient && !DedicatedServer && !CookOnTheFly)
{
throw new AutomationException("-noclient can only be used with -server or -cookonthefly.");
}
if (Build && !HasCookedTargets && !HasEditorTargets && !HasProgramTargets)
{
throw new AutomationException("-build is specified but there are no targets to build.");
}
if (Pak && FileServer)
{
throw new AutomationException("Can't use -pak and -fileserver at the same time.");
}
if (Cook && CookOnTheFly)
{
throw new AutomationException("Can't use both -cook and -cookonthefly.");
}
if (!HasDLCName && DLCIncludeEngineContent)
{
throw new AutomationException("DLCIncludeEngineContent flag is only valid when cooking dlc.");
}
if ((IsGeneratingPatch || HasDLCName) && !HasBasedOnReleaseVersion)
{
throw new AutomationException("Require based on release version to build patches or dlc");
}
if (HasCreateReleaseVersion && (IsGeneratingPatch || HasDLCName))
{
throw new AutomationException("Can't create a release version at the same time as creating dlc.");
}
if (HasBasedOnReleaseVersion && (IterativeCooking || IterativeDeploy))
{
throw new AutomationException("Can't use iterative cooking / deploy on dlc or patching or creating a release");
}
/*if (Compressed && !Pak)
{
throw new AutomationException("-compressed can only be used with -pak");
}*/
if (CreateChunkInstall && (!Manifests || !Stage))
{
throw new AutomationException("-createchunkinstall can only be used with -manifests & -stage");
}
if (CreateChunkInstall && String.IsNullOrEmpty(ChunkInstallDirectory))
{
throw new AutomationException("-createchunkinstall must specify the chunk install data directory with -chunkinstalldirectory=");
}
if (CreateChunkInstall && String.IsNullOrEmpty(ChunkInstallVersionString))
{
throw new AutomationException("-createchunkinstall must specify the chunk install data version string with -chunkinstallversion=");
}
}
protected bool bLogged = false;
public virtual void ValidateAndLog()
{
// Avoid spamming, log only once
if (!bLogged)
{
// In alphabetical order.
CommandUtils.LogLog("Project Params **************");
CommandUtils.LogLog("AdditionalServerMapParams={0}", AdditionalServerMapParams);
CommandUtils.LogLog("Archive={0}", Archive);
CommandUtils.LogLog("ArchiveMetaData={0}", ArchiveMetaData);
CommandUtils.LogLog("CreateAppBundle={0}", CreateAppBundle);
CommandUtils.LogLog("BaseArchiveDirectory={0}", BaseArchiveDirectory);
CommandUtils.LogLog("BaseStageDirectory={0}", BaseStageDirectory);
CommandUtils.LogLog("Build={0}", Build);
CommandUtils.LogLog("Cook={0}", Cook);
CommandUtils.LogLog("Clean={0}", Clean);
CommandUtils.LogLog("Client={0}", Client);
CommandUtils.LogLog("ClientConfigsToBuild={0}", string.Join(",", ClientConfigsToBuild));
CommandUtils.LogLog("ClientCookedTargets={0}", ClientCookedTargets.ToString());
CommandUtils.LogLog("ClientTargetPlatform={0}", string.Join(",", ClientTargetPlatforms));
CommandUtils.LogLog("Compressed={0}", Compressed);
CommandUtils.LogLog("UseDebugParamForEditorExe={0}", UseDebugParamForEditorExe);
CommandUtils.LogLog("CookFlavor={0}", CookFlavor);
CommandUtils.LogLog("CookOnTheFly={0}", CookOnTheFly);
CommandUtils.LogLog("CookOnTheFlyStreaming={0}", CookOnTheFlyStreaming);
CommandUtils.LogLog("UnversionedCookedContent={0}", UnversionedCookedContent);
CommandUtils.LogLog("SkipCookingEditorContent={0}", SkipCookingEditorContent);
CommandUtils.LogLog("NumCookersToSpawn={0}", NumCookersToSpawn);
CommandUtils.LogLog("GeneratePatch={0}", GeneratePatch);
CommandUtils.LogLog("CreateReleaseVersion={0}", CreateReleaseVersion);
CommandUtils.LogLog("BasedOnReleaseVersion={0}", BasedOnReleaseVersion);
CommandUtils.LogLog("DLCName={0}", DLCName);
CommandUtils.LogLog("DLCIncludeEngineContent={0}", DLCIncludeEngineContent);
CommandUtils.LogLog("DiffCookedContentPath={0}", DiffCookedContentPath);
CommandUtils.LogLog("AdditionalCookerOptions={0}", AdditionalCookerOptions);
CommandUtils.LogLog("DedicatedServer={0}", DedicatedServer);
CommandUtils.LogLog("DirectoriesToCook={0}", DirectoriesToCook.ToString());
CommandUtils.LogLog("CulturesToCook={0}", CommandUtils.IsNullOrEmpty(CulturesToCook) ? "<Not Specified> (Use Defaults)" : CulturesToCook.ToString());
CommandUtils.LogLog("EditorTargets={0}", EditorTargets.ToString());
CommandUtils.LogLog("Foreign={0}", Foreign);
CommandUtils.LogLog("IsCodeBasedProject={0}", IsCodeBasedProject.ToString());
CommandUtils.LogLog("IsProgramTarget={0}", IsProgramTarget.ToString());
CommandUtils.LogLog("IterativeCooking={0}", IterativeCooking);
CommandUtils.LogLog("CookAll={0}", CookAll);
CommandUtils.LogLog("CookMapsOnly={0}", CookMapsOnly);
CommandUtils.LogLog("Deploy={0}", Deploy);
CommandUtils.LogLog("IterativeDeploy={0}", IterativeDeploy);
CommandUtils.LogLog("FastCook={0}", FastCook);
CommandUtils.LogLog("LogWindow={0}", LogWindow);
CommandUtils.LogLog("Manifests={0}", Manifests);
CommandUtils.LogLog("MapToRun={0}", MapToRun);
CommandUtils.LogLog("NoClient={0}", NoClient);
CommandUtils.LogLog("NumClients={0}", NumClients);
CommandUtils.LogLog("NoDebugInfo={0}", NoDebugInfo);
CommandUtils.LogLog("NoCleanStage={0}", NoCleanStage);
CommandUtils.LogLog("NoXGE={0}", NoXGE);
CommandUtils.LogLog("MapsToCook={0}", MapsToCook.ToString());
CommandUtils.LogLog("Pak={0}", Pak);
CommandUtils.LogLog("Package={0}", Package);
CommandUtils.LogLog("NullRHI={0}", NullRHI);
CommandUtils.LogLog("FakeClient={0}", FakeClient);
CommandUtils.LogLog("EditorTest={0}", EditorTest);
CommandUtils.LogLog("RunAutomationTests={0}", RunAutomationTests);
CommandUtils.LogLog("RunAutomationTest={0}", RunAutomationTest);
CommandUtils.LogLog("RunTimeoutSeconds={0}", RunTimeoutSeconds);
CommandUtils.LogLog("CrashIndex={0}", CrashIndex);
CommandUtils.LogLog("ProgramTargets={0}", ProgramTargets.ToString());
CommandUtils.LogLog("ProjectBinariesFolder={0}", ProjectBinariesFolder);
CommandUtils.LogLog("ProjectBinariesPath={0}", ProjectBinariesPath);
CommandUtils.LogLog("ProjectGameExeFilename={0}", ProjectGameExeFilename);
CommandUtils.LogLog("ProjectGameExePath={0}", ProjectGameExePath);
CommandUtils.LogLog("Distribution={0}", Distribution);
CommandUtils.LogLog("Prebuilt={0}", Prebuilt);
CommandUtils.LogLog("Prereqs={0}", Prereqs);
CommandUtils.LogLog("NoBootstrapExe={0}", NoBootstrapExe);
CommandUtils.LogLog("RawProjectPath={0}", RawProjectPath);
CommandUtils.LogLog("Run={0}", Run);
CommandUtils.LogLog("ServerConfigsToBuild={0}", string.Join(",", ServerConfigsToBuild));
CommandUtils.LogLog("ServerCookedTargets={0}", ServerCookedTargets.ToString());
CommandUtils.LogLog("ServerTargetPlatform={0}", string.Join(",", ServerTargetPlatforms));
CommandUtils.LogLog("ShortProjectName={0}", ShortProjectName.ToString());
CommandUtils.LogLog("SignedPak={0}", SignedPak);
CommandUtils.LogLog("SignPak={0}", SignPak);
CommandUtils.LogLog("SkipCook={0}", SkipCook);
CommandUtils.LogLog("SkipCookOnTheFly={0}", SkipCookOnTheFly);
CommandUtils.LogLog("SkipPak={0}", SkipPak);
CommandUtils.LogLog("SkipStage={0}", SkipStage);
CommandUtils.LogLog("Stage={0}", Stage);
CommandUtils.LogLog("bUsesSteam={0}", bUsesSteam);
CommandUtils.LogLog("bUsesCEF3={0}", bUsesCEF3);
CommandUtils.LogLog("bUsesSlate={0}", bUsesSlate);
CommandUtils.LogLog("bDebugBuildsActuallyUseDebugCRT={0}", bDebugBuildsActuallyUseDebugCRT);
CommandUtils.LogLog("bTreatNonShippingBinariesAsDebugFiles={0}", bTreatNonShippingBinariesAsDebugFiles);
CommandUtils.LogLog("UploadSymbols={0}", UploadSymbols);
CommandUtils.LogLog("NativizeAssets={0}", RunAssetNativization);
CommandUtils.LogLog("Project Params **************");
}
bLogged = true;
Validate();
}
#endregion
}
}