2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-06-27 08:41:46 -04:00
# include "ProjectsPrivatePCH.h"
# include "ProjectDescriptor.h"
# define LOCTEXT_NAMESPACE "ProjectDescriptor"
FProjectDescriptor : : FProjectDescriptor ( )
{
FileVersion = EProjectDescriptorVersion : : Latest ;
EpicSampleNameHash = 0 ;
}
void FProjectDescriptor : : Sign ( const FString & FilePath )
{
EpicSampleNameHash = GetTypeHash ( FPaths : : GetCleanFilename ( FilePath ) ) ;
}
bool FProjectDescriptor : : IsSigned ( const FString & FilePath ) const
{
return EpicSampleNameHash = = GetTypeHash ( FPaths : : GetCleanFilename ( FilePath ) ) ;
}
void FProjectDescriptor : : UpdateSupportedTargetPlatforms ( const FName & InPlatformName , bool bIsSupported )
{
if ( bIsSupported )
{
TargetPlatforms . AddUnique ( InPlatformName ) ;
}
else
{
TargetPlatforms . Remove ( InPlatformName ) ;
}
}
bool FProjectDescriptor : : Load ( const FString & FileName , FText & OutFailReason )
{
// Read the file to a string
FString FileContents ;
if ( ! FFileHelper : : LoadFileToString ( FileContents , * FileName ) )
{
OutFailReason = FText : : Format ( LOCTEXT ( " FailedToLoadDescriptorFile " , " Failed to open descriptor file '{0}' " ) , FText : : FromString ( FileName ) ) ;
return false ;
}
// Deserialize a JSON object from the string
TSharedPtr < FJsonObject > Object ;
TSharedRef < TJsonReader < > > Reader = TJsonReaderFactory < > : : Create ( FileContents ) ;
if ( ! FJsonSerializer : : Deserialize ( Reader , Object ) | | ! Object . IsValid ( ) )
{
2014-06-27 16:38:50 -04:00
OutFailReason = FText : : Format ( LOCTEXT ( " FailedToReadDescriptorFile " , " Failed to read file. {0} " ) , FText : : FromString ( Reader - > GetErrorMessage ( ) ) ) ;
2014-06-27 08:41:46 -04:00
return false ;
}
// Parse it as a project descriptor
return Read ( * Object . Get ( ) , OutFailReason ) ;
}
bool FProjectDescriptor : : Read ( const FJsonObject & Object , FText & OutFailReason )
{
// Read the file version
int32 FileVersionInt32 ;
if ( ! Object . TryGetNumberField ( TEXT ( " FileVersion " ) , FileVersionInt32 ) )
{
if ( ! Object . TryGetNumberField ( TEXT ( " ProjectFileVersion " ) , FileVersionInt32 ) )
{
OutFailReason = LOCTEXT ( " InvalidProjectFileVersion " , " File does not have a valid 'FileVersion' number. " ) ;
return false ;
}
}
// Check that it's within range
FileVersion = ( EProjectDescriptorVersion : : Type ) FileVersionInt32 ;
if ( FileVersion < = EProjectDescriptorVersion : : Invalid | | FileVersion > EProjectDescriptorVersion : : Latest )
{
FText ReadVersionText = FText : : FromString ( FString : : Printf ( TEXT ( " %d " ) , ( int32 ) FileVersion ) ) ;
FText LatestVersionText = FText : : FromString ( FString : : Printf ( TEXT ( " %d " ) , ( int32 ) EProjectDescriptorVersion : : Latest ) ) ;
OutFailReason = FText : : Format ( LOCTEXT ( " ProjectFileVersionTooLarge " , " File appears to be in a newer version ({0}) of the file format that we can load (max version: {1}). " ) , ReadVersionText , LatestVersionText ) ;
return false ;
}
// Read simple fields
Object . TryGetStringField ( TEXT ( " EngineAssociation " ) , EngineAssociation ) ;
Object . TryGetStringField ( TEXT ( " Category " ) , Category ) ;
Object . TryGetStringField ( TEXT ( " Description " ) , Description ) ;
// Read the modules
if ( ! FModuleDescriptor : : ReadArray ( Object , TEXT ( " Modules " ) , Modules , OutFailReason ) )
{
return false ;
}
2014-06-27 15:23:15 -04:00
// Read the plugins
if ( ! FPluginReferenceDescriptor : : ReadArray ( Object , TEXT ( " Plugins " ) , Plugins , OutFailReason ) )
{
return false ;
}
2014-06-27 08:41:46 -04:00
// Read the target platforms
const TArray < TSharedPtr < FJsonValue > > * TargetPlatformsValue ;
if ( Object . TryGetArrayField ( TEXT ( " TargetPlatforms " ) , TargetPlatformsValue ) )
{
for ( int32 Idx = 0 ; Idx < TargetPlatformsValue - > Num ( ) ; Idx + + )
{
FString TargetPlatform ;
if ( ( * TargetPlatformsValue ) [ Idx ] - > TryGetString ( TargetPlatform ) )
{
TargetPlatforms . Add ( * TargetPlatform ) ;
}
}
}
// Get the sample name hash
Object . TryGetNumberField ( TEXT ( " EpicSampleNameHash " ) , EpicSampleNameHash ) ;
return true ;
}
bool FProjectDescriptor : : Save ( const FString & FileName , FText & OutFailReason )
{
// Write the contents of the descriptor to a string. Make sure the writer is destroyed so that the contents are flushed to the string.
FString Text ;
TSharedRef < TJsonWriter < > > Writer = TJsonWriterFactory < > : : Create ( & Text ) ;
Write ( Writer . Get ( ) ) ;
Writer - > Close ( ) ;
// Save it to a file
if ( FFileHelper : : SaveStringToFile ( Text , * FileName ) )
{
return true ;
}
else
{
OutFailReason = FText : : Format ( LOCTEXT ( " FailedToWriteOutputFile " , " Failed to write output file '{0}'. Perhaps the file is Read-Only? " ) , FText : : FromString ( FileName ) ) ;
return false ;
}
}
void FProjectDescriptor : : Write ( TJsonWriter < > & Writer ) const
{
Writer . WriteObjectStart ( ) ;
// Write all the simple fields
Writer . WriteValue ( TEXT ( " FileVersion " ) , EProjectDescriptorVersion : : Latest ) ;
Writer . WriteValue ( TEXT ( " EngineAssociation " ) , EngineAssociation ) ;
Writer . WriteValue ( TEXT ( " Category " ) , Category ) ;
Writer . WriteValue ( TEXT ( " Description " ) , Description ) ;
// Write the module list
FModuleDescriptor : : WriteArray ( Writer , TEXT ( " Modules " ) , Modules ) ;
2014-06-27 15:23:15 -04:00
// Write the plugin list
FPluginReferenceDescriptor : : WriteArray ( Writer , TEXT ( " Plugins " ) , Plugins ) ;
2014-06-27 08:41:46 -04:00
// Write the target platforms
if ( TargetPlatforms . Num ( ) > 0 )
{
Writer . WriteArrayStart ( TEXT ( " TargetPlatforms " ) ) ;
for ( int Idx = 0 ; Idx < TargetPlatforms . Num ( ) ; Idx + + )
{
Writer . WriteValue ( TargetPlatforms [ Idx ] . ToString ( ) ) ;
}
Writer . WriteArrayEnd ( ) ;
}
// If it's a signed sample, write the name hash
if ( EpicSampleNameHash ! = 0 )
{
Writer . WriteValue ( TEXT ( " EpicSampleNameHash " ) , FString : : Printf ( TEXT ( " %u " ) , EpicSampleNameHash ) ) ;
}
Writer . WriteObjectEnd ( ) ;
}
2014-09-08 13:51:36 -04:00
FString FProjectDescriptor : : GetExtension ( )
{
static const FString ProjectExtension ( TEXT ( " uproject " ) ) ;
return ProjectExtension ;
}
2014-06-27 08:41:46 -04:00
# undef LOCTEXT_NAMESPACE