From 41865c3b90d55463eafadde44ccff17694671d8c Mon Sep 17 00:00:00 2001 From: Mike Seese Date: Sun, 15 Nov 2020 23:13:42 -0800 Subject: [PATCH] initial plugin! --- .gitignore | 2 + FileSDK.uplugin | 24 +++ Resources/Icon128.png | Bin 0 -> 15066 bytes Source/FileSDK/FileSDK.Build.cs | 46 ++++++ Source/FileSDK/Private/FileSDK.cpp | 20 +++ Source/FileSDK/Private/FileSDKBPLibrary.cpp | 158 ++++++++++++++++++++ Source/FileSDK/Public/FileInfo.h | 36 +++++ Source/FileSDK/Public/FileSDK.h | 15 ++ Source/FileSDK/Public/FileSDKBPLibrary.h | 149 ++++++++++++++++++ 9 files changed, 450 insertions(+) create mode 100644 .gitignore create mode 100644 FileSDK.uplugin create mode 100644 Resources/Icon128.png create mode 100644 Source/FileSDK/FileSDK.Build.cs create mode 100644 Source/FileSDK/Private/FileSDK.cpp create mode 100644 Source/FileSDK/Private/FileSDKBPLibrary.cpp create mode 100644 Source/FileSDK/Public/FileInfo.h create mode 100644 Source/FileSDK/Public/FileSDK.h create mode 100644 Source/FileSDK/Public/FileSDKBPLibrary.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c1430b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Binaries +Intermediate diff --git a/FileSDK.uplugin b/FileSDK.uplugin new file mode 100644 index 0000000..8a95eea --- /dev/null +++ b/FileSDK.uplugin @@ -0,0 +1,24 @@ +{ + "FileVersion": 3, + "Version": 1, + "VersionName": "1.0", + "FriendlyName": "Blueprint File SDK", + "Description": "A simple plugin to interact with files and folders within blueprints.", + "Category": "Blueprints", + "CreatedBy": "Incanta Games", + "CreatedByURL": "https://incanta.games", + "DocsURL": "https://github.com/IncantaGames/unreal-bp-file-sdk", + "MarketplaceURL": "", + "SupportURL": "https://discord.gg/5hFrK2D", + "CanContainContent": false, + "IsBetaVersion": false, + "IsExperimentalVersion": false, + "Installed": false, + "Modules": [ + { + "Name": "FileSDK", + "Type": "Runtime", + "LoadingPhase": "PreLoadingScreen" + } + ] +} \ No newline at end of file diff --git a/Resources/Icon128.png b/Resources/Icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..47b092df7296ad11d24dfb04cb5c781714c13cd4 GIT binary patch literal 15066 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 literal 0 HcmV?d00001 diff --git a/Source/FileSDK/FileSDK.Build.cs b/Source/FileSDK/FileSDK.Build.cs new file mode 100644 index 0000000..55a8de4 --- /dev/null +++ b/Source/FileSDK/FileSDK.Build.cs @@ -0,0 +1,46 @@ +// Some copyright should be here... + +using UnrealBuildTool; + +public class FileSDK : ModuleRules { + public FileSDK(ReadOnlyTargetRules Target) : base(Target) { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicIncludePaths.AddRange( + new string[] { + } + ); + + + PrivateIncludePaths.AddRange( + new string[] { + } + ); + + + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + } + ); + + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "CoreUObject", + "Engine", + "Slate", + "SlateCore", + } + ); + + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + } + ); + } +} diff --git a/Source/FileSDK/Private/FileSDK.cpp b/Source/FileSDK/Private/FileSDK.cpp new file mode 100644 index 0000000..cf63ddc --- /dev/null +++ b/Source/FileSDK/Private/FileSDK.cpp @@ -0,0 +1,20 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "FileSDK.h" + +#define LOCTEXT_NAMESPACE "FFileSDKModule" + +DEFINE_LOG_CATEGORY(LogFileSDK); + +void FFileSDKModule::StartupModule() { + // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module +} + +void FFileSDKModule::ShutdownModule() { + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FFileSDKModule, FileSDK) \ No newline at end of file diff --git a/Source/FileSDK/Private/FileSDKBPLibrary.cpp b/Source/FileSDK/Private/FileSDKBPLibrary.cpp new file mode 100644 index 0000000..970647f --- /dev/null +++ b/Source/FileSDK/Private/FileSDKBPLibrary.cpp @@ -0,0 +1,158 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "FileSDKBPLibrary.h" +#include "FileSDK.h" + +#include "HAL/FileManagerGeneric.h" + +UFileSDKBPLibrary::UFileSDKBPLibrary( + const FObjectInitializer& ObjectInitializer +) : Super(ObjectInitializer) { + // +} + +void UFileSDKBPLibrary::CreateFile( + FString FileName, + bool ClearContentsIfExists, + bool CreateDirectoryTree +) { + IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + + FString directoryName = FPaths::GetPath(FileName); + bool directoryExists = PlatformFile.DirectoryExists(*directoryName); + + if (!directoryExists && CreateDirectoryTree) { + FFileManagerGeneric::Get().MakeDirectory(*directoryName, true); + } else if (!directoryExists) { + UE_LOG( + LogFileSDK, + Fatal, + TEXT("Cannot create file %s because directory %s doesn't exist. Ensure the directory exists before or enable 'CreateDirectoryTree'"), + *FileName, + *directoryName + ); + } + + bool fileExists = PlatformFile.FileExists(*FileName); + + if ((ClearContentsIfExists && fileExists) || !fileExists) { + FFileHelper::SaveStringToFile(FString(), *FileName); + } +} + +bool UFileSDKBPLibrary::DeleteFile(FString FileName) { + IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + + if (PlatformFile.FileExists(*FileName)) { + return FFileManagerGeneric::Get().Delete(*FileName); + } else { + return false; + } +} + +bool UFileSDKBPLibrary::CreateDirectory( + FString DirectoryName, + bool CreateDirectoryTree +) { + return FFileManagerGeneric::Get().MakeDirectory(*DirectoryName, CreateDirectoryTree); +} + +bool UFileSDKBPLibrary::DeleteDirectory( + FString DirectoryName, + bool Recursive +) { + return FFileManagerGeneric::Get().DeleteDirectory(*DirectoryName, false, Recursive); +} + +bool UFileSDKBPLibrary::RenameFileOrDirectory( + FString Source, + FString Destination +) { + IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + + return PlatformFile.MoveFile(*Destination, *Source); +} + +bool UFileSDKBPLibrary::CopyFile( + FString Source, + FString Destination +) { + IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + + return PlatformFile.CopyFile(*Destination, *Source); +} + +bool UFileSDKBPLibrary::CopyDirectory( + FString Source, + FString Destination, + bool OverwriteDestination +) { + IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + + return PlatformFile.CopyDirectoryTree(*Destination, *Source, OverwriteDestination); +} + +bool UFileSDKBPLibrary::ReadStringFromFile(FString FileName, FString & Content) { + return FFileHelper::LoadFileToString(Content, *FileName); +} + +bool UFileSDKBPLibrary::WriteStringToFile(FString FileName, FString Content, bool Append) { + if (Append) { + return FFileHelper::SaveStringToFile( + Content, + *FileName, + FFileHelper::EEncodingOptions::AutoDetect, + &IFileManager::Get(), + std::ios_base::app + ); + } else { + return FFileHelper::SaveStringToFile(Content, *FileName); + } +} + +bool UFileSDKBPLibrary::WriteBytesToFile(FString FileName, TArray Content) { + return FFileHelper::SaveArrayToFile(Content, *FileName); +} + +bool UFileSDKBPLibrary::ReadBytesFromFile(FString FileName, TArray & Content) { + return FFileHelper::LoadFileToArray(Content, *FileName); +} + +TArray UFileSDKBPLibrary::GetFilesFromDirectory( + FString DirectoryToSearch, + FString FilterFilesWithExtension, + bool SearchSubfolders +) { + TArray FileNames; + IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + + if (SearchSubfolders) { + PlatformFile.FindFilesRecursively( + FileNames, + *DirectoryToSearch, + *FilterFilesWithExtension + ); + } else { + PlatformFile.FindFiles( + FileNames, + *DirectoryToSearch, + *FilterFilesWithExtension + ); + } + + return FileNames; +} + +void UFileSDKBPLibrary::GetFileOrDirectoryInfo(FString Path, FFileInfo & Info) { + IPlatformFile & PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + + FFileStatData data = PlatformFile.GetStatData(*Path); + + Info.CreationTime = data.CreationTime; + Info.AccessTime = data.AccessTime; + Info.ModificationTime = data.ModificationTime; + Info.FileSize = data.FileSize; + Info.bIsDirectory = data.bIsDirectory; + Info.bIsReadOnly = data.bIsReadOnly; + Info.bIsValid = data.bIsValid; +} diff --git a/Source/FileSDK/Public/FileInfo.h b/Source/FileSDK/Public/FileInfo.h new file mode 100644 index 0000000..997940e --- /dev/null +++ b/Source/FileSDK/Public/FileInfo.h @@ -0,0 +1,36 @@ +#pragma once + +#include "FileInfo.generated.h" + +USTRUCT(BlueprintType) +struct FFileInfo { + GENERATED_USTRUCT_BODY(); + + /** The time that the file or directory was originally created, or FDateTime::MinValue if the creation time is unknown */ + UPROPERTY(BlueprintReadOnly) + FDateTime CreationTime; + + /** The time that the file or directory was last accessed, or FDateTime::MinValue if the access time is unknown */ + UPROPERTY(BlueprintReadOnly) + FDateTime AccessTime; + + /** The time the the file or directory was last modified, or FDateTime::MinValue if the modification time is unknown */ + UPROPERTY(BlueprintReadOnly) + FDateTime ModificationTime; + + /** Size of the file (in bytes), or -1 if the file size is unknown */ + UPROPERTY(BlueprintReadOnly) + int64 FileSize; + + /** True if this data is for a directory, false if it's for a file */ + UPROPERTY(BlueprintReadOnly) + bool bIsDirectory; + + /** True if this file is read-only */ + UPROPERTY(BlueprintReadOnly) + bool bIsReadOnly; + + /** True if file or directory was found, false otherwise. Note that this value being true does not ensure that the other members are filled in with meaningful data, as not all file systems have access to all of this data */ + UPROPERTY(BlueprintReadOnly) + bool bIsValid; +}; diff --git a/Source/FileSDK/Public/FileSDK.h b/Source/FileSDK/Public/FileSDK.h new file mode 100644 index 0000000..72128c1 --- /dev/null +++ b/Source/FileSDK/Public/FileSDK.h @@ -0,0 +1,15 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Modules/ModuleManager.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogFileSDK, Log, All); + +class FFileSDKModule : public IModuleInterface { +public: + + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; diff --git a/Source/FileSDK/Public/FileSDKBPLibrary.h b/Source/FileSDK/Public/FileSDKBPLibrary.h new file mode 100644 index 0000000..5b6fb2f --- /dev/null +++ b/Source/FileSDK/Public/FileSDKBPLibrary.h @@ -0,0 +1,149 @@ +#pragma once + +#include "Kismet/BlueprintFunctionLibrary.h" +#include "FileInfo.h" + +#include "FileSDKBPLibrary.generated.h" + +UCLASS() +class UFileSDKBPLibrary : public UBlueprintFunctionLibrary { + GENERATED_UCLASS_BODY() + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Create File", + Keywords = "FileSDK create make generate file" + ), + Category = "FileSDK" + ) + static void CreateFile(FString FileName, bool ClearContentsIfExists = true, bool CreateDirectoryTree = true); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Delete File", + Keywords = "FileSDK delete file destroy" + ), + Category = "FileSDK" + ) + static bool DeleteFile(FString FileName); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Create Directory", + Keywords = "FileSDK create make generate directory folder" + ), + Category = "FileSDK" + ) + static bool CreateDirectory(FString DirectoryName, bool CreateDirectoryTree = true); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Delete Directory", + Keywords = "FileSDK delete destroy remove directory folder" + ), + Category = "FileSDK" + ) + static bool DeleteDirectory(FString DirectoryName, bool Recursive = true); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Rename File or Directory", + Keywords = "FileSDK rename move file directory folder" + ), + Category = "FileSDK" + ) + static bool RenameFileOrDirectory(FString Source, FString Destination); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Copy File", + Keywords = "FileSDK copy file" + ), + Category = "FileSDK" + ) + static bool CopyFile(FString Source, FString Destination); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Copy Directory", + Keywords = "FileSDK copy directory folder" + ), + Category = "FileSDK" + ) + static bool CopyDirectory( + FString Source, + FString Destination, + bool OverwriteDestination = false + ); + + UFUNCTION( + BlueprintPure, + meta = ( + DisplayName = "Read String from File", + Keywords = "FileSDK read file string text" + ), + Category = "FileSDK" + ) + static bool ReadStringFromFile(FString FileName, FString & Content); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Write String to File", + Keywords = "FileSDK write append save file string text" + ), + Category = "FileSDK" + ) + static bool WriteStringToFile(FString FileName, FString Content, bool Append = false); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Write Bytes to File", + Keywords = "FileSDK write save file bytes binary" + ), + Category = "FileSDK" + ) + static bool WriteBytesToFile(FString FileName, TArray Content); + + UFUNCTION( + BlueprintPure, + meta = ( + DisplayName = "Read Bytes from File", + Keywords = "FileSDK read file bytes binary" + ), + Category = "FileSDK" + ) + static bool ReadBytesFromFile(FString FileName, TArray & Content); + + UFUNCTION( + BlueprintCallable, + meta = ( + DisplayName = "Get Files from Directory", + Keywords = "FileSDK get search find files list directory contents" + ), + Category = "FileSDK" + ) + static TArray GetFilesFromDirectory( + FString DirectoryToSearch, + FString FilterFilesWithExtension, + bool SearchSubfolders = false + ); + + UFUNCTION( + BlueprintPure, + meta = ( + DisplayName = "Get File or Directory Info", + Keywords = "FileSDK get file" + ), + Category = "FileSDK" + ) + static void GetFileOrDirectoryInfo(FString Path, FFileInfo & Info); +};