diff --git a/HotPatcher/HotPatcher.uplugin b/HotPatcher/HotPatcher.uplugin index b2d429c6..451d026d 100644 --- a/HotPatcher/HotPatcher.uplugin +++ b/HotPatcher/HotPatcher.uplugin @@ -1,44 +1,44 @@ -{ - "FileVersion": 3, - "Version": 1, - "VersionName": "1.0", - "FriendlyName": "HotPatcher", - "Description": "", - "Category": "HotPatcher", - "CreatedBy": "imzlp", - "CreatedByURL": "https://imzlp.com/", - "DocsURL": "https://imzlp.com/posts/17590/", - "MarketplaceURL": "", - "SupportURL": "", - "CanContainContent": true, - "IsBetaVersion": false, - "IsExperimentalVersion": false, - "Installed": false, - "Modules": [ - { - "Name": "HotPatcherEditor", - "Type": "Editor", - "LoadingPhase": "Default" - }, - { - "Name": "HotPatcherCore", - "Type": "Editor", - "LoadingPhase": "Default" - }, - { - "Name": "HotPatcherRuntime", - "Type": "Runtime", - "LoadingPhase": "PreDefault" - }, - { - "Name": "BinariesPatchFeature", - "Type": "Runtime", - "LoadingPhase": "PreDefault" - }, - { - "Name": "CmdHandler", - "Type": "Developer", - "LoadingPhase": "PostConfigInit" - } - ] +{ + "FileVersion": 3, + "Version": 1, + "VersionName": "1.0", + "FriendlyName": "HotPatcher", + "Description": "", + "Category": "HotPatcher", + "CreatedBy": "imzlp", + "CreatedByURL": "https://imzlp.com/", + "DocsURL": "https://imzlp.com/posts/17590/", + "MarketplaceURL": "", + "SupportURL": "", + "CanContainContent": true, + "IsBetaVersion": false, + "IsExperimentalVersion": false, + "Installed": false, + "Modules": [ + { + "Name": "HotPatcherEditor", + "Type": "Editor", + "LoadingPhase": "Default" + }, + { + "Name": "HotPatcherCore", + "Type": "Editor", + "LoadingPhase": "Default" + }, + { + "Name": "HotPatcherRuntime", + "Type": "Runtime", + "LoadingPhase": "PreDefault" + }, + { + "Name": "BinariesPatchFeature", + "Type": "Runtime", + "LoadingPhase": "PreDefault" + }, + { + "Name": "CmdHandler", + "Type": "Developer", + "LoadingPhase": "PostConfigInit" + } + ] } \ No newline at end of file diff --git a/HotPatcher/Source/CookerWriterForUE5/CookerWriterForUE5.h b/HotPatcher/Source/CookerWriterForUE5/CookerWriterForUE5.h index c217133a..0391da37 100644 --- a/HotPatcher/Source/CookerWriterForUE5/CookerWriterForUE5.h +++ b/HotPatcher/Source/CookerWriterForUE5/CookerWriterForUE5.h @@ -1,6 +1,6 @@ #pragma once -#if ENGINE_MAJOR_VERSION > 4 && ENGINE_MINOR_VERSION > 0 +#if ENGINE_MAJOR_VERSION > 4 /*&& ENGINE_MINOR_VERSION > 0*/ #include "ZenStoreWriter.h" #include "PackageNameCache.h" #include "LooseCookedPackageWriter.h" diff --git a/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.cpp b/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.cpp index 145a730e..f09288e9 100644 --- a/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.cpp +++ b/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.cpp @@ -80,16 +80,16 @@ TFuture FLooseCookedPackageWriter::AsyncSave(FRecord& Record, const FC return AsyncSaveOutputFiles(Record, Context); } -void FLooseCookedPackageWriter::CompleteExportsArchiveForDiff(FName PackageName, FLargeMemoryWriter& ExportsArchive) +void FLooseCookedPackageWriter::CompleteExportsArchiveForDiff(const FPackageInfo& Info, FLargeMemoryWriter& ExportsArchive) { - FPackageWriterRecords::FPackage& BaseRecord = Records.FindRecordChecked(PackageName); + FPackageWriterRecords::FPackage& BaseRecord = Records.FindRecordChecked(Info.InputPackageName); FRecord& Record = static_cast(BaseRecord); Record.bCompletedExportsArchiveForDiff = true; // Add on all the attachments which are usually added on during Commit. The order must match AsyncSave. for (FBulkDataRecord& BulkRecord : Record.BulkDatas) { - if (BulkRecord.Info.BulkDataType == FBulkDataInfo::AppendToExports) + if (BulkRecord.Info.BulkDataType == FBulkDataInfo::AppendToExports && BulkRecord.Info.MultiOutputIndex == Info.MultiOutputIndex) { ExportsArchive.Serialize(const_cast(BulkRecord.Buffer.GetData()), BulkRecord.Buffer.GetSize()); @@ -97,8 +97,11 @@ void FLooseCookedPackageWriter::CompleteExportsArchiveForDiff(FName PackageName, } for (FLinkerAdditionalDataRecord& AdditionalRecord : Record.LinkerAdditionalDatas) { - ExportsArchive.Serialize(const_cast(AdditionalRecord.Buffer.GetData()), - AdditionalRecord.Buffer.GetSize()); + if (AdditionalRecord.Info.MultiOutputIndex == Info.MultiOutputIndex) + { + ExportsArchive.Serialize(const_cast(AdditionalRecord.Buffer.GetData()), + AdditionalRecord.Buffer.GetSize()); + } } uint32 FooterData = PACKAGE_FILE_TAG; @@ -108,7 +111,11 @@ void FLooseCookedPackageWriter::CompleteExportsArchiveForDiff(FName PackageName, void FLooseCookedPackageWriter::CollectForSavePackageData(FRecord& Record, FCommitContext& Context) { - Context.ExportsBuffers.Add(FExportBuffer{ Record.Package->Buffer, MoveTemp(Record.Package->Regions) }); + Context.ExportsBuffers.AddDefaulted(Record.Packages.Num()); + for (FPackageWriterRecords::FWritePackage& Package : Record.Packages) + { + Context.ExportsBuffers[Package.Info.MultiOutputIndex].Add(FExportBuffer{ Package.Buffer, MoveTemp(Package.Regions) }); + } } void FLooseCookedPackageWriter::CollectForSaveBulkData(FRecord& Record, FCommitContext& Context) @@ -122,7 +129,7 @@ void FLooseCookedPackageWriter::CollectForSaveBulkData(FRecord& Record, FCommitC // Already Added in CompleteExportsArchiveForDiff continue; } - Context.ExportsBuffers.Add(FExportBuffer{ BulkRecord.Buffer, MoveTemp(BulkRecord.Regions) }); + Context.ExportsBuffers[BulkRecord.Info.MultiOutputIndex].Add(FExportBuffer{ BulkRecord.Buffer, MoveTemp(BulkRecord.Regions) }); } else { @@ -132,6 +139,7 @@ void FLooseCookedPackageWriter::CollectForSaveBulkData(FRecord& Record, FCommitC OutputFile.Buffer = FCompositeBuffer(BulkRecord.Buffer); OutputFile.Regions = MoveTemp(BulkRecord.Regions); OutputFile.bIsSidecar = true; + OutputFile.bContributeToHash = BulkRecord.Info.MultiOutputIndex == 0; // Only caculate the main package output hash } } } @@ -145,7 +153,7 @@ void FLooseCookedPackageWriter::CollectForSaveLinkerAdditionalDataRecords(FRecor for (FLinkerAdditionalDataRecord& AdditionalRecord : Record.LinkerAdditionalDatas) { - Context.ExportsBuffers.Add(FExportBuffer{ AdditionalRecord.Buffer, MoveTemp(AdditionalRecord.Regions) }); + Context.ExportsBuffers[AdditionalRecord.Info.MultiOutputIndex].Add(FExportBuffer{ AdditionalRecord.Buffer, MoveTemp(AdditionalRecord.Regions) }); } } @@ -157,6 +165,7 @@ void FLooseCookedPackageWriter::CollectForSaveAdditionalFileRecords(FRecord& Rec OutputFile.Filename = AdditionalRecord.Info.Filename; OutputFile.Buffer = FCompositeBuffer(AdditionalRecord.Buffer); OutputFile.bIsSidecar = true; + OutputFile.bContributeToHash = AdditionalRecord.Info.MultiOutputIndex == 0; // Only calculate the main package output hash } } @@ -170,57 +179,68 @@ void FLooseCookedPackageWriter::CollectForSaveExportsFooter(FRecord& Record, FCo uint32 FooterData = PACKAGE_FILE_TAG; FSharedBuffer Buffer = FSharedBuffer::Clone(&FooterData, sizeof(FooterData)); - Context.ExportsBuffers.Add(FExportBuffer{ Buffer, TArray() }); + for (FPackageWriterRecords::FWritePackage& Package : Record.Packages) + { + Context.ExportsBuffers[Package.Info.MultiOutputIndex].Add(FExportBuffer{ Buffer, TArray() }); + } } -void FLooseCookedPackageWriter::AddToExportsSize(int32& ExportsSize) +void FLooseCookedPackageWriter::AddToExportsSize(int64& ExportsSize) { ExportsSize += sizeof(uint32); // Footer size } void FLooseCookedPackageWriter::CollectForSaveExportsBuffers(FRecord& Record, FCommitContext& Context) { - // Split the ExportsBuffer into (1) Header and (2) Exports + AllAppendedData - int64 HeaderSize = Record.Package->Info.HeaderSize; - check(Context.ExportsBuffers.Num() > 0); - FExportBuffer& HeaderAndExportsBuffer = Context.ExportsBuffers[0]; - FSharedBuffer& HeaderAndExportsData = HeaderAndExportsBuffer.Buffer; - - // Header (.uasset/.umap) + check(Context.ExportsBuffers.Num() == Record.Packages.Num()); + for (FPackageWriterRecords::FWritePackage& Package : Record.Packages) { - FWriteFileData& OutputFile = Context.OutputFiles.Emplace_GetRef(); - OutputFile.Filename = Record.Begin.LooseFilePath; - OutputFile.Buffer = FCompositeBuffer( - FSharedBuffer::MakeView(HeaderAndExportsData.GetData(), HeaderSize, HeaderAndExportsData)); - OutputFile.bIsSidecar = false; - } + TArray& ExportsBuffers = Context.ExportsBuffers[Package.Info.MultiOutputIndex]; + check(ExportsBuffers.Num() > 0); - // Exports + AllAppendedData (.uexp) - { - FWriteFileData& OutputFile = Context.OutputFiles.Emplace_GetRef(); - OutputFile.Filename = FPaths::ChangeExtension(Record.Begin.LooseFilePath, LexToString(EPackageExtension::Exports)); - OutputFile.bIsSidecar = false; + // Split the ExportsBuffer into (1) Header and (2) Exports + AllAppendedData + int64 HeaderSize = Package.Info.HeaderSize; + FExportBuffer& HeaderAndExportsBuffer = ExportsBuffers[0]; + FSharedBuffer& HeaderAndExportsData = HeaderAndExportsBuffer.Buffer; - int32 NumBuffers = Context.ExportsBuffers.Num(); - TArray BuffersForComposition; - BuffersForComposition.Reserve(NumBuffers); - - const uint8* ExportsStart = static_cast(HeaderAndExportsData.GetData()) + HeaderSize; - BuffersForComposition.Add(FSharedBuffer::MakeView(ExportsStart, HeaderAndExportsData.GetSize() - HeaderSize, - HeaderAndExportsData)); - OutputFile.Regions.Append(MoveTemp(HeaderAndExportsBuffer.Regions)); - - for (FExportBuffer& ExportsBuffer : TArrayView(Context.ExportsBuffers).Slice(1, NumBuffers - 1)) + // Header (.uasset/.umap) { - BuffersForComposition.Add(ExportsBuffer.Buffer); - OutputFile.Regions.Append(MoveTemp(ExportsBuffer.Regions)); + FWriteFileData& OutputFile = Context.OutputFiles.Emplace_GetRef(); + OutputFile.Filename = Package.Info.LooseFilePath; + OutputFile.Buffer = FCompositeBuffer( + FSharedBuffer::MakeView(HeaderAndExportsData.GetData(), HeaderSize, HeaderAndExportsData)); + OutputFile.bIsSidecar = false; + OutputFile.bContributeToHash = Package.Info.MultiOutputIndex == 0; // Only calculate the main package output hash } - OutputFile.Buffer = FCompositeBuffer(BuffersForComposition); - // Adjust regions so they are relative to the start of the uexp file - for (FFileRegion& Region : OutputFile.Regions) + // Exports + AllAppendedData (.uexp) { - Region.Offset -= HeaderSize; + FWriteFileData& OutputFile = Context.OutputFiles.Emplace_GetRef(); + OutputFile.Filename = FPaths::ChangeExtension(Package.Info.LooseFilePath, LexToString(EPackageExtension::Exports)); + OutputFile.bIsSidecar = false; + OutputFile.bContributeToHash = Package.Info.MultiOutputIndex == 0; // Only caculate the main package output hash + + int32 NumBuffers = ExportsBuffers.Num(); + TArray BuffersForComposition; + BuffersForComposition.Reserve(NumBuffers); + + const uint8* ExportsStart = static_cast(HeaderAndExportsData.GetData()) + HeaderSize; + BuffersForComposition.Add(FSharedBuffer::MakeView(ExportsStart, HeaderAndExportsData.GetSize() - HeaderSize, + HeaderAndExportsData)); + OutputFile.Regions.Append(MoveTemp(HeaderAndExportsBuffer.Regions)); + + for (FExportBuffer& ExportsBuffer : TArrayView(ExportsBuffers).Slice(1, NumBuffers - 1)) + { + BuffersForComposition.Add(ExportsBuffer.Buffer); + OutputFile.Regions.Append(MoveTemp(ExportsBuffer.Regions)); + } + OutputFile.Buffer = FCompositeBuffer(BuffersForComposition); + + // Adjust regions so they are relative to the start of the uexp file + for (FFileRegion& Region : OutputFile.Regions) + { + Region.Offset -= HeaderSize; + } } } } @@ -286,7 +306,8 @@ static void WriteToFile(const FString& Filename, const FCompositeBuffer& Buffer) void FLooseCookedPackageWriter::FWriteFileData::Write(FMD5& AccumulatedHash, EWriteOptions WriteOptions) const { - if (EnumHasAnyFlags(WriteOptions, EWriteOptions::ComputeHash)) + //@todo: FH: Should we calculate the hash of both output, currently only the main package output hash is calculated + if (EnumHasAnyFlags(WriteOptions, EWriteOptions::ComputeHash) && bContributeToHash) { for (const FSharedBuffer& Segment : Buffer.GetSegments()) { @@ -321,17 +342,20 @@ void FLooseCookedPackageWriter::FWriteFileData::Write(FMD5& AccumulatedHash, EWr void FLooseCookedPackageWriter::UpdateManifest(FRecord& Record) { - FName PackageName = Record.Begin.PackageName; - FIoChunkId ChunkId = CreateIoChunkId(FPackageId::FromName(PackageName).Value(), 0, EIoChunkType::ExportBundleData); - PackageStoreManifest.AddPackageData(PackageName, Record.Begin.LooseFilePath, ChunkId); + for (const FPackageWriterRecords::FWritePackage& Package : Record.Packages) + { + PackageStoreManifest.AddPackageData(Package.Info.InputPackageName, Package.Info.OutputPackageName, Package.Info.LooseFilePath, Package.Info.ChunkId); + } + for (const FPackageWriterRecords::FBulkData& BulkData : Record.BulkDatas) + { + PackageStoreManifest.AddBulkData(BulkData.Info.InputPackageName, BulkData.Info.OutputPackageName, BulkData.Info.LooseFilePath, BulkData.Info.ChunkId); + } } -bool FLooseCookedPackageWriter::GetPreviousCookedBytes(FName PackageName, FPreviousCookedBytesData& OutData) +bool FLooseCookedPackageWriter::GetPreviousCookedBytes(const FPackageInfo& Info, FPreviousCookedBytesData& OutData) { - FPackageWriterRecords::FPackage& BaseRecord = Records.FindRecordChecked(PackageName); - FRecord& Record = static_cast(BaseRecord); FArchiveStackTrace::FPackageData ExistingPackageData; - FArchiveStackTrace::LoadPackageIntoMemory(*Record.Begin.LooseFilePath, ExistingPackageData, OutData.Data); + FArchiveStackTrace::LoadPackageIntoMemory(*Info.LooseFilePath, ExistingPackageData, OutData.Data); OutData.Size = ExistingPackageData.Size; OutData.HeaderSize = ExistingPackageData.HeaderSize; OutData.StartOffset = ExistingPackageData.StartOffset; diff --git a/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.h b/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.h index d195f367..9275af99 100644 --- a/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.h +++ b/HotPatcher/Source/CookerWriterForUE5/LooseCookedPackageWriter.h @@ -34,7 +34,7 @@ class FLooseCookedPackageWriter : public TPackageWriterToSharedBuffer PackageNamesToRemove) override; virtual void RemoveCookedPackages() override; virtual void MarkPackagesUpToDate(TArrayView UpToDatePackages) override; - virtual bool GetPreviousCookedBytes(FName PackageName, FPreviousCookedBytesData& OutData) override; - virtual void CompleteExportsArchiveForDiff(FName PackageName, FLargeMemoryWriter& ExportsArchive) override; + virtual bool GetPreviousCookedBytes(const FPackageInfo& Info, FPreviousCookedBytesData& OutData) override; + virtual void CompleteExportsArchiveForDiff(const FPackageInfo& Info, FLargeMemoryWriter& ExportsArchive) override; virtual TFuture CommitPackageInternal(FPackageWriterRecords::FPackage&& BaseRecord, const FCommitPackageInfo& Info) override; virtual FPackageWriterRecords::FPackage* ConstructRecord() override; @@ -78,6 +78,7 @@ class FLooseCookedPackageWriter : public TPackageWriterToSharedBuffer Regions; bool bIsSidecar; + bool bContributeToHash = true; void Write(FMD5& AccumulatedHash, EWriteOptions WriteOptions) const; }; @@ -86,7 +87,7 @@ class FLooseCookedPackageWriter : public TPackageWriterToSharedBuffer ExportsBuffers; + TArray> ExportsBuffers; TArray OutputFiles; }; diff --git a/HotPatcher/Source/CookerWriterForUE5/Serialization/PackageWriterToSharedBuffer.h b/HotPatcher/Source/CookerWriterForUE5/Serialization/PackageWriterToSharedBuffer.h index 3dcad9ac..2dc1d7e5 100644 --- a/HotPatcher/Source/CookerWriterForUE5/Serialization/PackageWriterToSharedBuffer.h +++ b/HotPatcher/Source/CookerWriterForUE5/Serialization/PackageWriterToSharedBuffer.h @@ -58,7 +58,7 @@ class FPackageWriterRecords /** Always valid during CommitPackageInternal */ IPackageWriter::FBeginPackageInfo Begin; /** Always valid during CommitPackageInternal if Info.bSucceeded */ - TOptional Package; + TArray Packages; TArray BulkDatas; TArray AdditionalFiles; TArray LinkerAdditionalDatas; diff --git a/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs b/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs index 414e20f0..d777b22c 100644 --- a/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs +++ b/HotPatcher/Source/HotPatcherCore/HotPatcherCore.Build.cs @@ -156,7 +156,7 @@ public HotPatcherCore(ReadOnlyTargetRules Target) : base(Target) bool bEnablePackageContext = true; AddPublicDefinitions("WITH_PACKAGE_CONTEXT", (Version.MajorVersion > 4 || Version.MinorVersion > 23) && bEnablePackageContext); - if (Version.MajorVersion > 4 || Version.MajorVersion > 26) + if (Version.MajorVersion > 4 || Version.MinorVersion > 26) { PublicDependencyModuleNames.AddRange(new string[] { @@ -176,7 +176,7 @@ public HotPatcherCore(ReadOnlyTargetRules Target) : base(Target) }); } - if (Version.MajorVersion > 4 && Version.MinorVersion > 0) + if (Version.MajorVersion > 4 /*&& Version.MinorVersion > 0*/) { PublicIncludePaths.AddRange(new List() { @@ -192,7 +192,7 @@ public HotPatcherCore(ReadOnlyTargetRules Target) : base(Target) { "TOOL_NAME=\"HotPatcher\"", "CURRENT_VERSION_ID=76", - "CURRENT_PATCH_ID=2", + "CURRENT_PATCH_ID=3", "REMOTE_VERSION_FILE=\"https://imzlp.com/opensource/version.json\"" }); } diff --git a/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp b/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp index c913487e..0c1656eb 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/Cooker/MultiCooker/SingleCookerProxy.cpp @@ -184,7 +184,11 @@ void USingleCookerProxy::CleanClusterCachedPlatformData(const FCookCluster& Cook } ExportObj->ClearAllCachedCookedPlatformData(); } +#if ENGINE_MAJOR_VERSION > 4 + Package->MarkAsGarbage(); +#else Package->MarkPendingKill(); +#endif } } diff --git a/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp b/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp index 369c1f6b..8ff2f4d7 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/CreatePatch/PatcherProxy.cpp @@ -128,7 +128,7 @@ namespace PatchWorker // setup 14 serialize patch config bool SavePatchConfigWorker(FHotPatcherPatchContext& Context); // setup 15 - bool BackupMetadataWorker(FHotPatcherPatchContext& Context); + // bool BackupMetadataWorker(FHotPatcherPatchContext& Context); // setup 16 bool ShowSummaryWorker(FHotPatcherPatchContext& Context); // setup 17 @@ -197,7 +197,7 @@ void UPatcherProxy::Init(FPatcherEntitySettingBase* InSetting) ADD_PATCH_WORKER(PatchWorker::SaveDifferenceWorker); ADD_PATCH_WORKER(PatchWorker::SaveNewReleaseWorker); ADD_PATCH_WORKER(PatchWorker::SavePakFileInfoWorker); - ADD_PATCH_WORKER(PatchWorker::BackupMetadataWorker); + // ADD_PATCH_WORKER(PatchWorker::BackupMetadataWorker); ADD_PATCH_WORKER(PatchWorker::ShowSummaryWorker); ADD_PATCH_WORKER(PatchWorker::OnFaildDispatchWorker); } @@ -679,21 +679,25 @@ namespace PatchWorker bool GenerateGlobalAssetRegistryData(FHotPatcherPatchContext& Context) { SCOPED_NAMED_EVENT_TEXT("GenerateGlobalAssetRegistryData",FColor::Red); - FAssetDependenciesInfo TotalDiffAssets = UFlibAssetManageHelper::CombineAssetDependencies(Context.VersionDiff.AssetDiffInfo.AddAssetDependInfo,Context.VersionDiff.AssetDiffInfo.ModifyAssetDependInfo); - const TArray& AllAssets = TotalDiffAssets.GetAssetDetails(); - - TSet PackageAssetsSet; - for(const auto& Asset:AllAssets) - { - FString LongPackageName = UFlibAssetManageHelper::PackagePathToLongPackageName(Asset.PackagePath.ToString()); - PackageAssetsSet.Add(*LongPackageName); - } - for(const auto& PlatformName:Context.GetSettingObject()->GetPakTargetPlatformNames()) + if(Context.GetSettingObject()->GetSerializeAssetRegistryOptions().bSerializeAssetRegistry) { - ITargetPlatform* PlatformIns = UFlibHotPatcherCoreHelper::GetPlatformByName(PlatformName); + FAssetDependenciesInfo TotalDiffAssets = UFlibAssetManageHelper::CombineAssetDependencies(Context.VersionDiff.AssetDiffInfo.AddAssetDependInfo,Context.VersionDiff.AssetDiffInfo.ModifyAssetDependInfo); + const TArray& AllAssets = TotalDiffAssets.GetAssetDetails(); + + TSet PackageAssetsSet; + for(const auto& Asset:AllAssets) + { + FString LongPackageName = UFlibAssetManageHelper::PackagePathToLongPackageName(Asset.PackagePath.ToString()); + PackageAssetsSet.Add(*LongPackageName); + } + for(const auto& PlatformName:Context.GetSettingObject()->GetPakTargetPlatformNames()) + { + ITargetPlatform* PlatformIns = UFlibHotPatcherCoreHelper::GetPlatformByName(PlatformName); - UFlibHotPatcherCoreHelper::SerializeChunksManifests(PlatformIns,PackageAssetsSet,TSet{},true); + UFlibHotPatcherCoreHelper::SerializeChunksManifests(PlatformIns,PackageAssetsSet,TSet{},true); + } } + return true; } @@ -1443,28 +1447,28 @@ namespace PatchWorker }; // setup 15 - bool BackupMetadataWorker(FHotPatcherPatchContext& Context) - { - SCOPED_NAMED_EVENT_TEXT("BackupMetadataWorker",FColor::Red); - // backup Metadata - if(Context.GetPakFileNum()) - { - TimeRecorder TR(FString::Printf(TEXT("Backup Metadata"))); - FText DiaLogMsg = FText::Format(NSLOCTEXT("BackupMetadata", "BackupMetadata", "Backup Release {0} Metadatas."), FText::FromString(Context.GetSettingObject()->GetVersionId())); - Context.UnrealPakSlowTask->EnterProgressFrame(1.0, DiaLogMsg); - if(Context.GetSettingObject()->IsBackupMetadata()) - { - UFlibHotPatcherCoreHelper::BackupMetadataDir( - FPaths::ProjectDir(), - FApp::GetProjectName(), - Context.GetSettingObject()->GetPakTargetPlatforms(), - FPaths::Combine(Context.GetSettingObject()->GetSaveAbsPath(), - Context.GetSettingObject()->GetVersionId()) - ); - } - } - return true; - }; + // bool BackupMetadataWorker(FHotPatcherPatchContext& Context) + // { + // SCOPED_NAMED_EVENT_TEXT("BackupMetadataWorker",FColor::Red); + // // backup Metadata + // if(Context.GetPakFileNum()) + // { + // TimeRecorder TR(FString::Printf(TEXT("Backup Metadata"))); + // FText DiaLogMsg = FText::Format(NSLOCTEXT("BackupMetadata", "BackupMetadata", "Backup Release {0} Metadatas."), FText::FromString(Context.GetSettingObject()->GetVersionId())); + // Context.UnrealPakSlowTask->EnterProgressFrame(1.0, DiaLogMsg); + // if(Context.GetSettingObject()->IsBackupMetadata()) + // { + // UFlibHotPatcherCoreHelper::BackupMetadataDir( + // FPaths::ProjectDir(), + // FApp::GetProjectName(), + // Context.GetSettingObject()->GetPakTargetPlatforms(), + // FPaths::Combine(Context.GetSettingObject()->GetSaveAbsPath(), + // Context.GetSettingObject()->GetVersionId()) + // ); + // } + // } + // return true; + // }; // setup 16 bool ShowSummaryWorker(FHotPatcherPatchContext& Context) diff --git a/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp b/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp index f79535a9..436cd762 100644 --- a/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp +++ b/HotPatcher/Source/HotPatcherCore/Private/FlibHotPatcherCoreHelper.cpp @@ -27,6 +27,8 @@ #include "Serialization/ArrayWriter.h" #include "Settings/ProjectPackagingSettings.h" #include "ShaderCompiler.h" +#include "Materials/MaterialInstance.h" +#include "Materials/MaterialInstanceConstant.h" #include "ProfilingDebugging/LoadTimeTracker.h" #include "UObject/ConstructorHelpers.h" @@ -284,7 +286,7 @@ FString UFlibHotPatcherCoreHelper::GetProjectCookedDir() #include "Serialization/BulkDataManifest.h" #endif -#if ENGINE_MAJOR_VERSION > 4 && ENGINE_MINOR_VERSION > 0 +#if ENGINE_MAJOR_VERSION > 4 /*&& ENGINE_MINOR_VERSION > 0 */ #include "CookerWriterForUE5/CookerWriterForUE5.h" #endif @@ -313,7 +315,7 @@ FSavePackageContext* UFlibHotPatcherCoreHelper::CreateSaveContext(const ITargetP SavePackageContext = new FSavePackageContext(LooseFileWriter, BulkDataManifest, bLegacyBulkDataOffsets); #endif -#if ENGINE_MAJOR_VERSION > 4 && ENGINE_MINOR_VERSION > 0 +#if ENGINE_MAJOR_VERSION > 4 /*&& ENGINE_MINOR_VERSION > 0*/ ICookedPackageWriter* PackageWriter = nullptr; FString WriterDebugName; if (bUseZenLoader) @@ -599,7 +601,7 @@ bool UFlibHotPatcherCoreHelper::CookPackage( { CurrentPlatformPackageContext = *PlatformSavePackageContext.Find(Platform.Value->PlatformName()); } - #if ENGINE_MAJOR_VERSION > 4 && ENGINE_MINOR_VERSION > 0 + #if ENGINE_MAJOR_VERSION > 4 /*&& ENGINE_MINOR_VERSION > 0*/ IPackageWriter::FBeginPackageInfo BeginInfo; BeginInfo.PackageName = Package->GetFName(); BeginInfo.LooseFilePath = CookedSavePath; @@ -642,11 +644,11 @@ bool UFlibHotPatcherCoreHelper::CookPackage( #if WITH_PACKAGE_CONTEXT // in UE5.1 - #if ENGINE_MAJOR_VERSION > 4 && ENGINE_MINOR_VERSION > 0 + #if ENGINE_MAJOR_VERSION > 4 /*&& ENGINE_MINOR_VERSION > 0*/ // save cooked file to desk in UE5-main if(bSuccessed) { - const FAssetPackageData* AssetPackageData = UFlibAssetManageHelper::GetPackageDataByPackagePath(Package->GetFName().ToString()); + //const FAssetPackageData* AssetPackageData = UFlibAssetManageHelper::GetPackageDataByPackageName(Package->GetFName().ToString()); ICookedPackageWriter::FCommitPackageInfo Info; Info.bSucceeded = bSuccessed; Info.PackageName = Package->GetFName(); @@ -1127,6 +1129,11 @@ ITargetPlatform* UFlibHotPatcherCoreHelper::GetPlatformByName(const FString& Nam return result; } +#include "BaseWidgetBlueprint.h" +#include "Blueprint/UserWidget.h" +#include "Blueprint/WidgetTree.h" +#include "WidgetBlueprint.h" + FPatchVersionDiff UFlibHotPatcherCoreHelper::DiffPatchVersionWithPatchSetting(const FExportPatchSettings& PatchSetting, const FHotPatcherVersion& Base, const FHotPatcherVersion& New) { FPatchVersionDiff VersionDiffInfo; @@ -1153,7 +1160,11 @@ FPatchVersionDiff UFlibHotPatcherCoreHelper::DiffPatchVersionWithPatchSetting(co if(PatchSetting.IsRecursiveWidgetTree()) { - UFlibHotPatcherCoreHelper::AnalysisWidgetTree(Base,New,VersionDiffInfo); + AnalysisWidgetTree(Base,New,VersionDiffInfo); + } + if(PatchSetting.IsAnalysisMatInstance()) + { + AnalysisMaterialInstance(Base,New,VersionDiffInfo); } if(PatchSetting.IsForceSkipContent()) @@ -1181,12 +1192,21 @@ FPatchVersionDiff UFlibHotPatcherCoreHelper::DiffPatchVersionWithPatchSetting(co return VersionDiffInfo; } -#include "BaseWidgetBlueprint.h" -#include "Blueprint/UserWidget.h" -#include "Blueprint/WidgetTree.h" -#include "WidgetBlueprint.h" void UFlibHotPatcherCoreHelper::AnalysisWidgetTree(const FHotPatcherVersion& Base, const FHotPatcherVersion& New,FPatchVersionDiff& PakDiff,int32 flags) +{ + UClass* WidgetBlueprintClass = UWidgetBlueprint::StaticClass(); + UFlibHotPatcherCoreHelper::AnalysisDependenciesAssets(Base,New,PakDiff,WidgetBlueprintClass,TArray{WidgetBlueprintClass},true); +} + +void UFlibHotPatcherCoreHelper::AnalysisMaterialInstance(const FHotPatcherVersion& Base, const FHotPatcherVersion& New,FPatchVersionDiff& PakDiff,int32 flags) +{ + UClass* UMaterialClass = UMaterial::StaticClass(); + TArray MaterialInstanceClasses = GetDerivedClasses(UMaterialInstance::StaticClass(),true,true); + UFlibHotPatcherCoreHelper::AnalysisDependenciesAssets(Base,New,PakDiff,UMaterialClass,MaterialInstanceClasses,false); +} + +void UFlibHotPatcherCoreHelper::AnalysisDependenciesAssets(const FHotPatcherVersion& Base, const FHotPatcherVersion& New,FPatchVersionDiff& PakDiff,UClass* SearchClass,TArray DependenciesClass,bool bRecursive,int32 flags) { TArray AnalysisAssets; if(flags & 0x1) @@ -1202,32 +1222,36 @@ void UFlibHotPatcherCoreHelper::AnalysisWidgetTree(const FHotPatcherVersion& Bas } TArray AssetRegistryDepTypes {EAssetRegistryDependencyTypeEx::Hard}; - FName WidgetBlueprintName = UWidgetBlueprint::StaticClass()->GetFName();; + FName ClassName = SearchClass->GetFName();; for(const auto& OriginAsset:AnalysisAssets) { - if(OriginAsset.AssetType.IsEqual(WidgetBlueprintName)) + if(OriginAsset.AssetType.IsEqual(ClassName)) { - TArray RefAssets = UFlibHotPatcherCoreHelper::GetReferenceRecursivelyByClassName(OriginAsset,TArray{WidgetBlueprintName.ToString()},AssetRegistryDepTypes); - for(const auto& Asset:RefAssets) + for(auto& DepencenciesClassItem:DependenciesClass) { - if(!(Asset.AssetType.IsEqual(WidgetBlueprintName))) + FName DependenciesName = DepencenciesClassItem->GetFName(); + TArray RefAssets = UFlibHotPatcherCoreHelper::GetReferenceRecursivelyByClassName(OriginAsset,TArray{DependenciesName.ToString()},AssetRegistryDepTypes,bRecursive); + for(const auto& Asset:RefAssets) { - continue; - } - FString PackageName = UFlibAssetManageHelper::PackagePathToLongPackageName(Asset.PackagePath.ToString()); - bool bInBaseVersion = Base.AssetInfo.HasAsset(PackageName); - if(bInBaseVersion) - { - PakDiff.AssetDiffInfo.ModifyAssetDependInfo.AddAssetsDetail(Asset); - UE_LOG(LogHotPatcher,Log,TEXT("Add Parent Widget: %s"),*Asset.PackagePath.ToString()); + if(!(Asset.AssetType.IsEqual(DependenciesName))) + { + continue; + } + FString PackageName = UFlibAssetManageHelper::PackagePathToLongPackageName(Asset.PackagePath.ToString()); + bool bInBaseVersion = Base.AssetInfo.HasAsset(PackageName); + if(bInBaseVersion) + { + PakDiff.AssetDiffInfo.ModifyAssetDependInfo.AddAssetsDetail(Asset); + UE_LOG(LogHotPatcher,Log,TEXT("Add Parent: %s"),*Asset.PackagePath.ToString()); + } } } } } } -TArray UFlibHotPatcherCoreHelper::GetReferenceRecursivelyByClassName(const FAssetDetail& AssetDetail,const TArray& AssetTypeNames,const TArray& RefType) +TArray UFlibHotPatcherCoreHelper::GetReferenceRecursivelyByClassName(const FAssetDetail& AssetDetail,const TArray& AssetTypeNames,const TArray& RefType,bool bRecursive) { TArray Results; @@ -1239,7 +1263,7 @@ TArray UFlibHotPatcherCoreHelper::GetReferenceRecursivelyByClassNa } TArray CurrentAssetsRef; - UFlibAssetManageHelper::GetAssetReferenceRecursively(AssetDetail, SearchTypes, AssetTypeNames, CurrentAssetsRef); + UFlibAssetManageHelper::GetAssetReferenceRecursively(AssetDetail, SearchTypes, AssetTypeNames, CurrentAssetsRef,bRecursive); for(const auto& Asset:CurrentAssetsRef) { if(!AssetTypeNames.Contains(Asset.AssetType.ToString())) @@ -1623,7 +1647,9 @@ FProjectPackageAssetCollection UFlibHotPatcherCoreHelper::ImportProjectSettingsP { // allow the game to fill out the asset registry, as well as get a list of objects to always cook TArray FilesInPathStrings; + PRAGMA_DISABLE_DEPRECATION_WARNINGS; FGameDelegates::Get().GetCookModificationDelegate().ExecuteIfBound(FilesInPathStrings); + PRAGMA_ENABLE_DEPRECATION_WARNINGS; for(const auto& BuildFilename:FilesInPathStrings) { FString OutPackageName; @@ -1638,7 +1664,15 @@ FProjectPackageAssetCollection UFlibHotPatcherCoreHelper::ImportProjectSettingsP { TArray PackageToCook; TArray PackageToNeverCook; - UAssetManager::Get().ModifyCook(PackageToCook,PackageToNeverCook); +#if ENGINE_MAJOR_VERSION > 4 + ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); + const TArray& Platforms = TPM->GetActiveTargetPlatforms(); + UAssetManager::Get().ModifyCook(Platforms, PackageToCook, PackageToNeverCook); +#else + UAssetManager::Get().ModifyCook(PackageToCook, PackageToNeverCook); +#endif + + for(const auto& Package:PackageToCook) { AddSoftObjectPath(Package.ToString()); @@ -2307,13 +2341,20 @@ void UFlibHotPatcherCoreHelper::SaveGlobalShaderMapFiles(const TArrayViewPlatformName(); // Compile for all platforms - RecompileData.ShaderPlatform = -1; + RecompileData.ShaderPlatform = SP_NumPlatforms; RecompileData.ModifiedFiles = &Files; RecompileData.MeshMaterialMaps = NULL; check( IsInGameThread() ); FString OutputDir = FPaths::Combine(BaseOutputDir,Platforms[Index]->PlatformName()); + +#if ENGINE_MAJOR_VERSION > 4 + TArray GlobalShaderMap; + RecompileData.CommandType = ODSCRecompileCommand::Global; + RecompileData.GlobalShaderMap = &GlobalShaderMap; + RecompileShadersForRemote(RecompileData, OutputDir); +#else RecompileShadersForRemote (RecompileData.PlatformName, RecompileData.ShaderPlatform == -1 ? SP_NumPlatforms : (EShaderPlatform)RecompileData.ShaderPlatform, //-V547 @@ -2327,6 +2368,7 @@ void UFlibHotPatcherCoreHelper::SaveGlobalShaderMapFiles(const TArrayViewCleanManifestDirectories(); RegistryGenerator->Initialize(TArray()); RegistryGenerator->PreSave(CookedPackageNames); +#if ENGINE_MAJOR_VERSION > 4 + RegistryGenerator->FinalizeChunkIDs(CookedPackageNames, IgnorePackageNames, *TempSandboxFile, bGenerateStreamingInstallManifest); +#else RegistryGenerator->BuildChunkManifest(CookedPackageNames, IgnorePackageNames, TempSandboxFile.Get(), bGenerateStreamingInstallManifest); - +#endif #if ENGINE_MAJOR_VERSION > 4 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 26) FString TempSandboxManifestDir = FPaths::Combine(PlatformSandboxDir,FApp::GetProjectName(),TEXT("Metadata") , TEXT("ChunkManifest")); if(!FPaths::DirectoryExists(TempSandboxManifestDir)) @@ -2440,7 +2485,13 @@ bool UFlibHotPatcherCoreHelper::SerializeChunksManifests(ITargetPlatform* Target IFileManager::Get().MakeDirectory(*TempSandboxManifestDir, true); } #endif - bresult = RegistryGenerator->SaveManifests(TempSandboxFile.Get()); + bresult = RegistryGenerator->SaveManifests( +#if ENGINE_MAJOR_VERSION > 4 + *TempSandboxFile +#else +TempSandboxFile.Get() +#endif + ); #endif return bresult; } \ No newline at end of file diff --git a/HotPatcher/Source/HotPatcherCore/Public/FlibHotPatcherCoreHelper.h b/HotPatcher/Source/HotPatcherCore/Public/FlibHotPatcherCoreHelper.h index 3d6f8515..58fd588d 100644 --- a/HotPatcher/Source/HotPatcherCore/Public/FlibHotPatcherCoreHelper.h +++ b/HotPatcher/Source/HotPatcherCore/Public/FlibHotPatcherCoreHelper.h @@ -172,7 +172,9 @@ class HOTPATCHERCORE_API UFlibHotPatcherCoreHelper : public UBlueprintFunctionLi * 0x1 Add * 0x2 Modyfy */ + static void AnalysisDependenciesAssets(const FHotPatcherVersion& Base, const FHotPatcherVersion& New,FPatchVersionDiff& PakDiff,UClass* SearchClass,TArray DependenciesClass,bool bRecursive,int32 flags = 0x1|0x2); static void AnalysisWidgetTree(const FHotPatcherVersion& Base, const FHotPatcherVersion& New,FPatchVersionDiff& PakDiff,int32 flags = 0x1|0x2); + static void AnalysisMaterialInstance(const FHotPatcherVersion& Base, const FHotPatcherVersion& New,FPatchVersionDiff& PakDiff,int32 flags= 0x1|0x2); static FPatchVersionDiff DiffPatchVersionWithPatchSetting(const struct FExportPatchSettings& PatchSetting, const FHotPatcherVersion& Base, const FHotPatcherVersion& New); @@ -255,7 +257,7 @@ class HOTPATCHERCORE_API UFlibHotPatcherCoreHelper : public UBlueprintFunctionLi static uint32 GetCookSaveFlag(UPackage* Package,bool bUnversioned = true,bool bStorageConcurrent = false,bool CookLinkerDiff = false); static EObjectFlags GetObjectFlagForCooked(UPackage* Package); - static TArray GetReferenceRecursivelyByClassName(const FAssetDetail& AssetDetail,const TArray& AssetTypeNames,const TArray& RefType); + static TArray GetReferenceRecursivelyByClassName(const FAssetDetail& AssetDetail,const TArray& AssetTypeNames,const TArray& RefType,bool bRecursive = true); static TArray GetDerivedClasses(UClass* BaseClass,bool bRecursive,bool bContainSelf = false); diff --git a/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs b/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs index 90e99537..c7e58e07 100644 --- a/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs +++ b/HotPatcher/Source/HotPatcherEditor/HotPatcherEditor.Build.cs @@ -99,7 +99,7 @@ public HotPatcherEditor(ReadOnlyTargetRules Target) : base(Target) bool bEnablePackageContext = true; AddPublicDefinitions("WITH_PACKAGE_CONTEXT", (Version.MajorVersion > 4 || Version.MinorVersion > 23) && bEnablePackageContext); - if (Version.MajorVersion > 4 || Version.MajorVersion > 26) + if (Version.MajorVersion > 4 || Version.MinorVersion > 26) { PublicDependencyModuleNames.AddRange(new string[] { diff --git a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp index 60773bef..9187bb68 100644 --- a/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp +++ b/HotPatcher/Source/HotPatcherEditor/Private/HotPatcherEditor.cpp @@ -105,7 +105,12 @@ void FHotPatcherEditorModule::StartupModule() #ifndef DISABLE_PLUGIN_TOOLBAR_MENU // settings TSharedPtr ToolbarExtender = MakeShareable(new FExtender); - ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FHotPatcherEditorModule::AddToolbarExtension)); +#if ENGINE_MAJOR_VERSION > 4 + FName ExtensionHook = "Play"; +#else + FName ExtensionHook = "Settings"; +#endif + ToolbarExtender->AddToolBarExtension(ExtensionHook, EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FHotPatcherEditorModule::AddToolbarExtension)); LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender); #endif diff --git a/HotPatcher/Source/HotPatcherRuntime/HotPatcherRuntime.Build.cs b/HotPatcher/Source/HotPatcherRuntime/HotPatcherRuntime.Build.cs index e325ffe7..a63714de 100644 --- a/HotPatcher/Source/HotPatcherRuntime/HotPatcherRuntime.Build.cs +++ b/HotPatcher/Source/HotPatcherRuntime/HotPatcherRuntime.Build.cs @@ -31,8 +31,7 @@ public HotPatcherRuntime(ReadOnlyTargetRules Target) : base(Target) { PublicDependencyModuleNames.AddRange(new string[] { - "TargetPlatform", - "Paper2D" + "TargetPlatform" }); } @@ -90,6 +89,8 @@ public HotPatcherRuntime(ReadOnlyTargetRules Target) : base(Target) AddPublicDefinitions("ASSET_DEPENDENCIES_DEBUG_LOG", bEnableAssetDependenciesDebugLog); bool bCustomAssetGUID = false; + + if (Version.MajorVersion > 4) { bCustomAssetGUID = true; } if(bCustomAssetGUID) { PublicDefinitions.Add("CUSTOM_ASSET_GUID"); diff --git a/HotPatcher/Source/HotPatcherRuntime/Private/DependenciesParser/FDefaultAssetDependenciesParser.cpp b/HotPatcher/Source/HotPatcherRuntime/Private/DependenciesParser/FDefaultAssetDependenciesParser.cpp index e3fb66d3..1b7277a8 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Private/DependenciesParser/FDefaultAssetDependenciesParser.cpp +++ b/HotPatcher/Source/HotPatcherRuntime/Private/DependenciesParser/FDefaultAssetDependenciesParser.cpp @@ -6,9 +6,6 @@ #include "Engine/World.h" #include "Engine/WorldComposition.h" #include "Resources/Version.h" -#if WITH_EDITOR -#include "PaperSprite.h" -#endif void FAssetDependenciesParser::Parse(const FAssetDependencies& InParseConfig) { @@ -134,28 +131,7 @@ bool FAssetDependenciesParser::IsForceSkipAsset(const FString& LongPackageName,T { bIsIgnore = true; } -#if WITH_EDITOR - if(!bIsIgnore) - { - TArray AssetDetails; - if(UFlibAssetManageHelper::GetAssetReferenceByLongPackageName(LongPackageName, - TArray{EAssetRegistryDependencyType::Hard,EAssetRegistryDependencyType::Soft}, - AssetDetails)) - { - if(AssetDetails.Num() == 1 && - AssetDetails[0].AssetType.IsEqual(TEXT("PaperSprite"))) - { - FSoftObjectPath PaperSprite(AssetDetails[0].PackagePath); - UPaperSprite* PaperSpriteObj = Cast(PaperSprite.TryLoad()); - if(PaperSpriteObj && PaperSpriteObj->GetAtlasGroup()) - { - bIsIgnore = true; - MatchIgnoreStr = TEXT("only reference in a PaperSprite"); - } - } - } - } -#endif + if(bIsIgnore) { #if ASSET_DEPENDENCIES_DEBUG_LOG @@ -165,6 +141,31 @@ bool FAssetDependenciesParser::IsForceSkipAsset(const FString& LongPackageName,T return bIsIgnore; } +TArray ParserSkipAssetByDependencies(const FAssetData& CurrentAssetData,const TArray& CurrentAssetDependencies) +{ + SCOPED_NAMED_EVENT_TEXT("ParserSkipAssetByDependencies",FColor::Red); + bool bHasAtlsGroup = false; + TArray TextureSrouceRefs; + if(CurrentAssetData.AssetClass.IsEqual(TEXT("PaperSprite"))) + { + for(const auto& DependItemName:CurrentAssetDependencies) + { + FAssetDetail AssetDetail = UFlibAssetManageHelper::GetAssetDetailByPackageName(DependItemName.ToString()); + if(AssetDetail.IsValid()) + { + if(AssetDetail.AssetType.IsEqual(TEXT("PaperSpriteAtlas"))) + { + bHasAtlsGroup = true; + } + if(AssetDetail.AssetType.IsEqual(TEXT("Texture")) || AssetDetail.AssetType.IsEqual(TEXT("Texture2D"))) + { + TextureSrouceRefs.Add(DependItemName); + } + } + } + } + return bHasAtlsGroup ? TextureSrouceRefs : TArray{}; +} TSet FAssetDependenciesParser::GatherAssetDependicesInfoRecursively(FAssetRegistryModule& InAssetRegistryModule, FName InLongPackageName, const TArray& InAssetDependencyTypes, @@ -193,6 +194,11 @@ TSet FAssetDependenciesParser::GatherAssetDependicesInfoRecursively(FAsse bGetDependenciesSuccess = InAssetRegistryModule.Get().GetDependencies(InLongPackageName, CurrentAssetDependencies, TotalType); PRAGMA_ENABLE_DEPRECATION_WARNINGS + for(const auto& SkipForDependencies:ParserSkipAssetByDependencies(CurrentAssetData,CurrentAssetDependencies)) + { + CurrentAssetDependencies.Remove(SkipForDependencies); + } + // collect world composition tile packages to cook if(ParseConfig.bSupportWorldComposition && CurrentAssetData.GetClass() == UWorld::StaticClass()) { @@ -226,6 +232,7 @@ TSet FAssetDependenciesParser::GatherAssetDependicesInfoRecursively(FAsse { SCOPED_NAMED_EVENT_TEXT("check valid package and ignore rule",FColor::Red); + FCriticalSection SynchronizationObject; ParallelFor(CurrentAssetDependencies.Num(),[&](int32 index) { @@ -246,7 +253,7 @@ TSet FAssetDependenciesParser::GatherAssetDependicesInfoRecursively(FAsse AssetDependencies.Add(LongPackageName); } } - },true); + },GForceSingleThread); } if(bRecursively) diff --git a/HotPatcher/Source/HotPatcherRuntime/Private/FlibAssetManageHelper.cpp b/HotPatcher/Source/HotPatcherRuntime/Private/FlibAssetManageHelper.cpp index 119aa8aa..5a7cfa0b 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Private/FlibAssetManageHelper.cpp +++ b/HotPatcher/Source/HotPatcherRuntime/Private/FlibAssetManageHelper.cpp @@ -58,6 +58,11 @@ FString UFlibAssetManageHelper::PackagePathToFilename(const FString& InPackagePa return ResultAbsPath; } +FString UFlibAssetManageHelper::LongPackageNameToFilename(const FString& InLongPackageName) +{ + return UFlibAssetManageHelper::PackagePathToFilename(UFlibAssetManageHelper::LongPackageNameToPackagePath(InLongPackageName)); +} + bool UFlibAssetManageHelper::FilenameToPackagePath(const FString& InAbsPath, FString& OutPackagePath) { @@ -115,9 +120,9 @@ bool UFlibAssetManageHelper::GetAssetPackageGUID(const FString& InPackageName, F // FString Extersion = Package->ContainsMap() ? FPackageName::GetMapPackageExtension() : FPackageName::GetAssetPackageExtension(); // bool bCovStatus = FPackageName::TryConvertLongPackageNameToFilename(LongPackageName,FileName,Extersion); // } - - FileName = UFlibAssetManageHelper::PackagePathToFilename(InPackagePath); + FileName = UFlibAssetManageHelper::LongPackageNameToFilename(InPackageName); + if(!FileName.IsEmpty() && FPaths::FileExists(FileName)) { FMD5Hash FileMD5Hash = FMD5Hash::HashFile(*FileName); @@ -230,10 +235,10 @@ bool UFlibAssetManageHelper::GetAssetReference(const FAssetDetail& InAsset, cons } void UFlibAssetManageHelper::GetAssetReferenceRecursively(const FAssetDetail& InAsset, - const TArray& - SearchAssetDepTypes, - const TArray& SearchAssetsTypes, - TArray& OutRefAsset) + const TArray& + SearchAssetDepTypes, + const TArray& SearchAssetsTypes, + TArray& OutRefAsset, bool bRecursive) { SCOPED_NAMED_EVENT_TEXT("UFlibAssetManageHelper::GetAssetReferenceRecursively",FColor::Red); TArray CurrentAssetsRef; @@ -267,7 +272,10 @@ void UFlibAssetManageHelper::GetAssetReferenceRecursively(const FAssetDetail& In if(!OutRefAsset.Contains(AssetRef)) { OutRefAsset.AddUnique(AssetRef); - UFlibAssetManageHelper::GetAssetReferenceRecursively(AssetRef,SearchAssetDepTypes,SearchAssetsTypes,OutRefAsset); + if(bRecursive) + { + UFlibAssetManageHelper::GetAssetReferenceRecursively(AssetRef,SearchAssetDepTypes,SearchAssetsTypes,OutRefAsset, bRecursive); + } } } } @@ -309,7 +317,11 @@ FAssetDetail UFlibAssetManageHelper::GetAssetDetailByPackageName(const FString& { AssetDetail.PackagePath = OutAssetData.ObjectPath; AssetDetail.AssetType = OutAssetData.AssetClass; +#if ENGINE_MAJOR_VERSION > 4 + UFlibAssetManageHelper::GetAssetPackageGUID(AssetDetail.PackagePath.ToString(), AssetDetail.Guid); +#else UFlibAssetManageHelper::GetAssetPackageGUID(InPackageName, AssetDetail.Guid); +#endif } } } @@ -479,7 +491,11 @@ bool UFlibAssetManageHelper::ConvFAssetDataToFAssetDetail(const FAssetData& InAs FString PackageName = InAssetData.PackageName.ToString(); FString PackagePath = UFlibAssetManageHelper::LongPackageNameToPackagePath(PackageName); AssetDetail.PackagePath = FName(*PackagePath); +#if ENGINE_MAJOR_VERSION > 4 + UFlibAssetManageHelper::GetAssetPackageGUID(PackagePath, AssetDetail.Guid); +#else UFlibAssetManageHelper::GetAssetPackageGUID(PackageName, AssetDetail.Guid); +#endif OutAssetDetail = AssetDetail; return !OutAssetDetail.AssetType.IsNone() && !OutAssetDetail.AssetType.IsNone() && !OutAssetDetail.AssetType.IsNone(); @@ -649,9 +665,7 @@ SCOPED_NAMED_EVENT_TEXT("UFlibAssetManageHelper::GetAllInValidAssetInProject",FC ModuleDependencies.AssetDependencyDetails.GetKeys(ModuleAssetList); for (const auto& AssetLongPackageName : ModuleAssetList) { - FString AssetPackagePath = UFlibAssetManageHelper::LongPackageNameToPackagePath(AssetLongPackageName); - // UE_LOG(LogHotPatcher, Log, TEXT("Asset %s"), *AssetPackagePath); - FString AssetAbsPath = UFlibAssetManageHelper::PackagePathToFilename(AssetPackagePath); + FString AssetAbsPath = UFlibAssetManageHelper::LongPackageNameToFilename(AssetLongPackageName); if (!FPaths::FileExists(AssetAbsPath)) { OutInValidAsset.Add(AssetLongPackageName); @@ -670,7 +684,7 @@ const FAssetPackageData* UFlibAssetManageHelper::GetPackageDataByPackageName(con FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")); // FString TargetLongPackageName = UFlibAssetManageHelper::PackagePathToLongPackageName(InPackageName); const FString& TargetLongPackageName = InPackageName; -#if ENGINE_MAJOR_VERSION > 4 && ENGINE_MINOR_VERSION > 0 +#if ENGINE_MAJOR_VERSION > 4 /*&& ENGINE_MINOR_VERSION > 0*/ TOptional PackageDataOpt = AssetRegistryModule.Get().GetAssetPackageDataCopy(*TargetLongPackageName); if(PackageDataOpt.IsSet()) { @@ -683,7 +697,7 @@ const FAssetPackageData* UFlibAssetManageHelper::GetPackageDataByPackageName(con { return AssetPackageData; } -#if ENGINE_MAJOR_VERSION > 4 && ENGINE_MINOR_VERSION > 0 +#if ENGINE_MAJOR_VERSION > 4 /*&& ENGINE_MINOR_VERSION > 0*/ } #endif } @@ -699,8 +713,8 @@ bool UFlibAssetManageHelper::ConvLongPackageNameToCookedPath(const FString& InPr FString EngineAbsDir = FPaths::ConvertRelativePathToFull(FPaths::EngineDir()); FString CookedRootDir = FPaths::Combine(InProjectAbsDir, TEXT("Saved/Cooked"), InPlatformName); FString ProjectName = FApp::GetProjectName(); - FString AssetPackagePath = UFlibAssetManageHelper::LongPackageNameToPackagePath(InLongPackageName); - FString AssetAbsPath = UFlibAssetManageHelper::PackagePathToFilename(AssetPackagePath); + // FString AssetPackagePath = UFlibAssetManageHelper::LongPackageNameToPackagePath(InLongPackageName); + FString AssetAbsPath = UFlibAssetManageHelper::LongPackageNameToFilename(InLongPackageName); FString AssetModuleName; GetModuleNameByRelativePath(InLongPackageName,AssetModuleName); diff --git a/HotPatcher/Source/HotPatcherRuntime/Private/FlibPakHelper.cpp b/HotPatcher/Source/HotPatcherRuntime/Private/FlibPakHelper.cpp index ea4ced18..31768a92 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Private/FlibPakHelper.cpp +++ b/HotPatcher/Source/HotPatcherRuntime/Private/FlibPakHelper.cpp @@ -456,10 +456,14 @@ bool PreLoadPak(const FString& InPakPath,const FString& AesKey) FSHA1 UFlibPakHelper::GetPakEntryHASH(FPakFile* InPakFile,const FPakEntry& PakEntry) { FSHA1 Sha1; - FArchive* Reader = InPakFile->GetSharedReader(nullptr); + auto Reader = InPakFile->GetSharedReader(nullptr); Reader->Seek(PakEntry.Offset); FPakEntry SerializedEntry; +#if ENGINE_MAJOR_VERSION > 4 + SerializedEntry.Serialize(Reader.GetArchive(), InPakFile->GetInfo().Version); +#else SerializedEntry.Serialize(*Reader, InPakFile->GetInfo().Version); +#endif FMemory::Memcpy(Sha1.m_digest, &SerializedEntry.Hash, sizeof(SerializedEntry.Hash)); return Sha1; } diff --git a/HotPatcher/Source/HotPatcherRuntime/Private/FlibPatchParserHelper.cpp b/HotPatcher/Source/HotPatcherRuntime/Private/FlibPatchParserHelper.cpp index 7a6b3875..60810c8c 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Private/FlibPatchParserHelper.cpp +++ b/HotPatcher/Source/HotPatcherRuntime/Private/FlibPatchParserHelper.cpp @@ -2042,14 +2042,20 @@ TArray UFlibPatchParserHelper::GetDefaultForceSkipContentDir() { TArray result; TArray DefaultSkipEditorContentRules = { - // TEXT("/Engine/Editor*/") - // ,TEXT("/Engine/VREditor/") + TEXT("/Engine/Editor*/") + ,TEXT("/Engine/VREditor/") }; - for(const auto& Ruls:DefaultSkipEditorContentRules) + bool bSkipEditorContent = false; + GConfig->GetBool(TEXT("/Script/UnrealEd.ProjectPackagingSettings"),TEXT("bSkipEditorContent"),bSkipEditorContent,GGameIni); + + if(bSkipEditorContent) { - FDirectoryPath PathIns; - PathIns.Path = Ruls; - result.Add(PathIns); + for(const auto& Ruls:DefaultSkipEditorContentRules) + { + FDirectoryPath PathIns; + PathIns.Path = Ruls; + result.Add(PathIns); + } } return result; } diff --git a/HotPatcher/Source/HotPatcherRuntime/Public/BaseTypes/FAssetScanConfig.h b/HotPatcher/Source/HotPatcherRuntime/Public/BaseTypes/FAssetScanConfig.h index 81d3b575..5a850677 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Public/BaseTypes/FAssetScanConfig.h +++ b/HotPatcher/Source/HotPatcherRuntime/Public/BaseTypes/FAssetScanConfig.h @@ -38,6 +38,8 @@ struct HOTPATCHERRUNTIME_API FAssetScanConfig TArray IncludeSpecifyAssets; UPROPERTY(EditAnywhere, BlueprintReadWrite) bool bRecursiveWidgetTree = true; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + bool bAnalysisMaterialInstance = true; UPROPERTY(EditAnywhere, BlueprintReadWrite) bool bSupportWorldComposition = true; diff --git a/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h b/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h index 7bb7ff4c..a1b72051 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h +++ b/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/FExportPatchSettings.h @@ -163,7 +163,7 @@ struct HOTPATCHERRUNTIME_API FExportPatchSettings:public FHotPatcherSettingBase FORCEINLINE bool IsStorageNewRelease()const{return bStorageNewRelease;} FORCEINLINE bool IsStoragePakFileInfo()const{return bStoragePakFileInfo;} - FORCEINLINE bool IsBackupMetadata()const {return bBackupMetadata;} + // FORCEINLINE bool IsBackupMetadata()const {return bBackupMetadata;} FORCEINLINE bool IsEnableProfiling()const { return bEnableProfiling; } FORCEINLINE FPakEncryptSettings GetEncryptSettings()const{ return EncryptSettings; } @@ -288,8 +288,8 @@ struct HOTPATCHERRUNTIME_API FExportPatchSettings:public FHotPatcherSettingBase bool bStorageDiffAnalysisResults = true; // UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SaveTo") // bool bStorageAssetDependencies = false; - UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "SaveTo") - bool bBackupMetadata = false; + // UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "SaveTo") + // bool bBackupMetadata = false; // UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Advanced") bool bEnableMultiThread = false; diff --git a/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/HotPatcherSettingBase.h b/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/HotPatcherSettingBase.h index 33b87f83..3ecd99de 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/HotPatcherSettingBase.h +++ b/HotPatcher/Source/HotPatcherRuntime/Public/CreatePatch/HotPatcherSettingBase.h @@ -64,6 +64,7 @@ struct HOTPATCHERRUNTIME_API FHotPatcherSettingBase:public FPatcherEntitySetting // virtual TArray GetAssetIgnoreFiltersPaths()const; FORCEINLINE bool IsAnalysisFilterDependencies()const { return GetAssetScanConfig().bAnalysisFilterDependencies; } FORCEINLINE bool IsRecursiveWidgetTree()const {return GetAssetScanConfig().bRecursiveWidgetTree;} + FORCEINLINE bool IsAnalysisMatInstance()const { return GetAssetScanConfig().bAnalysisMaterialInstance; } FORCEINLINE bool IsIncludeHasRefAssetsOnly()const { return GetAssetScanConfig().bIncludeHasRefAssetsOnly; } FORCEINLINE TArray GetAssetRegistryDependencyTypes()const { return GetAssetScanConfig().AssetRegistryDependencyTypes; } FORCEINLINE bool IsPackageTracker()const { return GetAssetScanConfig().bPackageTracker; } diff --git a/HotPatcher/Source/HotPatcherRuntime/Public/FlibAssetManageHelper.h b/HotPatcher/Source/HotPatcherRuntime/Public/FlibAssetManageHelper.h index 5be62d53..4c555d69 100644 --- a/HotPatcher/Source/HotPatcherRuntime/Public/FlibAssetManageHelper.h +++ b/HotPatcher/Source/HotPatcherRuntime/Public/FlibAssetManageHelper.h @@ -67,6 +67,9 @@ class HOTPATCHERRUNTIME_API UFlibAssetManageHelper : public UBlueprintFunctionLi UFUNCTION(BlueprintCallable, Category = "GWorld|Flib|AssetManagerEx") static FString PackagePathToFilename(const FString& InPackagePath); + UFUNCTION(BlueprintCallable, Category = "GWorld|Flib|AssetManagerEx") + static FString LongPackageNameToFilename(const FString& InLongPackageName); + UFUNCTION(BlueprintCallable, Category = "GWorld|Flib|AssetManagerEx") static bool FilenameToPackagePath(const FString& InAbsPath,FString& OutPackagePath); @@ -99,7 +102,7 @@ class HOTPATCHERRUNTIME_API UFlibAssetManageHelper : public UBlueprintFunctionLi static void GetAssetReferenceRecursively(const FAssetDetail& InAsset, const TArray& SearchAssetDepTypes, const TArray& SearchAssetsTypes, - TArray& OutRefAsset); + TArray& OutRefAsset, bool bRecursive = true); UFUNCTION(BlueprintPure, BlueprintCallable, Category = "GWorld|Flib|AssetManager") static bool GetAssetReferenceEx(const FAssetDetail& InAsset, const TArray& SearchAssetDepTypes, TArray& OutRefAsset); diff --git a/Mods/HotMultiCooker b/Mods/HotMultiCooker index 992cabc4..3584e990 160000 --- a/Mods/HotMultiCooker +++ b/Mods/HotMultiCooker @@ -1 +1 @@ -Subproject commit 992cabc42f437ee181ae08bd05ae2d46594d12e6 +Subproject commit 3584e990f86491fb23ef12340c586a7d6b820d98 diff --git a/README.md b/README.md index ea0ec7ca..0cc05dfd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Chinese Document:[README_Chinese.md](https://github.com/hxhb/HotPatcher/blob/m [HotPatcher](https://github.com/hxhb/HotPatcher) is a tool for managing hot update versions and resource packaging. It is used to track changes in the original resources of the project version to create patches. Support resource version management, difference comparison and packaging between versions, support exporting basic package information for multiple platforms, easily cook and package multi-platform Patches, support iterative packaging, rich configuration options, full-featured commandlet support, can be combined with ci/cd platform is integrated. ->The currently supported engine version is UE4.21-UE5 (UE5.0.3 is supported in [dev](https://github.com/hxhb/HotPatcher/dev)). I created a group to discuss UE4 hot update and HotPatcher plug-in issues (QQ group 958363331). +>The currently supported engine version is UE4.21-UE5 (UE5.0.3 is supported). I created a group to discuss UE4 hot update and HotPatcher plug-in issues (QQ group 958363331). Plug-in documentation: [UE4 resource hot update packaging tool HotPatcher](https://imzlp.com/posts/17590/) diff --git a/README_Chinese.md b/README_Chinese.md index f38a0a14..44e8f291 100644 --- a/README_Chinese.md +++ b/README_Chinese.md @@ -5,7 +5,7 @@ English Document:[README.md](https://github.com/hxhb/HotPatcher/edit/master/READ 在热更新领域,HotPatcher可以管理热更版本和资源打包,能够追踪工程版本的原始资源变动。支持资源版本管理、版本间的差异对比和打包、支持导出多平台的基础包信息、方便地Cook和打包多平台的Patch,并提供了数种开箱即用的包体优化方案,支持迭代打包、丰富的配置化选项,全功能的commandlet支持,可以非常方便地与ci/cd平台相集成。全平台、跨引擎版本(UE4.21 ~ UE5)支持。 ->目前支持的引擎版本为UE4.21-UE5(UE5.0.3在[dev](https://github.com/hxhb/HotPatcher/dev)分支支持),我创建了个群来讨论UE热更新和HotPatcher插件的问题(QQ群958363331)。 +>目前支持的引擎版本为UE4.21-UE5(已支持UE5.0.3),我创建了个群来讨论UE热更新和HotPatcher插件的问题(QQ群958363331)。 插件文档:[UE资源热更打包工具HotPatcher](https://imzlp.com/posts/17590/)