diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPAssetFinder.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPAssetFinder.cpp index 651823bf..c0323bb4 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPAssetFinder.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPAssetFinder.cpp @@ -41,304 +41,193 @@ void UMCPAssetFinder::Deinitialize() } // ============================================================ -// GetUpdatedAssets — the gateway for all static API +// Get / Refresh // ============================================================ -UMCPAssetFinder* UMCPAssetFinder::GetUpdatedAssets() +UMCPAssetFinder* UMCPAssetFinder::Get() +{ + UMCPAssetFinder* Self = GEngine ? GEngine->GetEngineSubsystem() : nullptr; + checkf(Self, TEXT("MCPAssetFinder::Get() called before engine initialization")); + return Self; +} + +void UMCPAssetFinder::CacheAssets(IAssetRegistry &Registry, UClass *Class, bool IncludeSubclasses) +{ + FName Key = Class->GetFName(); + TArray& List = AssetCache.Add(Key); + Registry.GetAssetsByClass(Class->GetClassPathName(), List, IncludeSubclasses); +} + +void UMCPAssetFinder::Refresh() { checkf(IsInGameThread(), TEXT("MCPAssetFinder must only be accessed from the game thread")); - if (!GEngine) return nullptr; - UMCPAssetFinder* Self = GEngine->GetEngineSubsystem(); - if (!Self) return nullptr; + UMCPAssetFinder* Self = Get(); IAssetRegistry& AR = FModuleManager::LoadModuleChecked("AssetRegistry").Get(); while (AR.IsLoadingAssets()) FPlatformProcess::Sleep(0.1f); - if (!Self->bDirty) return Self; + if (!Self->bDirty) return; - Self->AllBlueprintAssets.Empty(); - Self->AllMapAssets.Empty(); - Self->AllBlueprintAndMapAssets.Empty(); - Self->AllMaterialAssets.Empty(); - Self->AllMaterialInstanceAssets.Empty(); - Self->AllMaterialFunctionAssets.Empty(); - Self->AllStructAssets.Empty(); - Self->AllEnumAssets.Empty(); + Self->AssetCache.Empty(); - AR.GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), Self->AllBlueprintAssets, true); - AR.GetAssetsByClass(UWorld::StaticClass()->GetClassPathName(), Self->AllMapAssets, false); - AR.GetAssetsByClass(UMaterial::StaticClass()->GetClassPathName(), Self->AllMaterialAssets, false); - AR.GetAssetsByClass(UMaterialInstanceConstant::StaticClass()->GetClassPathName(), Self->AllMaterialInstanceAssets, false); - AR.GetAssetsByClass(UMaterialFunction::StaticClass()->GetClassPathName(), Self->AllMaterialFunctionAssets, false); - AR.GetAssetsByClass(UUserDefinedStruct::StaticClass()->GetClassPathName(), Self->AllStructAssets, false); - AR.GetAssetsByClass(UUserDefinedEnum::StaticClass()->GetClassPathName(), Self->AllEnumAssets, false); + // Cache all asset classes. + Self->CacheAssets(AR, UBlueprint::StaticClass(), true); + Self->CacheAssets(AR, UWorld::StaticClass(), false); + Self->CacheAssets(AR, UMaterial::StaticClass(), false); + Self->CacheAssets(AR, UMaterialInstanceConstant::StaticClass(), false); + Self->CacheAssets(AR, UMaterialFunction::StaticClass(), false); + Self->CacheAssets(AR, UUserDefinedStruct::StaticClass(), false); + Self->CacheAssets(AR, UUserDefinedEnum::StaticClass(), false); - Self->AllBlueprintAndMapAssets = Self->AllBlueprintAssets; - Self->AllBlueprintAndMapAssets.Append(Self->AllMapAssets); + // Combined list: blueprints + maps + TArray& Combined = Self->AssetCache.Add(BlueprintsAndMaps); + Combined = Self->AssetCache[UBlueprint::StaticClass()->GetFName()]; + Combined.Append(Self->AssetCache[UWorld::StaticClass()->GetFName()]); Self->bDirty = false; - UE_LOG(LogTemp, Display, TEXT("MCPAssetFinder: Refreshed — BP %d, Map %d, Mat %d, MI %d, MF %d, Struct %d, Enum %d"), - Self->AllBlueprintAssets.Num(), Self->AllMapAssets.Num(), Self->AllMaterialAssets.Num(), - Self->AllMaterialInstanceAssets.Num(), Self->AllMaterialFunctionAssets.Num(), - Self->AllStructAssets.Num(), Self->AllEnumAssets.Num()); - - return Self; + UE_LOG(LogTemp, Display, TEXT("MCPAssetFinder: Refreshed — %d asset types cached"), + Self->AssetCache.Num()); } // ============================================================ // Static asset list accessors // ============================================================ -const TArray& UMCPAssetFinder::GetBlueprintAssets() +const TArray& UMCPAssetFinder::GetAssets(FName Key) { - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllBlueprintAssets : EmptyAssetArray; + TArray* Found = Get()->AssetCache.Find(Key); + return Found ? *Found : EmptyAssetArray; } -const TArray& UMCPAssetFinder::GetBlueprintAndMapAssets() +const TArray& UMCPAssetFinder::GetAssets(UClass* Class) { - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllBlueprintAndMapAssets : EmptyAssetArray; + return GetAssets(Class->GetFName()); } -const TArray& UMCPAssetFinder::GetMapAssets() -{ - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllMapAssets : EmptyAssetArray; -} - -const TArray& UMCPAssetFinder::GetMaterialAssets() -{ - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllMaterialAssets : EmptyAssetArray; -} - -const TArray& UMCPAssetFinder::GetMaterialInstanceAssets() -{ - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllMaterialInstanceAssets : EmptyAssetArray; -} - -const TArray& UMCPAssetFinder::GetMaterialFunctionAssets() -{ - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllMaterialFunctionAssets : EmptyAssetArray; -} - -const TArray& UMCPAssetFinder::GetStructAssets() -{ - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllStructAssets : EmptyAssetArray; -} - -const TArray& UMCPAssetFinder::GetEnumAssets() -{ - UMCPAssetFinder* Self = GetUpdatedAssets(); - return Self ? Self->AllEnumAssets : EmptyAssetArray; -} +FName UMCPAssetFinder::BlueprintsAndMaps = FName(TEXT("BlueprintsAndMaps")); // ============================================================ -// Find helpers (search cached lists by name or path) +// Find / Search helpers // ============================================================ -namespace +FAssetData* UMCPAssetFinder::FindAsset(FName Class, const FString& NameOrPath, FString* OutError) { - FAssetData* FindInList(const TArray& List, const FString& NameOrPath, FString* OutError) + const TArray& List = GetAssets(Class); + bool IsPath = NameOrPath.Contains(TEXT("/")); + + FAssetData* Found = nullptr; + for (const FAssetData& Asset : List) { - bool IsPath = NameOrPath.Contains(TEXT("/")); - - // Short name match — check for duplicates - FAssetData* Found = nullptr; - - for (const FAssetData& Asset : List) + FName Name = IsPath ? Asset.PackageName : Asset.AssetName; + if (!Name.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase)) continue; + if (!Found) { - FName Name = IsPath ? Asset.PackageName : Asset.AssetName; - if (!Name.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase)) continue; - if (!Found) - { - Found = const_cast(&Asset); - continue; - } - if (OutError) - { - *OutError = FString::Printf( - TEXT("Ambiguous asset name '%s' — matches both '%s' and '%s'. Use the full package path to disambiguate."), - *NameOrPath, *Found->PackageName.ToString(), *Asset.PackageName.ToString()); - } - return nullptr; + Found = const_cast(&Asset); + continue; } - return Found; + if (OutError) + { + *OutError = FString::Printf( + TEXT("Ambiguous asset name '%s' — matches both '%s' and '%s'. Use the full package path to disambiguate."), + *NameOrPath, *Found->PackageName.ToString(), *Asset.PackageName.ToString()); + } + return nullptr; } + return Found; +} - TArray SearchInList(const TArray& List, const FString& Filter) +FAssetData* UMCPAssetFinder::FindAsset(UClass* Class, const FString& NameOrPath, FString* OutError) +{ + return FindAsset(Class->GetFName(), NameOrPath, OutError); +} + +TArray UMCPAssetFinder::SearchAssets(FName Class, const FString& Filter, FString* OutError) +{ + const TArray& List = GetAssets(Class); + TArray Results; + for (const FAssetData& Asset : List) { - TArray Results; - for (const FAssetData& Asset : List) + FString AssetName = Asset.AssetName.ToString(); + FString PackagePath = Asset.PackageName.ToString(); + if (AssetName.Contains(Filter, ESearchCase::IgnoreCase) || + PackagePath.Contains(Filter, ESearchCase::IgnoreCase)) { - FString AssetName = Asset.AssetName.ToString(); - FString PackagePath = Asset.PackageName.ToString(); - if (AssetName.Contains(Filter, ESearchCase::IgnoreCase) || - PackagePath.Contains(Filter, ESearchCase::IgnoreCase)) - { - Results.Add(const_cast(&Asset)); - } + Results.Add(const_cast(&Asset)); } - return Results; } + return Results; } -FAssetData* UMCPAssetFinder::FindBlueprintAsset(const FString& NameOrPath, FString* OutError, bool bIncludeLevelBlueprints) +TArray UMCPAssetFinder::SearchAssets(UClass* Class, const FString& Filter, FString* OutError) { - const TArray& List = bIncludeLevelBlueprints ? GetBlueprintAndMapAssets() : GetBlueprintAssets(); - return FindInList(List, NameOrPath, OutError); -} - -TArray UMCPAssetFinder::SearchBlueprintAssets(const FString& Filter, bool bIncludeLevelBlueprints) -{ - const TArray& List = bIncludeLevelBlueprints ? GetBlueprintAndMapAssets() : GetBlueprintAssets(); - return SearchInList(List, Filter); -} - -FAssetData* UMCPAssetFinder::FindMapAsset(const FString& NameOrPath, FString* OutError) -{ - return FindInList(GetMapAssets(), NameOrPath, OutError); -} - -FAssetData* UMCPAssetFinder::FindMaterialAsset(const FString& NameOrPath, FString* OutError) -{ - return FindInList(GetMaterialAssets(), NameOrPath, OutError); -} - -FAssetData* UMCPAssetFinder::FindMaterialInstanceAsset(const FString& NameOrPath, FString* OutError) -{ - return FindInList(GetMaterialInstanceAssets(), NameOrPath, OutError); -} - -FAssetData* UMCPAssetFinder::FindMaterialFunctionAsset(const FString& NameOrPath, FString* OutError) -{ - return FindInList(GetMaterialFunctionAssets(), NameOrPath, OutError); -} - -FAssetData* UMCPAssetFinder::FindStructAsset(const FString& NameOrPath, FString* OutError) -{ - return FindInList(GetStructAssets(), NameOrPath, OutError); -} - -FAssetData* UMCPAssetFinder::FindEnumAsset(const FString& NameOrPath, FString* OutError) -{ - return FindInList(GetEnumAssets(), NameOrPath, OutError); + return SearchAssets(Class->GetFName(), Filter, OutError); } FAssetData* UMCPAssetFinder::FindAnyAsset(const FString& NameOrPath, FString* OutError) { - FAssetData* Asset = FindBlueprintAsset(NameOrPath, OutError); - if (!Asset && (!OutError || OutError->IsEmpty())) Asset = FindMaterialAsset(NameOrPath, OutError); - if (!Asset && (!OutError || OutError->IsEmpty())) Asset = FindMaterialInstanceAsset(NameOrPath, OutError); - if (!Asset && (!OutError || OutError->IsEmpty())) Asset = FindMaterialFunctionAsset(NameOrPath, OutError); - return Asset; + FAssetData* Found = nullptr; + + for (auto& Pair : Get()->AssetCache) + { + if (Pair.Key == BlueprintsAndMaps) continue; + + FString LocalError; + FAssetData* Asset = FindAsset(Pair.Key, NameOrPath, &LocalError); + if (!LocalError.IsEmpty()) + { + if (OutError) *OutError = LocalError; + return nullptr; + } + if (!Asset) continue; + if (Found) + { + if (OutError) + { + *OutError = FString::Printf( + TEXT("Ambiguous asset name '%s' — matches '%s' and '%s'. Use the full package path to disambiguate."), + *NameOrPath, *Found->PackageName.ToString(), *Asset->PackageName.ToString()); + } + return nullptr; + } + Found = Asset; + } + return Found; } // ============================================================ // Load helpers // ============================================================ -UBlueprint* UMCPAssetFinder::LoadBlueprintByName(const FString& NameOrPath, FString& OutError, bool bIncludeLevelBlueprints) +UBlueprint* UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(FAssetData& Asset, FString& OutError) { - FAssetData* Asset = FindBlueprintAsset(NameOrPath, &OutError, bIncludeLevelBlueprints); - if (!Asset) - { - if (OutError.IsEmpty()) - { - OutError = FString::Printf(TEXT("Blueprint '%s' not found. Use list_blueprints to see available assets."), *NameOrPath); - } - return nullptr; - } - // Regular blueprint asset - UBlueprint* BP = Cast(Asset->GetAsset()); - if (BP) - { - return BP; - } + UBlueprint* BP = Cast(Asset.GetAsset()); + if (BP) return BP; // Map asset — extract the level blueprint - UWorld* World = Cast(Asset->GetAsset()); + UWorld* World = Cast(Asset.GetAsset()); if (World && World->PersistentLevel) { ULevelScriptBlueprint* LevelBP = World->PersistentLevel->GetLevelScriptBlueprint(true); - if (LevelBP) - { - return LevelBP; - } + if (LevelBP) return LevelBP; } - OutError = FString::Printf(TEXT("Asset '%s' loaded but its level blueprint could not be retrieved."), *NameOrPath); + OutError = FString::Printf(TEXT("Asset '%s' loaded but its level blueprint could not be retrieved."), + *Asset.AssetName.ToString()); return nullptr; } -UMaterial* UMCPAssetFinder::LoadMaterialByName(const FString& NameOrPath, FString& OutError) +UBlueprint* UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(const FString& NameOrPath, FString& OutError) { - FAssetData* Asset = FindMaterialAsset(NameOrPath, &OutError); - if (Asset) + FAssetData* Asset = FindAsset(BlueprintsAndMaps, NameOrPath, &OutError); + if (!Asset) { - UMaterial* Mat = Cast(Asset->GetAsset()); - if (Mat) return Mat; + if (OutError.IsEmpty()) + OutError = FString::Printf(TEXT("Blueprint '%s' not found."), *NameOrPath); + return nullptr; } - if (OutError.IsEmpty()) - OutError = FString::Printf(TEXT("Material '%s' not found. Use list_materials to see available assets."), *NameOrPath); - return nullptr; + return LoadBlueprintOrLevelBlueprint(*Asset, OutError); } -UMaterialInstanceConstant* UMCPAssetFinder::LoadMaterialInstanceByName(const FString& NameOrPath, FString& OutError) -{ - FAssetData* Asset = FindMaterialInstanceAsset(NameOrPath, &OutError); - if (Asset) - { - UMaterialInstanceConstant* MI = Cast(Asset->GetAsset()); - if (MI) return MI; - } - if (OutError.IsEmpty()) - OutError = FString::Printf(TEXT("Material Instance '%s' not found. Use list_materials to see available assets."), *NameOrPath); - return nullptr; -} - -UMaterialFunction* UMCPAssetFinder::LoadMaterialFunctionByName(const FString& NameOrPath, FString& OutError) -{ - FAssetData* Asset = FindMaterialFunctionAsset(NameOrPath, &OutError); - if (Asset) - { - UMaterialFunction* MF = Cast(Asset->GetAsset()); - if (MF) return MF; - } - if (OutError.IsEmpty()) - OutError = FString::Printf(TEXT("Material Function '%s' not found. Use list_material_functions to see available assets."), *NameOrPath); - return nullptr; -} - -UUserDefinedStruct* UMCPAssetFinder::LoadStructByName(const FString& NameOrPath, FString& OutError) -{ - FAssetData* Asset = FindStructAsset(NameOrPath, &OutError); - if (Asset) - { - UUserDefinedStruct* Struct = Cast(Asset->GetAsset()); - if (Struct) return Struct; - } - if (OutError.IsEmpty()) - OutError = FString::Printf(TEXT("UserDefinedStruct '%s' not found."), *NameOrPath); - return nullptr; -} - -UUserDefinedEnum* UMCPAssetFinder::LoadEnumByName(const FString& NameOrPath, FString& OutError) -{ - FAssetData* Asset = FindEnumAsset(NameOrPath, &OutError); - if (Asset) - { - UUserDefinedEnum* Enum = Cast(Asset->GetAsset()); - if (Enum) return Enum; - } - if (OutError.IsEmpty()) - OutError = FString::Printf(TEXT("UserDefinedEnum '%s' not found."), *NameOrPath); - return nullptr; -} diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_AnimMutation.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_AnimMutation.cpp index c889584c..2a3e9479 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_AnimMutation.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_AnimMutation.cpp @@ -59,7 +59,7 @@ void FBlueprintMCPServer::HandleCreateAnimBlueprint(const FJsonObject* Json, FJs // Check if asset already exists FString FullAssetPath = PackagePath / Name; - if (UMCPAssetFinder::FindBlueprintAsset(Name) || UMCPAssetFinder::FindBlueprintAsset(FullAssetPath)) + if (UMCPAssetFinder::FindAsset(UBlueprint::StaticClass(), Name) || UMCPAssetFinder::FindAsset(UBlueprint::StaticClass(), FullAssetPath)) { return MCPUtils::MakeErrorJson(Result, FString::Printf( TEXT("Blueprint '%s' already exists. Use a different name or delete the existing asset first."), @@ -214,7 +214,7 @@ void FBlueprintMCPServer::HandleAddAnimState(const FJsonObject* Json, FJsonObjec } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -316,7 +316,7 @@ void FBlueprintMCPServer::HandleRemoveAnimState(const FJsonObject* Json, FJsonOb } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -387,7 +387,7 @@ void FBlueprintMCPServer::HandleAddAnimTransition(const FJsonObject* Json, FJson } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -474,7 +474,7 @@ void FBlueprintMCPServer::HandleSetTransitionRule(const FJsonObject* Json, FJson } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -566,7 +566,7 @@ void FBlueprintMCPServer::HandleAddAnimNode(const FJsonObject* Json, FJsonObject } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -762,7 +762,7 @@ void FBlueprintMCPServer::HandleSetStateAnimation(const FJsonObject* Json, FJson } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -855,7 +855,7 @@ void FBlueprintMCPServer::HandleListAnimSlots(const FJsonObject* Json, FJsonObje } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -914,7 +914,7 @@ void FBlueprintMCPServer::HandleListSyncGroups(const FJsonObject* Json, FJsonObj } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -1261,7 +1261,7 @@ void FBlueprintMCPServer::HandleSetStateBlendSpace(const FJsonObject* Json, FJso } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Components.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Components.cpp index 01537d02..64039ad1 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Components.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Components.cpp @@ -24,7 +24,7 @@ void FBlueprintMCPServer::HandleListComponents(const FJsonObject* Json, FJsonObj } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -118,7 +118,7 @@ void FBlueprintMCPServer::HandleAddComponent(const FJsonObject* Json, FJsonObjec } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -271,7 +271,7 @@ void FBlueprintMCPServer::HandleRemoveComponent(const FJsonObject* Json, FJsonOb } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_DiffBlueprints.h b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_DiffBlueprints.h index 2cf4c208..d50edadf 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_DiffBlueprints.h +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_DiffBlueprints.h @@ -42,10 +42,10 @@ public: // Load both blueprints FString LoadErrorA, LoadErrorB; - UBlueprint* BPA = UMCPAssetFinder::LoadBlueprintByName(BlueprintA, LoadErrorA); + UBlueprint* BPA = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintA, LoadErrorA); if (!BPA) { MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("blueprintA: %s"), *LoadErrorA)); return; } - UBlueprint* BPB = UMCPAssetFinder::LoadBlueprintByName(BlueprintB, LoadErrorB); + UBlueprint* BPB = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintB, LoadErrorB); if (!BPB) { MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("blueprintB: %s"), *LoadErrorB)); return; } // Helper to gather graphs from a Blueprint diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Discovery.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Discovery.cpp index 6e74de42..f593d6d4 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Discovery.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Discovery.cpp @@ -29,7 +29,7 @@ void FBlueprintMCPServer::HandleGetPinInfo(const FJsonObject* Json, FJsonObject* } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -134,7 +134,7 @@ void FBlueprintMCPServer::HandleCheckPinCompatibility(const FJsonObject* Json, F } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Dispatchers.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Dispatchers.cpp index 50cdd917..9fd70eca 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Dispatchers.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Dispatchers.cpp @@ -28,7 +28,7 @@ void FBlueprintMCPServer::HandleAddEventDispatcher(const FJsonObject* Json, FJso // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -173,7 +173,7 @@ void FBlueprintMCPServer::HandleListEventDispatchers(const FJsonObject* Json, FJ } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Graphs.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Graphs.cpp index b9ce2ab8..b60df52e 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Graphs.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Graphs.cpp @@ -33,7 +33,7 @@ void FBlueprintMCPServer::HandleReparentBlueprint(const FJsonObject* Json, FJson // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -59,7 +59,7 @@ void FBlueprintMCPServer::HandleReparentBlueprint(const FJsonObject* Json, FJson if (!NewParentClass) { FString ParentLoadError; - UBlueprint* ParentBP = UMCPAssetFinder::LoadBlueprintByName(NewParentName, ParentLoadError); + UBlueprint* ParentBP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(NewParentName, ParentLoadError); if (ParentBP && ParentBP->GeneratedClass) { NewParentClass = ParentBP->GeneratedClass; @@ -134,7 +134,7 @@ void FBlueprintMCPServer::HandleCreateBlueprint(const FJsonObject* Json, FJsonOb // Check if asset already exists FString FullAssetPath = PackagePath / BlueprintName; - if (UMCPAssetFinder::FindBlueprintAsset(BlueprintName) || UMCPAssetFinder::FindBlueprintAsset(FullAssetPath)) + if (UMCPAssetFinder::FindAsset(UBlueprint::StaticClass(), BlueprintName) || UMCPAssetFinder::FindAsset(UBlueprint::StaticClass(), FullAssetPath)) { return MCPUtils::MakeErrorJson(Result, FString::Printf( TEXT("Blueprint '%s' already exists. Use a different name or delete the existing asset first."), @@ -156,7 +156,7 @@ void FBlueprintMCPServer::HandleCreateBlueprint(const FJsonObject* Json, FJsonOb if (!ParentClass) { FString ParentLoadError; - UBlueprint* ParentBP = UMCPAssetFinder::LoadBlueprintByName(ParentClassName, ParentLoadError); + UBlueprint* ParentBP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(ParentClassName, ParentLoadError); if (ParentBP && ParentBP->GeneratedClass) { ParentClass = ParentBP->GeneratedClass; @@ -285,7 +285,7 @@ void FBlueprintMCPServer::HandleCreateGraph(const FJsonObject* Json, FJsonObject // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -404,7 +404,7 @@ void FBlueprintMCPServer::HandleDeleteGraph(const FJsonObject* Json, FJsonObject } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -490,7 +490,7 @@ void FBlueprintMCPServer::HandleRenameGraph(const FJsonObject* Json, FJsonObject } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Interfaces.h b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Interfaces.h index 9c145566..9897d3a7 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Interfaces.h +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Interfaces.h @@ -34,7 +34,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -97,7 +97,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -138,7 +138,7 @@ public: if (!InterfaceClass) { FString IfaceLoadError; - UBlueprint* IfaceBP = UMCPAssetFinder::LoadBlueprintByName(InterfaceName, IfaceLoadError); + UBlueprint* IfaceBP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(InterfaceName, IfaceLoadError); if (IfaceBP && IfaceBP->GeneratedClass && IfaceBP->GeneratedClass->IsChildOf(UInterface::StaticClass())) { InterfaceClass = IfaceBP->GeneratedClass; @@ -242,7 +242,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialInstance.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialInstance.cpp index 9f2e1c52..80faa686 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialInstance.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialInstance.cpp @@ -41,7 +41,7 @@ void FBlueprintMCPServer::HandleCreateMaterialInstance(const FJsonObject* Json, // Check if asset already exists FString FullAssetPath = PackagePath / Name; - if (UMCPAssetFinder::FindMaterialInstanceAsset(Name) || UMCPAssetFinder::FindMaterialInstanceAsset(FullAssetPath)) + if (UMCPAssetFinder::FindAsset(UMaterialInstanceConstant::StaticClass(), Name) || UMCPAssetFinder::FindAsset(UMaterialInstanceConstant::StaticClass(), FullAssetPath)) { return MCPUtils::MakeErrorJson(Result, FString::Printf( TEXT("Material Instance '%s' already exists. Use a different name or delete the existing asset first."), @@ -52,7 +52,7 @@ void FBlueprintMCPServer::HandleCreateMaterialInstance(const FJsonObject* Json, UMaterialInterface* ParentMaterial = nullptr; { FString LoadError; - UMaterial* ParentMat = UMCPAssetFinder::LoadMaterialByName(ParentMaterialName, LoadError); + UMaterial* ParentMat = UMCPAssetFinder::LoadAsset(ParentMaterialName, LoadError); if (ParentMat) { ParentMaterial = ParentMat; @@ -60,7 +60,7 @@ void FBlueprintMCPServer::HandleCreateMaterialInstance(const FJsonObject* Json, else { FString MILoadError; - UMaterialInstanceConstant* ParentMI = UMCPAssetFinder::LoadMaterialInstanceByName(ParentMaterialName, MILoadError); + UMaterialInstanceConstant* ParentMI = UMCPAssetFinder::LoadAsset(ParentMaterialName, MILoadError); if (ParentMI) { ParentMaterial = ParentMI; @@ -146,7 +146,7 @@ void FBlueprintMCPServer::HandleSetMaterialInstanceParameter(const FJsonObject* // Load the Material Instance FString LoadError; - UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(MIName, LoadError); + UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadAsset(MIName, LoadError); if (!MI) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -367,7 +367,7 @@ void FBlueprintMCPServer::HandleGetMaterialInstanceParameters(const FJsonObject* } FString LoadError; - UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(NameParam, LoadError); + UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadAsset(NameParam, LoadError); if (!MI) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -615,7 +615,7 @@ void FBlueprintMCPServer::HandleReparentMaterialInstance(const FJsonObject* Json // Load the Material Instance FString LoadError; - UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(MIName, LoadError); + UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadAsset(MIName, LoadError); if (!MI) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -628,7 +628,7 @@ void FBlueprintMCPServer::HandleReparentMaterialInstance(const FJsonObject* Json UMaterialInterface* NewParent = nullptr; { FString MatLoadError; - UMaterial* NewParentMat = UMCPAssetFinder::LoadMaterialByName(NewParentName, MatLoadError); + UMaterial* NewParentMat = UMCPAssetFinder::LoadAsset(NewParentName, MatLoadError); if (NewParentMat) { NewParent = NewParentMat; @@ -636,7 +636,7 @@ void FBlueprintMCPServer::HandleReparentMaterialInstance(const FJsonObject* Json else { FString MILoadError; - UMaterialInstanceConstant* NewParentMI = UMCPAssetFinder::LoadMaterialInstanceByName(NewParentName, MILoadError); + UMaterialInstanceConstant* NewParentMI = UMCPAssetFinder::LoadAsset(NewParentName, MILoadError); if (NewParentMI) { NewParent = NewParentMI; diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialMutation.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialMutation.cpp index c0843664..3e7b21d6 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialMutation.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialMutation.cpp @@ -75,7 +75,7 @@ void FBlueprintMCPServer::HandleCreateMaterial(const FJsonObject* Json, FJsonObj // Check if asset already exists FString FullAssetPath = PackagePath / Name; - if (UMCPAssetFinder::FindMaterialAsset(Name) || UMCPAssetFinder::FindMaterialAsset(FullAssetPath)) + if (UMCPAssetFinder::FindAsset(UMaterial::StaticClass(), Name) || UMCPAssetFinder::FindAsset(UMaterial::StaticClass(), FullAssetPath)) { return MCPUtils::MakeErrorJson(Result, FString::Printf( TEXT("Material '%s' already exists. Use a different name or delete the existing asset first."), @@ -219,7 +219,7 @@ void FBlueprintMCPServer::HandleSetMaterialProperty(const FJsonObject* Json, FJs // Load material FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -563,7 +563,7 @@ void FBlueprintMCPServer::HandleAddMaterialExpression(const FJsonObject* Json, F return MCPUtils::MakeErrorJson(Result, TEXT("Specify either 'material' or 'materialFunction', not both")); } FString LoadError; - MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError); + MatFunc = UMCPAssetFinder::LoadAsset(MaterialFunctionName, LoadError); if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; } Owner = MatFunc; AssetDisplayName = MatFunc->GetName(); @@ -571,7 +571,7 @@ void FBlueprintMCPServer::HandleAddMaterialExpression(const FJsonObject* Json, F else { FString LoadError; - Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; } Owner = Material; AssetDisplayName = Material->GetName(); @@ -701,14 +701,14 @@ void FBlueprintMCPServer::HandleDeleteMaterialExpression(const FJsonObject* Json if (!MaterialFunctionName.IsEmpty()) { FString LoadError; - MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError); + MatFunc = UMCPAssetFinder::LoadAsset(MaterialFunctionName, LoadError); if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = MatFunc->GetName(); } else { FString LoadError; - Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = Material->GetName(); } @@ -828,14 +828,14 @@ void FBlueprintMCPServer::HandleConnectMaterialPins(const FJsonObject* Json, FJs if (!MaterialFunctionName.IsEmpty()) { FString LoadError; - MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError); + MatFunc = UMCPAssetFinder::LoadAsset(MaterialFunctionName, LoadError); if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = MatFunc->GetName(); } else { FString LoadError; - Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = Material->GetName(); } @@ -979,14 +979,14 @@ void FBlueprintMCPServer::HandleDisconnectMaterialPin(const FJsonObject* Json, F if (!MaterialFunctionName.IsEmpty()) { FString LoadError; - MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError); + MatFunc = UMCPAssetFinder::LoadAsset(MaterialFunctionName, LoadError); if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = MatFunc->GetName(); } else { FString LoadError; - Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = Material->GetName(); } @@ -1101,14 +1101,14 @@ void FBlueprintMCPServer::HandleSetExpressionValue(const FJsonObject* Json, FJso if (!MaterialFunctionName.IsEmpty()) { FString LoadError; - MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError); + MatFunc = UMCPAssetFinder::LoadAsset(MaterialFunctionName, LoadError); if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = MatFunc->GetName(); } else { FString LoadError; - Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = Material->GetName(); } @@ -1378,14 +1378,14 @@ void FBlueprintMCPServer::HandleMoveMaterialExpression(const FJsonObject* Json, if (!MaterialFunctionName.IsEmpty()) { FString LoadError; - MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError); + MatFunc = UMCPAssetFinder::LoadAsset(MaterialFunctionName, LoadError); if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = MatFunc->GetName(); } else { FString LoadError; - Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; } AssetDisplayName = Material->GetName(); } @@ -1482,7 +1482,7 @@ void FBlueprintMCPServer::HandleCreateMaterialFunction(const FJsonObject* Json, // Check if asset already exists FString FullAssetPath = PackagePath / Name; - if (UMCPAssetFinder::FindMaterialFunctionAsset(Name) || UMCPAssetFinder::FindMaterialFunctionAsset(FullAssetPath)) + if (UMCPAssetFinder::FindAsset(UMaterialFunction::StaticClass(), Name) || UMCPAssetFinder::FindAsset(UMaterialFunction::StaticClass(), FullAssetPath)) { return MCPUtils::MakeErrorJson(Result, FString::Printf( TEXT("Material Function '%s' already exists. Use a different name or delete the existing asset first."), @@ -1551,7 +1551,7 @@ void FBlueprintMCPServer::HandleSnapshotMaterialGraph(const FJsonObject* Json, F // Load material FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -1650,7 +1650,7 @@ void FBlueprintMCPServer::HandleDiffMaterialGraph(const FJsonObject* Json, FJson // Load material FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -1816,7 +1816,7 @@ void FBlueprintMCPServer::HandleRestoreMaterialGraph(const FJsonObject* Json, FJ // Load material FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialRead.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialRead.cpp index e49ef4de..d5974215 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialRead.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_MaterialRead.cpp @@ -48,7 +48,7 @@ void FBlueprintMCPServer::HandleListMaterials(const FJsonObject* Json, FJsonObje if (bIncludeMaterials) { - for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UMaterial::StaticClass())) { FString Name = Asset.AssetName.ToString(); FString Path = Asset.PackageName.ToString(); @@ -72,7 +72,7 @@ void FBlueprintMCPServer::HandleListMaterials(const FJsonObject* Json, FJsonObje if (bIncludeInstances) { - for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialInstanceAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UMaterialInstanceConstant::StaticClass())) { FString Name = Asset.AssetName.ToString(); FString Path = Asset.PackageName.ToString(); @@ -94,7 +94,7 @@ void FBlueprintMCPServer::HandleListMaterials(const FJsonObject* Json, FJsonObje } } - int32 Total = UMCPAssetFinder::GetMaterialAssets().Num() + UMCPAssetFinder::GetMaterialInstanceAssets().Num(); + int32 Total = UMCPAssetFinder::GetAssets(UMaterial::StaticClass()).Num() + UMCPAssetFinder::GetAssets(UMaterialInstanceConstant::StaticClass()).Num(); Result->SetNumberField(TEXT("count"), Entries.Num()); Result->SetNumberField(TEXT("total"), Total); @@ -117,7 +117,7 @@ void FBlueprintMCPServer::HandleGetMaterial(const FJsonObject* Json, FJsonObject // Try loading as UMaterial first FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(DecodedName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(DecodedName, LoadError); if (Material) { UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: GetMaterial — loaded material '%s'"), *Material->GetName()); @@ -272,7 +272,7 @@ void FBlueprintMCPServer::HandleGetMaterial(const FJsonObject* Json, FJsonObject // Try loading as MaterialInstance FString MILoadError; - UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(DecodedName, MILoadError); + UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadAsset(DecodedName, MILoadError); if (MI) { UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: GetMaterial — loaded material instance '%s'"), *MI->GetName()); @@ -362,7 +362,7 @@ void FBlueprintMCPServer::HandleGetMaterialGraph(const FJsonObject* Json, FJsonO FString DecodedName = MCPUtils::UrlDecode(Name); FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(DecodedName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(DecodedName, LoadError); if (!Material) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -412,7 +412,7 @@ void FBlueprintMCPServer::HandleDescribeMaterial(const FJsonObject* Json, FJsonO } FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -624,7 +624,7 @@ void FBlueprintMCPServer::HandleSearchMaterials(const FJsonObject* Json, FJsonOb TArray> Results; - for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UMaterial::StaticClass())) { if (Results.Num() >= MaxResults) break; @@ -706,7 +706,7 @@ void FBlueprintMCPServer::HandleFindMaterialReferences(const FJsonObject* Json, // Try to find the material's package path FString PackagePath; - FAssetData* MatAsset = UMCPAssetFinder::FindMaterialAsset(MaterialName); + FAssetData* MatAsset = UMCPAssetFinder::FindAsset(UMaterial::StaticClass(), MaterialName); if (MatAsset) { PackagePath = MatAsset->PackageName.ToString(); @@ -714,7 +714,7 @@ void FBlueprintMCPServer::HandleFindMaterialReferences(const FJsonObject* Json, else { // Try material instance - FAssetData* MIAsset = UMCPAssetFinder::FindMaterialInstanceAsset(MaterialName); + FAssetData* MIAsset = UMCPAssetFinder::FindAsset(UMaterialInstanceConstant::StaticClass(), MaterialName); if (MIAsset) { PackagePath = MIAsset->PackageName.ToString(); @@ -759,7 +759,7 @@ void FBlueprintMCPServer::HandleListMaterialFunctions(const FJsonObject* Json, F TArray> Entries; - for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialFunctionAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UMaterialFunction::StaticClass())) { FString Name = Asset.AssetName.ToString(); FString Path = Asset.PackageName.ToString(); @@ -780,7 +780,7 @@ void FBlueprintMCPServer::HandleListMaterialFunctions(const FJsonObject* Json, F } Result->SetNumberField(TEXT("count"), Entries.Num()); - Result->SetNumberField(TEXT("total"), UMCPAssetFinder::GetMaterialFunctionAssets().Num()); + Result->SetNumberField(TEXT("total"), UMCPAssetFinder::GetAssets(UMaterialFunction::StaticClass()).Num()); Result->SetArrayField(TEXT("functions"), Entries); } @@ -799,7 +799,7 @@ void FBlueprintMCPServer::HandleGetMaterialFunction(const FJsonObject* Json, FJs FString DecodedName = MCPUtils::UrlDecode(Name); FString LoadError; - UMaterialFunction* MF = UMCPAssetFinder::LoadMaterialFunctionByName(DecodedName, LoadError); + UMaterialFunction* MF = UMCPAssetFinder::LoadAsset(DecodedName, LoadError); if (!MF) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -883,7 +883,7 @@ void FBlueprintMCPServer::HandleValidateMaterial(const FJsonObject* Json, FJsonO // Load material FString LoadError; - UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError); + UMaterial* Material = UMCPAssetFinder::LoadAsset(MaterialName, LoadError); if (!Material) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Mutation.h b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Mutation.h index 7d5dd919..cf66562a 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Mutation.h +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Mutation.h @@ -91,7 +91,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -183,7 +183,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -359,7 +359,7 @@ public: // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -505,7 +505,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -553,7 +553,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -614,7 +614,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -713,7 +713,7 @@ public: // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -965,7 +965,7 @@ public: // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -1093,7 +1093,7 @@ public: // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -1326,7 +1326,7 @@ public: // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -1378,7 +1378,7 @@ public: if (!ResolvedClass) { FString BPLoadError; - UBlueprint* ValueBP = UMCPAssetFinder::LoadBlueprintByName(Value, BPLoadError); + UBlueprint* ValueBP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Value, BPLoadError); if (ValueBP && ValueBP->GeneratedClass) { ResolvedClass = ValueBP->GeneratedClass; @@ -1418,7 +1418,7 @@ public: // Try loading as a Blueprint asset FString ObjLoadError; - UBlueprint* ValueBP = UMCPAssetFinder::LoadBlueprintByName(Value, ObjLoadError); + UBlueprint* ValueBP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Value, ObjLoadError); if (ValueBP && ValueBP->GeneratedClass) { ResolvedObj = ValueBP->GeneratedClass->GetDefaultObject(); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Params.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Params.cpp index 13a5f7ad..6a135ab8 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Params.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Params.cpp @@ -29,7 +29,7 @@ void FBlueprintMCPServer::HandleChangeFunctionParamType(const FJsonObject* Json, // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -247,7 +247,7 @@ void FBlueprintMCPServer::HandleRemoveFunctionParameter(const FJsonObject* Json, // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -408,7 +408,7 @@ void FBlueprintMCPServer::HandleAddFunctionParameter(const FJsonObject* Json, FJ // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_PinMutation.h b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_PinMutation.h index e0146f15..3b2502ce 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_PinMutation.h +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_PinMutation.h @@ -74,7 +74,7 @@ public: EntryResult->SetStringField(TEXT("pinName"), Entry.PinName); FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Entry.Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Entry.Blueprint, LoadError); if (!BP) { EntryResult->SetStringField(TEXT("error"), LoadError); @@ -189,7 +189,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -327,7 +327,7 @@ public: { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Blueprint, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Read.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Read.cpp index e532e970..cf0cbad5 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Read.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Read.cpp @@ -37,7 +37,7 @@ void FBlueprintMCPServer::HandleList(const FJsonObject* Json, FJsonObject* Resul TArray> Entries; if (bIncludeRegular) - for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UBlueprint::StaticClass())) { FString Name = Asset.AssetName.ToString(); FString Path = Asset.PackageName.ToString(); @@ -77,7 +77,7 @@ void FBlueprintMCPServer::HandleList(const FJsonObject* Json, FJsonObject* Resul // Also include level blueprints from maps if (bIncludeLevel) - for (const FAssetData& Asset : UMCPAssetFinder::GetMapAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UWorld::StaticClass())) { FString Name = Asset.AssetName.ToString(); FString Path = Asset.PackageName.ToString(); @@ -109,7 +109,7 @@ void FBlueprintMCPServer::HandleList(const FJsonObject* Json, FJsonObject* Resul } Result->SetNumberField(TEXT("count"), Entries.Num()); - Result->SetNumberField(TEXT("total"), UMCPAssetFinder::GetBlueprintAssets().Num() + UMCPAssetFinder::GetMapAssets().Num()); + Result->SetNumberField(TEXT("total"), UMCPAssetFinder::GetAssets(UBlueprint::StaticClass()).Num() + UMCPAssetFinder::GetAssets(UWorld::StaticClass()).Num()); Result->SetArrayField(TEXT("blueprints"), Entries); } @@ -122,7 +122,7 @@ void FBlueprintMCPServer::HandleGetBlueprint(const FJsonObject* Json, FJsonObjec } FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Name, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Name, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -145,7 +145,7 @@ void FBlueprintMCPServer::HandleGetGraph(const FJsonObject* Json, FJsonObject* R FString DecodedGraphName = MCPUtils::UrlDecode(GraphName); FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Name, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Name, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -257,7 +257,7 @@ void FBlueprintMCPServer::HandleSearch(const FJsonObject* Json, FJsonObject* Res }; TArray> Results; - for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UBlueprint::StaticClass())) { if (Results.Num() >= MaxResults) break; @@ -274,7 +274,7 @@ void FBlueprintMCPServer::HandleSearch(const FJsonObject* Json, FJsonObject* Res } // Also search level blueprints - for (const FAssetData& MapAsset : UMCPAssetFinder::GetMapAssets()) + for (const FAssetData& MapAsset : UMCPAssetFinder::GetAssets(UWorld::StaticClass())) { if (Results.Num() >= MaxResults) break; @@ -318,7 +318,7 @@ void FBlueprintMCPServer::HandleTestSave(const FJsonObject* Json, FJsonObject* R UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: test-save requested for '%s'"), *Name); FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Name, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Name, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -356,7 +356,7 @@ void FBlueprintMCPServer::HandleFindReferences(const FJsonObject* Json, FJsonObj // Build set of known Blueprint package names for filtering TSet BlueprintPackages; - for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UBlueprint::StaticClass())) { BlueprintPackages.Add(Asset.PackageName.ToString()); } @@ -587,7 +587,7 @@ void FBlueprintMCPServer::HandleSearchByType(const FJsonObject* Json, FJsonObjec }; // Search regular blueprints - for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UBlueprint::StaticClass())) { if (Results.Num() >= MaxResults) break; @@ -607,7 +607,7 @@ void FBlueprintMCPServer::HandleSearchByType(const FJsonObject* Json, FJsonObjec } // Search level blueprints from maps - for (const FAssetData& MapAsset : UMCPAssetFinder::GetMapAssets()) + for (const FAssetData& MapAsset : UMCPAssetFinder::GetAssets(UWorld::StaticClass())) { if (Results.Num() >= MaxResults) break; diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Snapshot.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Snapshot.cpp index 9a8a7249..c13448ec 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Snapshot.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Snapshot.cpp @@ -269,7 +269,7 @@ void FBlueprintMCPServer::HandleSnapshotGraph(const FJsonObject* Json, FJsonObje // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -369,7 +369,7 @@ void FBlueprintMCPServer::HandleDiffGraph(const FJsonObject* Json, FJsonObject* // Load the current blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -588,7 +588,7 @@ void FBlueprintMCPServer::HandleRestoreGraph(const FJsonObject* Json, FJsonObjec // Load the current blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -821,7 +821,7 @@ void FBlueprintMCPServer::HandleFindDisconnectedPins(const FJsonObject* Json, FJ } else if (!PathFilter.IsEmpty()) { - for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UBlueprint::StaticClass())) { if (Asset.PackageName.ToString().Contains(PathFilter) || Asset.AssetName.ToString().Contains(PathFilter)) { @@ -845,7 +845,7 @@ void FBlueprintMCPServer::HandleFindDisconnectedPins(const FJsonObject* Json, FJ for (const FString& BPName : BlueprintsToScan) { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BPName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BPName, LoadError); if (!BP) continue; BlueprintsScanned++; @@ -1206,10 +1206,10 @@ void FBlueprintMCPServer::HandleAnalyzeRebuildImpact(const FJsonObject* Json, FJ int32 TotalBreakMakeNodes = 0; int32 TotalConnectionsAtRisk = 0; - for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets()) + for (const FAssetData& Asset : UMCPAssetFinder::GetAssets(UBlueprint::StaticClass())) { FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Asset.AssetName.ToString(), LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(Asset.AssetName.ToString(), LoadError); if (!BP) continue; FBlueprintImpact Impact; diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_UserTypes.h b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_UserTypes.h index ed3f8aae..006e5a34 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_UserTypes.h +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_UserTypes.h @@ -239,7 +239,7 @@ public: { // Find the struct FString StructError; - UUserDefinedStruct* Struct = UMCPAssetFinder::LoadStructByName(AssetPath, StructError); + UUserDefinedStruct* Struct = UMCPAssetFinder::LoadAsset(AssetPath, StructError); if (!Struct) { return MCPUtils::MakeErrorJson(Result, StructError); @@ -312,7 +312,7 @@ public: { // Find the struct FString StructError; - UUserDefinedStruct* Struct = UMCPAssetFinder::LoadStructByName(AssetPath, StructError); + UUserDefinedStruct* Struct = UMCPAssetFinder::LoadAsset(AssetPath, StructError); if (!Struct) { return MCPUtils::MakeErrorJson(Result, StructError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Validation.h b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Validation.h index f922e835..828fd490 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Validation.h +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Validation.h @@ -139,7 +139,7 @@ public: TArray MatchingAssets; if (!Blueprint.IsEmpty()) { - FAssetData* Asset = UMCPAssetFinder::FindBlueprintAsset(Blueprint, nullptr, /*bIncludeLevelBlueprints=*/true); + FAssetData* Asset = UMCPAssetFinder::FindAsset(UMCPAssetFinder::BlueprintsAndMaps, Blueprint); if (!Asset) { return MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("Blueprint '%s' not found."), *Blueprint)); @@ -148,7 +148,7 @@ public: } else { - MatchingAssets = UMCPAssetFinder::SearchBlueprintAssets(Query, /*bIncludeLevelBlueprints=*/true); + MatchingAssets = UMCPAssetFinder::SearchAssets(UMCPAssetFinder::BlueprintsAndMaps, Query); } int32 TotalMatching = MatchingAssets.Num(); @@ -185,7 +185,7 @@ public: // Load the Blueprint (handles both regular and level blueprints) FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(PackagePath, LoadError, /*bIncludeLevelBlueprints=*/true); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(PackagePath, LoadError); if (!BP) { continue; diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Variables.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Variables.cpp index aa649957..fcc351a4 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Variables.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPHandlers_Variables.cpp @@ -35,7 +35,7 @@ void FBlueprintMCPServer::HandleChangeVariableType(const FJsonObject* Json, FJso // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -251,7 +251,7 @@ void FBlueprintMCPServer::HandleAddVariable(const FJsonObject* Json, FJsonObject // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -333,7 +333,7 @@ void FBlueprintMCPServer::HandleRemoveVariable(const FJsonObject* Json, FJsonObj // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); @@ -401,7 +401,7 @@ void FBlueprintMCPServer::HandleSetVariableMetadata(const FJsonObject* Json, FJs // Load Blueprint FString LoadError; - UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError); + UBlueprint* BP = UMCPAssetFinder::LoadBlueprintOrLevelBlueprint(BlueprintName, LoadError); if (!BP) { return MCPUtils::MakeErrorJson(Result, LoadError); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPServer.cpp b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPServer.cpp index 45aae93f..8766b15f 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPServer.cpp +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPServer.cpp @@ -491,6 +491,7 @@ FString FMCPServer::HandleToolsCall(int32 Id, const FJsonObject* Params) void FMCPServer::DispatchToolCall(const FString& ToolName, const FJsonObject* Params, FJsonObject* Result) { + UMCPAssetFinder::Refresh(); if (UClass** HandlerClass = MCPHandlerRegistry.Find(ToolName)) { const bool bIsMutation = MutationEndpoints.Contains(ToolName); diff --git a/Plugins/BlueprintMCP/Source/BlueprintMCP/Public/MCPAssetFinder.h b/Plugins/BlueprintMCP/Source/BlueprintMCP/Public/MCPAssetFinder.h index 93c68614..7b19e507 100644 --- a/Plugins/BlueprintMCP/Source/BlueprintMCP/Public/MCPAssetFinder.h +++ b/Plugins/BlueprintMCP/Source/BlueprintMCP/Public/MCPAssetFinder.h @@ -11,6 +11,7 @@ class UBlueprint; class UMaterial; class UMaterialInstanceConstant; class UMaterialFunction; +class IAssetRegistry; /** * Engine subsystem that caches asset registry data for the BlueprintMCP server. @@ -25,49 +26,66 @@ class UMCPAssetFinder : public UEngineSubsystem public: virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; + + static FName BlueprintsAndMaps; + + // Call once before processing a request. Rebuilds caches if the asset registry has changed. + // After this call, all query methods read from a stable snapshot until the next Refresh(). + static void Refresh(); + // --- Static API: asset lists --- - static const TArray& GetBlueprintAssets(); - static const TArray& GetBlueprintAndMapAssets(); - static const TArray& GetMapAssets(); - static const TArray& GetMaterialAssets(); - static const TArray& GetMaterialInstanceAssets(); - static const TArray& GetMaterialFunctionAssets(); - static const TArray& GetStructAssets(); - static const TArray& GetEnumAssets(); + static const TArray& GetAssets(FName Class); + static const TArray& GetAssets(UClass *Class); // --- Static API: find/load helpers --- - // Find functions return nullptr if not found or if the short name is ambiguous. - // Pass OutError to get a descriptive message on failure. - static FAssetData* FindAnyAsset(const FString& NameOrPath, FString* OutError = nullptr); - static FAssetData* FindBlueprintAsset(const FString& NameOrPath, FString* OutError = nullptr, bool bIncludeLevelBlueprints = false); - static TArray SearchBlueprintAssets(const FString& Filter, bool bIncludeLevelBlueprints = false); - static FAssetData* FindMapAsset(const FString& NameOrPath, FString* OutError = nullptr); - static UBlueprint* LoadBlueprintByName(const FString& NameOrPath, FString& OutError, bool bIncludeLevelBlueprints = true); + static FAssetData* FindAsset(FName Class, const FString& NameOrPath, FString* OutError = nullptr); + static FAssetData* FindAsset(UClass *Class, const FString& NameOrPath, FString* OutError = nullptr); - static FAssetData* FindMaterialAsset(const FString& NameOrPath, FString* OutError = nullptr); - static UMaterial* LoadMaterialByName(const FString& NameOrPath, FString& OutError); - static FAssetData* FindMaterialInstanceAsset(const FString& NameOrPath, FString* OutError = nullptr); - static UMaterialInstanceConstant* LoadMaterialInstanceByName(const FString& NameOrPath, FString& OutError); - static FAssetData* FindMaterialFunctionAsset(const FString& NameOrPath, FString* OutError = nullptr); - static UMaterialFunction* LoadMaterialFunctionByName(const FString& NameOrPath, FString& OutError); - static FAssetData* FindStructAsset(const FString& NameOrPath, FString* OutError = nullptr); - static UUserDefinedStruct* LoadStructByName(const FString& NameOrPath, FString& OutError); - static FAssetData* FindEnumAsset(const FString& NameOrPath, FString* OutError = nullptr); - static UUserDefinedEnum* LoadEnumByName(const FString& NameOrPath, FString& OutError); + // --- Static API: find/load helpers --- + static TArray SearchAssets(FName Class, const FString& NameOrPath, FString* OutError = nullptr); + static TArray SearchAssets(UClass *Class, const FString& NameOrPath, FString* OutError = nullptr); + + // Load an asset from an FAssetData. Returns nullptr and sets OutError on failure. + template + static T* LoadAsset(FAssetData& Asset, FString& OutError) + { + T* Result = Cast(Asset.GetAsset()); + if (!Result) + OutError = FString::Printf(TEXT("Asset '%s' found but could not be loaded as %s."), + *Asset.AssetName.ToString(), *T::StaticClass()->GetName()); + return Result; + } + + // Load an asset by name or path. Returns nullptr and sets OutError on failure. + template + static T* LoadAsset(const FString& NameOrPath, FString& OutError) + { + FAssetData* Asset = FindAsset(T::StaticClass(), NameOrPath, &OutError); + if (!Asset) + { + if (OutError.IsEmpty()) + OutError = FString::Printf(TEXT("'%s' not found."), *NameOrPath); + return nullptr; + } + return LoadAsset(*Asset, OutError); + } + + static FAssetData* FindAnyAsset(const FString& NameOrPath, FString* OutError = nullptr); + + // Load a blueprint or level blueprint from an asset (handles UWorld → level blueprint extraction). + static UBlueprint* LoadBlueprintOrLevelBlueprint(FAssetData& Asset, FString& OutError); + static UBlueprint* LoadBlueprintOrLevelBlueprint(const FString& NameOrPath, FString& OutError); private: - /** Get the subsystem, refreshing asset caches if stale. Returns nullptr if engine is not initialized. */ - static UMCPAssetFinder* GetUpdatedAssets(); + // Fetch assets from the Unreal asset registry and store them locally. + void CacheAssets(IAssetRegistry &Registry, UClass *Class, bool IncludeSubclasses); - // Cached asset lists - TArray AllBlueprintAssets; - TArray AllMapAssets; - TArray AllBlueprintAndMapAssets; - TArray AllMaterialAssets; - TArray AllMaterialInstanceAssets; - TArray AllMaterialFunctionAssets; - TArray AllStructAssets; - TArray AllEnumAssets; + // Returns the subsystem instance, or nullptr if the engine is not initialized. + static UMCPAssetFinder* Get(); + + // All cached asset lists, keyed by UClass::GetName() (e.g. "Blueprint", "World", "Material"). + // The special key "BlueprintsAndMaps" combines Blueprint and World assets. + TMap> AssetCache; // Change detection — set true by asset registry delegates bool bDirty = true;