Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

156 lines
8.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "LauncherProfile.h"
#define LOCTEXT_NAMESPACE "SProjectLauncherValidation"
FString LexToStringLocalized(ELauncherProfileValidationErrors::Type Value)
{
static_assert(ELauncherProfileValidationErrors::Count == 31, "GetLocalizedValidationErrorMessage() needs to be updated to account for modified enum values.");
switch (Value)
{
case ELauncherProfileValidationErrors::CopyToDeviceRequiresCookByTheBook:
return LOCTEXT("CopyToDeviceRequiresCookByTheBookError", "Deployment by copying to device requires cooking or zen snapshot import.").ToString();
case ELauncherProfileValidationErrors::CustomRolesNotSupportedYet:
return LOCTEXT("CustomRolesNotSupportedYet", "Custom launch roles are not supported yet.").ToString();
case ELauncherProfileValidationErrors::DeployedDeviceGroupRequired:
return LOCTEXT("DeployedDeviceGroupRequired", "A device group must be selected when deploying builds.").ToString();
case ELauncherProfileValidationErrors::InitialCultureNotAvailable:
return LOCTEXT("InitialCultureNotAvailable", "The Initial Culture selected for launch is not in the build.").ToString();
case ELauncherProfileValidationErrors::InitialMapNotAvailable:
return LOCTEXT("InitialMapNotAvailable", "The Initial Map selected for launch is not in the build.").ToString();
case ELauncherProfileValidationErrors::MalformedLaunchCommandLine:
return LOCTEXT("MalformedLaunchCommandLine", "The specified launch command line is not formatted correctly.").ToString();
case ELauncherProfileValidationErrors::NoBuildConfigurationSelected:
return LOCTEXT("NoBuildConfigurationSelectedError", "A Build Configuration must be selected.").ToString();
case ELauncherProfileValidationErrors::NoCookedCulturesSelected:
return LOCTEXT("NoCookedCulturesSelectedError", "At least one Culture must be selected when cooking.").ToString();
case ELauncherProfileValidationErrors::NoLaunchRoleDeviceAssigned:
return LOCTEXT("NoLaunchRoleDeviceAssigned", "One or more launch roles do not have a device assigned.").ToString();
case ELauncherProfileValidationErrors::NoPlatformSelected:
return LOCTEXT("NoCookedPlatformSelectedError", "At least one Platform must be selected.").ToString();
case ELauncherProfileValidationErrors::NoProjectSelected:
return LOCTEXT("NoBuildGameSelectedError", "A Project must be selected.").ToString();
case ELauncherProfileValidationErrors::NoPackageDirectorySpecified:
return LOCTEXT("NoPackageDirectorySpecified", "The deployment requires a package directory to be specified.").ToString();
case ELauncherProfileValidationErrors::NoPlatformSDKInstalled:
return LOCTEXT("NoPlatformSDKInstalled", "A required platform SDK is missing.").ToString();
case ELauncherProfileValidationErrors::UnversionedAndIncremental:
return LOCTEXT("UnversionedAndIncremental", "Unversioned build cannot be incremental.").ToString();
case ELauncherProfileValidationErrors::GeneratingPatchesCanOnlyRunFromByTheBookCookMode:
return LOCTEXT("GeneratingPatchesCanOnlyRunFromByTheBookCookMode", "Generating patch requires cooking or zen snapshot import.").ToString();
case ELauncherProfileValidationErrors::GeneratingMultiLevelPatchesRequiresGeneratePatch:
return LOCTEXT("GeneratingMultiLevelPatchesRequiresGeneratePatch", "Generating multilevel patch requires generating patch.").ToString();
case ELauncherProfileValidationErrors::StagingBaseReleasePaksWithoutABaseReleaseVersion:
return LOCTEXT("StagingBaseReleasePaksWithoutABaseReleaseVersion", "Staging base release pak files requires a base release version to be specified").ToString();
case ELauncherProfileValidationErrors::GeneratingChunksRequiresCookByTheBook:
return LOCTEXT("GeneratingChunksRequiresCookByTheBook", "Generating Chunks requires cooking or zen snapshot import.").ToString();
case ELauncherProfileValidationErrors::GeneratingChunksRequiresUnrealPak:
return LOCTEXT("GeneratingChunksRequiresUnrealPak", "UnrealPak must be selected to Generate Chunks.").ToString();
case ELauncherProfileValidationErrors::GeneratingHttpChunkDataRequiresGeneratingChunks:
return LOCTEXT("GeneratingHttpChunkDataRequiresGeneratingChunks", "Generate Chunks must be selected to Generate Http Chunk Install Data.").ToString();
case ELauncherProfileValidationErrors::GeneratingHttpChunkDataRequiresValidDirectoryAndName:
return LOCTEXT("GeneratingHttpChunkDataRequiresValidDirectoryAndName", "Generating Http Chunk Install Data requires a valid directory and release name.").ToString();
case ELauncherProfileValidationErrors::ShippingDoesntSupportCommandlineOptionsCantUseCookOnTheFly:
return LOCTEXT("ShippingDoesntSupportCommandlineOptionsCantUseCookOnTheFly", "Shipping doesn't support commandline options and can't use cook on the fly").ToString();
case ELauncherProfileValidationErrors::CookOnTheFlyDoesntSupportServer:
return LOCTEXT("CookOnTheFlyDoesntSupportServer", "Cook on the fly doesn't support server target configurations").ToString();
case ELauncherProfileValidationErrors::LaunchDeviceIsUnauthorized:
return LOCTEXT("LaunchDeviceIsUnauthorized", "Device is unauthorized or locked.").ToString();
case ELauncherProfileValidationErrors::NoArchiveDirectorySpecified:
return LOCTEXT("NoArchiveDirectorySpecifiedError", "The archive step requires a valid directory.").ToString();
case ELauncherProfileValidationErrors::IoStoreRequiresPakFiles:
return LOCTEXT("IoStoreRequiresPakFilesError", "UnrealPak must be selected when using I/O store container file(s)").ToString();
case ELauncherProfileValidationErrors::BuildTargetCookVariantMismatch:
return LOCTEXT("BuildTargetCookVariantMismatch", "Build Target and Platform Variant mismatch.").ToString();
case ELauncherProfileValidationErrors::BuildTargetIsRequired:
return LOCTEXT("BuildTargetIsRequired", "This profile requires an explicit Build Target set.").ToString();
case ELauncherProfileValidationErrors::FallbackBuildTargetIsRequired:
return LOCTEXT("FallbackBuildTargetIsRequired", "An explicit Default Build Target is required for the selected Variant.").ToString();
case ELauncherProfileValidationErrors::CopyToDeviceRequiresNoPackaging:
return LOCTEXT("CopyToDeviceRequiresNoPackaging", "Deployment by copying to device requires 'Do not package' packaging.").ToString();
case ELauncherProfileValidationErrors::ZenPakStreamingRequiresDeployAndLaunch:
return LOCTEXT("ZenPakStreamingRequiresDeployAndLaunch", "Zen Pak Streaming requires deployment to a device and launching.").ToString();
default:
return TEXT("Unknown");
};
}
TSharedPtr<UE::Zen::Build::FBuildListRetriever> FLauncherProfile::BuildListRetriever;
TMap<FString, FLauncherProfile::FPlatformToBuildsMap> FLauncherProfile::PerProjectBuilds;
void FLauncherProfile::QueryZenSnapshotsForProject()
{
FString BuildType = TEXT("oplog");
FString Branch = FEngineVersion::Current().GetBranch();
Branch = Branch.Replace(TEXT("//"), TEXT("")).Replace(TEXT("/"), TEXT("-")).ToLower();
TSharedPtr<UE::Zen::Build::FBuildListRetriever> BuildRetriever = FLauncherProfile::GetBuildListRetriever();
BuildRetriever->QueryBuilds(GetProjectName(), BuildType, Branch,
[this](const TMap<FString, TArray<int32>>& PerPlatformBuilds) mutable
{
check(IsInGameThread());
FPlatformToBuildsMap& PlatformConfigToBuildMap = PerProjectBuilds.FindOrAdd(GetProjectName().ToLower());
PlatformConfigToBuildMap.Reset();
for (auto& Pair : PerPlatformBuilds)
{
// Find the closest changelist that is before the synced changelist
int32 ClosestBuild = -1;
const int32 ChangeListToMatch = FEngineVersion::Current().GetChangelist();
for (int32 Build : Pair.Value)
{
if (Build <= ChangeListToMatch)
{
ClosestBuild = Build;
}
else
{
break;
}
}
PlatformConfigToBuildMap.Add(Pair.Key, ClosestBuild);
}
}
);
}
int32 FLauncherProfile::GetZenSnapshot()
{
FString ProjectName = GetProjectName().ToLower();
if (PerProjectBuilds.Contains(ProjectName))
{
TArray<FString> Platforms = GetCookedPlatforms();
if (Platforms.Num() > 0)
{
FString Platform = Platforms[0].ToLower();
FPlatformToBuildsMap& Builds = PerProjectBuilds[ProjectName];
if (Builds.Contains(Platform))
{
return Builds[Platform];
}
}
}
else
{
QueryZenSnapshotsForProject();
}
return 0;
}
TSharedPtr<UE::Zen::Build::FBuildListRetriever> FLauncherProfile::GetBuildListRetriever()
{
if (!BuildListRetriever)
{
BuildListRetriever = MakeShared<UE::Zen::Build::FBuildListRetriever>();
BuildListRetriever->ConnectToBuildService();
}
return BuildListRetriever;
}
#undef LOCTEXT_NAMESPACE