diff --git a/Plugins/UEWingman/Source/UEWingman/HalfBaked/Blueprint_Dump.h b/Plugins/UEWingman/Source/UEWingman/HalfBaked/Blueprint_Dump.h index 1382d5ed..d328bc7d 100644 --- a/Plugins/UEWingman/Source/UEWingman/HalfBaked/Blueprint_Dump.h +++ b/Plugins/UEWingman/Source/UEWingman/HalfBaked/Blueprint_Dump.h @@ -24,13 +24,13 @@ class UWing_Blueprint_Dump : public UObject, public IWingHandler GENERATED_BODY() public: - UPROPERTY(meta=(Description="Blueprint name or package path")) + UPROPERTY(meta=(Description="Blueprint path")) FString Blueprint; virtual FString GetDescription() const override { return TEXT("Dump a Blueprint's structure: variables, interfaces, components, " - "and graph names. Does not include graph contents (use DumpGraphs for that)."); + "and graph names. Does not include graph contents (use Graph_Dump for that)."); } virtual void Handle() override diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_ContentBrowse.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_ContentBrowse.h new file mode 100644 index 00000000..96c95a4c --- /dev/null +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_ContentBrowse.h @@ -0,0 +1,103 @@ +#pragma once + +#include "CoreMinimal.h" +#include "WingServer.h" +#include "WingHandler.h" +#include "WingUtils.h" +#include "AssetRegistry/AssetRegistryModule.h" +#include "AssetRegistry/IAssetRegistry.h" +#include "Asset_ContentBrowse.generated.h" + + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- + +UCLASS() +class UWing_Asset_ContentBrowse : public UObject, public IWingHandler +{ + GENERATED_BODY() + +public: + UPROPERTY(meta=(Description="Content browser path to list, e.g. /Game or /Game/Maps")) + FString Path; + + virtual FString GetDescription() const override + { + return TEXT("List the subfolders and assets inside a content browser folder."); + } + + static FString GetExtraInfoString(const FAssetData& Data) + { + FString ParentClassName; + if (Data.GetTagValue(FName(TEXT("ParentClass")), ParentClassName)) + { + int32 DotIndex; + if (ParentClassName.FindLastChar('.', DotIndex)) + ParentClassName = ParentClassName.Mid(DotIndex + 1); + ParentClassName.RemoveFromEnd(TEXT("'")); + return FString::Printf(TEXT("(parent: %s)"), *ParentClassName); + } + return FString(); + } + + static FString GetAssetTypeString(const FAssetData& Data) + { + FString AssetType = WingUtils::FormatName(Data.GetClass()); + FString BlueprintTypeTag; + if (Data.GetTagValue(FName(TEXT("BlueprintType")), BlueprintTypeTag)) + { + BlueprintTypeTag.RemoveFromStart(TEXT("BPTYPE_")); + if (BlueprintTypeTag == TEXT("Normal")) + AssetType = TEXT("Blueprint"); + else if (BlueprintTypeTag == TEXT("Const")) + AssetType = TEXT("ConstBlueprint"); + else + AssetType = BlueprintTypeTag; + } + return AssetType; + } + + virtual void Handle() override + { + // Normalize: strip trailing slash + while (Path.EndsWith(TEXT("/"))) + { + Path.LeftChopInline(1); + } + + IAssetRegistry& AR = FModuleManager::LoadModuleChecked("AssetRegistry").Get(); + + TArray Results; + AR.EnumerateSubPaths(Path, [&Results](FString SubPath) + { + Results.Add(FString::Printf(TEXT("[Folder] %s\n"), *SubPath)); + return true; + }, false); + + // Collect assets in this folder (non-recursive) + FARFilter Filter; + Filter.PackagePaths.Add(FName(*Path)); + Filter.bRecursivePaths = false; + TArray Assets; + AR.GetAssets(Filter, Assets); + + for (const FAssetData &Asset : Assets) + { + if (Asset.IsRedirector()) continue; + FString TypeString = GetAssetTypeString(Asset); + FString ExtraInfo = GetExtraInfoString(Asset); + Results.Add(FString::Printf(TEXT("%-30s %s %s\n"), + *TypeString, *Asset.PackageName.ToString(), *ExtraInfo)); + } + + Results.Sort(); + for (const FString &Result : Results) UWingServer::Print(Result); + + if (Results.IsEmpty()) + { + UWingServer::Printf(TEXT("No contents found at '%s'.\n"), *Path); + return; + } + } +}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Create.h index 384465c3..d266a289 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Create.h @@ -63,7 +63,7 @@ public: } // Find the newly created variable description - FBlueprintVar Editor(BP, Name); + FWingBlueprintVar Editor(BP, Name); if (Editor.NotFound()) return; // Apply config if provided diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Delete.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Delete.h index 88cd9b09..d8a84d9e 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Delete.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Delete.h @@ -38,7 +38,7 @@ public: UBlueprint* BP = F.Walk(Blueprint).Cast(); if (!BP) return; - FBlueprintVar Editor(BP, Variable); + FWingBlueprintVar Editor(BP, Variable); if (Editor.NotFound()) return; FBlueprintEditorUtils::RemoveMemberVariable(BP, Editor.Desc->VarName); diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Dump.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Dump.h index 4c577141..8556c153 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Dump.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Dump.h @@ -38,7 +38,7 @@ public: UBlueprint* BP = F.Walk(Blueprint).Cast(); if (!BP) return; - FBlueprintVar Editor(BP, Variable); + FWingBlueprintVar Editor(BP, Variable); if (Editor.NotFound()) return; UWingServer::Printf(TEXT("Variable %s in %s:\n"), *Variable, *WingUtils::FormatName(BP)); diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Modify.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Modify.h index e76de135..38ed771a 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Modify.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintVariable_Modify.h @@ -44,7 +44,7 @@ public: UBlueprint* BP = F.Walk(Blueprint).Cast(); if (!BP) return; - FBlueprintVar Editor(BP, Variable); + FWingBlueprintVar Editor(BP, Variable); if (Editor.NotFound()) return; if (!Properties.Json || Properties.Json->Values.Num() == 0) diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingBlueprintVar.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingBlueprintVar.cpp index d76cfb19..12d5c774 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingBlueprintVar.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingBlueprintVar.cpp @@ -6,7 +6,7 @@ #include "EdGraphSchema_K2.h" #include "Kismet2/BlueprintEditorUtils.h" -FBlueprintVar::FBlueprintVar(UBlueprint* BP, const FString& VarName) +FWingBlueprintVar::FWingBlueprintVar(UBlueprint* BP, const FString& VarName) { FName VarFName(*VarName); int32 VarIndex = FBlueprintEditorUtils::FindNewVariableIndex(BP, VarFName); @@ -27,7 +27,7 @@ FBlueprintVar::FBlueprintVar(UBlueprint* BP, const FString& VarName) } } -void FBlueprintVar::Dump() +void FWingBlueprintVar::Dump() { LoadFlags(); LoadDefault(); @@ -41,7 +41,7 @@ void FBlueprintVar::Dump() } } -bool FBlueprintVar::ApplyJson(const FJsonObject* Json) +bool FWingBlueprintVar::ApplyJson(const FJsonObject* Json) { bool bHasDefault = Json->HasField(TEXT("DefaultValue")); bool bHasType = Json->HasField(TEXT("VarType")); @@ -66,7 +66,7 @@ bool FBlueprintVar::ApplyJson(const FJsonObject* Json) return true; } -void FBlueprintVar::LoadFlags() +void FWingBlueprintVar::LoadFlags() { InstanceEditable = !(Desc->PropertyFlags & CPF_DisableEditOnInstance); BlueprintReadOnly = (Desc->PropertyFlags & CPF_BlueprintReadOnly) != 0; @@ -80,7 +80,7 @@ void FBlueprintVar::LoadFlags() Description.Empty(); } -void FBlueprintVar::LoadDefault() +void FWingBlueprintVar::LoadDefault() { if (DefaultValueProp) DefaultValue = DefaultValueProp.GetText(); @@ -88,7 +88,7 @@ void FBlueprintVar::LoadDefault() DefaultValue.Empty(); } -void FBlueprintVar::SaveFlags() +void FWingBlueprintVar::SaveFlags() { // CPF flags if (InstanceEditable) @@ -124,14 +124,14 @@ void FBlueprintVar::SaveFlags() Desc->RemoveMetaData(TEXT("tooltip")); } -bool FBlueprintVar::SaveDefault() +bool FWingBlueprintVar::SaveDefault() { if (DefaultValueProp) return DefaultValueProp.SetText(DefaultValue); return true; } -TArray FBlueprintVar::MergedProperties() +TArray FWingBlueprintVar::MergedProperties() { TArray Props = WingProperty::GetAll( FBPVariableDescription::StaticStruct(), Desc, CPF_Edit); @@ -143,7 +143,7 @@ TArray FBlueprintVar::MergedProperties() WingProperty::Remove(Props, TEXT("DefaultValue")); Props.Append(WingProperty::GetAll( - FBlueprintVar::StaticStruct(), this, (EPropertyFlags)0)); + FWingBlueprintVar::StaticStruct(), this, (EPropertyFlags)0)); // Remove DefaultValue if we don't have a CDO property to back it. if (!DefaultValueProp) diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp index fc2adb13..0a3d93fc 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp @@ -313,7 +313,6 @@ TArray WingUtils::AllNodes(UBlueprint* BP) bool WingUtils::SaveBlueprintPackage(UBlueprint* BP) { UPackage* Package = BP->GetPackage(); - UE_LOG(LogTemp, Display, TEXT("UEWingman: SaveBlueprintPackage — begin for '%s'"), *BP->GetName()); // 1. Build absolute package filename — use .umap for map packages, .uasset otherwise FString PackageExtension = Package->ContainsMap() @@ -688,8 +687,7 @@ FString WingUtils::GetHandlerName(UClass* HandlerClass) { FString Name = HandlerClass->GetName(); // Strip "Wing_" prefix - if (Name.StartsWith(TEXT("Wing_"))) - Name = Name.Mid(4); + Name.RemoveFromStart(TEXT("Wing_")); return Name; } @@ -701,8 +699,7 @@ FString WingUtils::GetHandlerGroup(UClass* HandlerClass) { FString Name = HandlerClass->GetName(); // Strip "Wing_" prefix - if (Name.StartsWith(TEXT("Wing_"))) - Name = Name.Mid(4); + Name.RemoveFromStart(TEXT("Wing_")); // Everything before the underscore is the group int32 UnderscoreIdx; if (Name.FindChar(TEXT('_'), UnderscoreIdx)) diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingBlueprintVar.h b/Plugins/UEWingman/Source/UEWingman/Public/WingBlueprintVar.h index d5378c38..bb0c1d8c 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingBlueprintVar.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingBlueprintVar.h @@ -10,15 +10,15 @@ // and metadata as simple UPROPERTYs that the property system can // populate from JSON. USTRUCT() -struct FBlueprintVar +struct FWingBlueprintVar { GENERATED_BODY() FBPVariableDescription* Desc = nullptr; WingProperty DefaultValueProp; - FBlueprintVar() = default; - FBlueprintVar(UBlueprint* BP, const FString& VarName); + FWingBlueprintVar() = default; + FWingBlueprintVar(UBlueprint* BP, const FString& VarName); bool NotFound() const { return Desc == nullptr; }