2025-03-10 09:43:27 +08:00
// Copyright 2017-2020 David Romanski(Socke). All Rights Reserved.
# pragma once
# include "WebCommunication.h"
# include "WebCommunicationBPLibrary.generated.h"
class UWebCommunicationRequestCompleteObject ;
class FByteToFileThread ;
class FWebComTruncateUploadedFileThread ;
class UAsyncNodeWebCom ;
UCLASS ( )
class WEBCOMMUNICATION_API UWebCommunicationBPLibrary : public UBlueprintFunctionLibrary
{
GENERATED_UCLASS_BODY ( )
public :
static UWebCommunicationBPLibrary * webcom ;
~ UWebCommunicationBPLibrary ( ) ;
//Delegates
DECLARE_DYNAMIC_MULTICAST_DELEGATE_SixParams ( FhttpRequestCompleteDelegate , const FString , dataString , const TArray < FString > & , dataArray , const TArray < FString > & , header , const int32 , statusCode , const TArray < uint8 > & , byteData , const FString , requestID ) ;
UFUNCTION ( )
void httpRequestCompleteDelegate ( const FString dataString , const TArray < FString > & dataArray , const TArray < FString > & header , const int32 statusCode , const TArray < uint8 > & byteData , const FString requestID ) ;
UPROPERTY ( BlueprintAssignable , Category = " WebCommunication|Events|RequestComplete " )
FhttpRequestCompleteDelegate onhttpRequestCompleteDelegate ;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams ( FhttpRequestCompleteGoogleInfoDelegate , const FString , fileName , const int64 , fileSizeInBytes , const int32 , statusCode , const FString , downloadID , const FString , requestID ) ;
UFUNCTION ( )
void httpRequestCompleteGoogleInfoDelegate ( const FString fileName , const int64 fileSizeInBytes , const int32 statusCode , const FString downloadID , const FString requestID ) ;
UPROPERTY ( BlueprintAssignable , Category = " WebCommunication|Events|RequestCompleteGoogleInfo " )
FhttpRequestCompleteGoogleInfoDelegate onhttpRequestCompleteGoogleInfoDelegate ;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams ( FhttpFileProgressDelegate , const float , size , const int32 , bytesSent , const float , percentUpload , const int32 , bytesReceived , const float , percentDownload ) ;
/**
* This function is deprecated and will be removed . Please use httpFileDownload or httpFileUpload .
*/
//UFUNCTION()
// void httpFileProgressDelegate(const float size, const int32 bytesSent, const float percentUpload, const int32 bytesReceived, const float percentDownload);
//UPROPERTY(BlueprintAssignable, Category = "WebCommunication|Deprecated|Events|FileProgress")
// FhttpFileProgressDelegate onhttpFileProgressDelegate;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams ( FhttpFileDownloadDelegate , const float , size , const float , megaBytesReceived , const float , percentDownload , const float , megaBit , const FString , requestID ) ;
/**
* @ param size Filesize in Megabyte
* @ param megaBit Downloadspeed in Megabit / second
*/
UFUNCTION ( )
void httpFileDownloadDelegate ( const float size , const float megaBytesReceived , const float percentDownload , const float megaBit , const FString requestID ) ;
UPROPERTY ( BlueprintAssignable , Category = " WebCommunication|Events|Download " )
FhttpFileDownloadDelegate onhttpFileDownloadDelegate ;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams ( FhttpFileUploadDelegate , const float , size , const int32 , bytesSent , const float , percentUpload , const FString , requestID ) ;
/**
* @ param size Filesize in Byte
*/
UFUNCTION ( )
void httpFileUploadDelegate ( const float size , const int32 bytesSent , const float percentUpload , const FString requestID ) ;
UPROPERTY ( BlueprintAssignable , Category = " WebCommunication|Events|Upload " )
FhttpFileUploadDelegate onhttpFileUploadDelegate ;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams ( FhttpServerSendEventDelegate , const FString , response , const FString , requestID ) ;
UFUNCTION ( )
void httpServerSendEventDelegate ( const FString response , const FString requestID ) ;
UPROPERTY ( BlueprintAssignable , Category = " WebCommunication|Events|ServerSendEvent " )
FhttpServerSendEventDelegate onhttpServerSendEventDelegate ;
/**
* This function is deprecated and will be removed . Please use getWebCommunicationTarget .
*/
//UFUNCTION(BlueprintCallable, BlueprintPure, Category = "WebCommunication|Deprecated")
// static UWebCommunicationBPLibrary* getTarget();
/**
* Return a Target for the Events
*/
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " WebCommunication " )
static UWebCommunicationBPLibrary * getWebCommunicationTarget ( ) ;
/**
* This function is deprecated and will be removed . Please use httpRequestGET .
*/
//UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
// static UWebCommunicationBPLibrary* httpRequestGET(FString url, FString optionalRequestID, FString &requestID);
/**
* Send a GET HTTP Request to Webserver .
* @ param optionalRequestID Your own RequestID . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
* @ param requestID It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
* @ param bindServerSendEvent Activates the " Server Send Event " for this http request . If you as a client want to get multiple http responses from the server for one http request you can use the http technique " Server Sent Events " .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|GET " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header " ) )
static int32 CreateHttpRequestGET ( TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , FString optionalRequestID , bool bindServerSendEvent , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
/**
* For downloads . Data is copied to the hard disk if you cancel the download .
* @ param ActionIfFileExists Overwrite = overwrites an existing file otherwise a new one will be created . Cancel Download = If the file already exists , the download will be aborted . Resume = Download continues . If the file is missing , the download is started from the beginning .
* @ param optionalRequestID Your own RequestID . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
* @ param requestID It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|Download " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header " ) )
static int32 CreateHttpRequestGETDownload ( TArray < struct FhttpRequest > & httpRequests , FString & requestID , TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , EHTTPWebComFileDownloadResumeType ActionIfFileExists , EHTTPWebComFileUpload DirectoryType , FString filePathWithFileName , FString optionalRequestID = " " ) ;
/**
* For downloads . The file is downloaded in steps . This significantly reduces RAM consumption . The web server must support resuming aborted downloads .
* @ param ActionIfFileExists Overwrite = overwrites an existing file otherwise a new one will be created . Cancel Download = If the file already exists , the download will be aborted . Resume = Download continues . If the file is missing , the download is started from the beginning .
* @ param FileSizeStepsInBytes Default = 10 megabytes . Steps in which the download is aborted and restarted . Specified in bytes . You can use the node " MegabyteToByte " for conversion .
* @ param optionalRequestID Your own RequestID . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
* @ param requestID It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|Download " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header " ) )
static int32 CreateHttpRequestGETLowRamDownload ( TArray < struct FhttpRequest > & httpRequests , FString & requestID , TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , EHTTPWebComFileDownloadResumeType ActionIfFileExists , EHTTPWebComFileUpload DirectoryType , FString filePathWithFileName , int32 FileSizeStepsInBytes = 10485760 , FString optionalRequestID = " " ) ;
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|GET " , meta = ( AutoCreateRefTerm = " otherHttpRequests " ) )
static int32 CreateHttpRequestGoogleDrive ( TArray < struct FhttpRequest > otherHttpRequests , FString downloadID , FString optionalRequestID , int64 optionalFileSizeInByte , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|GET " , meta = ( AutoCreateRefTerm = " otherHttpRequests " ) )
static int32 CreateHttpRequestGoogleDriveFileInfo ( TArray < struct FhttpRequest > otherHttpRequests , FString downloadID , FString optionalRequestID , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|GET " , meta = ( AutoCreateRefTerm = " otherHttpRequests " ) )
static int32 CreateHttpRequestAnonfiles ( TArray < struct FhttpRequest > otherHttpRequests , FString url , FString optionalRequestID , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static void executeHttpRequests ( TArray < struct FhttpRequest > httpRequests , UWebCommunicationBPLibrary * & WebCommunicationTarget ) ;
/**
* Send a POST HTTP Request to Webserver .
* @ param url
* @ param POSTData
* @ param requestID Optional parameter . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
* @ param bindServerSendEvent Activates the " Server Send Event " for this http request . If you as a client want to get multiple http responses from the server for one http request you can use the http technique " Server Sent Events " .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|POST " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header " ) )
static int32 CreateHttpRequestPOST ( TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , TMap < FString , FString > POSTData , FString optionalRequestID , bool bindServerSendEvent , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
/**
* Individual HTTP Request . You have to set all parameters yourself .
*
* @ param url Server URL
* @ param header User - Agent , Content - Type
* @ param verb POST , GET , PUT , PATCH , DELETE
* @ param content Request Body or Filepath
* @ param requestID Optional parameter . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
* @ param addContentLengthHeader add Content - Length header with the length of the content .
* @ param bindServerSendEvent Activates the " Server Send Event " for this http request . If you as a client want to get multiple http responses from the server for one http request you can use the http technique " Server Sent Events " .
*/
2025-07-29 14:53:32 +08:00
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|Individual " , meta = ( AutoCreateRefTerm = " otherHttpRequests,binaryContent " ) )
2025-03-10 09:43:27 +08:00
static void CreateHttpRequestIndividual ( TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , FString verb ,
2025-07-29 14:53:32 +08:00
EHTTPWebComIndividualType contentBodyType , FString contentBody , TArray < uint8 > binaryContent , FString optionalRequestID , TArray < struct FhttpRequest > & httpRequests ,
2025-03-10 09:43:27 +08:00
FString & requestID , bool addContentLengthHeader = true , bool bindDownloadProgressEvent = false , bool bindUploadProgressEvent = false , bool bindServerSendEvent = false ) ;
/**
* Send a Fila to a Webserver .
*
* @ param url Server URL
* @ param DirectoryType Absolute or Relative
* @ param id name equivalent to < input type = " file " name = " myFile " > from an html upload
* @ param filePath File with path
* @ param uploadType Upload progress is only refreshed with type PUT
* @ param requestID Optional parameter . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
*/
/*UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
static void httpRequestFileUpload ( FString url , EHTTPWebComFileUpload DirectoryType , FString id , FString filePath , EHTTPWebComFileUploadType uploadType , FString optionalRequestID , FString & requestID ) ; */
/**
* Send a file to a Webserver .
*
* @ param otherHttpRequests
* @ param url Server URL
* @ param DirectoryType Absolute or Relative
* @ param filePath path with filename at the end
* @ param fileID name equivalent to < input type = " file " name = " myFile " > from an html upload
* @ param requestID Optional parameter . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|File Upload " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header,POSTData " ) )
static int32 CreateHttpRequestFileUploadPOST ( TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , EHTTPWebComFileUpload DirectoryType , FString filePath , FString fileID , TMap < FString , FString > POSTData , FString optionalRequestID , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
/**
* Send multiple files to a Webserver .
*
* @ param otherHttpRequests
* @ param url Server URL
* @ param DirectoryType Absolute or Relative
* @ param filePaths paths with filenames at the ends
* @ param fileIDs names equivalent to < input type = " file " name = " myFile " > from an html upload . It is also possible to enter only one file ID for all files .
* @ param requestID Optional parameter . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|File Upload " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header,POSTData " ) )
static int32 CreateHttpRequestFileMultiUploadPOST ( TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , EHTTPWebComFileUpload DirectoryType , TArray < FString > filePaths , TArray < FString > fileIDs , TMap < FString , FString > POSTData , FString optionalRequestID , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
/**
* Send a file to a Webserver .
*
* @ param otherHttpRequests
* @ param url Server URL
* @ param DirectoryType Absolute or Relative
* @ param filePath path with filename at the end
* @ param fileID name equivalent to < input type = " file " name = " myFile " > from an html upload
* @ param requestID Optional parameter . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
* @ param uploadType
PUT Stream ( Blank ) : With this option only the file is written into the http body and nothing else . If your server can handle it then use this option . Additionally headers will be created . fileid , filename , fileformat , mimetype
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PUT Stream ( Multiplart ) : With this option a header is created which goes with a trick into the body and writes the necessary information of the file into the body . Important ! The only way to write something at the end of the body is to write this information into the file .
After the upload is finished or canceled the plugin removes this information from the file .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PUT Stream ( Copy Multiplart ) : This option also writes information to the file . But a copy of the file is created before and the info is written into the copy . The copy will be deleted after the upload . Making a copy of a large file can lead to freezing because it is done in the game thread .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|File Upload " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header " ) )
static int32 CreateHttpRequestFileUploadPUT ( TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , EHTTPWebComFileUpload DirectoryType , FString filePath , FString fileID , EHTTPWebComFileUploadType uploadType , FString optionalRequestID , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
/**
* Send multiple files to a Webserver .
*
* @ param otherHttpRequests
* @ param url Server URL
* @ param DirectoryType Absolute or Relative
* @ param filePaths paths with filenames at the ends
* @ param fileIDs names equivalent to < input type = " file " name = " myFile " > from an html upload . It is also possible to enter only one file ID for all files .
* @ param requestID Optional parameter . It will be output again in the httpRequestComplete event . This allows the request being assigned to the response .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|File Upload " , meta = ( AutoCreateRefTerm = " otherHttpRequests,header " ) )
static int32 CreateHttpRequestFileMultiUploadPUT ( TArray < struct FhttpRequest > otherHttpRequests , FString url , TMap < FString , FString > header , EHTTPWebComFileUpload DirectoryType , TArray < FString > filePaths , TArray < FString > fileIDs , FString optionalRequestID , TArray < struct FhttpRequest > & httpRequests , FString & requestID ) ;
/**
* This function is deprecated and will be removed . Please use httpRequestPOST .
*/
//UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
// static TArray<FString> createAndAppendPOSTData(FString id, FString value, TArray<FString> POSTData);
/**
* This function is deprecated and will be removed . Please use httpRequestPOST .
*/
//UFUNCTION(BlueprintCallable, Category = "WebCommunication|Deprecated")
// static TArray<FString> createPOSTData(FString id, FString value);
/**
* Header is added to each request .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|Header " )
static void addPersistentHTTPRequestHeader ( FString id , FString value ) ;
UFUNCTION ( BlueprintCallable , Category = " WebCommunication|Header " )
static void removePersistentHTTPRequestHeader ( FString id ) ;
/**
* Create a File from bytes .
*
* @ param byteData from httpRequestCompleteDelegate Event
* @ param DirectoryType Absolute or Relative
* @ param filePath path with filename c : \ myFile . zip or content \ myFile . zip
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static void byteDataToFile ( EHTTPWebComFileBytesToFileActionType fileAction , TArray < uint8 > byteData , EHTTPWebComFileUpload DirectoryType , FString filePath ) ;
/**
* Returns a percent - encoded version of the passed in string . Do not use with strings with http : : // but for the parameters.
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static FString urlEncode ( FString urlParameter ) ;
/**
* Returns a percent - encoded version of the passed in string . Do not use with strings with http : : // but for the parameters.
*/
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " WebCommunication " )
static FString urlEncodePure ( FString urlParameter ) ;
/**
* Cancel Request
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static void cancelRequest ( FString requestID ) ;
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " WebCommunication " )
static int32 megabyteToByte ( int32 mb ) ;
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " WebCommunication " )
static float byteToMegabyte ( int32 byte ) ;
/**
* With a multipart PUT STREAM upload something must be written at the end of the file . With this function you can check if the part is still in the file .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static void searchUploadLeftovers ( EHTTPWebComFileUpload DirectoryType , FString filePath , bool & foundLeftovers , int64 & originalFileSize ) ;
/**
* With a multipart PUT STREAM upload something must be written at the end of the file . With this function the part can be removed . In this function the function searchUploadLeftovers is called .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static bool repairFileAfterUpload ( EHTTPWebComFileUpload DirectoryType , FString filePath ) ;
/**
* Determines the mime type based on the file extension .
*/
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static void getMimeTypeByFile ( EHTTPWebComFileUpload DirectoryType , FString filePath , FString & mimeType , bool & success ) ;
UFUNCTION ( BlueprintCallable , Category = " WebCommunication " )
static TMap < FString , FString > getMimeTypeMap ( ) ;
void addRequestToTruncateThread ( FhttpRequest & httpRequest ) ;
bool isFileBlocked ( FString filePath ) ;
TMap < FString , FString > additionalHeader ;
bool removeHeaders ;
FString getMimeTypeInternal ( FString fileType ) ;
TMap < FString , FString > mimeTypes ;
TMap < FString , FString > toCancelRequests ;
TMap < FString , TSharedRef < IHttpRequest , ESPMode : : ThreadSafe > > startedRequests ;
FByteToFileThread * getByteToFileThread ( ) ;
static FString Int64ToFString ( int64 Num ) ;
void startRequests ( TArray < struct FhttpRequest > & httpRequests ) ;
void registerUAsyncNodeHttpRequest ( FString requestID , UAsyncNodeWebCom * asyncNodeHttpRequest ) ;
void unregisterUAsyncNodeHttpRequest ( FString requestID ) ;
UAsyncNodeWebCom * getUAsyncNodeHttpRequest ( FString requestID ) ;
//void registerUAsyncNodeGoogleInfoRequest(FString requestID, UAsyncNodeHttpGoogleFileInfoRequest* asyncNodeHttpRequest);
//void unregisterUAsyncNodeGoogleInfoRequest(FString requestID);
//UAsyncNodeHttpGoogleFileInfoRequest* getUAsyncNodeGoogleInfoRequest(FString requestID);
private :
TMap < FString , UAsyncNodeWebCom * > asyncNodeHttpRequests ;
static void fireErrorMessageInGameThread ( UAsyncNodeWebCom * asyncNodeHttpRequest , int32 errorCode , FString requestID ) ;
void fillRequestGET ( struct FhttpRequest & requestStruct , TSharedRef < IHttpRequest , ESPMode : : ThreadSafe > request ) ;
void fillRequestPOST ( struct FhttpRequest & requestStruct , TSharedRef < IHttpRequest , ESPMode : : ThreadSafe > request ) ;
void fillHeader ( FhttpRequest & requestStruct , TSharedRef < IHttpRequest , ESPMode : : ThreadSafe > request ) ;
bool fillRequestUPLOAD ( struct FhttpRequest & requestStruct , TSharedRef < IHttpRequest , ESPMode : : ThreadSafe > request ) ;
TArray < uint8 > fstringToByteArray ( FString data ) ;
FString postMapToString ( TMap < FString , FString > POSTData ) ;
class FByteToFileThread * byteToFileThread = nullptr ;
class FWebComTruncateUploadedFileThread * truncateUploadedFileThread = nullptr ;
} ;
class FByteToFileThread : public FRunnable {
public :
FByteToFileThread ( ) {
FString threadName = " FByteToFileThread " + FGuid : : NewGuid ( ) . ToString ( ) ;
thread = FRunnableThread : : Create ( this , * threadName , 0 , EThreadPriority : : TPri_Normal ) ;
}
virtual uint32 Run ( ) override {
while ( true ) {
while ( fileQueue . IsEmpty ( ) = = false ) {
FfileToByteStruct fileToByteStruct ;
fileQueue . Dequeue ( fileToByteStruct ) ;
if ( fileToByteStruct . byteData . Num ( ) < = 0 ) {
UE_LOG ( LogTemp , Error , TEXT ( " UWebCommunicationBPLibrary: Empty byteData Array. " ) ) ;
break ;
}
if ( fileToByteStruct . filePath . IsEmpty ( ) ) {
UE_LOG ( LogTemp , Error , TEXT ( " UWebCommunicationBPLibrary: FilePath not set. " ) ) ;
break ;
}
FString dir ;
if ( fileToByteStruct . DirectoryType = = EHTTPWebComFileUpload : : E_ad ) {
dir = FPaths : : ConvertRelativePathToFull ( fileToByteStruct . filePath ) ;
}
else {
FString gameDir = FPaths : : ProjectDir ( ) ;
dir = FPaths : : ConvertRelativePathToFull ( gameDir + fileToByteStruct . filePath ) ;
}
switch ( fileToByteStruct . fileAction )
{
case EHTTPWebComFileBytesToFileActionType : : E_NOT_OVERWRITE :
if ( FPaths : : FileExists ( dir ) ) {
UE_LOG ( LogTemp , Warning , TEXT ( " UWebCommunicationBPLibrary: File exist. Cancel write to file. " ) ) ;
break ;
}
break ;
case EHTTPWebComFileBytesToFileActionType : : E_OVERWRITE :
FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . DeleteFile ( * dir ) ;
}
FArchive * writer = IFileManager : : Get ( ) . CreateFileWriter ( * dir , EFileWrite : : FILEWRITE_Append ) ;
if ( ! writer ) {
UE_LOG ( LogTemp , Error , TEXT ( " ByteDataToFile: Can't write into %s " ) , * dir ) ;
}
else {
writer - > Seek ( writer - > TotalSize ( ) ) ;
writer - > Serialize ( fileToByteStruct . byteData . GetData ( ) , fileToByteStruct . byteData . Num ( ) ) ;
writer - > Flush ( ) ;
writer - > Close ( ) ;
fileToByteStruct . byteData . Empty ( ) ;
fileToByteStruct . filePath . Empty ( ) ;
}
delete writer ;
}
pauseThread ( true ) ;
//workaround. suspend do not work on all platforms(IOS,Android). lets sleep
while ( paused ) {
FPlatformProcess : : Sleep ( 0.01 ) ;
}
}
thread = nullptr ;
return 0 ;
}
void saveFile ( FfileToByteStruct & fileToByteStruct ) {
fileQueue . Enqueue ( fileToByteStruct ) ;
pauseThread ( false ) ;
}
void pauseThread ( bool pause ) {
paused = pause ;
if ( thread ! = nullptr )
thread - > Suspend ( pause ) ;
}
protected :
TQueue < FfileToByteStruct > fileQueue ;
FRunnableThread * thread = nullptr ;
bool paused ;
} ;
class FWebComTruncateUploadedFileThread : public FRunnable {
public :
FWebComTruncateUploadedFileThread ( ) {
FString threadName = " FWebComTruncateUploadedFileThread " + FGuid : : NewGuid ( ) . ToString ( ) ;
thread = FRunnableThread : : Create ( this , * threadName , 0 , EThreadPriority : : TPri_Normal ) ;
}
virtual uint32 Run ( ) override {
while ( true ) {
while ( httpRequestQueue . IsEmpty ( ) = = false ) {
FhttpRequest httpRequest ;
httpRequestQueue . Dequeue ( httpRequest ) ;
//Wait until the file has been released.
FPlatformProcess : : Sleep ( 2 ) ;
if ( httpRequest . requestType = = EHTTPWebComRequestType : : PUT_STREAM_MP & & ! httpRequest . filePath . IsEmpty ( ) & & httpRequest . originalFileSize > 0 ) {
IFileHandle * f = FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . OpenWrite ( * httpRequest . filePath , true , true ) ;
if ( f ! = nullptr ) {
bool truncate = f - > Truncate ( httpRequest . originalFileSize ) ;
f - > Flush ( ) ;
if ( truncate ) {
UE_LOG ( LogTemp , Display , TEXT ( " UWebCommunicationBPLibrary: truncate okay: %s " ) , * httpRequest . filePath ) ;
}
else {
UE_LOG ( LogTemp , Display , TEXT ( " UWebCommunicationBPLibrary: truncate fail: %s " ) , * httpRequest . filePath ) ;
}
delete f ;
}
blockedFiles . Remove ( httpRequest . filePath ) ;
}
if ( httpRequest . requestType = = EHTTPWebComRequestType : : PUT_STREAM_COPY & & ! httpRequest . filePath . IsEmpty ( ) ) {
if ( FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . DeleteFile ( * httpRequest . filePath ) ) {
UE_LOG ( LogTemp , Display , TEXT ( " UWebCommunicationBPLibrary: upload copy has been deleted: %s " ) , * httpRequest . filePath ) ;
}
else {
UE_LOG ( LogTemp , Display , TEXT ( " UWebCommunicationBPLibrary: upload copy could not be deleted: %s " ) , * httpRequest . filePath ) ;
}
blockedFiles . Remove ( httpRequest . filePath ) ;
}
}
pauseThread ( true ) ;
//workaround. suspend do not work on all platforms(IOS,Android). lets sleep
while ( paused ) {
FPlatformProcess : : Sleep ( 1 ) ;
}
}
thread = nullptr ;
return 0 ;
}
void addRequest ( FhttpRequest & httpRequestP ) {
httpRequestQueue . Enqueue ( httpRequestP ) ;
blockedFiles . Add ( httpRequestP . filePath ) ;
pauseThread ( false ) ;
}
void pauseThread ( bool pause ) {
paused = pause ;
if ( thread ! = nullptr )
thread - > Suspend ( pause ) ;
}
TArray < FString > blockedFiles ;
protected :
TQueue < FhttpRequest > httpRequestQueue ;
FRunnableThread * thread = nullptr ;
bool paused ;
} ;