mirror of
https://github.com/storytold/RuntimeFilesDownloader.git
synced 2026-10-09 00:09:42 +00:00
first commit
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Respirant
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,30 @@
|
||||

|
||||
# RuntimeFilesDownloader
|
||||
This plugin will be useful for those who want to be able to download any files via HTTP protocol on runtime and save in device storage. It's easy to use in both C++ and Blueprints.
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
- Low library size (≈ 30 kb)
|
||||
- Fast downloading speed (780 kb file - 28 sec to download - 4.7 Mbps network speed)
|
||||
- No any third party libraries and external dependencies
|
||||
- Support for all available devices (tested on Windows and Android, but there are no restrictions to work on other devices)
|
||||
|
||||

|
||||

|
||||
|
||||
## How to install
|
||||
There're two ways to install the plugin:
|
||||
1) [Through the marketplace (not ready yet)](https://www.unrealengine.com/marketplace/product/runtime-files-downloader).
|
||||
2) Manual installation. Just extract the "RuntimeFilesDownloader" folder into your plugins project folder to get the following path: "[ProjectName]/Plugins/RuntimeFilesDownloader".
|
||||
|
||||
## How to use
|
||||
There are two ways to use this plugin: using Blueprints and C++:
|
||||
1. Blueprints. Just reopen your Unreal project and use "Create Downloader" and "Download File" nodes.
|
||||
2. C++. Open your "[ProjectName].Build.cs" and find a block of ` PublicDependencyModuleNames ` or ` PrivateDependencyModuleNames ` (it depends on your needs). Add `"RuntimeFilesDownloader"` String inside this block. After just include "RuntimeAudioImporterBPLibrary.h" using ` #include "RuntimeFilesDownloaderBPLibrary.h" ` where needed.
|
||||
|
||||
## Legal info
|
||||
|
||||
Unreal® is a trademark or registered trademark of Epic Games, Inc. in the United States of America and elsewhere.
|
||||
|
||||
Unreal® Engine, Copyright 1998 – 2020, Epic Games, Inc. All rights reserved.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "RuntimeFilesDownloader",
|
||||
"Description": "Runtime Files Downloader for Unreal Engine. Allows you to download any files via HTTP protocol on runtime and save in device storage",
|
||||
"Category": "Code Plugins",
|
||||
"CreatedBy": "Respirant",
|
||||
"CreatedByURL": "https://github.com/Respirant/RuntimeFilesDownloader",
|
||||
"DocsURL": "https://github.com/Respirant/RuntimeFilesDownloader",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "https://telegram.me/Respirant",
|
||||
"CanContainContent": false,
|
||||
"IsBetaVersion": false,
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "RuntimeFilesDownloader",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default",
|
||||
"WhitelistPlatforms": [
|
||||
"Win64",
|
||||
"Win32",
|
||||
"Mac",
|
||||
"Android",
|
||||
"IOS",
|
||||
"Linux"
|
||||
],
|
||||
"BlacklistPlatforms": [
|
||||
"XboxOne",
|
||||
"PS4",
|
||||
"HTML5",
|
||||
"TVOS",
|
||||
"Switch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// Respirant 2020.
|
||||
|
||||
#include "RuntimeFilesDownloader.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FRuntimeFilesDownloaderModule"
|
||||
|
||||
void FRuntimeFilesDownloaderModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
|
||||
}
|
||||
|
||||
void FRuntimeFilesDownloaderModule::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(FRuntimeFilesDownloaderModule, RuntimeFilesDownloader)
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
// Respirant 2020.
|
||||
|
||||
#include "RuntimeFilesDownloaderBPLibrary.h"
|
||||
#include "RuntimeFilesDownloader.h"
|
||||
|
||||
URuntimeFilesDownloaderBPLibrary::URuntimeFilesDownloaderBPLibrary(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
URuntimeFilesDownloaderBPLibrary::URuntimeFilesDownloaderBPLibrary() :
|
||||
FileUrl(TEXT(""))
|
||||
, FileSavePath(TEXT(""))
|
||||
{
|
||||
}
|
||||
|
||||
URuntimeFilesDownloaderBPLibrary::~URuntimeFilesDownloaderBPLibrary()
|
||||
{
|
||||
}
|
||||
|
||||
URuntimeFilesDownloaderBPLibrary* URuntimeFilesDownloaderBPLibrary::MakeDownloader()
|
||||
{
|
||||
URuntimeFilesDownloaderBPLibrary* Downloader = NewObject<URuntimeFilesDownloaderBPLibrary>();
|
||||
return Downloader;
|
||||
}
|
||||
|
||||
|
||||
URuntimeFilesDownloaderBPLibrary* URuntimeFilesDownloaderBPLibrary::DownloadFile(const FString& Url, FString SavePath)
|
||||
{
|
||||
URuntimeFilesDownloaderBPLibrary* Downloader = NewObject<URuntimeFilesDownloaderBPLibrary>();
|
||||
FileUrl = Url;
|
||||
FileSavePath = SavePath;
|
||||
|
||||
TSharedRef< IHttpRequest, ESPMode::ThreadSafe > HttpRequest = FHttpModule::Get().CreateRequest();
|
||||
|
||||
HttpRequest->SetVerb("GET");
|
||||
HttpRequest->SetURL(Url);
|
||||
HttpRequest->OnProcessRequestComplete().BindUObject(this, &URuntimeFilesDownloaderBPLibrary::OnReady);
|
||||
HttpRequest->OnRequestProgress().BindUObject(this, &URuntimeFilesDownloaderBPLibrary::OnProgress_Internal);
|
||||
|
||||
// Execute the request
|
||||
HttpRequest->ProcessRequest();
|
||||
AddToRoot();
|
||||
|
||||
return this;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void URuntimeFilesDownloaderBPLibrary::OnReady(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
|
||||
{
|
||||
RemoveFromRoot();
|
||||
Request->OnProcessRequestComplete().Unbind();
|
||||
|
||||
if (Response.IsValid() && EHttpResponseCodes::IsOk(Response->GetResponseCode()))
|
||||
{
|
||||
// Save file
|
||||
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
// Create save directory if not existent
|
||||
FString Path, Filename, Extension;
|
||||
FPaths::Split(FileSavePath, Path, Filename, Extension);
|
||||
if (!PlatformFile.DirectoryExists(*Path))
|
||||
{
|
||||
if (!PlatformFile.CreateDirectoryTree(*Path))
|
||||
{
|
||||
OnResult.Broadcast(EDownloadResult::DirectoryCreationFailed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Open/Create the file
|
||||
IFileHandle* FileHandle = PlatformFile.OpenWrite(*FileSavePath);
|
||||
if (FileHandle)
|
||||
{
|
||||
// Write the file
|
||||
FileHandle->Write(Response->GetContent().GetData(), Response->GetContentLength());
|
||||
// Close the file
|
||||
delete FileHandle;
|
||||
|
||||
OnResult.Broadcast(EDownloadResult::Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnResult.Broadcast(EDownloadResult::SaveFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnResult.Broadcast(EDownloadResult::DownloadFailed);
|
||||
}
|
||||
}
|
||||
|
||||
void URuntimeFilesDownloaderBPLibrary::OnProgress_Internal(FHttpRequestPtr Request, int32 BytesSent, int32 BytesReceived)
|
||||
{
|
||||
int32 FullSize = Request->GetContentLength();
|
||||
OnProgress.Broadcast(BytesSent, BytesReceived, FullSize);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Respirant 2020.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FRuntimeFilesDownloaderModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
// Respirant 2020.
|
||||
|
||||
#pragma once
|
||||
#include "Http.h"
|
||||
|
||||
#include "Misc/Paths.h"
|
||||
#include "HAL/PlatformFilemanager.h"
|
||||
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "RuntimeFilesDownloaderBPLibrary.generated.h"
|
||||
|
||||
UENUM(BlueprintType, Category = "RuntimeFilesDownloader")
|
||||
enum class EDownloadResult : uint8
|
||||
{
|
||||
Success,
|
||||
DownloadFailed,
|
||||
SaveFailed,
|
||||
DirectoryCreationFailed
|
||||
};
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnResult, const EDownloadResult, Result);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnProgress, const int32, BytesSent, const int32, BytesReceived, const int32, ContentLength);
|
||||
|
||||
UCLASS()
|
||||
class RUNTIMEFILESDOWNLOADER_API URuntimeFilesDownloaderBPLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* Bind to know when the download is complete (even if it fails).
|
||||
*/
|
||||
UPROPERTY(BlueprintAssignable, Category = "RuntimeFilesDownloader")
|
||||
FOnResult OnResult;
|
||||
/**
|
||||
* Bind to know when the download is complete (even if it fails).
|
||||
*/
|
||||
UPROPERTY(BlueprintAssignable, Category = "RuntimeFilesDownloader")
|
||||
FOnProgress OnProgress;
|
||||
|
||||
/**
|
||||
* The URL used to start this download.
|
||||
*/
|
||||
UPROPERTY(BlueprintReadOnly, Category = "RuntimeFilesDownloader")
|
||||
FString FileUrl;
|
||||
/**
|
||||
* The path set to save the downloaded file.
|
||||
*/
|
||||
UPROPERTY(BlueprintReadOnly, Category = "RuntimeFilesDownloader")
|
||||
FString FileSavePath;
|
||||
|
||||
URuntimeFilesDownloaderBPLibrary();
|
||||
~URuntimeFilesDownloaderBPLibrary();
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a FileDownloader object, starts downloading and saves it when done.
|
||||
*
|
||||
* @return The FileDownloader object. Bind to it's OnResult event to know when it's done downloading.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Meta = (DisplayName = "Create Downloader"), Category = "RuntimeFilesDownloader")
|
||||
static URuntimeFilesDownloaderBPLibrary* MakeDownloader();
|
||||
|
||||
/**
|
||||
* Starts downloading a file and saves it when done. Bind to the OnResult
|
||||
* event to know when the download is done (preferrably, before calling this function).
|
||||
*
|
||||
* @param Url The file Url to be downloaded.
|
||||
* @param SavePath The absolute path and file name to save the downloaded file.
|
||||
* @return Returns itself.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Meta = (DisplayName = "Download File"), Category = "RuntimeFilesDownloader")
|
||||
URuntimeFilesDownloaderBPLibrary* DownloadFile(const FString & Url, FString SavePath);
|
||||
|
||||
private:
|
||||
|
||||
void OnReady(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
|
||||
void OnProgress_Internal(FHttpRequestPtr Request, int32 BytesSent, int32 BytesReceived);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Respirant 2020.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class RuntimeFilesDownloader : ModuleRules
|
||||
{
|
||||
public RuntimeFilesDownloader(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"HTTP",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
Reference in New Issue
Block a user