// Copyright Epic Games, Inc. All Rights Reserved. #include "CookOnTheFly.h" #include "Modules/ModuleManager.h" #include "Misc/CommandLine.h" #include "Misc/DateTime.h" #include "HAL/FileManager.h" namespace UE { namespace Cook { FString FCookOnTheFlyMessageHeader::ToString() const { return FString::Printf(TEXT("Message='%s', Status='%s', Sender='%u', CorrelationId='%u'"), LexToString(MessageType), LexToString(MessageStatus), SenderId, CorrelationId); } FArchive& operator<<(FArchive& Ar, FCookOnTheFlyMessageHeader& Header) { uint32 MessageType = static_cast(Header.MessageType); uint32 MessageStatus = static_cast(Header.MessageStatus); Ar << MessageType; Ar << MessageStatus; Ar << Header.SenderId; Ar << Header.CorrelationId; Ar << Header.Timestamp; if (Ar.IsLoading()) { Header.MessageType = static_cast(MessageType); Header.MessageStatus = static_cast(MessageStatus); } return Ar; } FArchive& operator<<(FArchive& Ar, FCookOnTheFlyMessage& Message) { Ar << Message.Header; Ar << Message.Body; return Ar; } void FCookOnTheFlyMessage::SetBody(TArray InBody) { Body = MoveTemp(InBody); } TUniquePtr FCookOnTheFlyMessage::ReadBody() const { return MakeUnique(Body); } TUniquePtr FCookOnTheFlyMessage::WriteBody() { return MakeUnique(Body); } bool GetCookOnTheFlyHost(UE::Cook::FCookOnTheFlyHostOptions& OutHostOptions) { bool bOptionsOk = false; if (FParse::Param(FCommandLine::Get(), TEXT("CookOnTheFly"))) { // Cook-on-the-fly expects the same host as the Zen storage server FString Host; if (FParse::Value(FCommandLine::Get(), TEXT("-ZenStoreHost="), Host)) { if (!Host.ParseIntoArray(OutHostOptions.Hosts, TEXT("+"), true)) { OutHostOptions.Hosts.Add(Host); } bOptionsOk = true; } } double ServerWaitTimeInSeconds; if (FParse::Value(FCommandLine::Get(), TEXT("-CookOnTheFlyServerWaitTime="), ServerWaitTimeInSeconds)) { OutHostOptions.ServerStartupWaitTime = FTimespan::FromSeconds(ServerWaitTimeInSeconds); } return bOptionsOk; } bool SendCookOnTheFlyRequest(ECookOnTheFlyMessage RequestType, TFunction&& FillRequest, TFunction&& ProcessResponse) { if (!IsRunningCookOnTheFly()) { return false; } static FString FileHostIP; static bool bUseFileServer = FParse::Value(FCommandLine::Get(), TEXT("filehostip"), FileHostIP); if (bUseFileServer) { struct FFileServerMessageHandler : public IPlatformFile::IFileServerMessageHandler { FFileServerMessageHandler(TFunction&& InFillRequest, TFunction&& InProcessResponse) : FillRequestHandler(InFillRequest) , ProcessResponseHandler(InProcessResponse) { } virtual void FillPayload(FArchive& Payload) override { FillRequestHandler(Payload); } virtual void ProcessResponse(FArchive& Response) override { ProcessResponseHandler(Response); } TFunction FillRequestHandler; TFunction ProcessResponseHandler; }; FFileServerMessageHandler MessageHandler(MoveTemp(FillRequest), MoveTemp(ProcessResponse)); return IFileManager::Get().SendMessageToServer(LexToString(RequestType), &MessageHandler); } else { static ICookOnTheFlyModule& CookOnTheFlyModule = FModuleManager::LoadModuleChecked(TEXT("CookOnTheFly")); ICookOnTheFlyServerConnection& ServerConnection = CookOnTheFlyModule.GetServerConnection(); FCookOnTheFlyRequest Request(RequestType); { TUniquePtr Ar = Request.WriteBody(); FillRequest(*Ar); } FCookOnTheFlyResponse Response = ServerConnection.SendRequest(Request).Get(); if (Response.IsOk()) { TUniquePtr Ar = Response.ReadBody(); ProcessResponse(*Ar); } return Response.IsOk(); } } }} // namesapce UE::Cook