FileHelperBPLibrary.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Copyright 2022 RLoris
  2. #pragma once
  3. #include "XmlFile.h"
  4. #include "JsonObjectConverter.h"
  5. #include "Kismet/BlueprintFunctionLibrary.h"
  6. #include "FileHelperBPLibrary.generated.h"
  7. class UDataTable;
  8. USTRUCT(BlueprintType)
  9. struct FCustomNodeStat
  10. {
  11. GENERATED_BODY();
  12. public:
  13. UPROPERTY(BlueprintReadOnly, Category = "FileSystem")
  14. bool IsDirectory;
  15. UPROPERTY(BlueprintReadOnly, Category = "FileSystem")
  16. bool IsReadOnly;
  17. UPROPERTY(BlueprintReadOnly, Category = "FileSystem")
  18. FDateTime LastAccessTime;
  19. UPROPERTY(BlueprintReadOnly, Category = "FileSystem")
  20. FDateTime CreationTime;
  21. UPROPERTY(BlueprintReadOnly, Category = "FileSystem")
  22. FDateTime ModificationTime;
  23. UPROPERTY(BlueprintReadOnly, Category = "FileSystem")
  24. int64 FileSize;
  25. FCustomNodeStat() : IsDirectory(false), IsReadOnly(false), LastAccessTime(FDateTime::MinValue()), CreationTime(FDateTime::MinValue()), ModificationTime(FDateTime::MinValue()), FileSize(0) {}
  26. };
  27. USTRUCT(BlueprintType)
  28. struct FProjectPath
  29. {
  30. GENERATED_BODY();
  31. public:
  32. UPROPERTY(BlueprintReadOnly, Category = "Path")
  33. FString Directory;
  34. UPROPERTY(BlueprintReadOnly, Category = "Path")
  35. FString Config;
  36. UPROPERTY(BlueprintReadOnly, Category = "Path")
  37. FString Content;
  38. UPROPERTY(BlueprintReadOnly, Category = "Path")
  39. FString Intermediate;
  40. UPROPERTY(BlueprintReadOnly, Category = "Path")
  41. FString Log;
  42. UPROPERTY(BlueprintReadOnly, Category = "Path")
  43. FString Mods;
  44. UPROPERTY(BlueprintReadOnly, Category = "Path")
  45. FString Plugins;
  46. UPROPERTY(BlueprintReadOnly, Category = "Path")
  47. FString Saved;
  48. UPROPERTY(BlueprintReadOnly, Category = "Path")
  49. FString User;
  50. UPROPERTY(BlueprintReadOnly, Category = "Path")
  51. FString PersistentDownload;
  52. UPROPERTY(BlueprintReadOnly, Category = "Path")
  53. FString PlatformExtensions;
  54. };
  55. USTRUCT(BlueprintType)
  56. struct FEnginePath
  57. {
  58. GENERATED_BODY();
  59. public:
  60. UPROPERTY(BlueprintReadOnly, Category = "Path")
  61. FString Directory;
  62. UPROPERTY(BlueprintReadOnly, Category = "Path")
  63. FString Config;
  64. UPROPERTY(BlueprintReadOnly, Category = "Path")
  65. FString Content;
  66. UPROPERTY(BlueprintReadOnly, Category = "Path")
  67. FString Intermediate;
  68. UPROPERTY(BlueprintReadOnly, Category = "Path")
  69. FString Plugins;
  70. UPROPERTY(BlueprintReadOnly, Category = "Path")
  71. FString Saved;
  72. UPROPERTY(BlueprintReadOnly, Category = "Path")
  73. FString User;
  74. UPROPERTY(BlueprintReadOnly, Category = "Path")
  75. FString DefaultLayout;
  76. UPROPERTY(BlueprintReadOnly, Category = "Path")
  77. FString PlatformExtensions;
  78. UPROPERTY(BlueprintReadOnly, Category = "Path")
  79. FString UserLayout;
  80. };
  81. /*
  82. * Function library class.
  83. * Each function in it is expected to be static and represents blueprint node that can be called in any blueprint.
  84. *
  85. * When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable.
  86. * BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins.
  87. * BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins.
  88. * DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu.
  89. * Its lets you name the node using characters not allowed in C++ function names.
  90. * CompactNodeTitle - the word(s) that appear on the node.
  91. * Keywords - the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu.
  92. * Good example is "Print String" node which you can find also by using keyword "log".
  93. * Category - the category your node will be under in the Blueprint drop-down menu.
  94. *
  95. * For more info on custom blueprint nodes visit documentation:
  96. * https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation
  97. */
  98. UCLASS()
  99. class UFileHelperBPLibrary : public UBlueprintFunctionLibrary
  100. {
  101. GENERATED_UCLASS_BODY()
  102. public:
  103. /* Paths */
  104. UFUNCTION(BlueprintPure, meta = (DisplayName = "GetEngineDirectories", CompactNodeTitle = "EngineDirs", Keywords = "File plugin path engine directory", ToolTip = "Gets the engine directories"), Category = "Path")
  105. static FEnginePath GetEngineDirectories();
  106. UFUNCTION(BlueprintPure, meta = (DisplayName = "GetProjectDirectories", CompactNodeTitle = "ProjectDirs", Keywords = "File plugin path project directory", ToolTip = "Gets the project directories"), Category = "Path")
  107. static FProjectPath GetProjectDirectories();
  108. /* Text file */
  109. UFUNCTION(BlueprintCallable, meta = (DisplayName = "ReadTextFile", CompactNodeTitle = "ReadText", Keywords = "File plugin read text", ToolTip = "Read a standard text file"), Category = "File|Text")
  110. static bool ReadText(FString Path, FString& Output);
  111. UFUNCTION(BlueprintCallable, meta = (DisplayName = "WriteTextFile", CompactNodeTitle = "WriteText", Keywords = "File plugin write text", ToolTip = "Save a standard text file"), Category = "File|Text")
  112. static bool SaveText(FString Path, FString Text, FString& Error, bool Append = false, bool Force = false);
  113. UFUNCTION(BlueprintCallable, meta = (DisplayName = "ReadLineFile", CompactNodeTitle = "ReadLine", Keywords = "File plugin read text lines pattern", ToolTip = "Read the lines of a standard text file"), Category = "File|Text")
  114. static bool ReadLine(FString Path, FString Pattern, TArray<FString>& Lines);
  115. UFUNCTION(BlueprintCallable, meta = (DisplayName = "ReadLineRangeFile", CompactNodeTitle = "ReadLineRange", Keywords = "File plugin read text lines range", ToolTip = "Read range of lines of a standard text file"), Category = "File|Text")
  116. static bool ReadLineRange(FString InPath, TArray<FString>& OutLines, int32 InStartIdx = 0, int32 InEndIdx = -1);
  117. UFUNCTION(BlueprintCallable, meta = (DisplayName = "WriteLineFile", CompactNodeTitle = "WriteLine", Keywords = "File plugin write text lines", ToolTip = "Save lines in a standard text file"), Category = "File|Text")
  118. static bool SaveLine(FString Path, const TArray<FString>& Text, FString& Error, bool Append = false, bool Force = false);
  119. UFUNCTION(BlueprintCallable, meta = (DisplayName = "ReadByteFile", CompactNodeTitle = "ReadByte", Keywords = "File plugin read byte", ToolTip = "Read byte file"), Category = "File|Byte")
  120. static bool ReadByte(FString Path, TArray<uint8>& Bytes);
  121. UFUNCTION(BlueprintCallable, meta = (DisplayName = "WriteByteFile", CompactNodeTitle = "WriteByte", Keywords = "File plugin write byte", ToolTip = "Save byte to file"), Category = "File|Byte")
  122. static bool SaveByte(FString Path, const TArray<uint8>& Bytes, FString& Error, bool Append = false, bool Force = false);
  123. /* Base64 */
  124. UFUNCTION(BlueprintPure, meta = (DisplayName = "StrToBase64", CompactNodeTitle = "ToBase64", Keywords = "File plugin string convert base64 encode", ToolTip = "Encodes a string to base64"), Category = "File|Text")
  125. static FString StringToBase64(const FString Source);
  126. UFUNCTION(BlueprintPure, meta = (DisplayName = "StrFromBase64", CompactNodeTitle = "FromBase64", Keywords = "File plugin string convert decode base64", ToolTip = "Decodes a string from base64"), Category = "File|Text")
  127. static bool StringFromBase64(FString Base64Str, FString& Result);
  128. UFUNCTION(BlueprintPure, meta = (DisplayName = "BytesToBase64", CompactNodeTitle = "ToBase64", Keywords = "File plugin bytes convert base64 encode", ToolTip = "Encodes a byte array to base64"), Category = "File|Byte")
  129. static FString BytesToBase64(const TArray<uint8> Bytes);
  130. UFUNCTION(BlueprintPure, meta = (DisplayName = "BytesFromBase64", CompactNodeTitle = "FromBase64", Keywords = "File plugin bytes convert base64 decode", ToolTip = "Decodes a byte array from base64"), Category = "File|Byte")
  131. static bool BytesFromBase64(const FString Source, TArray<uint8>& Out);
  132. /* CSV file */
  133. UFUNCTION(BlueprintCallable, meta = (DisplayName = "WriteCSVFile", CompactNodeTitle = "WriteCSV", Keywords = "File plugin write csv", ToolTip = "Save a csv file"), Category = "File|CSV")
  134. static bool SaveCSV(FString Path, TArray<FString> Headers, TArray<FString> Data, int32& Total, bool Force = false);
  135. UFUNCTION(BlueprintCallable, meta = (DisplayName = "ReadCSVFile", CompactNodeTitle = "ReadCSV", Keywords = "File plugin read csv", ToolTip = "Read a csv file"), Category = "File|CSV")
  136. static bool ReadCSV(FString Path, TArray<FString>& Headers, TArray<FString>& Data, int32& Total, bool HeaderFirst = true);
  137. /* CSV convert */
  138. UFUNCTION(BlueprintCallable, meta = (DisplayName = "StringToCSV", CompactNodeTitle = "StrToCSV", Keywords = "File plugin string csv", ToolTip = "convert a string to csv"), Category = "CSV")
  139. static bool StringToCSV(FString Content, TArray<FString>& Headers, TArray<FString>& Data, int32& Total, bool HeaderFirst = true);
  140. UFUNCTION(BlueprintCallable, meta = (DisplayName = "CSVToString", CompactNodeTitle = "CSVToStr", Keywords = "File plugin csv string", ToolTip = "convert a csv to string"), Category = "CSV")
  141. static bool CSVToString(FString& Result, TArray<FString> Headers, TArray<FString> Data, int32& Total);
  142. /* File system */
  143. UFUNCTION(BlueprintCallable, meta = (DisplayName = "IsFile", CompactNodeTitle = "IsFile", Keywords = "File plugin check file exist", ToolTip = "Check whether a file exists"), Category = "FileSystem")
  144. static bool IsFile(FString Path);
  145. UFUNCTION(BlueprintCallable, meta = (DisplayName = "IsDirectory", CompactNodeTitle = "IsDir", Keywords = "File plugin check directory exist", ToolTip = "Check whether a directory exists"), Category = "FileSystem")
  146. static bool IsDirectory(FString Path);
  147. UFUNCTION(BlueprintPure, meta = (DisplayName = "IsValidFilename", CompactNodeTitle = "IsValidName", Keywords = "File plugin check filename valid", ToolTip = "Check whether a filename is valid and can be used"), Category = "FileSystem")
  148. static bool IsValidFilename(FString Filename);
  149. UFUNCTION(BlueprintPure, meta = (DisplayName = "IsValidPath", CompactNodeTitle = "IsValidPath", Keywords = "File plugin check path valid", ToolTip = "Check whether a path is valid and can be used"), Category = "FileSystem")
  150. static bool IsValidPath(FString Path);
  151. UFUNCTION(BlueprintPure, meta = (DisplayName = "ValidateFilename", CompactNodeTitle = "ValidateName", Keywords = "File plugin validate path", ToolTip = "Validate a filename to be used on this file system"), Category = "FileSystem")
  152. static bool ValidateFilename(FString Filename, FString& ValidName);
  153. UFUNCTION(BlueprintCallable, meta = (DisplayName = "SetReadOnlyFlag", CompactNodeTitle = "SetReadOnly", Keywords = "File plugin read only path", ToolTip = "Updates the read only property on file"), Category = "FileSystem")
  154. static bool SetReadOnlyFlag(FString FilePath, bool Flag);
  155. UFUNCTION(BlueprintCallable, meta = (DisplayName = "GetReadOnlyFlag", CompactNodeTitle = "IsReadOnly", Keywords = "File plugin read only path", ToolTip = "Gets the read only property on file"), Category = "FileSystem")
  156. static bool GetReadOnlyFlag(FString FilePath);
  157. UFUNCTION(BlueprintCallable, meta = (DisplayName = "GetFileSize", CompactNodeTitle = "GetSize", Keywords = "File plugin size directory", ToolTip = "Gets the size of a file"), Category = "FileSystem")
  158. static int64 GetFileSize(FString FilePath);
  159. UFUNCTION(BlueprintCallable, meta = (DisplayName = "ListDirectory", CompactNodeTitle = "LsDir", Keywords = "File plugin list directory pattern regex recursive", ToolTip = "List nodes from directory"), Category = "FileSystem")
  160. static bool ListDirectory(FString Path, FString Pattern, TArray<FString>& Nodes, bool ShowFile = true, bool ShowDirectory = true, bool Recursive = false);
  161. UFUNCTION(BlueprintCallable, meta = (DisplayName = "MakeDirectory", CompactNodeTitle = "MkDir", Keywords = "File plugin make directory recursive", ToolTip = "Create a new directory"), Category = "FileSystem")
  162. static bool MakeDirectory(FString Path, bool Recursive = true);
  163. UFUNCTION(BlueprintCallable, meta = (DisplayName = "RemoveDirectory", CompactNodeTitle = "RmDir", Keywords = "File plugin remove directory recursive", ToolTip = "Removes a directory"), Category = "FileSystem")
  164. static bool RemoveDirectory(FString Path, bool Recursive = false);
  165. UFUNCTION(BlueprintCallable, meta = (DisplayName = "CopyDirectory", CompactNodeTitle = "CpDir", Keywords = "File plugin copy directory recursive", ToolTip = "Copies a directory"), Category = "FileSystem")
  166. static bool CopyDirectory(FString Source, FString Dest);
  167. UFUNCTION(BlueprintCallable, meta = (DisplayName = "MoveDirectory", CompactNodeTitle = "MvDir", Keywords = "File plugin move directory recursive", ToolTip = "Moves a directory"), Category = "FileSystem")
  168. static bool MoveDirectory(FString Source, FString Dest);
  169. UFUNCTION(BlueprintCallable, meta = (DisplayName = "NodeStats", CompactNodeTitle = "NodeStats", Keywords = "File plugin stats directory node", ToolTip = "Gets the stats of a node"), Category = "FileSystem")
  170. static bool NodeStats(FString Path, FCustomNodeStat& Stats);
  171. UFUNCTION(BlueprintCallable, meta = (DisplayName = "RemoveFile", CompactNodeTitle = "RmFile", Keywords = "File plugin remove file recursive", ToolTip = "Removes a file"), Category = "FileSystem")
  172. static bool RemoveFile(FString Path);
  173. UFUNCTION(BlueprintCallable, meta = (DisplayName = "CopyFile", CompactNodeTitle = "CpFile", Keywords = "File plugin copy file recursive", ToolTip = "Copies a file"), Category = "FileSystem")
  174. static bool CopyFile(FString Source, FString Dest, bool Force = false);
  175. UFUNCTION(BlueprintCallable, meta = (DisplayName = "MoveFile", CompactNodeTitle = "MvFile", Keywords = "File plugin move file recursive", ToolTip = "Moves a file"), Category = "FileSystem")
  176. static bool MoveFile(FString Source, FString Dest, bool Force = false);
  177. UFUNCTION(BlueprintCallable, meta = (DisplayName = "RenameFile", CompactNodeTitle = "RenameFile", Keywords = "File plugin rename file recursive", ToolTip = "Renames a file"), Category = "FileSystem")
  178. static bool RenameFile(FString Path, FString NewName);
  179. UFUNCTION(BlueprintPure, meta = (DisplayName = "PathParts", Keywords = "File plugin path parts", ToolTip = "Gets the parts of a path"), Category = "FileSystem")
  180. static void GetPathParts(FString Path, FString& PathPart, FString& BasePart, FString& ExtensionPart, FString& FileName);
  181. /* Datatable */
  182. UFUNCTION(BlueprintCallable, meta = (DisplayName = "DataTableToCSV", Keywords = "File plugin datatable csv convert export", ToolTip = "Converts a datatable to csv string"), Category = "Datatable")
  183. static bool DatatableToCSV(UDataTable* Table, FString& Output);
  184. UFUNCTION(BlueprintCallable, meta = (DisplayName = "DataTableToJSON", Keywords = "File plugin datatable json convert export", ToolTip = "Converts a datatable to json string"), Category = "Datatable")
  185. static bool DataTableToJSON(UDataTable* Table, FString& Output);
  186. UFUNCTION(BlueprintCallable, meta = (DisplayName = "CSVToDataTable", Keywords = "File plugin datatable csv convert import", ToolTip = "Converts a csv string to datatable"), Category = "Datatable")
  187. static UDataTable* CSVToDataTable(FString CSV, UScriptStruct* Struct, bool& Success);
  188. UFUNCTION(BlueprintCallable, meta = (DisplayName = "JSONToDataTable", Keywords = "File plugin datatable json convert import", ToolTip = "Converts a json string to datatable"), Category = "Datatable")
  189. static UDataTable* JSONToDataTable(FString JSON, UScriptStruct* Struct, bool& Success);
  190. /* Config file ini */
  191. UFUNCTION(BlueprintCallable, Category = "Config", CustomThunk, meta = (CustomStructureParam = "OutValue"))
  192. static void ReadConfig(FString FilePath, FString Section, FString Key, bool& Success, bool SingleLineArrayRead, UStruct*& OutValue);
  193. DECLARE_FUNCTION(execReadConfig)
  194. {
  195. P_GET_PROPERTY(FStrProperty, FilePath);
  196. P_GET_PROPERTY(FStrProperty, Section);
  197. P_GET_PROPERTY(FStrProperty, Key);
  198. P_GET_UBOOL_REF(Success);
  199. P_GET_UBOOL(SingleLineArrayRead);
  200. Stack.Step(Stack.Object, NULL);
  201. FProperty* Property = Stack.MostRecentProperty;
  202. void* ValuePtr = Stack.MostRecentPropertyAddress;
  203. P_FINISH;
  204. Success = UFileHelperBPLibrary::ReadConfigFile(FilePath, Section, Key, Property, ValuePtr, SingleLineArrayRead);
  205. }
  206. UFUNCTION(BlueprintCallable, Category = "Config", CustomThunk, meta = (CustomStructureParam = "Value"))
  207. static void WriteConfig(FString FilePath, FString Section, FString Key, bool& Success, bool SingleLineArrayWrite, const UStruct* Value);
  208. DECLARE_FUNCTION(execWriteConfig)
  209. {
  210. P_GET_PROPERTY(FStrProperty, FilePath);
  211. P_GET_PROPERTY(FStrProperty, Section);
  212. P_GET_PROPERTY(FStrProperty, Key);
  213. P_GET_UBOOL_REF(Success);
  214. P_GET_UBOOL(SingleLineArrayWrite);
  215. Stack.Step(Stack.Object, NULL);
  216. FProperty* Property = Stack.MostRecentProperty;
  217. void* ValuePtr = Stack.MostRecentPropertyAddress;
  218. P_FINISH;
  219. Success = UFileHelperBPLibrary::WriteConfigFile(FilePath, Section, Key, Property, ValuePtr, SingleLineArrayWrite);
  220. }
  221. UFUNCTION(BlueprintCallable, Category = "Config")
  222. static bool RemoveConfig(FString FilePath, FString Section, FString Key);
  223. protected:
  224. /* Utility */
  225. static TArray<FString> SplitString(FString String, FString Separator, ESearchCase::Type SearchCase);
  226. static bool StringArrayToCSV(TArray<FString> Lines, TArray<FString>& Headers, TArray<FString>& Data, int32& Total, FString Delimiter = ",", bool HeaderFirst = true);
  227. // config ini
  228. static bool WriteConfigFile(FString Filename, FString Section, FString Key, FProperty* Type, void* Value, bool SingleLineArray);
  229. static bool ReadConfigFile(FString Filename, FString Section, FString Key, FProperty* Type, void* Value, bool SingleLineArray);
  230. // datatable csv
  231. static bool WriteTableToCSV(const UDataTable& InDataTable, FString& Output);
  232. static bool WriteRowToCSV(const UScriptStruct* InRowStruct, const void* InRowData, FString& ExportedText);
  233. static bool WriteStructEntryToCSV(const void* InRowData, FProperty* InProperty, const void* InPropertyData, FString& ExportedText);
  234. // datatable json
  235. static FString GetKeyFieldName(const UDataTable& InDataTable);
  236. static bool WriteTableToJSON(const UDataTable& InDataTable, FString& OutExportText);
  237. static bool WriteTableAsObjectToJSON(const UDataTable& InDataTable, TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter);
  238. static bool WriteRowToJSON(const UScriptStruct* InRowStruct, const void* InRowData, TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter);
  239. static bool WriteStructToJSON(const UScriptStruct* InStruct, const void* InStructData, TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter);
  240. static bool WriteStructEntryToJSON(const void* InRowData, const FProperty* InProperty, const void* InPropertyData, TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter);
  241. static bool WriteContainerEntryToJSON(const FProperty* InProperty, const void* InPropertyData, const FString* InIdentifier, TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter);
  242. static void WriteJSONObjectStartWithOptionalIdentifier(TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter, const FString* InIdentifier);
  243. static void WriteJSONValueWithOptionalIdentifier(TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter, const FString* InIdentifier, const TCHAR* InValue);
  244. };