You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2836261 on 2016/01/20 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Flush FAsyncPackage cache after pre-load to reduce peak memory usage when async loading (5.5-10x).
Change 2828630 on 2016/01/14 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Adding debug code to catch memory stomps in the async loading buffers that's independent from mallocstomp allocator. Changed the signature of PageProtect functions to be able to read-only protect memory.
Change 2816129 on 2016/01/05 by Steve.Robb@Dev-Core
Fixes for Realloc and alignment logic which caused redundant reallocations and incorrect binning.
Change 2821054 on 2016/01/08 by Steve.Robb@Dev-Core
Further Realloc savings when realigning within a block.
Change 2806820 on 2015/12/17 by Steve.Robb@Dev-Core
New AlignDown function, like Align, but which rounds a value/pointer down to the next alignment instead of up.
Change 2806816 on 2015/12/17 by Steve.Robb@Dev-Core
Sort UHT modules by type to improve iteration times in conjunction with makefiles.
Change 2823235 on 2016/01/11 by Steve.Robb@Dev-Core
UHT error messages about missing GENERATED_BODY() macros updated to represent intended use.
Change 2806815 on 2015/12/17 by Steve.Robb@Dev-Core
Module types split into Game and Engine runtime versions.
Change 2833809 on 2016/01/19 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
StaticLoadObject will now respect LOAD_NoRedirects flag.
Change 2811194 on 2015/12/22 by Bob.Tellez@Z2434_DevCore
#UE4 Prevent loading packages that have a newer LegacyFileVersion since serialization for FCustomVersion is not forward compatible. UE-24443
Change 2806818 on 2015/12/17 by Steve.Robb@Dev-Core
Removal of stats from MallocBinned2, to be readded later.
Change 2807069 on 2015/12/17 by Steve.Robb@Dev-Core
Clarification of some bucket hashing terminology.
Change 2815117 on 2016/01/04 by Steve.Robb@Dev-Core
Fix for a missing root build path on game modules.
Change 2815673 on 2016/01/05 by Steve.Robb@Dev-Core
Move FMalloc verification into a proxy object.
Change 2822873 on 2016/01/11 by Steve.Robb@Dev-Core
Fixes to off-by-one errors and removal of BinnedSizeLimit (assumed to be the same as MAX_POOLED_ALLOCATION_SIZE after OBO fix).
Change 2822923 on 2016/01/11 by Steve.Robb@Dev-Core
Simplification of MemSizeToPoolTable indexing.
Change 2824974 on 2016/01/12 by Steve.Robb@Dev-Core
Assert fixed.
AllocateBlockFromPool's return value made debuggable.
Change 2825241 on 2016/01/12 by Steve.Robb@Dev-Core
UHT now returns an error code on a warning when -warningsaserrors is specified.
Change 2825291 on 2016/01/12 by Steve.Robb@Dev-Core
WarningsAsErrors enabled on UHT, after disabling the hardcoded behavior in CL# 2825241.
Change 2829846 on 2016/01/15 by Steve.Robb@Dev-Core
GitHub #1938 - wrong Max value of enum is used during net serialization
Change 2829914 on 2016/01/15 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Reduce the amount of memory allocated for async cache buffers when guarding against memory stomps.
Change 2829988 on 2016/01/15 by Steve.Robb@Dev-Core
Generalized large pool allocations.
More redundancy removed.
Change 2831935 on 2016/01/18 by Chris.Wood@Chris.Wood.StreamB
Added UserActivity property to crash description in CRP and CR website.
[OR-12043] - Phone Home where crashes occur - pass context info to Crash Reporter
DB column added to db-09 by ColinR matching this change.
Published to server on Jan 18th 2016
Change 2834003 on 2016/01/19 by Chris.Wood@Chris.Wood.StreamB
Added Linux to normal callstack parsing code on CR website
[UE-25527] - Linux CrashReporter is missing information
Published to server on Jan 19th 2016
Change 2835466 on 2016/01/20 by Joe.Conley@Joe.Conley_EGJWD5708_Dev-Core-Minimal
Fix issue for cancelling package loads when there are still packages queued. Call their PackageLoadedDelegate with a "Cancelled" result.
Should solve remaining issue with UE-24062 - "Calling CancelAsyncLoading triggers an assert in FAsyncPackage::DetachLinker()"
- (ULevelStreaming::AsyncLevelLoadComplete was not being called if packages were still queued when cancel was issued)
Change 2836803 on 2016/01/20 by Chris.Wood@Chris.Wood.StreamB
CrashReportWebsite - fix exception thrown when parsing certain callstack formats
Change 2837952 on 2016/01/21 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Changing FAsyncIORequest to be stored as reference when cancelling IO requests to improve performance.
Change 2838289 on 2016/01/21 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
[CL 2845588 by Robert Manuszewski in Main branch]
414 lines
14 KiB
C++
414 lines
14 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CrashReportClientApp.h"
|
|
#include "GenericPlatformCrashContext.h"
|
|
|
|
#include "XmlFile.h"
|
|
#include "CrashDescription.h"
|
|
#include "CrashReportAnalytics.h"
|
|
#include "CrashReportUtil.h"
|
|
#include "Runtime/Analytics/Analytics/Public/Analytics.h"
|
|
#include "Runtime/Analytics/Analytics/Public/Interfaces/IAnalyticsProvider.h"
|
|
#include "EngineBuildSettings.h"
|
|
|
|
// #CrashReport: 2015-07-23 Move crashes from C:\Users\[USER]\AppData\Local\Microsoft\Windows\WER\ReportQueue to C:\Users\[USER]\AppData\Local\CrashReportClient\Saved
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FCrashProperty
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FCrashProperty::FCrashProperty( const FString& InMainCategory, const FString& InSecondCategory, FPrimaryCrashProperties* InOwner )
|
|
: Owner( InOwner )
|
|
, CachedValue( TEXT("") )
|
|
, MainCategory( InMainCategory )
|
|
, SecondCategory( InSecondCategory )
|
|
, bSet( false )
|
|
{
|
|
|
|
}
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const FString& NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = NewValue;
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const TCHAR* NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = NewValue;
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const TArray<FString>& NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = Owner->EncodeArrayStringAsXMLString( NewValue );
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const bool NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = NewValue ? TEXT( "1" ) : TEXT( "0" );
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const int64 NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = LexicalConversion::ToString( NewValue );
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
const FString& FCrashProperty::AsString() const
|
|
{
|
|
if (!bSet)
|
|
{
|
|
Owner->GetCrashProperty( CachedValue, MainCategory, SecondCategory );
|
|
bSet = true;
|
|
}
|
|
return CachedValue;
|
|
}
|
|
|
|
|
|
bool FCrashProperty::AsBool() const
|
|
{
|
|
return AsString().ToBool();
|
|
}
|
|
|
|
int64 FCrashProperty::AsInt64() const
|
|
{
|
|
int64 Value = 0;
|
|
TTypeFromString<int64>::FromString( Value, *AsString() );
|
|
return Value;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FPrimaryCrashProperties
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FPrimaryCrashProperties* FPrimaryCrashProperties::Singleton = nullptr;
|
|
|
|
FPrimaryCrashProperties::FPrimaryCrashProperties()
|
|
// At this moment only these properties can be changed by the crash report client.
|
|
: PlatformFullName( FGenericCrashContext::RuntimePropertiesTag, TEXT( "PlatformFullName" ), this )
|
|
, CommandLine( FGenericCrashContext::RuntimePropertiesTag, TEXT( "CommandLine" ), this )
|
|
, UserName( FGenericCrashContext::RuntimePropertiesTag, TEXT("UserName"), this )
|
|
, MachineId( FGenericCrashContext::RuntimePropertiesTag, TEXT( "MachineId" ), this )
|
|
, EpicAccountId( FGenericCrashContext::RuntimePropertiesTag, TEXT( "EpicAccountId" ), this )
|
|
// Multiline properties
|
|
, CallStack( FGenericCrashContext::RuntimePropertiesTag, TEXT( "CallStack" ), this )
|
|
, SourceContext( FGenericCrashContext::RuntimePropertiesTag, TEXT( "SourceContext" ), this )
|
|
, Modules( FGenericCrashContext::RuntimePropertiesTag, TEXT( "Modules" ), this )
|
|
, UserDescription( FGenericCrashContext::RuntimePropertiesTag, TEXT( "UserDescription" ), this )
|
|
, ErrorMessage( FGenericCrashContext::RuntimePropertiesTag, TEXT( "ErrorMessage" ), this )
|
|
, FullCrashDumpLocation( FGenericCrashContext::RuntimePropertiesTag, TEXT( "FullCrashDumpLocation" ), this )
|
|
, TimeOfCrash( FGenericCrashContext::RuntimePropertiesTag, TEXT( "TimeOfCrash" ), this )
|
|
, bAllowToBeContacted( FGenericCrashContext::RuntimePropertiesTag, TEXT( "bAllowToBeContacted" ), this )
|
|
, XmlFile( nullptr )
|
|
{
|
|
CrashVersion = ECrashDescVersions::VER_1_NewCrashFormat;
|
|
CrashDumpMode = ECrashDumpMode::Default;
|
|
bHasMiniDumpFile = false;
|
|
bHasLogFile = false;
|
|
bHasPrimaryData = false;
|
|
}
|
|
|
|
void FPrimaryCrashProperties::Shutdown()
|
|
{
|
|
delete Get();
|
|
}
|
|
|
|
void FPrimaryCrashProperties::UpdateIDs()
|
|
{
|
|
const bool bAddPersonalData = FCrashReportClientConfig::Get().GetAllowToBeContacted() || FEngineBuildSettings::IsInternalBuild();
|
|
bAllowToBeContacted = bAddPersonalData;
|
|
if (bAddPersonalData)
|
|
{
|
|
// The Epic ID can be looked up from this ID.
|
|
EpicAccountId = FPlatformMisc::GetEpicAccountId();
|
|
}
|
|
else
|
|
{
|
|
EpicAccountId = FString();
|
|
}
|
|
|
|
// Add real user name only if log files were allowed since the user name is in the log file and the user consented to sending this information.
|
|
const bool bSendUserName = FCrashReportClientConfig::Get().GetSendLogFile() || FEngineBuildSettings::IsInternalBuild();
|
|
if (bSendUserName)
|
|
{
|
|
// Remove periods from user names to match AutoReporter user names
|
|
// The name prefix is read by CrashRepository.AddNewCrash in the website code
|
|
UserName = FString( FPlatformProcess::UserName() ).Replace( TEXT( "." ), TEXT( "" ) );
|
|
}
|
|
else
|
|
{
|
|
UserName = FString();
|
|
}
|
|
|
|
MachineId = FPlatformMisc::GetMachineId().ToString( EGuidFormats::Digits );
|
|
}
|
|
|
|
void FPrimaryCrashProperties::ReadXML( const FString& CrashContextFilepath )
|
|
{
|
|
XmlFilepath = CrashContextFilepath;
|
|
XmlFile = new FXmlFile( XmlFilepath );
|
|
TimeOfCrash = FDateTime::UtcNow().GetTicks();
|
|
UpdateIDs();
|
|
}
|
|
|
|
void FPrimaryCrashProperties::SetCrashGUID( const FString& Filepath )
|
|
{
|
|
FString CrashDirectory = FPaths::GetPath( Filepath );
|
|
FPaths::NormalizeDirectoryName( CrashDirectory );
|
|
// Grab the last component...
|
|
CrashGUID = FPaths::GetCleanFilename( CrashDirectory );
|
|
}
|
|
|
|
FString FPrimaryCrashProperties::EncodeArrayStringAsXMLString( const TArray<FString>& ArrayString ) const
|
|
{
|
|
const FString Encoded = FString::Join( ArrayString, TEXT("\n") );
|
|
return Encoded;
|
|
}
|
|
|
|
void FPrimaryCrashProperties::SendAnalytics()
|
|
{
|
|
// Connect the crash report client analytics provider.
|
|
FCrashReportAnalytics::Initialize();
|
|
|
|
IAnalyticsProvider& Analytics = FCrashReportAnalytics::GetProvider();
|
|
|
|
TArray<FAnalyticsEventAttribute> CrashAttributes;
|
|
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "bHasPrimaryData" ), bHasPrimaryData ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "CrashVersion" ), (int32)CrashVersion ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "CrashGUID" ), CrashGUID ) );
|
|
|
|
// AppID = GameName
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "GameName" ), GameName ) );
|
|
|
|
// AppVersion = EngineVersion
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EngineVersion" ), EngineVersion.ToString() ) );
|
|
|
|
// @see UpdateIDs()
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "MachineID" ), MachineId.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "UserName" ), UserName.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EpicAccountId" ), EpicAccountId.AsString() ) );
|
|
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "Platform" ), PlatformFullName.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "TimeOfCrash" ), TimeOfCrash.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EngineMode" ), EngineMode ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "AppDefaultLocale" ), AppDefaultLocale ) );
|
|
|
|
Analytics.RecordEvent( TEXT( "CrashReportClient.ReportCrash" ), CrashAttributes );
|
|
|
|
// Shutdown analytics.
|
|
FCrashReportAnalytics::Shutdown();
|
|
}
|
|
|
|
void FPrimaryCrashProperties::Save()
|
|
{
|
|
XmlFile->Save( XmlFilepath );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FCrashContextReader
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FCrashContext::FCrashContext( const FString& CrashContextFilepath )
|
|
{
|
|
ReadXML( CrashContextFilepath );
|
|
|
|
const bool bIsValid = XmlFile->IsValid();
|
|
if (bIsValid)
|
|
{
|
|
// Setup properties required for the analytics.
|
|
GetCrashProperty( CrashVersion, FGenericCrashContext::RuntimePropertiesTag, TEXT( "CrashVersion" ) );
|
|
GetCrashProperty( CrashGUID, FGenericCrashContext::RuntimePropertiesTag, TEXT( "CrashGUID" ) );
|
|
GetCrashProperty( CrashDumpMode, FGenericCrashContext::RuntimePropertiesTag, TEXT( "CrashDumpMode" ) );
|
|
GetCrashProperty( GameName, FGenericCrashContext::RuntimePropertiesTag, TEXT( "GameName" ) );
|
|
GetCrashProperty( EngineVersion, FGenericCrashContext::RuntimePropertiesTag, TEXT( "EngineVersion" ) );
|
|
|
|
GetCrashProperty( BaseDir, FGenericCrashContext::RuntimePropertiesTag, TEXT( "BaseDir" ) );
|
|
FString Misc_OSVersionMajor;
|
|
GetCrashProperty( Misc_OSVersionMajor, FGenericCrashContext::RuntimePropertiesTag, TEXT( "Misc.OSVersionMajor" ) );
|
|
FString Misc_OSVersionMinor;
|
|
GetCrashProperty( Misc_OSVersionMinor, FGenericCrashContext::RuntimePropertiesTag, TEXT( "Misc.OSVersionMinor" ) );
|
|
|
|
bool Misc_Is64bitOperatingSystem = false;
|
|
GetCrashProperty( Misc_Is64bitOperatingSystem, FGenericCrashContext::RuntimePropertiesTag, TEXT( "Misc.Is64bitOperatingSystem" ) );
|
|
|
|
// Extract the Platform component.
|
|
TArray<FString> SubDirs;
|
|
BaseDir.ParseIntoArray( SubDirs, TEXT( "/" ), true );
|
|
const int SubDirsNum = SubDirs.Num();
|
|
const FString PlatformName = SubDirsNum > 0 ? SubDirs[SubDirsNum - 1] : TEXT( "" );
|
|
if (Misc_OSVersionMajor.Len() > 0)
|
|
{
|
|
PlatformFullName = FString::Printf( TEXT( "%s [%s %s %s]" ), *PlatformName, *Misc_OSVersionMajor, *Misc_OSVersionMinor, Misc_Is64bitOperatingSystem ? TEXT( "64b" ) : TEXT( "32b" ) );
|
|
}
|
|
else
|
|
{
|
|
PlatformFullName = PlatformName;
|
|
}
|
|
|
|
GetCrashProperty( EngineMode, FGenericCrashContext::RuntimePropertiesTag, TEXT( "EngineMode" ) );
|
|
GetCrashProperty( AppDefaultLocale, FGenericCrashContext::RuntimePropertiesTag, TEXT( "AppDefaultLocale" ) );
|
|
|
|
if (CrashDumpMode == ECrashDumpMode::FullDump)
|
|
{
|
|
// Set the full dump crash location when we have a full dump.
|
|
const FString LocationForBranch = FCrashReportClientConfig::Get().GetFullCrashDumpLocationForBranch( EngineVersion.GetBranch() );
|
|
if (!LocationForBranch.IsEmpty())
|
|
{
|
|
FullCrashDumpLocation = LocationForBranch / CrashGUID + TEXT("_") + EngineVersion.ToString();
|
|
}
|
|
}
|
|
|
|
bHasPrimaryData = true;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FCrashDescription
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FCrashWERContext::FCrashWERContext( const FString& WERXMLFilepath )
|
|
: FPrimaryCrashProperties()
|
|
{
|
|
ReadXML( WERXMLFilepath );
|
|
CrashGUID = FPaths::GetCleanFilename( FPaths::GetPath( WERXMLFilepath ) );
|
|
|
|
const bool bIsValid = XmlFile->IsValid();
|
|
if (bIsValid)
|
|
{
|
|
FString BuildVersion;
|
|
FString BranchName;
|
|
uint32 BuiltFromCL = 0;
|
|
int EngineVersionComponents = 0;
|
|
|
|
GetCrashProperty( GameName, TEXT( "ProblemSignatures" ), TEXT( "Parameter0" ) );
|
|
|
|
GetCrashProperty( BuildVersion, TEXT( "ProblemSignatures" ), TEXT( "Parameter1" ) );
|
|
if (!BuildVersion.IsEmpty())
|
|
{
|
|
EngineVersionComponents++;
|
|
}
|
|
|
|
FString Parameter8Value;
|
|
GetCrashProperty( Parameter8Value, TEXT( "ProblemSignatures" ), TEXT( "Parameter8" ) );
|
|
if (!Parameter8Value.IsEmpty())
|
|
{
|
|
TArray<FString> ParsedParameters8;
|
|
Parameter8Value.ParseIntoArray( ParsedParameters8, TEXT( "!" ), false );
|
|
|
|
if (ParsedParameters8.Num() > 1)
|
|
{
|
|
CommandLine = FGenericCrashContext::UnescapeXMLString( ParsedParameters8[1] );
|
|
CrashDumpMode = CommandLine.AsString().Contains( TEXT( "-fullcrashdump" ) ) ? ECrashDumpMode::FullDump : ECrashDumpMode::Default;
|
|
}
|
|
|
|
if (ParsedParameters8.Num() > 2)
|
|
{
|
|
ErrorMessage = ParsedParameters8[2];
|
|
}
|
|
}
|
|
|
|
FString Parameter9Value;
|
|
GetCrashProperty( Parameter9Value, TEXT( "ProblemSignatures" ), TEXT( "Parameter9" ) );
|
|
if (!Parameter9Value.IsEmpty())
|
|
{
|
|
TArray<FString> ParsedParameters9;
|
|
Parameter9Value.ParseIntoArray( ParsedParameters9, TEXT( "!" ), false );
|
|
|
|
if (ParsedParameters9.Num() > 0)
|
|
{
|
|
BranchName = ParsedParameters9[0].Replace( TEXT( "+" ), TEXT( "/" ) );
|
|
|
|
const FString DepotRoot = TEXT( "//depot/" );
|
|
if (BranchName.StartsWith( DepotRoot ))
|
|
{
|
|
BranchName = BranchName.Mid( DepotRoot.Len() );
|
|
}
|
|
EngineVersionComponents++;
|
|
}
|
|
|
|
if (ParsedParameters9.Num() > 1)
|
|
{
|
|
const FString BaseDirectory = ParsedParameters9[1];
|
|
|
|
TArray<FString> SubDirs;
|
|
BaseDirectory.ParseIntoArray( SubDirs, TEXT( "/" ), true );
|
|
const int SubDirsNum = SubDirs.Num();
|
|
const FString PlatformName = SubDirsNum > 0 ? SubDirs[SubDirsNum - 1] : TEXT( "" );
|
|
|
|
FString Product;
|
|
GetCrashProperty( Product, TEXT( "OSVersionInformation" ), TEXT( "Product" ) );
|
|
if (Product.Len() > 0)
|
|
{
|
|
PlatformFullName = FString::Printf( TEXT( "%s [%s]" ), *PlatformName, *Product );
|
|
}
|
|
else
|
|
{
|
|
PlatformFullName = PlatformName;
|
|
}
|
|
}
|
|
|
|
if (ParsedParameters9.Num() > 2)
|
|
{
|
|
EngineMode = ParsedParameters9[2];
|
|
}
|
|
|
|
if (ParsedParameters9.Num() > 3)
|
|
{
|
|
TTypeFromString<uint32>::FromString( BuiltFromCL, *ParsedParameters9[3] );
|
|
EngineVersionComponents++;
|
|
}
|
|
}
|
|
|
|
// We have all three components of the engine version, so initialize it.
|
|
if (EngineVersionComponents == 3)
|
|
{
|
|
InitializeEngineVersion( BuildVersion, BranchName, BuiltFromCL );
|
|
}
|
|
|
|
bHasPrimaryData = true;
|
|
}
|
|
}
|
|
|
|
void FCrashWERContext::InitializeEngineVersion( const FString& BuildVersion, const FString& BranchName, uint32 BuiltFromCL )
|
|
{
|
|
uint16 Major = 0;
|
|
uint16 Minor = 0;
|
|
uint16 Patch = 0;
|
|
|
|
TArray<FString> ParsedBuildVersion;
|
|
BuildVersion.ParseIntoArray( ParsedBuildVersion, TEXT( "." ), false );
|
|
|
|
if (ParsedBuildVersion.Num() >= 3)
|
|
{
|
|
TTypeFromString<uint16>::FromString( Patch, *ParsedBuildVersion[2] );
|
|
}
|
|
|
|
if (ParsedBuildVersion.Num() >= 2)
|
|
{
|
|
TTypeFromString<uint16>::FromString( Minor, *ParsedBuildVersion[1] );
|
|
}
|
|
|
|
if (ParsedBuildVersion.Num() >= 1)
|
|
{
|
|
TTypeFromString<uint16>::FromString( Major, *ParsedBuildVersion[0] );
|
|
}
|
|
|
|
EngineVersion = FEngineVersion( Major, Minor, Patch, BuiltFromCL, BranchName );
|
|
}
|