From 78203c7af0985d363d264ab06ecb5cf0322a1509 Mon Sep 17 00:00:00 2001 From: lipengzha Date: Sun, 8 Jan 2023 23:32:15 +0800 Subject: [PATCH] v80.0 HotPatcher Modular (#72) --- .gitmodules | 9 + HotPatcher/HotPatcher.uplugin | 2 +- HotPatcher/Resources/Payments/alipay.png | Bin 0 -> 74271 bytes HotPatcher/Resources/Payments/wechatpay.png | Bin 0 -> 147463 bytes .../Source/CmdHandler/CmdHandler.Build.cs | 1 - .../Source/CmdHandler/Private/CmdHandler.cpp | 69 ++- .../Cooker/HotAssetScannerCommandlet.cpp | 4 +- .../Cooker/HotGlobalShaderCommandlet.cpp | 4 +- .../Commandlets/HotPluginCommandlet.cpp | 78 --- .../Classes/Commandlets/HotPluginCommandlet.h | 17 - .../Commandlets/HotShaderPatchCommandlet.cpp | 67 --- .../Commandlets/HotShaderPatchCommandlet.h | 17 - .../HotPatcherCore/HotPatcherCore.Build.cs | 3 +- .../MultiCooker/FlibHotCookerHelper.cpp | 2 +- .../Cooker/MultiCooker/SingleCookerProxy.cpp | 2 +- .../Private/CreatePatch/PatcherProxy.cpp | 10 +- .../Private/FlibHotPatcherCoreHelper.cpp | 2 +- .../Private/GameFeature/GameFeatureProxy.cpp | 85 --- .../FCookShaderCollectionProxy.cpp | 2 +- .../FlibShaderCodeLibraryHelper.cpp | 6 +- .../ShaderPatch/FlibShaderPatchHelper.cpp | 217 ------- .../Private/ShaderPatch/ShaderPatchProxy.cpp | 104 ---- .../FGameFeaturePackagerSettings.h | 73 --- .../Public/GameFeature/GameFeatureProxy.h | 24 - .../HotPatcherCore/Public/HotPatcherCore.h | 5 +- .../FlibShaderCodeLibraryHelper.h | 19 + .../ShaderPatch/FExportShaderPatchSettings.h | 65 -- .../ShaderPatch/FlibShaderPatchHelper.h | 55 -- .../Public/ShaderPatch/ShaderPatchProxy.h | 24 - .../HotPatcherEditor.Build.cs | 5 +- .../Private/Cooker/SCookersPage.cpp | 17 +- .../Private/CreatePatch/SPatchersPage.cpp | 19 +- .../GameFeature/SGameFeaturePackageWidget.cpp | 283 --------- .../GameFeature/SGameFeaturePackageWidget.h | 60 -- .../Private/HotPatcherActionManager.cpp | 178 +++++- .../Private/HotPatcherEditor.cpp | 6 +- .../Private/HotPatcherModBaseModule.cpp | 11 + .../Private/HotPatcherStyle.cpp | 140 +++-- .../HotPatcherEditor/Private/SHotPatcher.cpp | 3 +- .../FVersionUpdaterManager.cpp | 36 ++ .../SVersionUpdater/FVersionUpdaterManager.h | 22 +- .../SVersionUpdater/SVersionUpdaterWidget.cpp | 567 +++++++++++++++--- .../SVersionUpdater/SVersionUpdaterWidget.h | 90 ++- .../SVersionUpdater/VersionUpdaterStyle.cpp | 14 +- .../ShaderPatch/SShaderPatchWidget.cpp | 225 ------- .../Public/HotPatcherActionManager.h | 42 +- .../Public/HotPatcherEditor.h | 2 + .../Public/HotPatcherModBaseModule.h | 17 + .../Public/ShaderPatch/SShaderPatchWidget.h | 60 -- .../Public/CreatePatch/FExportPatchSettings.h | 4 +- Mods/GameFeaturePacker | 1 + Mods/HDiffPatchUE | 1 + Mods/HotChunker | 2 +- Mods/HotMultiCooker | 2 +- Mods/RemakePak | 2 +- Mods/ShaderPatcherUE | 1 + Mods/libzstd | 2 +- 57 files changed, 1077 insertions(+), 1701 deletions(-) create mode 100644 HotPatcher/Resources/Payments/alipay.png create mode 100644 HotPatcher/Resources/Payments/wechatpay.png delete mode 100644 HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.cpp delete mode 100644 HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.h delete mode 100644 HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.cpp delete mode 100644 HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.h delete mode 100644 HotPatcher/Source/HotPatcherCore/Private/GameFeature/GameFeatureProxy.cpp rename HotPatcher/Source/HotPatcherCore/Private/{ShaderPatch => ShaderLibUtils}/FCookShaderCollectionProxy.cpp (96%) rename HotPatcher/Source/HotPatcherCore/Private/{ShaderPatch => ShaderLibUtils}/FlibShaderCodeLibraryHelper.cpp (94%) delete mode 100644 HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FlibShaderPatchHelper.cpp delete mode 100644 HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/ShaderPatchProxy.cpp delete mode 100644 HotPatcher/Source/HotPatcherCore/Public/GameFeature/FGameFeaturePackagerSettings.h delete mode 100644 HotPatcher/Source/HotPatcherCore/Public/GameFeature/GameFeatureProxy.h rename HotPatcher/Source/HotPatcherCore/Public/{ShaderPatch => ShaderLibUtils}/FlibShaderCodeLibraryHelper.h (72%) delete mode 100644 HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FExportShaderPatchSettings.h delete mode 100644 HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FlibShaderPatchHelper.h delete mode 100644 HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/ShaderPatchProxy.h delete mode 100644 HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.cpp delete mode 100644 HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.h create mode 100644 HotPatcher/Source/HotPatcherEditor/Private/HotPatcherModBaseModule.cpp delete mode 100644 HotPatcher/Source/HotPatcherEditor/Private/ShaderPatch/SShaderPatchWidget.cpp create mode 100644 HotPatcher/Source/HotPatcherEditor/Public/HotPatcherModBaseModule.h delete mode 100644 HotPatcher/Source/HotPatcherEditor/Public/ShaderPatch/SShaderPatchWidget.h create mode 160000 Mods/GameFeaturePacker create mode 160000 Mods/HDiffPatchUE create mode 160000 Mods/ShaderPatcherUE diff --git a/.gitmodules b/.gitmodules index 69d7a302..2cbeb46c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,12 @@ [submodule "Mods/HotChunker"] path = Mods/HotChunker url = git@github.com:hxhb/HotChunker.git +[submodule "Mods/HDiffPatchUE"] + path = Mods/HDiffPatchUE + url = git@github.com:hxhb/HDiffPatchUE.git +[submodule "Mods/GameFeaturePacker"] + path = Mods/GameFeaturePacker + url = git@github.com:hxhb/GameFeaturePacker.git +[submodule "Mods/ShaderPatcherUE"] + path = Mods/ShaderPatcherUE + url = git@github.com:hxhb/ShaderPatcherUE.git diff --git a/HotPatcher/HotPatcher.uplugin b/HotPatcher/HotPatcher.uplugin index 451d026d..c90b7017 100644 --- a/HotPatcher/HotPatcher.uplugin +++ b/HotPatcher/HotPatcher.uplugin @@ -23,7 +23,7 @@ { "Name": "HotPatcherCore", "Type": "Editor", - "LoadingPhase": "Default" + "LoadingPhase": "PreDefault" }, { "Name": "HotPatcherRuntime", diff --git a/HotPatcher/Resources/Payments/alipay.png b/HotPatcher/Resources/Payments/alipay.png new file mode 100644 index 0000000000000000000000000000000000000000..a2c5d2e123adb55caa0887805aae9568a2dc559f GIT binary patch literal 74271 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
    hxml!PRjPcH+G}Pu+?wNPxZFLXM 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

    F*THbwZDufUi7fJ4f$e@Dp%}NUz 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 literal 0 HcmV?d00001 diff --git a/HotPatcher/Resources/Payments/wechatpay.png b/HotPatcher/Resources/Payments/wechatpay.png new file mode 100644 index 0000000000000000000000000000000000000000..faa2a901b733af0b5bf9b1be1a191889f27d2721 GIT binary patch literal 147463 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

    G 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

    Nao0}Z$57ohMu{H!h$z?B)fH>sVO(XV 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�o?kZaLmrkpZH!*WdIW@4op&0 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 {D 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 *Section, *Key, DefaultValue, FileName )) { GConfig->SetInt( *Section, *Key, NewValue, FileName ); - UE_LOG(LogCmdHandler, Display, TEXT("Override section: %s key: %s from %d to %d."), *Section,*Key,DefaultValue,NewValue); + UE_LOG(LogCmdHandler, Display, TEXT("Override Section: %s key: %s from %d to %d."), *Section,*Key,DefaultValue,NewValue); bRet = true; } else { - UE_LOG(LogCmdHandler, Warning, TEXT("section: %s key: %s is not found!"), *Section,*Key); + UE_LOG(LogCmdHandler, Warning, TEXT("Override Section: %s key: %s is not found!"), *Section,*Key); } return bRet; } +#if WITH_EDITOR +static bool bDDCUrl = false; static FString MultiCookerDDCBackendName = TEXT("MultiCookerDDC"); -void AddMultiCookerBackendToConfig(const FString& DDCAddr) +bool AddMultiCookerBackendToConfig(const FString& DDCAddr) { - if(DDCAddr.IsEmpty()) + bool bStatus = false; + UE_LOG(LogCmdHandler,Display,TEXT("-ddcurl: %s"),*DDCAddr); + if(DDCAddr.IsEmpty() || DDCAddr.StartsWith(TEXT(" "))) { UE_LOG(LogCmdHandler, Warning, TEXT("not use MultiCookerDDC")); - return; + return bStatus; } auto EngineIniIns = GConfig->FindConfigFile(GEngineIni); auto MultiCookerDDCBackendSection = EngineIniIns->FindOrAddSection(MultiCookerDDCBackendName); - + MultiCookerDDCBackendSection->Empty(); + auto UpdateKeyLambda = [](FConfigSection* Section,const FString& Key,const FString& Value) { if(Section->Find(*Key)) { Section->Remove(*Key); } + UE_LOG(LogCmdHandler, Display, TEXT("Override Section MultiCookerDDC key: %s to %d."),*Key,*Value); Section->Add(*Key,FConfigValue(*Value)); }; UpdateKeyLambda(MultiCookerDDCBackendSection,TEXT("MinimumDaysToKeepFile"),TEXT("7")); UpdateKeyLambda(MultiCookerDDCBackendSection,TEXT("Root"),TEXT("(Type=KeyLength, Length=120, Inner=AsyncPut)")); UpdateKeyLambda(MultiCookerDDCBackendSection,TEXT("AsyncPut"),TEXT("(Type=AsyncPut, Inner=Hierarchy)")); - UpdateKeyLambda(MultiCookerDDCBackendSection,TEXT("Hierarchy"),TEXT("(Type=Hierarchical, Inner=Boot, Inner=PakWrite, Inner=PakRead, Inner=Local, Inner=Shared)")); + UpdateKeyLambda(MultiCookerDDCBackendSection,TEXT("Hierarchy"),TEXT("(Type=Hierarchical, Inner=Boot, Inner=Pak, Inner=EnginePak, Inner=Local, Inner=Shared)")); UpdateKeyLambda(MultiCookerDDCBackendSection,TEXT("Boot"),TEXT("(Type=Boot, Filename=\"%GAMEDIR%DerivedDataCache/Boot.ddc\", MaxCacheSize=512)")); FString DDC = FString::Printf( - TEXT("(Type=FileSystem, ReadOnly=false, Clean=true, Flush=false, DeleteUnused=true, UnusedFileAge=10, FoldersToClean=10, MaxFileChecksPerSec=1, ConsiderSlowAt=70, PromptIfMissing=false, Path=%s, EnvPathOverride=UE-SharedDataCachePath, EditorOverrideSetting=SharedDerivedDataCache)"), + TEXT("(Type=FileSystem, ReadOnly=false, Clean=true, Flush=false, DeleteUnused=false, UnusedFileAge=10, FoldersToClean=10, MaxFileChecksPerSec=1, Path=%s, EnvPathOverride=UE-SharedDataCachePath, EditorOverrideSetting=SharedDerivedDataCache)"), *DDCAddr ); UpdateKeyLambda(MultiCookerDDCBackendSection,TEXT("Shared"),DDC); @@ -61,13 +67,15 @@ void AddMultiCookerBackendToConfig(const FString& DDCAddr) { DDCBackendName = MultiCookerDDCBackendName; FCommandLine::Append(*FString::Printf(TEXT(" -ddc=%s"),*DDCBackendName)); - UE_LOG(LogCmdHandler, Warning, TEXT("Append cmd: %s"),FCommandLine::Get()); + UE_LOG(LogCmdHandler, Display, TEXT("Append cmd: %s"),FCommandLine::Get()); + bStatus = true; } - UE_LOG(LogCmdHandler, Warning, TEXT("use MultiCookerDDC: %s"),*DDCBackendName); + + UE_LOG(LogCmdHandler, Display, TEXT("Use DDCBackend: %s"),*DDCBackendName); + return bStatus; } -static bool bDDCUrl = false; -void FCmdHandlerModule::StartupModule() +void OverrideEditorEnv() { int32 OverrideNumUnusedShaderCompilingThreads = 3; if(FParse::Value(FCommandLine::Get(), TEXT("-MaxShaderWorker="), OverrideNumUnusedShaderCompilingThreads)) @@ -92,12 +100,11 @@ void FCmdHandlerModule::StartupModule() FString DDCURL; if(FParse::Value(FCommandLine::Get(),TEXT("-ddcurl="),DDCURL) && !DDCURL.IsEmpty()) { - AddMultiCookerBackendToConfig(DDCURL); - bDDCUrl = true; + bDDCUrl = AddMultiCookerBackendToConfig(DDCURL); } } -void FCmdHandlerModule::ShutdownModule() +void UnOverrideEditorEnv() { if(bDDCUrl) { @@ -105,6 +112,38 @@ void FCmdHandlerModule::ShutdownModule() EngineIniIns->Remove(MultiCookerDDCBackendName); } } + +#else + +void OverrideRuntimeEnv() +{ + +} + +void UnOverrideRuntimeEnv() +{ + +} +#endif + +void FCmdHandlerModule::StartupModule() +{ +#if WITH_EDITOR + OverrideEditorEnv(); +#else + OverrideRuntimeEnv(); +#endif +} + +void FCmdHandlerModule::ShutdownModule() +{ +#if WITH_EDITOR + UnOverrideEditorEnv(); +#else + UnOverrideRuntimeEnv(); +#endif +} + #undef LOCTEXT_NAMESPACE IMPLEMENT_MODULE(FCmdHandlerModule, CmdHandler) \ No newline at end of file diff --git a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotAssetScannerCommandlet.cpp b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotAssetScannerCommandlet.cpp index 4ec2c03d..ce78f9bb 100644 --- a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotAssetScannerCommandlet.cpp +++ b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotAssetScannerCommandlet.cpp @@ -1,14 +1,12 @@ #include "HotAssetScannerCommandlet.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" #include "CommandletHelper.h" // engine header #include "CoreMinimal.h" +#include "FlibPatchParserHelper.h" #include "Async/ParallelFor.h" #include "Misc/FileHelper.h" #include "Misc/CommandLine.h" #include "Misc/Paths.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" -#include "ShaderPatch/ShaderPatchProxy.h" #include "BaseTypes/FPackageTracker.h" DEFINE_LOG_CATEGORY(LogHotAssetScannerCommandlet); diff --git a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotGlobalShaderCommandlet.cpp b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotGlobalShaderCommandlet.cpp index 3401631a..11b5c933 100644 --- a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotGlobalShaderCommandlet.cpp +++ b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/Cooker/HotGlobalShaderCommandlet.cpp @@ -1,15 +1,15 @@ #include "HotGlobalShaderCommandlet.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" #include "CommandletHelper.h" // engine header #include "CoreMinimal.h" #include "FlibHotPatcherCoreHelper.h" #include "Async/ParallelFor.h" #include "Cooker/MultiCooker/FlibHotCookerHelper.h" +#include "Kismet/KismetStringLibrary.h" #include "Misc/FileHelper.h" #include "Misc/CommandLine.h" #include "Misc/Paths.h" -#include "ShaderPatch/FlibShaderCodeLibraryHelper.h" +#include "ShaderLibUtils/FlibShaderCodeLibraryHelper.h" #define PLATFORMS_PARAM_NAME TEXT("-platforms=") #define SAVETO_PARAM_NAME TEXT("-saveto=") diff --git a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.cpp b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.cpp deleted file mode 100644 index 2574804f..00000000 --- a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "HotPluginCommandlet.h" -#include "ThreadUtils/FProcWorkerThread.hpp" -#include "GameFeature/FGameFeaturePackagerSettings.h" -#include "FlibPatchParserHelper.h" - -#include "CommandletHelper.h" - -// engine header -#include "CoreMinimal.h" -#include "GameFeature/GameFeatureProxy.h" -#include "Misc/FileHelper.h" -#include "Misc/CommandLine.h" -#include "Kismet/KismetSystemLibrary.h" -#include "Misc/Paths.h" - -DEFINE_LOG_CATEGORY(LogHotPluginCommandlet); - -TSharedPtr PluginProc; - -int32 UHotPluginCommandlet::Main(const FString& Params) -{ - Super::Main(Params); - UE_LOG(LogHotPluginCommandlet, Display, TEXT("UHotPluginCommandlet::Main")); - - FString config_path; - bool bStatus = FParse::Value(*Params, *FString(PATCHER_CONFIG_PARAM_NAME).ToLower(), config_path); - if (!bStatus) - { - UE_LOG(LogHotPluginCommandlet, Error, TEXT("not -config=xxxx.json params.")); - return -1; - } - - if (!FPaths::FileExists(config_path)) - { - UE_LOG(LogHotPluginCommandlet, Error, TEXT("cofnig file %s not exists."), *config_path); - return -1; - } - - FString JsonContent; - bool bExportStatus = false; - if (FFileHelper::LoadFileToString(JsonContent, *config_path)) - { - - if(IsRunningCommandlet()) - { - FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")); - AssetRegistryModule.Get().SearchAllAssets(true); - } - - TSharedPtr PluginPackagerSetting = MakeShareable(new FGameFeaturePackagerSettings); - THotPatcherTemplateHelper::TDeserializeJsonStringAsStruct(JsonContent,*PluginPackagerSetting); - - TMap KeyValues = THotPatcherTemplateHelper::GetCommandLineParamsMap(Params); - THotPatcherTemplateHelper::ReplaceProperty(*PluginPackagerSetting, KeyValues); - TArray AddPlatforms = CommandletHelper::ParserPlatforms(Params,ADD_PATCH_PLATFORMS); - - FString FinalConfig; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*PluginPackagerSetting,FinalConfig); - UE_LOG(LogHotPluginCommandlet, Display, TEXT("%s"), *FinalConfig); - - - UGameFeatureProxy* GameFeatureProxy = NewObject(); - GameFeatureProxy->AddToRoot(); - GameFeatureProxy->Init(PluginPackagerSetting.Get()); - GameFeatureProxy->OnPaking.AddStatic(&::CommandletHelper::ReceiveMsg); - GameFeatureProxy->OnShowMsg.AddStatic(&::CommandletHelper::ReceiveShowMsg); - bExportStatus = GameFeatureProxy->DoExport(); - - UE_LOG(LogHotPluginCommandlet,Display,TEXT("Generate Game Feature Misstion is %s!"),bExportStatus?TEXT("Successed"):TEXT("Failure")); - } - - if(FParse::Param(FCommandLine::Get(), TEXT("wait"))) - { - system("pause"); - } - - return 0; -} diff --git a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.h b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.h deleted file mode 100644 index 60a7dda3..00000000 --- a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotPluginCommandlet.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "HotPatcherCommandletBase.h" -#include "Commandlets/Commandlet.h" -#include "HotPluginCommandlet.generated.h" - -DECLARE_LOG_CATEGORY_EXTERN(LogHotPluginCommandlet, Log, All); - -UCLASS() -class UHotPluginCommandlet :public UHotPatcherCommandletBase -{ - GENERATED_BODY() - -public: - - virtual int32 Main(const FString& Params)override; -}; \ No newline at end of file diff --git a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.cpp b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.cpp deleted file mode 100644 index 61e03547..00000000 --- a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "HotShaderPatchCommandlet.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" -#include "CommandletHelper.h" -// engine header -#include "CoreMinimal.h" -#include "Misc/FileHelper.h" -#include "Misc/CommandLine.h" -#include "Misc/Paths.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" -#include "ShaderPatch/ShaderPatchProxy.h" - -DEFINE_LOG_CATEGORY(LogHotShaderPatchCommandlet); - -int32 UHotShaderPatchCommandlet::Main(const FString& Params) -{ - Super::Main(Params); - UE_LOG(LogHotShaderPatchCommandlet, Display, TEXT("UHotShaderPatchCommandlet::Main")); - - FString config_path; - bool bStatus = FParse::Value(*Params, *FString(PATCHER_CONFIG_PARAM_NAME).ToLower(), config_path); - if (!bStatus) - { - UE_LOG(LogHotShaderPatchCommandlet, Warning, TEXT("not -config=xxxx.json params.")); - return -1; - } - - if (bStatus && !FPaths::FileExists(config_path)) - { - UE_LOG(LogHotShaderPatchCommandlet, Error, TEXT("cofnig file %s not exists."), *config_path); - return -1; - } - if(IsRunningCommandlet()) - { - // load asset registry - FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")); - AssetRegistryModule.Get().SearchAllAssets(true); - } - - TSharedPtr ExportShaderPatchSetting = MakeShareable(new FExportShaderPatchSettings); - - FString JsonContent; - if (FPaths::FileExists(config_path) && FFileHelper::LoadFileToString(JsonContent, *config_path)) - { - THotPatcherTemplateHelper::TDeserializeJsonStringAsStruct(JsonContent,*ExportShaderPatchSetting); - } - - TMap KeyValues = THotPatcherTemplateHelper::GetCommandLineParamsMap(Params); - THotPatcherTemplateHelper::ReplaceProperty(*ExportShaderPatchSetting, KeyValues); - - FString FinalConfig; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*ExportShaderPatchSetting,FinalConfig); - UE_LOG(LogHotShaderPatchCommandlet, Display, TEXT("%s"), *FinalConfig); - - UShaderPatchProxy* ShaderPatchProxy = NewObject(); - ShaderPatchProxy->AddToRoot(); - ShaderPatchProxy->Init(ExportShaderPatchSetting.Get()); - bool bExportStatus = ShaderPatchProxy->DoExport(); - - UE_LOG(LogHotShaderPatchCommandlet,Display,TEXT("Export Shader Patch Misstion is %s!"),bExportStatus?TEXT("Successed"):TEXT("Failure")); - - if(FParse::Param(FCommandLine::Get(), TEXT("wait"))) - { - system("pause"); - } - - return bExportStatus ? 0 : -1; -} diff --git a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.h b/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.h deleted file mode 100644 index 2ef5866e..00000000 --- a/HotPatcher/Source/HotPatcherCore/Classes/Commandlets/HotShaderPatchCommandlet.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "HotPatcherCommandletBase.h" -#include "Commandlets/Commandlet.h" -#include "HotShaderPatchCommandlet.generated.h" - -DECLARE_LOG_CATEGORY_EXTERN(LogHotShaderPatchCommandlet, All, All); - -UCLASS() -class UHotShaderPatchCommandlet :public UHotPatcherCommandletBase -{ - GENERATED_BODY() - -public: - - virtual int32 Main(const FString& Params)override; -}; \ No newline at end of file diff --git a/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs b/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs index edfe51f9..2e86b4c7 100644 --- a/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs +++ b/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs @@ -61,7 +61,6 @@ public HotPatcherCore(ReadOnlyTargetRules Target) : base(Target) "InputCore", "CoreUObject", "Engine", - "RenderCore", "Sockets" // ... add private dependencies that you statically link with here ... } @@ -190,7 +189,7 @@ public HotPatcherCore(ReadOnlyTargetRules Target) : base(Target) PublicDefinitions.AddRange(new string[] { "TOOL_NAME=\"HotPatcher\"", - "CURRENT_VERSION_ID=79", + "CURRENT_VERSION_ID=80", "CURRENT_PATCH_ID=0", "REMOTE_VERSION_FILE=\"https://imzlp.com/opensource/version.json\"" }); diff --git a/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/FlibHotCookerHelper.cpp b/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/FlibHotCookerHelper.cpp index d97eb794..f4499c11 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/FlibHotCookerHelper.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/FlibHotCookerHelper.cpp @@ -7,7 +7,7 @@ #include "FlibPatchParserHelper.h" #include "Cooker/MultiCooker/FCookShaderCollectionProxy.h" #include "Interfaces/IPluginManager.h" -#include "ShaderPatch/FlibShaderCodeLibraryHelper.h" +#include "ShaderLibUtils/FlibShaderCodeLibraryHelper.h" // FString UFlibHotCookerHelper::GetMultiCookerBaseDir() // { diff --git a/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp b/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp index 168370fb..f1343434 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp @@ -8,7 +8,7 @@ #include "UObject/UObjectHash.h" #include "UObject/UObjectIterator.h" #include "Async/ParallelFor.h" -#include "ShaderPatch/FlibShaderCodeLibraryHelper.h" +#include "ShaderLibUtils/FlibShaderCodeLibraryHelper.h" #include "ThreadUtils/FThreadUtils.hpp" #include "Cooker/MultiCooker/FCookShaderCollectionProxy.h" #include "Engine/Engine.h" diff --git a/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp b/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp index 4a51b5da..f69fdcc3 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp @@ -7,7 +7,7 @@ #include "CreatePatch/HotPatcherContext.h" #include "FlibHotPatcherCoreHelper.h" -#include "ShaderPatch/FlibShaderCodeLibraryHelper.h" +#include "ShaderLibUtils/FlibShaderCodeLibraryHelper.h" #include "Cooker/MultiCooker/FCookShaderCollectionProxy.h" // engine header @@ -1030,7 +1030,7 @@ namespace PatchWorker // // Update SlowTask Progress { - FText Dialog = FText::Format(NSLOCTEXT("ExportPatch", "GeneratedPak", "Generating Pak list of Chunk {0}."), FText::FromString(Chunk.ChunkName)); + FText Dialog = FText::Format(NSLOCTEXT("ExportPatch_GeneratedPakList", "GeneratedPak", "Generating Pak list of Chunk {0}."), FText::FromString(Chunk.ChunkName)); Context.OnPaking.Broadcast(TEXT("GeneratedPak"),*Dialog.ToString()); Context.UnrealPakSlowTask->EnterProgressFrame(1.0, Dialog); } @@ -1094,7 +1094,7 @@ namespace PatchWorker Context.OnPaking.Broadcast(TEXT("SavedPakFile"),Msg); }else { - FText Msg = LOCTEXT("SavedPakFileMsg", "Successed to Package the patch as Pak."); + FText Msg = LOCTEXT("SavedPakFileMsg_PackageSuccessed", "Successed to Package the patch as Pak."); FHotPatcherDelegates::Get().GetNotifyFileGenerated().Broadcast(Msg,PakSavePath); } FPakFileInfo CurrentPakInfo; @@ -1148,7 +1148,7 @@ namespace PatchWorker // // Update SlowTask Progress { - FText Dialog = FText::Format(NSLOCTEXT("ExportPatch", "GeneratedPak", "Generating Io Store list of Chunk {0}."), FText::FromString(Chunk.ChunkName)); + FText Dialog = FText::Format(NSLOCTEXT("ExportPatch_GeneratedPak", "GeneratedPak", "Generating Io Store list of Chunk {0}."), FText::FromString(Chunk.ChunkName)); Context.OnPaking.Broadcast(TEXT("GeneratedIoStore"),*Dialog.ToString()); Context.UnrealPakSlowTask->EnterProgressFrame(1.0, Dialog); } @@ -1406,7 +1406,7 @@ namespace PatchWorker Context.OnPaking.Broadcast(TEXT("SavedPakFileMsg"),Msg); }else { - FText Msg = LOCTEXT("SavedPakFileMsg", "Successed to Export the Pak File info."); + FText Msg = LOCTEXT("SavedPakFileMsg_ExportSuccessed", "Successed to Export the Pak File info."); FHotPatcherDelegates::Get().GetNotifyFileGenerated().Broadcast(Msg, SavePakFilesPath); } } diff --git a/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp b/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp index da63966d..440d86a7 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp @@ -5,7 +5,7 @@ #include "HotPatcherCore.h" #include "CreatePatch/FExportPatchSettings.h" #include "CreatePatch/FExportReleaseSettings.h" -#include "ShaderPatch/FlibShaderCodeLibraryHelper.h" +#include "ShaderLibUtils/FlibShaderCodeLibraryHelper.h" #include "ThreadUtils/FThreadUtils.hpp" // engine header diff --git a/HotPatcher/Source/HotPatcherCore/Private/GameFeature/GameFeatureProxy.cpp b/HotPatcher/Source/HotPatcherCore/Private/GameFeature/GameFeatureProxy.cpp deleted file mode 100644 index 890cf145..00000000 --- a/HotPatcher/Source/HotPatcherCore/Private/GameFeature/GameFeatureProxy.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "GameFeature/GameFeatureProxy.h" - -#include - - -#include "CreatePatch/PatcherProxy.h" - -bool UGameFeatureProxy::DoExport() -{ - PatchSettings = MakeShareable(new FExportPatchSettings); - for(const auto& FeatureName:GetSettingObject()->FeatureNames) - { - if(GetSettingObject()->IsSaveConfig()) - { - FString SaveToFile = FPaths::Combine(GetSettingObject()->GetSaveAbsPath(),FString::Printf(TEXT("%s_GameFeatureConfig.json"),*FeatureName)); - FString SerializedJsonStr; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*GetSettingObject(),SerializedJsonStr); - FFileHelper::SaveStringToFile(SerializedJsonStr, *SaveToFile); - } - - // make patch setting - { - PatchSettings->bByBaseVersion = false; - PatchSettings->VersionId = FeatureName; - FDirectoryPath FeaturePluginPath; - FeaturePluginPath.Path = FString::Printf(TEXT("/%s"),*PatchSettings->VersionId); - - PatchSettings->GetAssetScanConfigRef().AssetIncludeFilters.Add(FeaturePluginPath); - - FPlatformExternAssets PlatformExternAssets; - { - PlatformExternAssets.TargetPlatform = ETargetPlatform::AllPlatforms; - FExternFileInfo FeaturePlugin; - - if(UFlibPatchParserHelper::GetPluginPakPathByName(PatchSettings->VersionId,FeaturePlugin.FilePath.FilePath,FeaturePlugin.MountPath)) - { - FeaturePlugin.Type = EPatchAssetType::NEW; - PlatformExternAssets.AddExternFileToPak.Add(FeaturePlugin); - - TSharedPtr Plugin = IPluginManager::Get().FindPlugin(FeatureName); - if(Plugin) - { - for(const auto& NonContentDir:GetSettingObject()->NonContentDirs) - { - FString PluginConfigDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(Plugin->GetBaseDir(),NonContentDir)); - if(FPaths::DirectoryExists(PluginConfigDir)) - { - FExternDirectoryInfo ConfigDir; - ConfigDir.DirectoryPath.Path = PluginConfigDir; - ConfigDir.MountPoint = FPaths::Combine(Plugin->GetBaseDir(),NonContentDir); - PlatformExternAssets.AddExternDirectoryToPak.Add(ConfigDir); - } - } - } - } - } - PatchSettings->AddExternAssetsToPlatform.Add(PlatformExternAssets); - PatchSettings->bCookPatchAssets = GetSettingObject()->bCookPatchAssets; - - { - PatchSettings->SerializeAssetRegistryOptions = GetSettingObject()->SerializeAssetRegistryOptions; - PatchSettings->SerializeAssetRegistryOptions.AssetRegistryMountPointRegular = FString::Printf(TEXT("%s[%s]"),AS_PLUGINDIR_MARK,*FeatureName); - PatchSettings->SerializeAssetRegistryOptions.AssetRegistryNameRegular = FString::Printf(TEXT("AssetRegistry.bin")); - } - { - PatchSettings->CookShaderOptions = GetSettingObject()->CookShaderOptions; - PatchSettings->CookShaderOptions.bSharedShaderLibrary = true; - PatchSettings->CookShaderOptions.bNativeShader = true; - PatchSettings->CookShaderOptions.ShaderLibMountPointRegular = FString::Printf(TEXT("%s[%s]"),AS_PLUGINDIR_MARK,*FeatureName); - } - PatchSettings->IoStoreSettings = GetSettingObject()->IoStoreSettings; - PatchSettings->EncryptSettings = GetSettingObject()->EncryptSettings; - PatchSettings->PakTargetPlatforms.Append(GetSettingObject()->TargetPlatforms); - PatchSettings->SavePath.Path = GetSettingObject()->GetSaveAbsPath(); - PatchSettings->bStorageNewRelease = false; - PatchSettings->bStorageConfig = true; - } - PatcherProxy = NewObject(); - PatcherProxy->AddToRoot(); - PatcherProxy->Init(PatchSettings.Get()); - PatcherProxy->DoExport(); - - } - return Super::DoExport(); -} diff --git a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FCookShaderCollectionProxy.cpp b/HotPatcher/Source/HotPatcherCore/Private/ShaderLibUtils/FCookShaderCollectionProxy.cpp similarity index 96% rename from HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FCookShaderCollectionProxy.cpp rename to HotPatcher/Source/HotPatcherCore/Private/ShaderLibUtils/FCookShaderCollectionProxy.cpp index ff73df46..f4484a30 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FCookShaderCollectionProxy.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/ShaderLibUtils/FCookShaderCollectionProxy.cpp @@ -1,7 +1,7 @@ #include "Cooker/MultiCooker/FCookShaderCollectionProxy.h" #include "FlibHotPatcherCoreHelper.h" #include "Cooker/MultiCooker/FlibHotCookerHelper.h" -#include "ShaderPatch/FlibShaderCodeLibraryHelper.h" +#include "ShaderLibUtils//FlibShaderCodeLibraryHelper.h" #include "Interfaces/ITargetPlatform.h" #include "Resources/Version.h" diff --git a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FlibShaderCodeLibraryHelper.cpp b/HotPatcher/Source/HotPatcherCore/Private/ShaderLibUtils/FlibShaderCodeLibraryHelper.cpp similarity index 94% rename from HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FlibShaderCodeLibraryHelper.cpp rename to HotPatcher/Source/HotPatcherCore/Private/ShaderLibUtils/FlibShaderCodeLibraryHelper.cpp index f1136024..41fff6ee 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FlibShaderCodeLibraryHelper.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/ShaderLibUtils/FlibShaderCodeLibraryHelper.cpp @@ -1,6 +1,6 @@ // Fill out your copyright notice in the Description page of Project Settings. -#include "ShaderPatch/FlibShaderCodeLibraryHelper.h" +#include "ShaderLibUtils//FlibShaderCodeLibraryHelper.h" #include "HotPatcherLog.h" #include "FlibHotPatcherCoreHelper.h" #include "HotPatcherCore.h" @@ -13,6 +13,10 @@ #define REMAPPED_PLUGINS TEXT("RemappedPlugins") +FString UFlibShaderCodeLibraryHelper::ShaderExtension = TEXT(".ushaderbytecode"); +FString UFlibShaderCodeLibraryHelper::ShaderAssetInfoExtension = TEXT(".assetinfo.json"); +FString UFlibShaderCodeLibraryHelper::StableExtension = TEXT(".scl.csv"); + // FMergeShaderCollectionProxy::FMergeShaderCollectionProxy(const TArray& InShaderCodeFiles):ShaderCodeFiles(InShaderCodeFiles) // { // Init(); diff --git a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FlibShaderPatchHelper.cpp b/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FlibShaderPatchHelper.cpp deleted file mode 100644 index db0da2a0..00000000 --- a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/FlibShaderPatchHelper.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - - -#include "ShaderPatch/FlibShaderPatchHelper.h" -#include "ETargetPlatform.h" -#include "FlibHotPatcherCoreHelper.h" -#include "Misc/Paths.h" -#include "ShaderCodeLibrary.h" -#include "Settings/ProjectPackagingSettings.h" - - -FString UFlibShaderPatchHelper::ShaderExtension = TEXT(".ushaderbytecode"); -FString UFlibShaderPatchHelper::ShaderAssetInfoExtension = TEXT(".assetinfo.json"); -FString UFlibShaderPatchHelper::StableExtension = TEXT(".scl.csv"); - -bool UFlibShaderPatchHelper::CreateShaderCodePatch(TArray const& OldMetaDataDirs, FString const& NewMetaDataDir, FString const& OutDir, bool bNativeFormat,bool bDeterministicShaderCodeOrder) -{ -#if ENGINE_MAJOR_VERSION > 4 || ENGINE_MINOR_VERSION > 26 - return FShaderLibraryCooker::CreatePatchLibrary(OldMetaDataDirs,NewMetaDataDir,OutDir,bNativeFormat,bDeterministicShaderCodeOrder); -#else - #if ENGINE_MINOR_VERSION > 25 - return FShaderCodeLibrary::CreatePatchLibrary(OldMetaDataDirs,NewMetaDataDir,OutDir,bNativeFormat,bDeterministicShaderCodeOrder); - #else - #if ENGINE_MINOR_VERSION > 23 - return FShaderCodeLibrary::CreatePatchLibrary(OldMetaDataDirs,NewMetaDataDir,OutDir,bNativeFormat); - #else - return false; - #endif - #endif -#endif -} - -TArray UFlibShaderPatchHelper::ConvDirectoryPathToStr(const TArray& Dirs) -{ - TArray result; - for(const auto& Dir:Dirs) - { - FString Path = FPaths::ConvertRelativePathToFull(Dir.Path); - if(FPaths::DirectoryExists(Path)) - { - result.AddUnique(Path); - } - } - return result; -} - -FString UFlibShaderPatchHelper::GetShaderStableInfoFileNameByShaderArchiveFileName(const FString& ShaderArchiveFileName) -{ - FString ShaderInfoFileName = ShaderArchiveFileName; - ShaderInfoFileName.RemoveFromStart(TEXT("ShaderArchive-")); - ShaderInfoFileName.RemoveFromEnd(TEXT(".ushaderbytecode")); - ShaderInfoFileName = FString::Printf(TEXT("ShaderStableInfo-%s.scl.csv"),*ShaderInfoFileName); - return ShaderInfoFileName; -} - -FString UFlibShaderPatchHelper::GetShaderInfoFileNameByShaderArchiveFileName(const FString& ShaderArchiveFileName) -{ - FString ShaderInfoFileName = ShaderArchiveFileName; - ShaderInfoFileName.RemoveFromStart(TEXT("ShaderArchive-")); - ShaderInfoFileName.RemoveFromEnd(TEXT(".ushaderbytecode")); - ShaderInfoFileName = FString::Printf(TEXT("ShaderAssetInfo-%s.assetinfo.json"),*ShaderInfoFileName); - return ShaderInfoFileName; -} - - - -// void UFlibShaderPatchHelper::InitShaderCodeLibrary(const TArray& Platforms) -// { -// const UProjectPackagingSettings* const PackagingSettings = GetDefault(); -// // IsUsingShaderCodeLibrary(); -// // CurrentCookMode == ECookMode::CookByTheBookFromTheEditor || CurrentCookMode == ECookMode::CookByTheBook; -// bool const bCacheShaderLibraries = true; -// if (bCacheShaderLibraries && PackagingSettings->bShareMaterialShaderCode) -// { -// FShaderCodeLibrary::InitForCooking(PackagingSettings->bSharedMaterialNativeLibraries); -// -// bool bAllPlatformsNeedStableKeys = false; -// // support setting without Hungarian prefix for the compatibility, but allow newer one to override -// GConfig->GetBool(TEXT("DevOptions.Shaders"), TEXT("NeedsShaderStableKeys"), bAllPlatformsNeedStableKeys, GEngineIni); -// GConfig->GetBool(TEXT("DevOptions.Shaders"), TEXT("bNeedsShaderStableKeys"), bAllPlatformsNeedStableKeys, GEngineIni); -// -// for (const ITargetPlatform* TargetPlatform : UFlibHotPatcherCoreHelper::GetTargetPlatformsByNames(Platforms)) -// { -// // Find out if this platform requires stable shader keys, by reading the platform setting file. -// bool bNeedShaderStableKeys = bAllPlatformsNeedStableKeys; -// FConfigFile PlatformIniFile; -// FConfigCacheIni::LoadLocalIniFile(PlatformIniFile, TEXT("Engine"), true, *TargetPlatform->IniPlatformName()); -// PlatformIniFile.GetBool(TEXT("DevOptions.Shaders"), TEXT("NeedsShaderStableKeys"), bNeedShaderStableKeys); -// PlatformIniFile.GetBool(TEXT("DevOptions.Shaders"), TEXT("bNeedsShaderStableKeys"), bNeedShaderStableKeys); -// -// bool bNeedsDeterministicOrder = PackagingSettings->bDeterministicShaderCodeOrder; -// FConfigFile PlatformGameIniFile; -// FConfigCacheIni::LoadLocalIniFile(PlatformGameIniFile, TEXT("Game"), true, *TargetPlatform->IniPlatformName()); -// PlatformGameIniFile.GetBool(TEXT("/Script/UnrealEd.ProjectPackagingSettings"), TEXT("bDeterministicShaderCodeOrder"), bNeedsDeterministicOrder); -// -// TArray ShaderFormats; -// TargetPlatform->GetAllTargetedShaderFormats(ShaderFormats); -// TArray ShaderFormatsWithStableKeys; -// for (FName& Format : ShaderFormats) -// { -// FShaderCodeLibrary::FShaderFormatDescriptor NewDesc; -// NewDesc.ShaderFormat = Format; -// NewDesc.bNeedsStableKeys = bNeedShaderStableKeys; -// NewDesc.bNeedsDeterministicOrder = bNeedsDeterministicOrder; -// ShaderFormatsWithStableKeys.Push(NewDesc); -// } -// -// if (ShaderFormats.Num() > 0) -// { -// FShaderCodeLibrary::CookShaderFormats(ShaderFormatsWithStableKeys); -// } -// } -// } -// } - - -// void UFlibShaderPatchHelper::CleanShaderCodeLibraries(const TArray& Platforms) -// { -// const UProjectPackagingSettings* const PackagingSettings = GetDefault(); -// bool const bCacheShaderLibraries = true;// IsUsingShaderCodeLibrary(); -// ITargetPlatformManagerModule& TPM = GetTargetPlatformManagerRef(); -// bool bIterativeCook = true;// IsCookFlagSet(ECookInitializationFlags::Iterative) || PackageDatas->GetNumCooked() != 0; -// -// // If not iterative then clean up our temporary files -// if (bCacheShaderLibraries && PackagingSettings->bShareMaterialShaderCode && !bIterativeCook) -// { -// for (const ITargetPlatform* TargetPlatform : UFlibHotPatcherCoreHelper::GetTargetPlatformsByNames(Platforms)) -// { -// TArray ShaderFormats; -// TargetPlatform->GetAllTargetedShaderFormats(ShaderFormats); -// if (ShaderFormats.Num() > 0) -// { -// FShaderCodeLibrary::CleanDirectories(ShaderFormats); -// } -// } -// } -// } -// -// FString ConvertToFullSandboxPath( const FString &FileName, bool bForWrite, const FString& PlatformName ) -// { -// FString Result = FPaths::ConvertRelativePathToFull(FileName);//ConvertToFullSandboxPath( FileName, bForWrite ); -// Result.ReplaceInline(TEXT("[Platform]"), *PlatformName); -// return Result; -// } -// -// static FString GenerateShaderCodeLibraryName(FString const& Name, bool bIsIterateSharedBuild) -// { -// FString ActualName = (!bIsIterateSharedBuild) ? Name : Name + TEXT("_SC"); -// return ActualName; -// } - -// void UFlibShaderPatchHelper::SaveShaderLibrary(const ITargetPlatform* TargetPlatform, FString const& Name, const TArray>* ChunkAssignments) -// { -// bool bIsIterateSharedBuild = true; // IsCookFlagSet(ECookInitializationFlags::IterateSharedBuild) -// FString ActualName = GenerateShaderCodeLibraryName(Name, bIsIterateSharedBuild); -// FString BasePath = FPaths::ProjectContentDir(); -// -// FString ShaderCodeDir = ConvertToFullSandboxPath(*BasePath, true, TargetPlatform->PlatformName()); -// -// const FString RootMetaDataPath = FPaths::ProjectDir() / TEXT("Metadata") / TEXT("PipelineCaches"); -// const FString MetaDataPathSB = FPaths::ConvertRelativePathToFull(*RootMetaDataPath); -// const FString MetaDataPath = MetaDataPathSB.Replace(TEXT("[Platform]"), *TargetPlatform->PlatformName()); -// -// // note that shader formats can be shared across the target platforms -// TArray ShaderFormats; -// TargetPlatform->GetAllTargetedShaderFormats(ShaderFormats); -// if (ShaderFormats.Num() > 0) -// { -// FString TargetPlatformName = TargetPlatform->PlatformName(); -// TMap> OutSCLCSVPaths; -// TArray& PlatformSCLCSVPaths = OutSCLCSVPaths.FindOrAdd(FName(TargetPlatformName)); -// bool bStoraged = FShaderCodeLibrary::SaveShaderCode(ShaderCodeDir, MetaDataPath, ShaderFormats, PlatformSCLCSVPaths, ChunkAssignments); -// -// if (UNLIKELY(!bStoraged)) -// { -// UE_LOG(LogTemp, Error, TEXT("%s"),*FString::Printf(TEXT("Saving shared material shader code library failed for %s."), *TargetPlatformName)); -// } -// else -// { -// const UProjectPackagingSettings* const PackagingSettings = GetDefault(); -// if (PackagingSettings->bSharedMaterialNativeLibraries) -// { -// bStoraged = FShaderCodeLibrary::PackageNativeShaderLibrary(ShaderCodeDir, ShaderFormats); -// if (!bStoraged) -// { -// // This is fatal - In this case we should cancel any launch on device operation or package write but we don't want to assert and crash the editor -// UE_LOG(LogTemp, Error, TEXT("%s"),*FString::Printf(TEXT("Package Native Shader Library failed for %s."), *TargetPlatformName)); -// } -// } -// for (const FString& Item : PlatformSCLCSVPaths) -// { -// UE_LOG(LogTemp, Display, TEXT("Saved scl.csv %s for platform %s, %d bytes"), *Item, *TargetPlatformName, -// IFileManager::Get().FileSize(*Item)); -// } -// } -// } -// } - -// void UFlibShaderPatchHelper::SaveGlobalShaderLibrary(const TArray& Platforms) -// { -// const TCHAR* GlobalShaderLibName = TEXT("Global"); -// bool bIsIterateSharedBuild = true; // IsCookFlagSet(ECookInitializationFlags::IterateSharedBuild) -// FString ActualName = GenerateShaderCodeLibraryName(GlobalShaderLibName, bIsIterateSharedBuild); -// -// const UProjectPackagingSettings* const PackagingSettings = GetDefault(); -// bool const bCacheShaderLibraries = true;//IsUsingShaderCodeLibrary(); -// if (bCacheShaderLibraries && PackagingSettings->bShareMaterialShaderCode) -// { -// // Save shader code map - cleaning directories is deliberately a separate loop here as we open the cache once per shader platform and we don't assume that they can't be shared across target platforms. -// for (const ITargetPlatform* TargetPlatform : UFlibHotPatcherCoreHelper::GetTargetPlatformsByNames(Platforms)) -// { -// SaveShaderLibrary(TargetPlatform, GlobalShaderLibName, nullptr); -// } -// -// FShaderCodeLibrary::CloseLibrary(ActualName); -// } -// } diff --git a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/ShaderPatchProxy.cpp b/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/ShaderPatchProxy.cpp deleted file mode 100644 index 858b59f4..00000000 --- a/HotPatcher/Source/HotPatcherCore/Private/ShaderPatch/ShaderPatchProxy.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. -#include "ShaderPatch/ShaderPatchProxy.h" -#include "FlibHotPatcherCoreHelper.h" -#include "Commandlets/HotShaderPatchCommandlet.h" -#include "ShaderPatch/FlibShaderPatchHelper.h" - -#define LOCTEXT_NAMESPACE "HotPatcherShaderPatchProxy" - -bool UShaderPatchProxy::DoExport() -{ - bool bStatus = false; - for(const auto& PlatformConfig:GetSettingObject()->ShaderPatchConfigs) - { - UE_LOG(LogHotShaderPatchCommandlet,Display,TEXT("Generating Shader Patch for %s"),*THotPatcherTemplateHelper::GetEnumNameByValue(PlatformConfig.Platform)); - - FString SaveToPath = FPaths::Combine(GetSettingObject()->GetSaveAbsPath(),GetSettingObject()->VersionID,THotPatcherTemplateHelper::GetEnumNameByValue(PlatformConfig.Platform)); - bool bCreateStatus = UFlibShaderPatchHelper::CreateShaderCodePatch( - UFlibShaderPatchHelper::ConvDirectoryPathToStr(PlatformConfig.OldMetadataDir), - FPaths::ConvertRelativePathToFull(PlatformConfig.NewMetadataDir.Path), - SaveToPath, - PlatformConfig.bNativeFormat, - PlatformConfig.bDeterministicShaderCodeOrder - ); - - auto GetShaderPatchFormatLambda = [](const FString& ShaderPatchDir)->TMap> - { - TMap> FormatLibraryMap; - TArray LibraryFiles; - IFileManager::Get().FindFiles(LibraryFiles, *(ShaderPatchDir), *UFlibShaderPatchHelper::ShaderExtension); - - for (FString const& Path : LibraryFiles) - { - FString Name = FPaths::GetBaseFilename(Path); - if (Name.RemoveFromStart(TEXT("ShaderArchive-"))) - { - TArray Components; - if (Name.ParseIntoArray(Components, TEXT("-")) == 2) - { - FName Format(*Components[1]); - TSet& Libraries = FormatLibraryMap.FindOrAdd(Format); - Libraries.Add(Components[0]); - } - } - } - return FormatLibraryMap; - }; - - if(bCreateStatus) - { - TMap> ShaderFormatLibraryMap = GetShaderPatchFormatLambda(SaveToPath); - FText Msg = LOCTEXT("GeneratedShaderPatch", "Successd to Generated the Shader Patch."); - TArray FormatNames; - ShaderFormatLibraryMap.GetKeys(FormatNames); - for(const auto& FormatName:FormatNames) - { - TArray LibraryNames= ShaderFormatLibraryMap[FormatName].Array(); - for(const auto& LibrartName:LibraryNames) - { - FString OutputFilePath = UFlibShaderPatchHelper::GetCodeArchiveFilename(SaveToPath, LibrartName, FormatName); - if(FPaths::FileExists(OutputFilePath)) - { - bStatus = true; - if(!IsRunningCommandlet()) - { - FHotPatcherDelegates::Get().GetNotifyFileGenerated().Broadcast(Msg, OutputFilePath); - } - else - { - UE_LOG(LogHotShaderPatchCommandlet,Display,TEXT("%s"),*Msg.ToString()); - } - } - else - { - UE_LOG(LogHotShaderPatchCommandlet,Display,TEXT("ERROR: %s not found!"),*OutputFilePath); - } - } - } - } - } - - if(GetSettingObject()->bStorageConfig) - { - FString SerializedJsonStr; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*GetSettingObject(),SerializedJsonStr); - - FString SaveToPath = FPaths::Combine(GetSettingObject()->GetSaveAbsPath(),GetSettingObject()->VersionID,GetSettingObject()->VersionID).Append(TEXT(".json")); - - if (FFileHelper::SaveStringToFile(SerializedJsonStr, *SaveToPath)) - { - FText Msg = LOCTEXT("SavedShaderPatchConfigMas", "Successd to Export the Shader Patch Config."); - if(!IsRunningCommandlet()) - { - FHotPatcherDelegates::Get().GetNotifyFileGenerated().Broadcast(Msg, SaveToPath); - } - else - { - UE_LOG(LogHotShaderPatchCommandlet,Display,TEXT("%s"),*Msg.ToString()); - } - } - } - return bStatus; -} - -#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/HotPatcher/Source/HotPatcherCore/Public/GameFeature/FGameFeaturePackagerSettings.h b/HotPatcher/Source/HotPatcherCore/Public/GameFeature/FGameFeaturePackagerSettings.h deleted file mode 100644 index ea20f025..00000000 --- a/HotPatcher/Source/HotPatcherCore/Public/GameFeature/FGameFeaturePackagerSettings.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "HotPatcherLog.h" -#include "CreatePatch/HotPatcherSettingBase.h" -#include "FlibPatchParserHelper.h" -#include "HotPatcherLog.h" -#include "CreatePatch/FExportPatchSettings.h" - -// engine header -#include "Misc/FileHelper.h" -#include "CoreMinimal.h" -#include "ETargetPlatform.h" -#include "UObject/ObjectMacros.h" -#include "UObject/Object.h" -#include "Engine/EngineTypes.h" -#include "Kismet/KismetStringLibrary.h" -#include "Serialization/JsonSerializer.h" -#include "Serialization/JsonWriter.h" - -#include "FGameFeaturePackagerSettings.generated.h" - -/** Singleton wrapper to allow for using the setting structure in SSettingsView */ -USTRUCT(BlueprintType) -struct HOTPATCHERCORE_API FGameFeaturePackagerSettings:public FHotPatcherSettingBase -{ - GENERATED_USTRUCT_BODY() -public: - FGameFeaturePackagerSettings() - { - SerializeAssetRegistryOptions.bSerializeAssetRegistry = true; - NonContentDirs.AddUnique(TEXT("Config")); - } - virtual ~FGameFeaturePackagerSettings(){}; - - FORCEINLINE static FGameFeaturePackagerSettings* Get() - { - static FGameFeaturePackagerSettings StaticIns; - - return &StaticIns; - } - - UPROPERTY(EditAnywhere) - TArray FeatureNames; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - bool bAutoLoadFeaturePlugin = true; - // Config/ Script/ etc. - UPROPERTY(EditAnywhere, BlueprintReadWrite) - TArray NonContentDirs; - /* - * Cook Asset in current patch - * shader code gets saved inline inside material assets - * bShareMaterialShaderCode as false - */ - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Base") - bool bCookPatchAssets = true; - - // UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Base", meta=(EditCondition = "bCookPatchAssets")) - FCookShaderOptions CookShaderOptions; - // UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Base", meta=(EditCondition = "bCookPatchAssets")) - FAssetRegistryOptions SerializeAssetRegistryOptions; - - // support UE4.26 later - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Base") - FIoStoreSettings IoStoreSettings; - - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Base") - FPakEncryptSettings EncryptSettings; - - UPROPERTY(EditAnywhere, Category="Base") - TArray TargetPlatforms; -}; - diff --git a/HotPatcher/Source/HotPatcherCore/Public/GameFeature/GameFeatureProxy.h b/HotPatcher/Source/HotPatcherCore/Public/GameFeature/GameFeatureProxy.h deleted file mode 100644 index 9ef18b37..00000000 --- a/HotPatcher/Source/HotPatcherCore/Public/GameFeature/GameFeatureProxy.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include "ThreadUtils/FThreadUtils.hpp" -#include "FGameFeaturePackagerSettings.h" -// engine header -#include "Templates/SharedPointer.h" -#include "CreatePatch/HotPatcherProxyBase.h" -#include "GameFeatureProxy.generated.h" - - -UCLASS() -class HOTPATCHERCORE_API UGameFeatureProxy:public UHotPatcherProxyBase -{ - GENERATED_BODY() -public: - virtual bool DoExport() override; - virtual FGameFeaturePackagerSettings* GetSettingObject()override{ return (FGameFeaturePackagerSettings*)Setting; } - -protected: - UPROPERTY() - UPatcherProxy* PatcherProxy; -private: - TSharedPtr PatchSettings; - TSharedPtr ThreadWorker; -}; diff --git a/HotPatcher/Source/HotPatcherCore/Public/HotPatcherCore.h b/HotPatcher/Source/HotPatcherCore/Public/HotPatcherCore.h index 28c2b790..ff1e2bc2 100644 --- a/HotPatcher/Source/HotPatcherCore/Public/HotPatcherCore.h +++ b/HotPatcher/Source/HotPatcherCore/Public/HotPatcherCore.h @@ -19,12 +19,13 @@ HOTPATCHERCORE_API void ReceiveOutputMsg(class FProcWorkerThread* Worker,const F DECLARE_MULTICAST_DELEGATE_TwoParams(FNotificationEvent,FText,const FString&) -class FHotPatcherCoreModule : public IModuleInterface +class HOTPATCHERCORE_API FHotPatcherCoreModule : public IModuleInterface { public: static FHotPatcherCoreModule& Get(); /** IModuleInterface implementation */ virtual void StartupModule() override; virtual void ShutdownModule() override; - + virtual int32 GetMainVersion()const{ return CURRENT_VERSION_ID; } + virtual int32 GetPatchVersion()const { return CURRENT_PATCH_ID; } }; diff --git a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FlibShaderCodeLibraryHelper.h b/HotPatcher/Source/HotPatcherCore/Public/ShaderLibUtils/FlibShaderCodeLibraryHelper.h similarity index 72% rename from HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FlibShaderCodeLibraryHelper.h rename to HotPatcher/Source/HotPatcherCore/Public/ShaderLibUtils/FlibShaderCodeLibraryHelper.h index 54345cc8..211aea1c 100644 --- a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FlibShaderCodeLibraryHelper.h +++ b/HotPatcher/Source/HotPatcherCore/Public/ShaderLibUtils/FlibShaderCodeLibraryHelper.h @@ -61,4 +61,23 @@ class HOTPATCHERCORE_API UFlibShaderCodeLibraryHelper : public UBlueprintFunctio static void CancelMaterialShaderCompile(UMaterialInterface* MaterialInterface); static void CleanShaderWorkerDir(); + + static FString ShaderExtension; + static FString ShaderAssetInfoExtension; + static FString StableExtension; + + FORCEINLINE static FString GetCodeArchiveFilename(const FString& BaseDir, const FString& LibraryName, FName Platform) + { + return BaseDir / FString::Printf(TEXT("ShaderArchive-%s-"), *LibraryName) + Platform.ToString() + ShaderExtension; + } + FORCEINLINE static FString GetShaderAssetInfoFilename(const FString& BaseDir, const FString& LibraryName, FName Platform) + { + return BaseDir / FString::Printf(TEXT("ShaderAssetInfo-%s-"), *LibraryName) + Platform.ToString() + ShaderAssetInfoExtension; + } + + FORCEINLINE static FString GetStableInfoArchiveFilename(const FString& BaseDir, const FString& LibraryName, FName Platform) + { + return BaseDir / FString::Printf(TEXT("ShaderStableInfo-%s-"), *LibraryName) + Platform.ToString() + StableExtension; + } + }; diff --git a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FExportShaderPatchSettings.h b/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FExportShaderPatchSettings.h deleted file mode 100644 index d447faf5..00000000 --- a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FExportShaderPatchSettings.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include "HotPatcherLog.h" -#include "CreatePatch/HotPatcherSettingBase.h" -#include "FlibPatchParserHelper.h" -#include "HotPatcherLog.h" -#include "ETargetPlatform.h" - -// engine header -#include "Misc/FileHelper.h" -#include "CoreMinimal.h" - -#include "UObject/ObjectMacros.h" -#include "UObject/Object.h" -#include "Engine/EngineTypes.h" -#include "Kismet/KismetStringLibrary.h" -#include "Serialization/JsonSerializer.h" -#include "Serialization/JsonWriter.h" - -#include "FExportShaderPatchSettings.generated.h" - - -USTRUCT(BlueprintType) -struct FShaderPatchConf -{ - GENERATED_USTRUCT_BODY() - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - ETargetPlatform Platform = ETargetPlatform::None; - UPROPERTY(EditAnywhere, BlueprintReadWrite) - TArray OldMetadataDir; - UPROPERTY(EditAnywhere, BlueprintReadWrite) - FDirectoryPath NewMetadataDir; - UPROPERTY(EditAnywhere, BlueprintReadWrite) - bool bNativeFormat = false; - // since UE 4.26 (Below 4.26 this parameter has no effect) - UPROPERTY(EditAnywhere, BlueprintReadWrite) - bool bDeterministicShaderCodeOrder = true; -}; - -/** Singleton wrapper to allow for using the setting structure in SSettingsView */ -USTRUCT(BlueprintType) -struct HOTPATCHERCORE_API FExportShaderPatchSettings:public FHotPatcherSettingBase -{ - GENERATED_USTRUCT_BODY() -public: - FExportShaderPatchSettings(){} - virtual ~FExportShaderPatchSettings(){}; - - FORCEINLINE static FExportShaderPatchSettings* Get() - { - static FExportShaderPatchSettings StaticIns; - - return &StaticIns; - } - - UPROPERTY(EditAnywhere, Category="Version") - FString VersionID; - - UPROPERTY(EditAnywhere, Category="Config") - TArray ShaderPatchConfigs; - -}; - - diff --git a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FlibShaderPatchHelper.h b/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FlibShaderPatchHelper.h deleted file mode 100644 index 1afea619..00000000 --- a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/FlibShaderPatchHelper.h +++ /dev/null @@ -1,55 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "Engine/EngineTypes.h" -#include "CoreMinimal.h" - -#include "ETargetPlatform.h" -#include "Kismet/BlueprintFunctionLibrary.h" -#include "FlibShaderPatchHelper.generated.h" - - - -/** - * - */ -UCLASS() -class HOTPATCHERCORE_API UFlibShaderPatchHelper : public UBlueprintFunctionLibrary -{ - GENERATED_BODY() -public: - - UFUNCTION(BlueprintCallable) - static bool CreateShaderCodePatch(TArray const& OldMetaDataDirs, FString const& NewMetaDataDir, FString const& OutDir, bool bNativeFormat,bool bDeterministicShaderCodeOrder = true); - - UFUNCTION(BlueprintCallable) - static TArray ConvDirectoryPathToStr(const TArray& Dirs); - - static FString ShaderExtension; - static FString ShaderAssetInfoExtension; - static FString StableExtension; - - FORCEINLINE static FString GetCodeArchiveFilename(const FString& BaseDir, const FString& LibraryName, FName Platform) - { - return BaseDir / FString::Printf(TEXT("ShaderArchive-%s-"), *LibraryName) + Platform.ToString() + ShaderExtension; - } - FORCEINLINE static FString GetShaderAssetInfoFilename(const FString& BaseDir, const FString& LibraryName, FName Platform) - { - return BaseDir / FString::Printf(TEXT("ShaderAssetInfo-%s-"), *LibraryName) + Platform.ToString() + ShaderAssetInfoExtension; - } - - FORCEINLINE static FString GetStableInfoArchiveFilename(const FString& BaseDir, const FString& LibraryName, FName Platform) - { - return BaseDir / FString::Printf(TEXT("ShaderStableInfo-%s-"), *LibraryName) + Platform.ToString() + StableExtension; - } - - static FString GetShaderStableInfoFileNameByShaderArchiveFileName(const FString& ShaderArchiveFileName); - static FString GetShaderInfoFileNameByShaderArchiveFileName(const FString& ShaderArchiveFileName); - - // static void InitShaderCodeLibrary(const TArray& Platforms); - // static void CleanShaderCodeLibraries(const TArray& Platforms); - // void SaveGlobalShaderLibrary(const TArray& Platforms); - // void SaveShaderLibrary(const ITargetPlatform* TargetPlatform, FString const& Name, const TArray>* ChunkAssignments); -}; - diff --git a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/ShaderPatchProxy.h b/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/ShaderPatchProxy.h deleted file mode 100644 index 10e9d0d2..00000000 --- a/HotPatcher/Source/HotPatcherCore/Public/ShaderPatch/ShaderPatchProxy.h +++ /dev/null @@ -1,24 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "CreatePatch/HotPatcherProxyBase.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" -#include "ShaderPatchProxy.generated.h" - -/** - * - */ -UCLASS() -class HOTPATCHERCORE_API UShaderPatchProxy : public UHotPatcherProxyBase -{ - GENERATED_BODY() -public: - virtual bool DoExport() override; - FORCEINLINE bool IsRunningCommandlet()const{return ::IsRunningCommandlet();} - FORCEINLINE virtual FExportShaderPatchSettings* GetSettingObject()override - { - return (FExportShaderPatchSettings*)Setting; - } -}; diff --git a/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs b/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs index c7e58e07..da0fe5b1 100644 --- a/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs +++ b/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs @@ -81,10 +81,7 @@ public HotPatcherEditor(ReadOnlyTargetRules Target) : base(Target) BuildVersion Version; BuildVersion.TryRead(BuildVersion.GetDefaultFileName(), out Version); AddPublicDefinitions("WITH_EDITOR_SECTION", Version.MajorVersion > 4 || Version.MinorVersion > 24); - // Game feature - bool bEnableGameFeature = false; - AddPublicDefinitions("ENGINE_GAME_FEATURE", bEnableGameFeature || (Target.Version.MajorVersion > 4 || Target.Version.MinorVersion > 26)); - + System.Console.WriteLine("MajorVersion {0} MinorVersion: {1} PatchVersion {2}",Target.Version.MajorVersion,Target.Version.MinorVersion,Target.Version.PatchVersion); PublicDefinitions.AddRange(new string[] diff --git a/HotPatcher/Source/HotPatcherEditor/Private/Cooker/SCookersPage.cpp b/HotPatcher/Source/HotPatcherEditor/Private/Cooker/SCookersPage.cpp index c3d01eb7..e6c3246d 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/Cooker/SCookersPage.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/Cooker/SCookersPage.cpp @@ -29,7 +29,7 @@ void SCookersPage::Construct(const FArguments& InArgs, TSharedPtr Action = Cooker.Value.RequestWidget(GetContext()); + if(Cooker.Value.RequestWidget) + { + TSharedRef Action = Cooker.Value.RequestWidget(GetContext()); - Widget->AddSlot().AutoHeight().Padding(0.0, 8.0, 0.0, 0.0) - [ - Action - ]; - ActionWidgetMap.Add(*Cooker.Key,Action); + Widget->AddSlot().AutoHeight().Padding(0.0, 8.0, 0.0, 0.0) + [ + Action + ]; + ActionWidgetMap.Add(*Cooker.Key,Action); + } } } ChildSlot diff --git a/HotPatcher/Source/HotPatcherEditor/Private/CreatePatch/SPatchersPage.cpp b/HotPatcher/Source/HotPatcherEditor/Private/CreatePatch/SPatchersPage.cpp index cadf328e..440805aa 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/CreatePatch/SPatchersPage.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/CreatePatch/SPatchersPage.cpp @@ -3,8 +3,6 @@ #include "CreatePatch/SPatchersPage.h" #include "CreatePatch/SHotPatcherPatchWidget.h" #include "CreatePatch/SHotPatcherReleaseWidget.h" -#include "ShaderPatch/SShaderPatchWidget.h" -#include "GameFeature/SGameFeaturePackageWidget.h" // engine header #include "HotPatcherEditor.h" @@ -31,7 +29,7 @@ void SPatchersPage::Construct(const FArguments& InArgs, TSharedPtr Action = Patcher.Value.RequestWidget(GetContext()); - Widget->AddSlot().AutoHeight().Padding(0.0, 8.0, 0.0, 0.0) - [ - Action - ]; - ActionWidgetMap.Add(*Patcher.Key,Action); + if(Patcher.Value.RequestWidget) + { + TSharedRef Action = Patcher.Value.RequestWidget(GetContext()); + Widget->AddSlot().AutoHeight().Padding(0.0, 8.0, 0.0, 0.0) + [ + Action + ]; + ActionWidgetMap.Add(*Patcher.Key,Action); + } } } diff --git a/HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.cpp b/HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.cpp deleted file mode 100644 index 329c727f..00000000 --- a/HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include "SGameFeaturePackageWidget.h" -#include "FlibPatchParserHelper.h" -#include "FlibHotPatcherCoreHelper.h" -#include "FlibHotPatcherEditorHelper.h" -#include "HotPatcherEditor.h" -#include "GameFeature/FGameFeaturePackagerSettings.h" -#include "CreatePatch/PatcherProxy.h" -#include "CreatePatch/SHotPatcherPatchWidget.h" -#include "GameFeature/GameFeatureProxy.h" -#include "Interfaces/IPluginManager.h" -#include "Kismet/KismetSystemLibrary.h" -#include "Kismet/KismetTextLibrary.h" -#include "Misc/EngineVersionComparison.h" - -#if !UE_VERSION_OLDER_THAN(5,1,0) - typedef FAppStyle FEditorStyle; -#endif - -#define LOCTEXT_NAMESPACE "SHotPatcherGameFeaturePackager" - -void SGameFeaturePackageWidget::Construct(const FArguments& InArgs, - TSharedPtr InCreateModel) -{ - GameFeaturePackagerSettings = MakeShareable(new FGameFeaturePackagerSettings); - CreateExportFilterListView(); - - SetContext(InCreateModel); - - ChildSlot - [ - SNew(SVerticalBox) - + SVerticalBox::Slot() - .AutoHeight() - .Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding")) - [ - SNew(SHorizontalBox) - + SHorizontalBox::Slot() - .VAlign(VAlign_Center) - [ - SettingsView->GetWidget()->AsShared() - ] - ] - - + SVerticalBox::Slot() - .AutoHeight() - .Padding(0.0, 8.0, 0.0, 0.0) - + SVerticalBox::Slot() - .AutoHeight() - .HAlign(HAlign_Right) - .Padding(4, 4, 10, 4) - [ - SNew(SButton) - .Text(LOCTEXT("GenerateGameFeature", "Generate GameFeature")) - .OnClicked(this,&SGameFeaturePackageWidget::DoGameFeaturePackager) - .IsEnabled(this,&SGameFeaturePackageWidget::CanGameFeaturePackager) - .ToolTipText(this,&SGameFeaturePackageWidget::GetGenerateTooltipText) - ] - ]; -} - -void SGameFeaturePackageWidget::ImportConfig() -{ - UE_LOG(LogHotPatcher, Log, TEXT("Import Game Feature Packager Config")); - TArray Files = this->OpenFileDialog(); - if (!Files.Num()) return; - - FString LoadFile = Files[0]; - - FString JsonContent; - if (UFlibAssetManageHelper::LoadFileToString(LoadFile, JsonContent)) - { - // UFlibHotPatcherCoreHelper::DeserializeReleaseConfig(ExportReleaseSettings, JsonContent); - THotPatcherTemplateHelper::TDeserializeJsonStringAsStruct(JsonContent,*GameFeaturePackagerSettings); - SettingsView->GetDetailsView()->ForceRefresh(); - } -} - -void SGameFeaturePackageWidget::ExportConfig() const -{ - UE_LOG(LogHotPatcher, Log, TEXT("Export Game Feature Packager Config")); - TArray Files = this->SaveFileDialog(); - - if (!Files.Num()) return; - - FString SaveToFile = Files[0].EndsWith(TEXT(".json")) ? Files[0] : Files[0].Append(TEXT(".json")); - - if (GameFeaturePackagerSettings) - { - FString SerializedJsonStr; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*GameFeaturePackagerSettings,SerializedJsonStr); - if (FFileHelper::SaveStringToFile(SerializedJsonStr, *SaveToFile)) - { - FText Msg = LOCTEXT("SavedGameFeatureConfigMas", "Successd to Export the Game Feature Packager Config."); - UFlibHotPatcherEditorHelper::CreateSaveFileNotify(Msg, SaveToFile); - } - } -} - -void SGameFeaturePackageWidget::ResetConfig() -{ - UE_LOG(LogHotPatcher, Log, TEXT("Reset Game Feature Packager Config")); - FString DefaultSettingJson; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*FGameFeaturePackagerSettings::Get(),DefaultSettingJson); - THotPatcherTemplateHelper::TDeserializeJsonStringAsStruct(DefaultSettingJson,*GameFeaturePackagerSettings); - SettingsView->GetDetailsView()->ForceRefresh(); -} - -// #if ENGINE_GAME_FEATURE -// #include "GameFeaturesSubsystem.h" -// #endif -void SGameFeaturePackageWidget::DoGenerate() -{ -#if ENGINE_GAME_FEATURE - if(GetConfigSettings()->bAutoLoadFeaturePlugin) - { - // FString FeatureName = GetConfigSettings()->FeatureName; - FString OutPluginURL; - UWorld* World = GEditor->GetEditorWorldContext().World(); - - for(const auto& FeatureName:GetConfigSettings()->FeatureNames) - { - if(World) - { - auto GameFeatureFounder = [](const FString& FeatureName) - { - bool bFound = false; - FString FeaturePluginDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(FPaths::ProjectPluginsDir(),TEXT("GameFeatures"),FeatureName)); - FString FeatureUPluginPath = FPaths::Combine(FeaturePluginDir,FString::Printf(TEXT("%s.uplugin"),*FeatureName)); - - if(FPaths::DirectoryExists(FeaturePluginDir) && FPaths::FileExists(FeatureUPluginPath)) - { - bFound = true; - } - return bFound; - }; - - if(IPluginManager::Get().FindPlugin(TEXT("GameFeatures")).IsValid() && - IPluginManager::Get().FindPlugin(TEXT("ModularGameplay")).IsValid() - ) - { - if(GameFeatureFounder(FeatureName)) - { - UKismetSystemLibrary::ExecuteConsoleCommand(World,FString::Printf(TEXT("LoadGameFeaturePlugin %s"),*FeatureName)); - UKismetSystemLibrary::ExecuteConsoleCommand(World,FString::Printf(TEXT("DeactivateGameFeaturePlugin %s"),*FeatureName)); - } - } - else - { - UE_LOG(LogHotPatcher,Warning,TEXT("GameFeatures or ModularGameplay is not Enabled!")); - } - } - } - TArray FeatureNamesTemp = GetConfigSettings()->FeatureNames; - for(const auto& FeatureName:FeatureNamesTemp) - { - if(!IPluginManager::Get().FindPlugin(FeatureName)) - { - GetConfigSettings()->FeatureNames.Remove(FeatureName); - UE_LOG(LogHotPatcher,Error,TEXT("%s load faild, %s"),*FeatureName); - } - } - FeaturePackager(); - // UGameFeaturesSubsystem::Get().GetPluginURLForBuiltInPluginByName(FeatureName,OutPluginURL); - // UGameFeaturesSubsystem::Get().LoadGameFeaturePlugin(OutPluginURL,FGameFeaturePluginDeactivateComplete::CreateLambda([this](const UE::GameFeatures::FResult& InStatus) - // { - // if(InStatus.IsValid() && !InStatus.HasError()) - // { - // FeaturePackager(); - // } - // else - // { - // UE_LOG(LogHotPatcher,Error,TEXT("Package Feature %s faild, %s"),*GetConfigSettings()->FeatureName,**InStatus.TryGetError()); - // } - // })); - } -#endif -} - -void SGameFeaturePackageWidget::FeaturePackager() -{ - if(!GetConfigSettings()->IsStandaloneMode()) - { - UGameFeatureProxy* GameFeatureProxy = NewObject(); - GameFeatureProxy->AddToRoot(); - GameFeatureProxy->Init(GetConfigSettings()); - GameFeatureProxy->DoExport(); - } - else - { - FString CurrentConfig; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*GetConfigSettings(),CurrentConfig); - FString SaveConfigTo = FPaths::ConvertRelativePathToFull(FPaths::Combine(FPaths::ProjectSavedDir(),TEXT("HotPatcher"),FString::Printf(TEXT("GameFeatureConfig.json")))); - FFileHelper::SaveStringToFile(CurrentConfig,*SaveConfigTo); - FString MissionCommand = FString::Printf(TEXT("\"%s\" -run=HotPlugin -config=\"%s\" %s"),*UFlibPatchParserHelper::GetProjectFilePath(),*SaveConfigTo,*GetConfigSettings()->GetCombinedAdditionalCommandletArgs()); - UE_LOG(LogHotPatcher,Log,TEXT("HotPatcher %s Mission: %s %s"),*GetMissionName(),*UFlibHotPatcherCoreHelper::GetUECmdBinary(),*MissionCommand); - FHotPatcherEditorModule::Get().RunProcMission(UFlibHotPatcherCoreHelper::GetUECmdBinary(),MissionCommand,GetMissionName()); - } -} - -FText SGameFeaturePackageWidget::GetGenerateTooltipText() const -{ - FString FinalString; - struct FStatus - { - FStatus(bool InMatch,const FString& InDisplay):bMatch(InMatch) - { - Display = FString::Printf(TEXT("%s:%s"),*InDisplay,InMatch?TEXT("true"):TEXT("false")); - } - FString GetDisplay()const{return Display;} - bool bMatch; - FString Display; - }; - TArray AllStatus; - AllStatus.Emplace(HasValidConfig(),TEXT("HasValidGameFeatureConfig")); - bool bHasSavePath = GameFeaturePackagerSettings->GetSaveAbsPath().IsEmpty()?false:FPaths::DirectoryExists(GameFeaturePackagerSettings->GetSaveAbsPath()); - AllStatus.Emplace(bHasSavePath,TEXT("HasSavePath")); - - for(const auto& Status:AllStatus) - { - FinalString+=FString::Printf(TEXT("%s\n"),*Status.GetDisplay()); - } - return UKismetTextLibrary::Conv_StringToText(FinalString); -} - -// #include "DetailsCustomization/CustomGameFeatursDetails.h" - -void SGameFeaturePackageWidget::CreateExportFilterListView() -{ - // Create a property view - FPropertyEditorModule& EditModule = FModuleManager::Get().GetModuleChecked("PropertyEditor"); - - FDetailsViewArgs DetailsViewArgs; - { - DetailsViewArgs.bAllowSearch = true; - DetailsViewArgs.bHideSelectionTip = true; - DetailsViewArgs.bLockable = false; - DetailsViewArgs.bSearchInitialKeyFocus = true; - DetailsViewArgs.bUpdatesFromSelection = false; - DetailsViewArgs.NotifyHook = nullptr; - DetailsViewArgs.bShowOptions = true; - DetailsViewArgs.bShowModifiedPropertiesOption = false; - DetailsViewArgs.bShowScrollBar = false; - DetailsViewArgs.bShowOptions = true; - DetailsViewArgs.bUpdatesFromSelection= true; - } - - FStructureDetailsViewArgs StructureViewArgs; - { - StructureViewArgs.bShowObjects = true; - StructureViewArgs.bShowAssets = true; - StructureViewArgs.bShowClasses = true; - StructureViewArgs.bShowInterfaces = true; - } - - SettingsView = EditModule.CreateStructureDetailView(DetailsViewArgs, StructureViewArgs, nullptr); - FStructOnScope* Struct = new FStructOnScope(FGameFeaturePackagerSettings::StaticStruct(), (uint8*)GameFeaturePackagerSettings.Get()); - // SettingsView->GetOnFinishedChangingPropertiesDelegate().AddRaw(ExportReleaseSettings.Get(),&FGameFeaturePackagerSettings::OnFinishedChangingProperties); - // SettingsView->GetDetailsView()->RegisterInstancedCustomPropertyLayout(FGameFeaturePackagerSettings::StaticStruct(),FOnGetDetailCustomizationInstance::CreateStatic(&FReleaseSettingsDetails::MakeInstance)); - // SettingsView->GetDetailsView()->RegisterInstancedCustomPropertyTypeLayout(FGameFeaturePackagerSettings::StaticStruct()->GetFName(),FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FCustomGameFeaturePackagerSettingsDetails::MakeInstance)); - SettingsView->SetStructureData(MakeShareable(Struct)); -} - -bool SGameFeaturePackageWidget::CanGameFeaturePackager() const -{ - bool bHasSavePath = GameFeaturePackagerSettings->GetSaveAbsPath().IsEmpty()?false:FPaths::DirectoryExists(GameFeaturePackagerSettings->GetSaveAbsPath()); - return HasValidConfig() && bHasSavePath; -} - -bool SGameFeaturePackageWidget::HasValidConfig() const -{ - bool bHasTarget = !!GetConfigSettings()->TargetPlatforms.Num(); - return bHasTarget; -} - -FReply SGameFeaturePackageWidget::DoGameFeaturePackager() -{ - DoGenerate(); - return FReply::Handled(); -} - - - -#undef LOCTEXT_NAMESPACE diff --git a/HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.h b/HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.h deleted file mode 100644 index 8c7f94a4..00000000 --- a/HotPatcher/Source/HotPatcherEditor/Private/GameFeature/SGameFeaturePackageWidget.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. - -#pragma once - -#include "Model/FPatchersModeContext.h" -#include "SHotPatcherWidgetBase.h" -#include "GameFeature/FGameFeaturePackagerSettings.h" - -// engine header -#include "Templates/SharedPointer.h" -#include "IStructureDetailsView.h" - -/** - * Implements the cooked platforms panel. - */ -class SGameFeaturePackageWidget - : public SHotPatcherWidgetBase -{ -public: - - SLATE_BEGIN_ARGS(SGameFeaturePackageWidget) { } - SLATE_END_ARGS() - -public: - - /** - * Constructs the widget. - * - * @param InArgs The Slate argument list. - */ - void Construct( const FArguments& InArgs,TSharedPtr InCreateModel); - -public: - virtual void ImportConfig(); - virtual void ImportProjectConfig(){}; - virtual void ExportConfig()const; - virtual void ResetConfig(); - virtual void DoGenerate(); - - virtual FGameFeaturePackagerSettings* GetConfigSettings() override{return GameFeaturePackagerSettings.Get();}; - virtual FGameFeaturePackagerSettings* GetConfigSettings()const {return GameFeaturePackagerSettings.Get();}; - - virtual FString GetMissionName() override{return TEXT("Game Feature Packager");} - virtual FText GetGenerateTooltipText() const override; -protected: - void CreateExportFilterListView(); - bool CanGameFeaturePackager()const; - bool HasValidConfig()const; - FReply DoGameFeaturePackager(); - void FeaturePackager(); - -private: - - // TSharedPtr mCreatePatchModel; - TSharedPtr PatchSettings; - /** Settings view ui element ptr */ - TSharedPtr SettingsView; - TSharedPtr GameFeaturePackagerSettings; -}; - diff --git a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherActionManager.cpp b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherActionManager.cpp index e3a4b635..0986ffed 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherActionManager.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherActionManager.cpp @@ -1,12 +1,10 @@ #include "HotPatcherActionManager.h" - #include "HotPatcherCore.h" +#include "HotPatcherEditor.h" +#include "Kismet/KismetTextLibrary.h" #include "CreatePatch/SHotPatcherPatchWidget.h" #include "CreatePatch/SHotPatcherReleaseWidget.h" -#include "ShaderPatch/SShaderPatchWidget.h" -#include "GameFeature/SGameFeaturePackageWidget.h" #include "Cooker/OriginalCooker/SOriginalCookWidget.h" -#include "Kismet/KismetTextLibrary.h" #include "SVersionUpdater/FVersionUpdaterManager.h" #define LOCTEXT_NAMESPACE "FHotPatcherActionManager" @@ -15,8 +13,51 @@ FHotPatcherActionManager FHotPatcherActionManager::Manager; void FHotPatcherActionManager::Init() { - FVersionUpdaterManager::Get().RequestRemoveVersion(GRemoteVersionFile); + FVersionUpdaterManager::Get().ModCurrentVersionGetter = [this](const FString& ActionName)->float + { + float CurrentVersion = 0.f; + FHotPatcherModDesc ModDesc; + if(GetModDescByName(ActionName,ModDesc)) + { + CurrentVersion = ModDesc.CurrentVersion; + } + return CurrentVersion; + }; + + FVersionUpdaterManager::Get().ModIsActivteCallback = [this](const FString& ModName)->bool + { + return IsActiviteMod(*ModName); + }; + auto HotPatcherModDescMap2ChildModDesc = [](const TMap& HotPatcherModDescMap)->TArray + { + TArray result; + for(const auto& HotPatcherMod:HotPatcherModDescMap) + { + FChildModDesc ChildModDesc; + ChildModDesc.ModName = HotPatcherMod.Value.ModName; + ChildModDesc.CurrentVersion = HotPatcherMod.Value.CurrentVersion; + ChildModDesc.MinToolVersion = HotPatcherMod.Value.MinHotPatcherVersion; + ChildModDesc.bIsBuiltInMod = HotPatcherMod.Value.bIsBuiltInMod; + ChildModDesc.Description = HotPatcherMod.Value.Description; + ChildModDesc.URL = HotPatcherMod.Value.URL; + ChildModDesc.UpdateURL = HotPatcherMod.Value.UpdateURL; + result.Add(ChildModDesc); + } + return result; + }; + + FVersionUpdaterManager::Get().RequestLocalRegistedMods = [this,HotPatcherModDescMap2ChildModDesc]()->TArray + { + return HotPatcherModDescMap2ChildModDesc(ModsDesc); + }; + FVersionUpdaterManager::Get().RequestUnsupportLocalMods = [this,HotPatcherModDescMap2ChildModDesc]()->TArray + { + return HotPatcherModDescMap2ChildModDesc(UnSupportModsDesc); + }; + SetupDefaultActions(); + + FVersionUpdaterManager::Get().RequestRemoveVersion(GRemoteVersionFile); } void FHotPatcherActionManager::Shutdown() @@ -38,7 +79,15 @@ void FHotPatcherActionManager::RegisteHotPatcherAction(const FString& Category, { return R.Priority > L.Priority; }); + + FHotPatcherActionDesc Desc; + Desc.Category = Category; + Desc.ActionName = ActionName; + Desc.ToolTip = Action.ActionToolTip.Get().ToString(); + Desc.Priority = Action.Priority; + Desc.RequestWidgetPtr = Action.RequestWidget; + ActionsDesc.Add(ActionName,Desc); OnHotPatcherActionRegisted.Broadcast(Category,ActionName,Action); } @@ -48,6 +97,7 @@ void FHotPatcherActionManager::RegisteHotPatcherAction(const FHotPatcherActionDe FHotPatcherAction NewPatcherAction ( *NewAction.ActionName, + *NewAction.ModName, UKismetTextLibrary::Conv_StringToText(NewAction.ActionName), UKismetTextLibrary::Conv_StringToText(NewAction.ToolTip), FSlateIcon(), @@ -55,9 +105,36 @@ void FHotPatcherActionManager::RegisteHotPatcherAction(const FHotPatcherActionDe NewAction.RequestWidgetPtr, NewAction.Priority ); + FHotPatcherActionManager::Get().RegisteHotPatcherAction(NewAction.Category,NewAction.ActionName,NewPatcherAction); } +void FHotPatcherActionManager::RegisteHotPatcherMod(const FHotPatcherModDesc& ModDesc) +{ + if(ModDesc.MinHotPatcherVersion > GetHotPatcherVersion()) + { + UE_LOG(LogHotPatcherEdotor,Warning,TEXT("%s Min Support Version is %.1f,Current HotPatcher Version is %.1f"),*ModDesc.ModName,ModDesc.MinHotPatcherVersion,GetHotPatcherVersion()); + UnSupportModsDesc.Add(*ModDesc.ModName,ModDesc); + } + else + { + for(const auto& ActionDesc:ModDesc.ModActions) + { + FHotPatcherActionManager::Get().RegisteHotPatcherAction(ActionDesc); + } + ModsDesc.Add(*ModDesc.ModName,ModDesc); + } +} + +void FHotPatcherActionManager::UnRegisteHotPatcherMod(const FHotPatcherModDesc& ModDesc) +{ + for(const auto& ActionDesc:ModDesc.ModActions) + { + FHotPatcherActionManager::Get().UnRegisteHotPatcherAction(ActionDesc.Category,ActionDesc.ActionName); + } + ModsDesc.Remove(*ModDesc.ModName); +} + void FHotPatcherActionManager::UnRegisteHotPatcherAction(const FString& Category, const FString& ActionName) { TMap& CategoryIns = HotPatcherActions.FindOrAdd(Category); @@ -67,9 +144,20 @@ void FHotPatcherActionManager::UnRegisteHotPatcherAction(const FString& Category Action = *CategoryIns.Find(ActionName); CategoryIns.Remove(ActionName); } + ActionsDesc.Remove(*ActionName); OnHotPatcherActionUnRegisted.Broadcast(Category,ActionName,Action); } +float FHotPatcherActionManager::GetHotPatcherVersion() const +{ + FString Version = FString::Printf( + TEXT("%d.%d"), + FHotPatcherCoreModule::Get().GetMainVersion(), + FHotPatcherCoreModule::Get().GetPatchVersion() + ); + return UKismetStringLibrary::Conv_StringToFloat(Version); +} + FHotPatcherAction* FHotPatcherActionManager::GetTopActionByCategory(const FString CategoryName) { FHotPatcherAction* result = nullptr; @@ -88,6 +176,19 @@ FHotPatcherAction* FHotPatcherActionManager::GetTopActionByCategory(const FStrin return result; } +bool FHotPatcherActionManager::IsActiviteMod(const FString& ModName) +{ + return ModsDesc.Contains(*ModName); +} + +bool FHotPatcherActionManager::IsSupportEditorAction(FString ActionName) +{ + FHotPatcherActionDesc Desc; + bool bDescStatus = GetActionDescByName(ActionName,Desc); + + return IsActiveAction(ActionName) && (bDescStatus && Desc.RequestWidgetPtr); +} + bool FHotPatcherActionManager::IsActiveAction(FString ActionName) { if(FVersionUpdaterManager::Get().IsRequestFinished()) @@ -117,45 +218,64 @@ bool FHotPatcherActionManager::IsActiveAction(FString ActionName) return true; } +bool FHotPatcherActionManager::GetActionDescByName(const FString& ActionName, FHotPatcherActionDesc& Desc) +{ + bool bStatus = ActionsDesc.Contains(ActionName); + if(bStatus) + { + Desc = *ActionsDesc.Find(ActionName); + } + return bStatus; +}; + +bool FHotPatcherActionManager::GetModDescByName(const FString& ModName, FHotPatcherModDesc& ModDesc) +{ + bool bStatus = ModsDesc.Contains(*ModName); + if(bStatus) + { + ModDesc = *ModsDesc.Find(*ModName); + } + return bStatus; +} +#define HOTPATCHEER_CORE_MODENAME TEXT("HotPatcherCore") +#define CMDHANDLER_MODENAME TEXT("CmdHandler") + void FHotPatcherActionManager::SetupDefaultActions() { - TArray DefaultActions; - DefaultActions.Emplace( - TEXT("Patcher"),LOCTEXT("ByExportRelease", "ByRelease"), LOCTEXT("ExportReleaseActionHint", "Export Release ALL Asset Dependencies."), FSlateIcon(),nullptr, + TArray BuiltInMods; + + FHotPatcherModDesc HotPatcherCoreMod; + HotPatcherCoreMod.ModName = HOTPATCHEER_CORE_MODENAME; + HotPatcherCoreMod.bIsBuiltInMod = true; + HotPatcherCoreMod.CurrentVersion = 1.0; + HotPatcherCoreMod.Description = TEXT("Unreal Engine Asset Manage and Package Solution."); + HotPatcherCoreMod.URL = TEXT("https://imzlp.com/posts/17590/"); + HotPatcherCoreMod.UpdateURL = TEXT("https://github.com/hxhb/HotPatcher"); + + HotPatcherCoreMod.ModActions.Emplace( + TEXT("Patcher"),HOTPATCHEER_CORE_MODENAME,TEXT("ByRelease"), TEXT("Export Release ALL Asset Dependencies."), CREATE_ACTION_WIDGET_LAMBDA(SHotPatcherReleaseWidget,TEXT("ByRelease")), 0 ); - DefaultActions.Emplace( - TEXT("Patcher"),LOCTEXT("ByCreatePatch", "ByPatch"), LOCTEXT("CreatePatchActionHint", "Create an Patch form Release version."), FSlateIcon(),nullptr, + HotPatcherCoreMod.ModActions.Emplace( + TEXT("Patcher"),HOTPATCHEER_CORE_MODENAME,TEXT("ByPatch"), TEXT("Create an Patch form Release version."), CREATE_ACTION_WIDGET_LAMBDA(SHotPatcherPatchWidget,TEXT("ByPatch")), 1 ); - DefaultActions.Emplace( - TEXT("Patcher"),LOCTEXT("ByShaderPatch", "ByShaderPatch"), LOCTEXT("CreateShaderPatchActionHint", "Create an Shader code Patch form Metadata."), FSlateIcon(),nullptr, - CREATE_ACTION_WIDGET_LAMBDA(SShaderPatchWidget,TEXT("ByShaderPatch")), - -1 - ); -#if ENGINE_GAME_FEATURE - DefaultActions.Emplace( - TEXT("Patcher"),LOCTEXT("ByGameFeature", "ByGameFeature"), LOCTEXT("CreateGameFeatureActionHint", "Create an Game Feature Package."), FSlateIcon(),nullptr, - CREATE_ACTION_WIDGET_LAMBDA(SGameFeaturePackageWidget,TEXT("ByGameFeature")), - 0 - ); -#endif - + #if ENABLE_ORIGINAL_COOKER - DefaultActions.Emplace( - TEXT("Cooker"),LOCTEXT("ByOriginal", "ByOriginal"),LOCTEXT("OriginalCookerActionHint", "Use single-process Cook Content(UE Default)"),FSlateIcon(),nullptr, + HotPatcherCoreMod.ModActions.Emplace( + TEXT("Cooker"),TEXT("HotPatcherCore"),HOTPATCHEER_CORE_MODENAME,TEXT("Use single-process Cook Content(UE Default)"), CREATE_ACTION_WIDGET_LAMBDA(SOriginalCookWidget,TEXT("ByOriginal")), 0 ); #endif - for(const auto& Action:DefaultActions) + BuiltInMods.Add(HotPatcherCoreMod); + + for(const auto& Mod:BuiltInMods) { - RegisteHotPatcherAction(Action.Category.ToString(),Action.ActionName.Get().ToString(),Action); + RegisteHotPatcherMod(Mod); } } - - #undef LOCTEXT_NAMESPACE diff --git a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp index 15397470..ad5ee77c 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp @@ -46,6 +46,8 @@ static const FName HotPatcherTabName("HotPatcher"); +DEFINE_LOG_CATEGORY(LogHotPatcherEdotor) + #define LOCTEXT_NAMESPACE "FHotPatcherEditorModule" @@ -395,7 +397,7 @@ void FHotPatcherEditorModule::MakePakExternalActionsSubMenu(UToolMenu* Menu) Section.AddMenuEntry( FName(*PakExternalConfig.PakName), - FText::Format(LOCTEXT("PakExternal", "{0} ({1})"), UKismetTextLibrary::Conv_StringToText(PakExternalConfig.PakName),UKismetTextLibrary::Conv_StringToText(AppendPlatformName)), + FText::Format(LOCTEXT("PakExternal_PakNamePlatform", "{0} ({1})"), UKismetTextLibrary::Conv_StringToText(PakExternalConfig.PakName),UKismetTextLibrary::Conv_StringToText(AppendPlatformName)), FText(), FSlateIcon(), FUIAction( @@ -414,7 +416,7 @@ void FHotPatcherEditorModule::MakeHotPatcherPresetsActionsSubMenu(UToolMenu* Men { Section.AddMenuEntry( FName(*PakConfig.VersionId), - FText::Format(LOCTEXT("PakExternal", "VersionID: {0}"), UKismetTextLibrary::Conv_StringToText(PakConfig.VersionId)), + FText::Format(LOCTEXT("PakExternal_VersionID", "VersionID: {0}"), UKismetTextLibrary::Conv_StringToText(PakConfig.VersionId)), FText(), FSlateIcon(), FUIAction( diff --git a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherModBaseModule.cpp b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherModBaseModule.cpp new file mode 100644 index 00000000..51c2cdc9 --- /dev/null +++ b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherModBaseModule.cpp @@ -0,0 +1,11 @@ +#include "HotPatcherModBaseModule.h" + +void FHotPatcherModBaseModule::StartupModule() +{ + FHotPatcherActionManager::Get().RegisteHotPatcherMod(GetModDesc()); +} + +void FHotPatcherModBaseModule::ShutdownModule() +{ + FHotPatcherActionManager::Get().UnRegisteHotPatcherMod(GetModDesc()); +} diff --git a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherStyle.cpp b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherStyle.cpp index 31c547b4..c8b08858 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherStyle.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherStyle.cpp @@ -1,71 +1,69 @@ -// Copyright 2019 Lipeng Zha, Inc. All Rights Reserved. - -#include "HotPatcherStyle.h" -#include "HotPatcherEditor.h" -#include "Framework/Application/SlateApplication.h" -#include "Styling/SlateStyleRegistry.h" -#include "Slate/SlateGameResources.h" -#include "Interfaces/IPluginManager.h" - -TSharedPtr< FSlateStyleSet > FHotPatcherStyle::StyleInstance = NULL; - -void FHotPatcherStyle::Initialize() -{ - if (!StyleInstance.IsValid()) - { - StyleInstance = Create(); - FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); - } -} - -void FHotPatcherStyle::Shutdown() -{ - FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); - ensure(StyleInstance.IsUnique()); - StyleInstance.Reset(); -} - -FName FHotPatcherStyle::GetStyleSetName() -{ - static FName StyleSetName(TEXT("HotPatcherStyle")); - return StyleSetName; -} - -#define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) -#define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) -#define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) -#define TTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) -#define OTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) - -const FVector2D Icon16x16(16.0f, 16.0f); -const FVector2D Icon20x20(20.0f, 20.0f); -const FVector2D Icon40x40(40.0f, 40.0f); - -TSharedRef< FSlateStyleSet > FHotPatcherStyle::Create() -{ - TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("HotPatcherStyle")); - Style->SetContentRoot(IPluginManager::Get().FindPlugin("HotPatcher")->GetBaseDir() / TEXT("Resources")); - - Style->Set("HotPatcher.PluginAction", new IMAGE_BRUSH(TEXT("ButtonIcon_40x"), Icon40x40)); - - return Style; -} - -#undef IMAGE_BRUSH -#undef BOX_BRUSH -#undef BORDER_BRUSH -#undef TTF_FONT -#undef OTF_FONT - -void FHotPatcherStyle::ReloadTextures() -{ - if (FSlateApplication::IsInitialized()) - { - FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); - } -} - -const ISlateStyle& FHotPatcherStyle::Get() -{ - return *StyleInstance; -} +// Copyright 2019 Lipeng Zha, Inc. All Rights Reserved. + +#include "HotPatcherStyle.h" +#include "HotPatcherEditor.h" +#include "Framework/Application/SlateApplication.h" +#include "Styling/SlateStyleRegistry.h" +#include "Slate/SlateGameResources.h" +#include "Interfaces/IPluginManager.h" + +TSharedPtr< FSlateStyleSet > FHotPatcherStyle::StyleInstance = NULL; + +void FHotPatcherStyle::Initialize() +{ + if (!StyleInstance.IsValid()) + { + StyleInstance = Create(); + FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); + } +} + +void FHotPatcherStyle::Shutdown() +{ + FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); + ensure(StyleInstance.IsUnique()); + StyleInstance.Reset(); +} + +FName FHotPatcherStyle::GetStyleSetName() +{ + static FName StyleSetName(TEXT("HotPatcherStyle")); + return StyleSetName; +} + +#define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define TTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) +#define OTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) + +const FVector2D Icon16x16(16.0f, 16.0f); +const FVector2D Icon20x20(20.0f, 20.0f); +const FVector2D Icon40x40(40.0f, 40.0f); + +TSharedRef< FSlateStyleSet > FHotPatcherStyle::Create() +{ + TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("HotPatcherStyle")); + Style->SetContentRoot(IPluginManager::Get().FindPlugin("HotPatcher")->GetBaseDir() / TEXT("Resources")); + Style->Set("HotPatcher.PluginAction", new IMAGE_BRUSH(TEXT("ButtonIcon_40x"), Icon40x40)); + return Style; +} + +#undef IMAGE_BRUSH +#undef BOX_BRUSH +#undef BORDER_BRUSH +#undef TTF_FONT +#undef OTF_FONT + +void FHotPatcherStyle::ReloadTextures() +{ + if (FSlateApplication::IsInitialized()) + { + FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); + } +} + +const ISlateStyle& FHotPatcherStyle::Get() +{ + return *StyleInstance; +} diff --git a/HotPatcher/Source/HotPatcherEditor/Private/SHotPatcher.cpp b/HotPatcher/Source/HotPatcherEditor/Private/SHotPatcher.cpp index ce7308ca..1e98d83f 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/SHotPatcher.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/SHotPatcher.cpp @@ -21,7 +21,7 @@ void SHotPatcher::Construct(const FArguments& InArgs) HotPatcherCategorys.Add(TEXT("Cooker"),FHotPatcherCategory(TEXT("Cooker"),SNew(SCookersPage, MakeShareable(new FCookersModeContext)))); HotPatcherCategorys.Add(TEXT("Patcher"),FHotPatcherCategory(TEXT("Patcher"),SNew(SPatchersPage, MakeShareable(new FPatchersModeContext)))); HotPatcherCategorys.Append(FHotPatcherActionManager::Get().GetHotPatcherCategorys()); - + float HotPatcherVersion = FHotPatcherActionManager::Get().GetHotPatcherVersion(); ChildSlot [ SNew(SOverlay) @@ -39,6 +39,7 @@ void SHotPatcher::Construct(const FArguments& InArgs) [ SAssignNew(VersionUpdaterWidget,SVersionUpdaterWidget) .ToolName(FText::FromString(GToolName)) + .ToolVersion(HotPatcherVersion) .DeveloperName(FText::FromString(TEXT("lipengzha"))) .DeveloperWebsite(FText::FromString(TEXT("https://imzlp.com"))) .UpdateWebsite(FText::FromString(TEXT("https://imzlp.com/posts/17590/"))) diff --git a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.cpp b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.cpp index 4f850975..ee2a68f4 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.cpp @@ -5,6 +5,7 @@ #include "Interfaces/IHttpRequest.h" #include "Interfaces/IHttpResponse.h" #include "HttpModule.h" +#include "Kismet/KismetStringLibrary.h" #include "Serialization/JsonReader.h" #include "Serialization/JsonSerializer.h" @@ -103,6 +104,41 @@ void FVersionUpdaterManager::OnRequestComplete(FHttpRequestPtr RequestPtr, FHttp RemoteVersion.ActiveActions.Add(*Name,GetActionArray(*Actions,*Name)); } } + + const TArray>* ActionDescs = nullptr; + if(Actions && (*Actions)->TryGetArrayField(TEXT("ModsDesc"),ActionDescs)) + { + for(const TSharedPtr& ModDescJsonValue:*ActionDescs) + { + const TSharedPtr& ModDescJsonObject = ModDescJsonValue.Get()->AsObject(); + FChildModDesc ModDesc; + ModDescJsonObject->TryGetStringField(TEXT("ModName"),ModDesc.ModName); + + auto ReadFloatValue = [](const TSharedPtr& ModDescJsonObject,const FString& Name)->float + { + float Result = 0.f; + FString ValueStr; + if(ModDescJsonObject->TryGetStringField(Name,ValueStr)) + { + Result = UKismetStringLibrary::Conv_StringToFloat(ValueStr); + } + return Result; + }; + + ModDesc.RemoteVersion = ReadFloatValue(ModDescJsonObject,TEXT("Version")); + ModDesc.MinToolVersion = ReadFloatValue(ModDescJsonObject,TEXT("MinToolVersion")); + ModDescJsonObject->TryGetStringField(TEXT("Desc"),ModDesc.Description); + ModDescJsonObject->TryGetStringField(TEXT("URL"),ModDesc.URL); + ModDescJsonObject->TryGetStringField(TEXT("UpdateURL"),ModDesc.UpdateURL); + ModDescJsonObject->TryGetBoolField(TEXT("bIsBuiltInMod"),ModDesc.bIsBuiltInMod); + + if(ModCurrentVersionGetter) + { + ModDesc.CurrentVersion = ModCurrentVersionGetter(ModDesc.ModName); + } + RemoteVersion.ModsDesc.Add(*ModDesc.ModName,ModDesc); + } + } } Remotes.Add(*ToolName,RemoteVersion); } diff --git a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.h b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.h index 2c7c2196..ce0c630d 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.h +++ b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/FVersionUpdaterManager.h @@ -4,6 +4,18 @@ #include "Misc/RemoteConfigIni.h" #include "FCountServerlessWrapper.h" +struct FChildModDesc +{ + FString ModName; + float CurrentVersion = 0.f; + float RemoteVersion = 0.f; + float MinToolVersion = 0.f; + FString Description; + FString URL; + FString UpdateURL; + bool bIsBuiltInMod = false; +}; + struct FRemteVersionDescrible { FRemteVersionDescrible()=default; @@ -16,9 +28,9 @@ struct FRemteVersionDescrible FString URL; bool b3rdMods; TMap> ActiveActions; + TMap ModsDesc; }; - struct FVersionUpdaterManager { static FVersionUpdaterManager& Get() @@ -40,4 +52,12 @@ struct FVersionUpdaterManager bool bRequestFinished = false; TArray> OnRequestFinishedCallback; TSharedPtr Counter; +public: + // get mod current version. + TFunction ModCurrentVersionGetter = nullptr; + // check is valid activite mod callback; + TFunction ModIsActivteCallback = nullptr; + + TFunction()> RequestLocalRegistedMods = nullptr; + TFunction()> RequestUnsupportLocalMods = nullptr; }; \ No newline at end of file diff --git a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.cpp b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.cpp index 14657b4d..486a56d5 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.cpp @@ -14,9 +14,340 @@ #include "VersionUpdaterStyle.h" #include "Interfaces/IHttpRequest.h" #include "Interfaces/IHttpResponse.h" +#include "Interfaces/IPluginManager.h" +#include "Misc/EngineVersionComparison.h" + +#if !UE_VERSION_OLDER_THAN(5,1,0) + typedef FAppStyle FEditorStyle; +#endif #define LOCTEXT_NAMESPACE "VersionUpdaterWidget" +void SChildModWidget::Construct(const FArguments& InArgs) +{ + ToolName = InArgs._ToolName.Get(); + ToolVersion = InArgs._ToolVersion.Get(); + ModDesc = InArgs._ModDesc.Get(); + + bool bIsInstalled = GetCurrentVersion() > 0.f; + bool bUnSupportMod = ModDesc.MinToolVersion > ToolVersion; + + ChildSlot + [ + SAssignNew(HorizontalBox,SHorizontalBox) + + SHorizontalBox::Slot() + .AutoWidth() + .VAlign(VAlign_Center) + .Padding(0.0f, 0.0f, 0.0f, 0.0f) + [ + SNew(STextBlock) + .Text_Lambda([this,bIsInstalled]()->FText + { + FString DisplayStr; + if(ModDesc.bIsBuiltInMod) + { + DisplayStr = FString::Printf(TEXT("%s (Built-in Mod)"),*GetModName()); + } + else if(bIsInstalled) + { + DisplayStr = FString::Printf(TEXT("%s v%.1f"),*GetModName(),GetCurrentVersion()); + } + else if(GetRemoteVersion() > 0.f) + { + DisplayStr = FString::Printf(TEXT("%s v%.1f"),*GetModName(),GetRemoteVersion()); + } + return UKismetTextLibrary::Conv_StringToText(DisplayStr); + }) + ] + ]; + + if(!ModDesc.Description.IsEmpty()) + { + HorizontalBox->AddSlot() + .AutoWidth() + .VAlign(VAlign_Center) + .Padding(10.0f, 0.0f, 0.0f, 0.0f) + [ + SNew(SHyperlink) + .Text(UKismetTextLibrary::Conv_StringToText(ModDesc.Description)) + .OnNavigate_Lambda([this]() + { + if(!ModDesc.URL.IsEmpty()) + { + FPlatformProcess::LaunchURL(*ModDesc.URL, NULL, NULL); + } + }) + ]; + } + + if(bUnSupportMod && !ModDesc.bIsBuiltInMod) + { + HorizontalBox->AddSlot() + .Padding(8.0f, 0.0f, 4.0f, 0.0f) + .AutoWidth() + .VAlign(VAlign_Center) + [ + SNew(STextBlock) + .Text_Lambda([this]()->FText + { + FString UnSupportDisplay = FString::Printf(TEXT("(Require %s v%.1f)"),*ToolName,ModDesc.MinToolVersion); + return UKismetTextLibrary::Conv_StringToText(UnSupportDisplay); + }) + ]; + } + // Update Version + if(!ModDesc.bIsBuiltInMod && + bIsInstalled && + !bUnSupportMod && + ModDesc.RemoteVersion > ModDesc.CurrentVersion) + { + FString LaunchURL = ModDesc.UpdateURL; + if(LaunchURL.IsEmpty()){ LaunchURL = ModDesc.URL;} + + if(!LaunchURL.IsEmpty()) + { + HorizontalBox->AddSlot() + .Padding(8.0f, 0.0f, 4.0f, 0.0f) + .AutoWidth() + .VAlign(VAlign_Center) + [ + SNew(SBox) + .WidthOverride(12) + .HeightOverride(12) + [ + SNew(SImage) + .Image(FVersionUpdaterStyle::GetBrush("Updater.SpawnableIconOverlay")) + ] + ]; + + HorizontalBox->AddSlot() + .Padding(0.0f, 0.0f, 4.0f, 0.0f) + .AutoWidth() + .VAlign(VAlign_Center) + [ + SNew(STextBlock) + .Text(UKismetTextLibrary::Conv_StringToText(FString::Printf(TEXT("New Version: ")))) + ]; + + HorizontalBox->AddSlot() + .Padding(0.0f, 0.0f, 4.0f, 0.0f) + .AutoWidth() + .VAlign(VAlign_Center) + [ + SNew(SHyperlink) + .Text(UKismetTextLibrary::Conv_StringToText(FString::Printf(TEXT("%.1f"),ModDesc.RemoteVersion))) + .OnNavigate_Lambda([LaunchURL]() + { + FPlatformProcess::LaunchURL(*LaunchURL, NULL, NULL); + }) + ]; + } + } +} + +void SChildModManageWidget::Construct(const FArguments& InArgs) +{ + ToolName = InArgs._ToolName.Get(); + ToolVersion = InArgs._ToolVersion.Get(); + bShowPayInfo = InArgs._bShowPayInfo.Get(); + + ChildSlot + [ + SNew(SVerticalBox) + +SVerticalBox::Slot() + .VAlign(VAlign_Center) + .AutoHeight() + [ + SAssignNew(ExpanderButton,SButton) + .ButtonStyle(FEditorStyle::Get(), "NoBorder") + .HAlign(HAlign_Center) + .ContentPadding(2) + .OnClicked_Lambda([this]()->FReply + { + EVisibility ChildModVisibility = ChildModBorder->GetVisibility(); + if (ChildModVisibility == EVisibility::Visible) + { + ChildModBorder->SetVisibility(EVisibility::Collapsed); + } + if (ChildModVisibility == EVisibility::Collapsed) + { + ChildModBorder->SetVisibility(EVisibility::Visible); + } + + return FReply::Handled(); + }) + .ToolTipText_Lambda([this]()->FText { return UKismetTextLibrary::Conv_StringToText(FString::Printf(TEXT("%s Mods"),*ToolName)); }) + [ + SNew(SImage) + .Image_Lambda([this]()->const FSlateBrush* + { + if( ExpanderButton->IsHovered() ) + { + return FEditorStyle::GetBrush("DetailsView.PulldownArrow.Down.Hovered"); + } + else + { + return FEditorStyle::GetBrush("DetailsView.PulldownArrow.Down"); + } + }) + ] + ] + +SVerticalBox::Slot() + .VAlign(VAlign_Center) + .AutoHeight() + [ + SAssignNew(ChildModBorder,SBorder) + .BorderImage(FVersionUpdaterStyle::GetBrush("Updater.GroupBorder")) + [ + SNew(SHorizontalBox) + +SHorizontalBox::Slot() + .VAlign(VAlign_Top) + .HAlign(HAlign_Fill) + .Padding(5,4,20,4) + [ + SAssignNew(ChildModBox,SVerticalBox) + ] + +SHorizontalBox::Slot() + .VAlign(VAlign_Center) + .Padding(20,4,20,4) + .AutoWidth() + [ + SAssignNew(PayBox,SVerticalBox) + ] + ] + ] + ]; + if(bShowPayInfo) + { + PayBox->AddSlot() + .VAlign(VAlign_Center) + .HAlign(HAlign_Center) + .AutoHeight() + .Padding(0.f,2.f,0.f,2.f) + [ + SNew(STextBlock) + .Text_Lambda([]()->FText{ return UKismetTextLibrary::Conv_StringToText(TEXT("Help me make HotPatcher better.")); }) + ]; + PayBox->AddSlot() + .VAlign(VAlign_Center) + .HAlign(HAlign_Center) + .FillHeight(1.0) + .Padding(0.f,2.f,0.f,0.f) + [ + SNew(SBox) + [ + SAssignNew(PayImage,SImage) + .Image(FVersionUpdaterStyle::GetBrush("Updater.WechatPay")) + ] + ]; + + PayBox->AddSlot() + .VAlign(VAlign_Center) + .HAlign(HAlign_Center) + .AutoHeight() + .Padding(0.f,2.f,0.f,0.f) + [ + SAssignNew(PaymentButtonWrapper,SHorizontalBox) + ]; + AddPayment(TEXT("WechatPay"),"Updater.WechatPay"); + AddPayment(TEXT("AliPay"),"Updater.AliPay"); + SetPaymentFocus(TEXT("WechatPay")); + } +} + +bool SChildModManageWidget::AddModCategory(const FString& Category,const TArray& ModsDesc) +{ + bool bStatus = false; + if(ChildModBox.IsValid() && ModsDesc.Num()) + { + ChildModBox.Get()->AddSlot() + .AutoHeight() + .VAlign(EVerticalAlignment::VAlign_Center) + .Padding(5.f,2.f,0.f,2.f) + [ + SNew(STextBlock) + .ColorAndOpacity(FColor::Green) + .Text(UKismetTextLibrary::Conv_StringToText(Category)) + ]; + + for(const auto& ModDesc:ModsDesc) + { + AddChildMod(ModDesc); + } + bStatus = true; + } + return bStatus; +} + +bool SChildModManageWidget::AddChildMod(const FChildModDesc& ModDesc) +{ + bool bStatus = false; + if(ChildModBox.IsValid()) + { + ChildModBox.Get()->AddSlot() + .AutoHeight() + .VAlign(EVerticalAlignment::VAlign_Center) + .Padding(15.f,2.f,0.f,2.f) + [ + SNew(SChildModWidget) + .ToolName(ToolName) + .ToolVersion(ToolVersion) + .ModDesc(ModDesc) + ]; + bStatus = true; + } + return bStatus; +} + +bool SChildModManageWidget::AddPayment(const FString& Name, const FString& ImageBrushName) +{ + bool bStatus = false; + if(PaymentButtonWrapper.IsValid()) + { + TSharedPtr TmpPayTextBlock = nullptr; + SChildModManageWidget::FPaymentInfo PaymentInfo; + PaymentInfo.Name = Name; + PaymentInfo.BrushName = ImageBrushName; + + PaymentButtonWrapper->AddSlot() + .HAlign(HAlign_Center) + .VAlign(VAlign_Center) + .AutoWidth() + [ + SAssignNew(PaymentInfo.Button,SButton) + .ButtonColorAndOpacity(FLinearColor::Transparent) + .OnClicked_Lambda([this,Name]()->FReply + { + SetPaymentFocus(Name); + return FReply::Handled(); + }) + [ + SAssignNew(PaymentInfo.TextBlock,STextBlock) + .ColorAndOpacity(FLinearColor::White) + .Text_Lambda([Name]()->FText{ return UKismetTextLibrary::Conv_StringToText(Name); }) + ] + ]; + + PaymentInfoMap.Add(Name,PaymentInfo); + bStatus = true; + } + return bStatus; +} + +void SChildModManageWidget::SetPaymentFocus(const FString& Name) +{ + for(const auto& PaymentInfo:PaymentInfoMap) + { + PaymentInfo.Value.TextBlock->SetColorAndOpacity(FLinearColor::White); + } + + if(PaymentInfoMap.Contains(Name)) + { + SChildModManageWidget::FPaymentInfo& FocusPaymentInfo = *PaymentInfoMap.Find(Name); + FocusPaymentInfo.TextBlock->SetColorAndOpacity(FColor::Orange); + PayImage->SetImage(FVersionUpdaterStyle::GetBrush(*FocusPaymentInfo.BrushName)); + } +} void SVersionUpdaterWidget::Construct(const FArguments& InArgs) { @@ -34,113 +365,137 @@ void SVersionUpdaterWidget::Construct(const FArguments& InArgs) InArgs._DeveloperWebsite.Get().ToString(), InArgs._UpdateWebsite.Get().ToString() ); + ToolVersion = InArgs._ToolVersion.Get(); CurrentVersion = InArgs._CurrentVersion.Get(); PatchVersion = InArgs._PatchVersion.Get(); + bool bhPayment = FPaths::FileExists(IPluginManager::Get().FindPlugin(ToolName)->GetBaseDir() / TEXT("Resources/hPayment.txt")); + bool bhMods = FPaths::FileExists(IPluginManager::Get().FindPlugin(ToolName)->GetBaseDir() / TEXT("Resources/hMods.txt")); ChildSlot [ - SNew(SBorder) - .Padding(2) - .BorderImage(FVersionUpdaterStyle::GetBrush("Updater.GroupBorder")) + SNew(SVerticalBox) + + SVerticalBox::Slot() + .VAlign(VAlign_Center) + .AutoHeight() [ - SNew(SHorizontalBox) - + SHorizontalBox::Slot() - .FillWidth(1.0f) - .VAlign(VAlign_Center) - .Padding(4.0f, 0.0f, 4.0f, 0.0f) + SNew(SBorder) + .Padding(2) + .BorderImage(FVersionUpdaterStyle::GetBrush("Updater.GroupBorder")) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() - .AutoWidth() - .VAlign(VAlign_Center) - [ - SNew(SBox) - .WidthOverride(40) - .HeightOverride(40) - [ - SNew(SImage) - .Image(FVersionUpdaterStyle::GetBrush("Updater.QuickLaunch")) - ] - ] - + SHorizontalBox::Slot() - .AutoWidth() - .Padding(10,0,10,0) + .FillWidth(1.0f) .VAlign(VAlign_Center) + .Padding(4.0f, 0.0f, 4.0f, 0.0f) [ - SNew(SVerticalBox) - + SVerticalBox::Slot() - .AutoHeight() - .Padding(2, 4, 2, 4) + SNew(SHorizontalBox) + + SHorizontalBox::Slot() + .AutoWidth() + .VAlign(VAlign_Center) [ - SNew(SHorizontalBox) - + SHorizontalBox::Slot() - .AutoWidth() - [ - SNew(SHyperlink) - .Text_Raw(this,&SVersionUpdaterWidget::GetToolName) - .OnNavigate(this, &SVersionUpdaterWidget::HyLinkClickEventOpenUpdateWebsite) - ] - + SHorizontalBox::Slot() - .FillWidth(1.0) + SNew(SBox) + .WidthOverride(40) + .HeightOverride(40) [ - SNew(SOverlay) + SNew(SImage) + .Image(FVersionUpdaterStyle::GetBrush("Updater.QuickLaunch")) ] ] - + SVerticalBox::Slot() + + SHorizontalBox::Slot() + .AutoWidth() + .Padding(10,0,10,0) + .VAlign(VAlign_Center) + [ + SNew(SVerticalBox) + + SVerticalBox::Slot() .AutoHeight() .Padding(2, 4, 2, 4) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() - .Padding(0,0,4,0) [ - SNew(STextBlock) - .Text_Raw(this,&SVersionUpdaterWidget::GetCurrentVersionText) + SNew(SHyperlink) + .Text_Raw(this,&SVersionUpdaterWidget::GetToolName) + .OnNavigate(this, &SVersionUpdaterWidget::HyLinkClickEventOpenUpdateWebsite) ] + SHorizontalBox::Slot() - .AutoWidth() + .FillWidth(1.0) + [ + SNew(SOverlay) + ] + ] + + SVerticalBox::Slot() + .AutoHeight() + .Padding(2, 4, 2, 4) [ - SAssignNew(UpdateInfoWidget,SHorizontalBox) - .Visibility(EVisibility::Collapsed) + SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() + .Padding(0,0,4,0) [ - SNew(SBox) - .WidthOverride(18) - .HeightOverride(18) - [ - SNew(SImage) - .Image(FVersionUpdaterStyle::GetBrush("Updater.SpawnableIconOverlay")) - ] + SNew(STextBlock) + .Text_Raw(this,&SVersionUpdaterWidget::GetCurrentVersionText) ] + SHorizontalBox::Slot() - .Padding(2,0,0,0) .AutoWidth() [ - SNew(SHyperlink) - .Text_Raw(this,&SVersionUpdaterWidget::GetLatstVersionText) - .OnNavigate(this, &SVersionUpdaterWidget::HyLinkClickEventOpenUpdateWebsite) + SAssignNew(UpdateInfoWidget,SHorizontalBox) + .Visibility(EVisibility::Collapsed) + + SHorizontalBox::Slot() + .AutoWidth() + [ + SNew(SBox) + .WidthOverride(18) + .HeightOverride(18) + [ + SNew(SImage) + .Image(FVersionUpdaterStyle::GetBrush("Updater.SpawnableIconOverlay")) + ] + ] + + SHorizontalBox::Slot() + .Padding(2,0,0,0) + .AutoWidth() + [ + SNew(SHyperlink) + .Text_Raw(this,&SVersionUpdaterWidget::GetLatstVersionText) + .OnNavigate(this, &SVersionUpdaterWidget::HyLinkClickEventOpenUpdateWebsite) + ] ] ] - ] + ] + ] + + SHorizontalBox::Slot() + .FillWidth(1.0f) + .VAlign(VAlign_Center) + [ + SNew(SOverlay) + ] + + SHorizontalBox::Slot() + .AutoWidth() + .Padding(10,0,10,0) + .VAlign(VAlign_Center) + [ + SNew(SHyperlink) + .Text_Raw(this,&SVersionUpdaterWidget::GetDeveloperDescrible) + .OnNavigate(this, &SVersionUpdaterWidget::HyLinkClickEventOpenDeveloperWebsite) ] ] - + SHorizontalBox::Slot() - .FillWidth(1.0f) - .VAlign(VAlign_Center) - [ - SNew(SOverlay) - ] - + SHorizontalBox::Slot() - .AutoWidth() - .Padding(10,0,10,0) - .VAlign(VAlign_Center) - [ - SNew(SHyperlink) - .Text_Raw(this,&SVersionUpdaterWidget::GetDeveloperDescrible) - .OnNavigate(this, &SVersionUpdaterWidget::HyLinkClickEventOpenDeveloperWebsite) - ] + ] + + SVerticalBox::Slot() + .VAlign(VAlign_Center) + .Padding(0,4,0,4) + .AutoHeight() + [ + SAssignNew(ChildModManageWidget,SChildModManageWidget) + .ToolName(ToolName) + .ToolVersion(ToolVersion) + .bShowPayInfo(!bhPayment) + .Visibility_Lambda([bhMods]()->EVisibility{ + EVisibility Visibility = EVisibility::Visible; + if(bhMods) { Visibility = EVisibility::Collapsed; } + return Visibility; + }) ] ]; if(!FVersionUpdaterManager::Get().IsRequestFinished()) @@ -156,6 +511,7 @@ void SVersionUpdaterWidget::Construct(const FArguments& InArgs) { OnRemoveVersionFinished(); } + FVersionUpdaterManager::Get().Update(); } @@ -178,6 +534,7 @@ void SVersionUpdaterWidget::SetToolUpdateInfo(const FString& InToolName, const F UpdateWebsite = InUpdateWebsite; } + void SVersionUpdaterWidget::OnRemoveVersionFinished() { FRemteVersionDescrible* ToolRemoteVersion = FVersionUpdaterManager::Get().GetRemoteVersionByName(*GetToolName().ToString()); @@ -185,13 +542,79 @@ void SVersionUpdaterWidget::OnRemoveVersionFinished() { int32 RemoteMainVersion = ToolRemoteVersion->Version; int32 RemotePatchVersion = ToolRemoteVersion->PatchVersion; - + SetToolUpdateInfo(GetToolName().ToString(),ToolRemoteVersion->Author,ToolRemoteVersion->Website,ToolRemoteVersion->URL); if(CurrentVersion < RemoteMainVersion || (CurrentVersion == RemoteMainVersion && RemotePatchVersion > PatchVersion)) { UpdateInfoWidget->SetVisibility(EVisibility::Visible); } RemoteVersion = *ToolRemoteVersion; + + TArray RemoteOfficalMods; + for(const auto& ModDesc:RemoteVersion.ModsDesc) + { + RemoteOfficalMods.Add(ModDesc.Value); + } + + auto GetChildModsByCondition = [this](const TArray& ModsDesc,TFunction Condition = [](const FChildModDesc&)->bool{return true;}) ->TArray + { + TArray ChildMods; + for(const auto& ModDesc:ModsDesc) + { + if(Condition && Condition(ModDesc)) + { + ChildMods.Add(ModDesc); + } + } + return ChildMods; + }; + + auto DiffMods = [](const TArray& L,const TArray& R,bool bReverse = true)->TArray + { + TArray ResultMods; + TArray LocalMods = FVersionUpdaterManager::Get().RequestLocalRegistedMods(); + for(const auto& LMod:L) + { + bool bContainInR = false; + for(const auto& RMod:R) + { + if(RMod.ModName.Equals(LMod.ModName)){ bContainInR = true;break; } + } + if(bReverse) + { + bContainInR = !bContainInR; + } + if(bContainInR) { ResultMods.Add(LMod); } + } + return ResultMods; + }; + + TArray InstalledLocalMods; + if(FVersionUpdaterManager::Get().RequestLocalRegistedMods) + { + InstalledLocalMods = FVersionUpdaterManager::Get().RequestLocalRegistedMods(); + } + + TArray BuiltInMods = GetChildModsByCondition(InstalledLocalMods,[](const FChildModDesc& Desc)->bool { return Desc.bIsBuiltInMod;}); + TArray NotBuiltInMods = GetChildModsByCondition(InstalledLocalMods,[](const FChildModDesc& Desc)->bool { return !Desc.bIsBuiltInMod;}); + TArray ThirdPartyMods = DiffMods(NotBuiltInMods,RemoteOfficalMods); + TArray InstalledOfficalMods = DiffMods(NotBuiltInMods,ThirdPartyMods); + TArray NotInstalledOfficalMods = DiffMods(RemoteOfficalMods,InstalledLocalMods); + TArray UnSupportLocalMods; + if(FVersionUpdaterManager::Get().RequestUnsupportLocalMods) + { + UnSupportLocalMods = FVersionUpdaterManager::Get().RequestUnsupportLocalMods(); + } + // Built-in Mods + ChildModManageWidget->AddModCategory(TEXT("Built-In"),DiffMods(RemoteOfficalMods,BuiltInMods,false)); + // Not Installed Offical Mod + ChildModManageWidget->AddModCategory(TEXT("Installed"),DiffMods(RemoteOfficalMods,InstalledOfficalMods,false)); + // local 3rd mods + ChildModManageWidget->AddModCategory(TEXT("ThirdParty"),ThirdPartyMods); + // Unsupport Mods (MinToolVersion > CurrentToolMod) + ChildModManageWidget->AddModCategory(TEXT("Unsupport Mods"),UnSupportLocalMods); + // Not-Installed Offical Mod + ChildModManageWidget->AddModCategory(TEXT("Not-Installed (Professional Mods)"),NotInstalledOfficalMods); } } diff --git a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.h b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.h index c3ef6d22..8642dc74 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.h +++ b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/SVersionUpdaterWidget.h @@ -8,6 +8,89 @@ #include "FVersionUpdaterManager.h" +class SChildModWidget : public SCompoundWidget +{ +public: + SLATE_BEGIN_ARGS(SChildModWidget): + _ToolName(), + _ToolVersion(), + _ModDesc() + {} + SLATE_ATTRIBUTE( FString, ToolName ) + SLATE_ATTRIBUTE( float, ToolVersion ) + SLATE_ATTRIBUTE( FChildModDesc, ModDesc ) + SLATE_END_ARGS() + + FText GetModDisplay() const + { + return FText::FromString( + FString::Printf(TEXT("%s v%.1f"),*GetModName(),GetCurrentVersion()) + ); + }; + +public: + /** + * Construct the widget + * + * @param InArgs A declaration from which to construct the widget + */ + void Construct(const FArguments& InArgs); + + float GetCurrentVersion()const { return ModDesc.CurrentVersion; } + float GetRemoteVersion()const { return ModDesc.RemoteVersion; } + FString GetModName()const { return ModDesc.ModName; }; + +private: + FString ToolName; + float ToolVersion = 0.f; + FChildModDesc ModDesc; + TSharedPtr HorizontalBox; +}; + +class SChildModManageWidget : public SCompoundWidget +{ +public: + SLATE_BEGIN_ARGS(SChildModManageWidget): + _ToolName(), + _ToolVersion(), + _bShowPayInfo() + {} + SLATE_ATTRIBUTE( FString, ToolName ) + SLATE_ATTRIBUTE( float, ToolVersion ) + SLATE_ATTRIBUTE( bool, bShowPayInfo ) + SLATE_END_ARGS() + +public: + void Construct(const FArguments& InArgs); + bool AddModCategory(const FString& Category,const TArray& ModsDesc); + bool AddChildMod(const FChildModDesc& ModDesc); + bool AddPayment(const FString& Name,const FString& ImageBrushName); + void SetPaymentFocus(const FString& Name); + +protected: + FString ToolName; + float ToolVersion = 0.f; + bool bShowPayInfo = true; + + // child mod + TSharedPtr ExpanderButton; + TSharedPtr ChildModBorder; + TSharedPtr ChildModBox; + // payment + TSharedPtr PayBox; + TSharedPtr PaymentButtonWrapper; + TSharedPtr PayImage; + + struct FPaymentInfo + { + FString Name; + FString BrushName; + TSharedPtr Button; + TSharedPtr TextBlock; + }; + TMap PaymentInfoMap; +}; + class SVersionUpdaterWidget : public SCompoundWidget { @@ -15,6 +98,7 @@ class SVersionUpdaterWidget : public SCompoundWidget SLATE_BEGIN_ARGS(SVersionUpdaterWidget): _CurrentVersion(), _ToolName(), + _ToolVersion(), _DeveloperName(), _DeveloperWebsite(), _UpdateWebsite() @@ -22,6 +106,7 @@ class SVersionUpdaterWidget : public SCompoundWidget SLATE_ATTRIBUTE( int32, CurrentVersion ) SLATE_ATTRIBUTE( int32, PatchVersion ) SLATE_ATTRIBUTE( FText, ToolName ) + SLATE_ATTRIBUTE( float, ToolVersion ) SLATE_ATTRIBUTE( FText, DeveloperName ) SLATE_ATTRIBUTE( FText, DeveloperWebsite ) SLATE_ATTRIBUTE( FText, UpdateWebsite ) @@ -52,17 +137,20 @@ class SVersionUpdaterWidget : public SCompoundWidget virtual void SetToolUpdateInfo(const FString& ToolName,const FString& DeveloperName,const FString& DeveloperWebsite,const FString& UpdateWebsite); int32 GetCurrentVersion()const { return CurrentVersion; } int32 GetPatchVersion()const { return PatchVersion; } - + + private: void OnRemoveVersionFinished(); int32 CurrentVersion = 0; int32 PatchVersion = 0; FString ToolName; + float ToolVersion = 0.f; FString UpdateWebsite; FString DeveloperWebsite; FString DeveloperName; TSharedPtr UpdateInfoWidget; FRemteVersionDescrible RemoteVersion; + TSharedPtr ChildModManageWidget; }; diff --git a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/VersionUpdaterStyle.cpp b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/VersionUpdaterStyle.cpp index 1b1a4d16..2552c885 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/VersionUpdaterStyle.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/SVersionUpdater/VersionUpdaterStyle.cpp @@ -41,6 +41,7 @@ const FVector2D Updater_Icon12x12(12.0f, 12.0f); const FVector2D Updater_Icon16x16(16.0f, 16.0f); const FVector2D Updater_Icon20x20(20.0f, 20.0f); const FVector2D Updater_Icon40x40(40.0f, 40.0f); +const FVector2D Updater_IconPay(120.0f, 120.0f); TSharedRef< FSlateStyleSet > FVersionUpdaterStyle::Create(const FString& Name) { @@ -58,7 +59,18 @@ TSharedRef< FSlateStyleSet > FVersionUpdaterStyle::Create(const FString& Name) Style->Set("Updater.Star", new IMAGE_CORE_BRUSH("Sequencer/Star", Updater_Icon12x12)); Style->Set("Updater.SpawnableIconOverlay", new IMAGE_CORE_BRUSH(TEXT("Sequencer/SpawnableIconOverlay"), FVector2D(13, 13))); - + + FString PluginResourceDir = IPluginManager::Get().FindPlugin("HotPatcher")->GetBaseDir() / TEXT("Resources/Payments"); + Style->Set( + "Updater.WechatPay", + new FSlateImageBrush( FPaths::Combine(PluginResourceDir , TEXT("wechatpay.png")), + Updater_IconPay) + ); + Style->Set( + "Updater.AliPay", + new FSlateImageBrush( FPaths::Combine(PluginResourceDir , TEXT("alipay.png")), + Updater_IconPay) + ); return Style; } diff --git a/HotPatcher/Source/HotPatcherEditor/Private/ShaderPatch/SShaderPatchWidget.cpp b/HotPatcher/Source/HotPatcherEditor/Private/ShaderPatch/SShaderPatchWidget.cpp deleted file mode 100644 index 7f190aaf..00000000 --- a/HotPatcher/Source/HotPatcherEditor/Private/ShaderPatch/SShaderPatchWidget.cpp +++ /dev/null @@ -1,225 +0,0 @@ -#include "ShaderPatch/SShaderPatchWidget.h" -#include "FlibPatchParserHelper.h" -#include "FlibHotPatcherCoreHelper.h" -#include "FlibHotPatcherEditorHelper.h" -#include "HotPatcherEditor.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" -#include "ShaderPatch/FlibShaderPatchHelper.h" -#include "RHI.h" -#include "Kismet/KismetTextLibrary.h" -#include "ShaderPatch/ShaderPatchProxy.h" - -#define LOCTEXT_NAMESPACE "SHotPatcherShaderPatch" - -void SShaderPatchWidget::Construct(const FArguments& InArgs, - TSharedPtr InContext) -{ - SetContext(InContext); - - ExportShaderPatchSettings = MakeShareable(new FExportShaderPatchSettings); - CreateExportFilterListView(); - - ChildSlot - [ - SNew(SVerticalBox) - + SVerticalBox::Slot() - .AutoHeight() - .Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding")) - [ - SNew(SHorizontalBox) - + SHorizontalBox::Slot() - .VAlign(VAlign_Center) - [ - SettingsView->GetWidget()->AsShared() - ] - ] - - + SVerticalBox::Slot() - .AutoHeight() - .Padding(0.0, 8.0, 0.0, 0.0) - + SVerticalBox::Slot() - .AutoHeight() - .HAlign(HAlign_Right) - .Padding(4, 4, 10, 4) - [ - SNew(SButton) - .Text(LOCTEXT("GenerateShaderPatch", "Export ShaderPatch")) - .OnClicked(this,&SShaderPatchWidget::DoExportShaderPatch) - .IsEnabled(this,&SShaderPatchWidget::CanExportShaderPatch) - .ToolTipText(this,&SShaderPatchWidget::GetGenerateTooltipText) - ] - ]; -} - -void SShaderPatchWidget::ImportConfig() -{ - UE_LOG(LogHotPatcher, Log, TEXT("Import Shader Patch Config")); - TArray Files = this->OpenFileDialog(); - if (!Files.Num()) return; - - FString LoadFile = Files[0]; - - FString JsonContent; - if (UFlibAssetManageHelper::LoadFileToString(LoadFile, JsonContent)) - { - // UFlibHotPatcherCoreHelper::DeserializeReleaseConfig(ExportReleaseSettings, JsonContent); - THotPatcherTemplateHelper::TDeserializeJsonStringAsStruct(JsonContent,*ExportShaderPatchSettings); - SettingsView->GetDetailsView()->ForceRefresh(); - } -} - -void SShaderPatchWidget::ExportConfig() const -{ - UE_LOG(LogHotPatcher, Log, TEXT("Export Shader Patch Config")); - TArray Files = this->SaveFileDialog(); - - if (!Files.Num()) return; - - FString SaveToFile = Files[0].EndsWith(TEXT(".json")) ? Files[0] : Files[0].Append(TEXT(".json")); - - if (ExportShaderPatchSettings) - { - FString SerializedJsonStr; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*ExportShaderPatchSettings,SerializedJsonStr); - if (FFileHelper::SaveStringToFile(SerializedJsonStr, *SaveToFile)) - { - FText Msg = LOCTEXT("SavedShaderPatchConfigMas", "Successd to Export the Shader Patch Config."); - UFlibHotPatcherEditorHelper::CreateSaveFileNotify(Msg, SaveToFile); - } - } -} - -void SShaderPatchWidget::ResetConfig() -{ - UE_LOG(LogHotPatcher, Log, TEXT("Reset Shader Patch Config")); - FString DefaultSettingJson; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*FExportShaderPatchSettings::Get(),DefaultSettingJson); - THotPatcherTemplateHelper::TDeserializeJsonStringAsStruct(DefaultSettingJson,*ExportShaderPatchSettings); - SettingsView->GetDetailsView()->ForceRefresh(); -} - -void SShaderPatchWidget::DoGenerate() -{ - UShaderPatchProxy* ShaderPatchProxy = NewObject(); - ShaderPatchProxy->AddToRoot(); - ShaderPatchProxy->Init(ExportShaderPatchSettings.Get()); - if(!ShaderPatchProxy->GetSettingObject()->bStandaloneMode) - { - ShaderPatchProxy->DoExport(); - } - else - { - FString CurrentConfig; - THotPatcherTemplateHelper::TSerializeStructAsJsonString(*GetConfigSettings(),CurrentConfig); - FString SaveConfigTo = FPaths::ConvertRelativePathToFull(FPaths::Combine(FPaths::ProjectSavedDir(),TEXT("HotPatcher"),TEXT("ShaderPatchConfig.json"))); - FFileHelper::SaveStringToFile(CurrentConfig,*SaveConfigTo); - FString MissionCommand = FString::Printf(TEXT("\"%s\" -run=HotShaderPatch -config=\"%s\" %s"),*UFlibPatchParserHelper::GetProjectFilePath(),*SaveConfigTo,*GetConfigSettings()->GetCombinedAdditionalCommandletArgs()); - UE_LOG(LogHotPatcher,Log,TEXT("HotPatcher %s Mission: %s %s"),*GetMissionName(),*UFlibHotPatcherCoreHelper::GetUECmdBinary(),*MissionCommand); - FHotPatcherEditorModule::Get().RunProcMission(UFlibHotPatcherCoreHelper::GetUECmdBinary(),MissionCommand,GetMissionName()); - } -} - -FText SShaderPatchWidget::GetGenerateTooltipText() const -{ - FString FinalString; - struct FStatus - { - FStatus(bool InMatch,const FString& InDisplay):bMatch(InMatch) - { - Display = FString::Printf(TEXT("%s:%s"),*InDisplay,InMatch?TEXT("true"):TEXT("false")); - } - FString GetDisplay()const{return Display;} - bool bMatch; - FString Display; - }; - TArray AllStatus; - AllStatus.Emplace(HasValidConfig(),TEXT("HasValidShaderPatchConfig")); - bool bHasSavePath = ExportShaderPatchSettings->GetSaveAbsPath().IsEmpty()?false:FPaths::DirectoryExists(ExportShaderPatchSettings->GetSaveAbsPath()); - AllStatus.Emplace(bHasSavePath,TEXT("HasSavePath")); - - for(const auto& Status:AllStatus) - { - FinalString+=FString::Printf(TEXT("%s\n"),*Status.GetDisplay()); - } - return UKismetTextLibrary::Conv_StringToText(FinalString); -} - -void SShaderPatchWidget::CreateExportFilterListView() -{ - // Create a property view - FPropertyEditorModule& EditModule = FModuleManager::Get().GetModuleChecked("PropertyEditor"); - - FDetailsViewArgs DetailsViewArgs; - { - DetailsViewArgs.bAllowSearch = true; - DetailsViewArgs.bHideSelectionTip = true; - DetailsViewArgs.bLockable = false; - DetailsViewArgs.bSearchInitialKeyFocus = true; - DetailsViewArgs.bUpdatesFromSelection = false; - DetailsViewArgs.NotifyHook = nullptr; - DetailsViewArgs.bShowOptions = true; - DetailsViewArgs.bShowModifiedPropertiesOption = false; - DetailsViewArgs.bShowScrollBar = false; - DetailsViewArgs.bShowOptions = true; - DetailsViewArgs.bUpdatesFromSelection= true; - } - - FStructureDetailsViewArgs StructureViewArgs; - { - StructureViewArgs.bShowObjects = true; - StructureViewArgs.bShowAssets = true; - StructureViewArgs.bShowClasses = true; - StructureViewArgs.bShowInterfaces = true; - } - - SettingsView = EditModule.CreateStructureDetailView(DetailsViewArgs, StructureViewArgs, nullptr); - FStructOnScope* Struct = new FStructOnScope(FExportShaderPatchSettings::StaticStruct(), (uint8*)ExportShaderPatchSettings.Get()); - // SettingsView->GetOnFinishedChangingPropertiesDelegate().AddRaw(ExportReleaseSettings.Get(),&FExportShaderPatchSettings::OnFinishedChangingProperties); - // SettingsView->GetDetailsView()->RegisterInstancedCustomPropertyLayout(FExportShaderPatchSettings::StaticStruct(),FOnGetDetailCustomizationInstance::CreateStatic(&FReleaseSettingsDetails::MakeInstance)); - SettingsView->SetStructureData(MakeShareable(Struct)); -} - -bool SShaderPatchWidget::CanExportShaderPatch() const -{ - bool bHasSavePath = ExportShaderPatchSettings->GetSaveAbsPath().IsEmpty()?false:FPaths::DirectoryExists(ExportShaderPatchSettings->GetSaveAbsPath()); - return HasValidConfig() && bHasSavePath; -} - -bool SShaderPatchWidget::HasValidConfig() const -{ - auto HasValidDir = [](const TArray& Dirs)->bool - { - bool bresult = false; - if(!!Dirs.Num()) - { - for(const auto& Dir:Dirs) - { - if(FPaths::DirectoryExists(FPaths::ConvertRelativePathToFull(Dir.Path))) - { - bresult = true; - break; - } - } - } - return bresult; - }; - bool HasValidPatchConfig = false; - for(const auto& Platform:ExportShaderPatchSettings->ShaderPatchConfigs) - { - if(HasValidDir(Platform.OldMetadataDir) && - FPaths::DirectoryExists(Platform.NewMetadataDir.Path)) - { - HasValidPatchConfig = true; - break; - } - } - return HasValidPatchConfig; -} - -FReply SShaderPatchWidget::DoExportShaderPatch() -{ - DoGenerate(); - return FReply::Handled(); -} - -#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherActionManager.h b/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherActionManager.h index eafbbdf8..b6374965 100644 --- a/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherActionManager.h +++ b/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherActionManager.h @@ -10,15 +10,17 @@ using FRequestWidgetPtr = TFunction(TShar struct HOTPATCHEREDITOR_API FHotPatcherActionDesc { - FHotPatcherActionDesc(FString InCategory,FString InActionName,FString InToolTip,FRequestWidgetPtr InRequestWidgetPtr,int32 InPriority = 0): - Category(InCategory),ActionName(InActionName),ToolTip(InToolTip),RequestWidgetPtr(InRequestWidgetPtr),Priority(InPriority){} + FHotPatcherActionDesc()=default; + FHotPatcherActionDesc(FString InCategory,FString InModName,FString InActionName,FString InToolTip,FRequestWidgetPtr InRequestWidgetPtr,int32 InPriority = 0): + Category(InCategory),ModName(InModName),ActionName(InActionName),ToolTip(InToolTip),RequestWidgetPtr(InRequestWidgetPtr),Priority(InPriority) + {} FString Category; + FString ModName; FString ActionName; FString ToolTip; FRequestWidgetPtr RequestWidgetPtr; int32 Priority = 0; - }; struct HOTPATCHEREDITOR_API FHotPatcherAction @@ -26,6 +28,7 @@ struct HOTPATCHEREDITOR_API FHotPatcherAction FHotPatcherAction()=default; FHotPatcherAction( FName InCategory, + FName InModName, const TAttribute& InActionName, const TAttribute& InActionToolTip, const FSlateIcon& InIcon, @@ -33,10 +36,10 @@ struct HOTPATCHEREDITOR_API FHotPatcherAction FRequestWidgetPtr InRequestWidget, int32 InPriority ) - :Category(InCategory),ActionName(InActionName),ActionToolTip(InActionToolTip),Icon(InIcon),ActionCallback(InCallback),RequestWidget(InRequestWidget),Priority(InPriority){} - + :Category(InCategory),ModName(InModName),ActionName(InActionName),ActionToolTip(InActionToolTip),Icon(InIcon),ActionCallback(InCallback),RequestWidget(InRequestWidget),Priority(InPriority){} FName Category; + FName ModName; TAttribute ActionName; TAttribute ActionToolTip; FSlateIcon Icon; @@ -45,6 +48,18 @@ struct HOTPATCHEREDITOR_API FHotPatcherAction int32 Priority = 0; }; +struct HOTPATCHEREDITOR_API FHotPatcherModDesc +{ + FString ModName; + bool bIsBuiltInMod = false; + float CurrentVersion = 0.f; + FString Description; + FString URL; + FString UpdateURL; + float MinHotPatcherVersion = 0.0f; + TArray ModActions; +}; + struct FHotPatcherCategory { FHotPatcherCategory()=default; @@ -71,9 +86,12 @@ struct HOTPATCHEREDITOR_API FHotPatcherActionManager void RegisteHotPatcherAction(const FString& Category,const FString& ActionName,const FHotPatcherAction& Action); void RegisteHotPatcherAction(const FHotPatcherActionDesc& NewAction); - + void RegisteHotPatcherMod(const FHotPatcherModDesc& ModDesc); + void UnRegisteHotPatcherMod(const FHotPatcherModDesc& ModDesc); void UnRegisteHotPatcherAction(const FString& Category, const FString& ActionName); + float GetHotPatcherVersion()const; + FHotPatcherActionDelegate OnHotPatcherActionRegisted; FHotPatcherActionDelegate OnHotPatcherActionUnRegisted; @@ -84,13 +102,23 @@ struct HOTPATCHEREDITOR_API FHotPatcherActionManager FHotPatcherActionsType& GetHotPatcherActions() { return HotPatcherActions; } FHotPatcherAction* GetTopActionByCategory(const FString CategoryName); + + bool IsActiviteMod(const FString& ModName); + + bool IsSupportEditorAction(FString ActionName); bool IsActiveAction(FString ActionName); + bool GetActionDescByName(const FString& ActionName,FHotPatcherActionDesc& Desc); + bool GetModDescByName(const FString& ModName,FHotPatcherModDesc& ModDesc); private: virtual ~FHotPatcherActionManager(){} protected: void SetupDefaultActions(); FHotPatcherActionsType HotPatcherActions; FHotPatcherCategoryType HotPatcherCategorys; - + TMap ActionsDesc; + TMap ModsDesc; + TMap UnSupportModsDesc; }; + + diff --git a/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherEditor.h b/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherEditor.h index ffee617d..71f8a240 100644 --- a/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherEditor.h +++ b/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherEditor.h @@ -28,6 +28,8 @@ #define InvokeTab TryInvokeTab #endif +DECLARE_LOG_CATEGORY_EXTERN(LogHotPatcherEdotor,All,All) + class FToolBarBuilder; class FMenuBuilder; diff --git a/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherModBaseModule.h b/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherModBaseModule.h new file mode 100644 index 00000000..a43353e6 --- /dev/null +++ b/HotPatcher/Source/HotPatcherEditor/Public/HotPatcherModBaseModule.h @@ -0,0 +1,17 @@ +#pragma once + +#include "CoreMinimal.h" +#include "HotPatcherActionManager.h" +#include "Modules/ModuleManager.h" + +class HOTPATCHEREDITOR_API FHotPatcherModBaseModule : public IModuleInterface +{ +public: + + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; + virtual FHotPatcherModDesc GetModDesc()const { return ModDesc; }; +private: + FHotPatcherModDesc ModDesc; +}; diff --git a/HotPatcher/Source/HotPatcherEditor/Public/ShaderPatch/SShaderPatchWidget.h b/HotPatcher/Source/HotPatcherEditor/Public/ShaderPatch/SShaderPatchWidget.h deleted file mode 100644 index ae8bdf6e..00000000 --- a/HotPatcher/Source/HotPatcherEditor/Public/ShaderPatch/SShaderPatchWidget.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. - -#pragma once - -#include "Model/FPatchersModeContext.h" -#include "SHotPatcherWidgetBase.h" -#include "ShaderPatch/FExportShaderPatchSettings.h" - -// engine header -#include "Interfaces/ITargetPlatformManagerModule.h" -#include "Interfaces/ITargetPlatform.h" -#include "Templates/SharedPointer.h" -#include "IDetailsView.h" -#include "PropertyEditorModule.h" -#include "IStructureDetailsView.h" - -/** - * Implements the cooked platforms panel. - */ -class SShaderPatchWidget - : public SHotPatcherWidgetBase -{ -public: - - SLATE_BEGIN_ARGS(SShaderPatchWidget) { } - SLATE_END_ARGS() - -public: - - /** - * Constructs the widget. - * - * @param InArgs The Slate argument list. - */ - void Construct( const FArguments& InArgs,TSharedPtr InContext); - -public: - virtual void ImportConfig(); - virtual void ImportProjectConfig(){}; - virtual void ExportConfig()const; - virtual void ResetConfig(); - virtual void DoGenerate(); - virtual FExportShaderPatchSettings* GetConfigSettings() override{return ExportShaderPatchSettings.Get();}; - virtual FString GetMissionName() override{return TEXT("Shader Patch");} - virtual FText GetGenerateTooltipText() const override; -protected: - void CreateExportFilterListView(); - bool CanExportShaderPatch()const; - bool HasValidConfig()const; - FReply DoExportShaderPatch(); - -private: - - // TSharedPtr mCreatePatchModel; - - /** Settings view ui element ptr */ - TSharedPtr SettingsView; - TSharedPtr ExportShaderPatchSettings; -}; - diff --git a/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h b/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h index 7faded44..2693367a 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h +++ b/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h @@ -225,9 +225,9 @@ struct HOTPATCHERRUNTIME_API FExportPatchSettings:public FHotPatcherSettingBase UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pak Options") bool bCustomPakNameRegular = false; // Can use value: {VERSION} {BASEVERSION} {CHUNKNAME} {PLATFORM} - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pak Options|Regular",meta=(EditCondition = "bCustomPakNameRegular")) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pak Options",meta=(EditCondition = "bCustomPakNameRegular")) FString PakNameRegular = TEXT("{VERSION}_{CHUNKNAME}_{PLATFORM}_001_P"); - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pak Options|Regular") + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pak Options") bool bCustomPakSaveDirRegular = false; // Can use value: {VERSION} {BASEVERSION} {CHUNKNAME} {PLATFORM} UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pak Options",meta=(EditCondition = "bCustomPakSaveDirRegular")) diff --git a/Mods/GameFeaturePacker b/Mods/GameFeaturePacker new file mode 160000 index 00000000..2ec40b6e --- /dev/null +++ b/Mods/GameFeaturePacker @@ -0,0 +1 @@ +Subproject commit 2ec40b6e362d94a1319ae2aad0a3e7a272dada2a diff --git a/Mods/HDiffPatchUE b/Mods/HDiffPatchUE new file mode 160000 index 00000000..86159174 --- /dev/null +++ b/Mods/HDiffPatchUE @@ -0,0 +1 @@ +Subproject commit 861591749d88b235a4932486ecabcdab29235d99 diff --git a/Mods/HotChunker b/Mods/HotChunker index c4cecb36..503703ea 160000 --- a/Mods/HotChunker +++ b/Mods/HotChunker @@ -1 +1 @@ -Subproject commit c4cecb3659e2d3461d82c44f9519c23eae45ca38 +Subproject commit 503703ea1505b188851ed13efbbdbf960f6a0080 diff --git a/Mods/HotMultiCooker b/Mods/HotMultiCooker index 0c7ac4d2..36c1c5be 160000 --- a/Mods/HotMultiCooker +++ b/Mods/HotMultiCooker @@ -1 +1 @@ -Subproject commit 0c7ac4d27fe84d24da01eb0dcaeae369a85097d6 +Subproject commit 36c1c5be6f4d4b716c8a5f13d2f8334ff7371f7f diff --git a/Mods/RemakePak b/Mods/RemakePak index 4d062815..2ab9ef55 160000 --- a/Mods/RemakePak +++ b/Mods/RemakePak @@ -1 +1 @@ -Subproject commit 4d062815794804453921f7712cef077fd6adf583 +Subproject commit 2ab9ef552ff864d57594c0a6feaecc0e5921cf09 diff --git a/Mods/ShaderPatcherUE b/Mods/ShaderPatcherUE new file mode 160000 index 00000000..5addb290 --- /dev/null +++ b/Mods/ShaderPatcherUE @@ -0,0 +1 @@ +Subproject commit 5addb290e19f9ba4cd5603d044d0e1b6cfce96a7 diff --git a/Mods/libzstd b/Mods/libzstd index 67b9da60..a357b694 160000 --- a/Mods/libzstd +++ b/Mods/libzstd @@ -1 +1 @@ -Subproject commit 67b9da60032b67bf0845ed9e6f66bb7839e9527a +Subproject commit a357b694425156c6330412931819ad60910b4cec