More MCP refactors, including creation of MCPAssetFinder.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -58,7 +59,7 @@ void FBlueprintMCPServer::HandleCreateAnimBlueprint(const FJsonObject* Json, FJs
|
|||||||
|
|
||||||
// Check if asset already exists
|
// Check if asset already exists
|
||||||
FString FullAssetPath = PackagePath / Name;
|
FString FullAssetPath = PackagePath / Name;
|
||||||
if (FindBlueprintAsset(Name) || FindBlueprintAsset(FullAssetPath))
|
if (UMCPAssetFinder::FindBlueprintAsset(Name) || UMCPAssetFinder::FindBlueprintAsset(FullAssetPath))
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
||||||
TEXT("Blueprint '%s' already exists. Use a different name or delete the existing asset first."),
|
TEXT("Blueprint '%s' already exists. Use a different name or delete the existing asset first."),
|
||||||
@@ -170,10 +171,6 @@ void FBlueprintMCPServer::HandleCreateAnimBlueprint(const FJsonObject* Json, FJs
|
|||||||
// Save
|
// Save
|
||||||
bool bSaved = MCPUtils::SaveBlueprintPackage(NewAnimBP);
|
bool bSaved = MCPUtils::SaveBlueprintPackage(NewAnimBP);
|
||||||
|
|
||||||
// Refresh asset cache
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
AllBlueprintAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), AllBlueprintAssets, true);
|
|
||||||
|
|
||||||
// Collect graph names
|
// Collect graph names
|
||||||
TArray<TSharedPtr<FJsonValue>> GraphNames;
|
TArray<TSharedPtr<FJsonValue>> GraphNames;
|
||||||
@@ -217,7 +214,7 @@ void FBlueprintMCPServer::HandleAddAnimState(const FJsonObject* Json, FJsonObjec
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -319,7 +316,7 @@ void FBlueprintMCPServer::HandleRemoveAnimState(const FJsonObject* Json, FJsonOb
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -390,7 +387,7 @@ void FBlueprintMCPServer::HandleAddAnimTransition(const FJsonObject* Json, FJson
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -477,7 +474,7 @@ void FBlueprintMCPServer::HandleSetTransitionRule(const FJsonObject* Json, FJson
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -569,7 +566,7 @@ void FBlueprintMCPServer::HandleAddAnimNode(const FJsonObject* Json, FJsonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -765,7 +762,7 @@ void FBlueprintMCPServer::HandleSetStateAnimation(const FJsonObject* Json, FJson
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -858,7 +855,7 @@ void FBlueprintMCPServer::HandleListAnimSlots(const FJsonObject* Json, FJsonObje
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -917,7 +914,7 @@ void FBlueprintMCPServer::HandleListSyncGroups(const FJsonObject* Json, FJsonObj
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1264,7 +1261,7 @@ void FBlueprintMCPServer::HandleSetStateBlendSpace(const FJsonObject* Json, FJso
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -23,7 +24,7 @@ void FBlueprintMCPServer::HandleListComponents(const FJsonObject* Json, FJsonObj
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -117,7 +118,7 @@ void FBlueprintMCPServer::HandleAddComponent(const FJsonObject* Json, FJsonObjec
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -270,7 +271,7 @@ void FBlueprintMCPServer::HandleRemoveComponent(const FJsonObject* Json, FJsonOb
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "BlueprintMCPHandlers_DiffBlueprints.h"
|
#include "BlueprintMCPHandlers_DiffBlueprints.h"
|
||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -8,14 +9,13 @@
|
|||||||
|
|
||||||
void UMCPHandler_DiffTwoBlueprints::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_DiffTwoBlueprints::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
// Load both blueprints
|
// Load both blueprints
|
||||||
FString LoadErrorA, LoadErrorB;
|
FString LoadErrorA, LoadErrorB;
|
||||||
UBlueprint* BPA = Helper->LoadBlueprintByName(BlueprintA, LoadErrorA);
|
UBlueprint* BPA = UMCPAssetFinder::LoadBlueprintByName(BlueprintA, LoadErrorA);
|
||||||
if (!BPA) { MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("blueprintA: %s"), *LoadErrorA)); return; }
|
if (!BPA) { MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("blueprintA: %s"), *LoadErrorA)); return; }
|
||||||
|
|
||||||
UBlueprint* BPB = Helper->LoadBlueprintByName(BlueprintB, LoadErrorB);
|
UBlueprint* BPB = UMCPAssetFinder::LoadBlueprintByName(BlueprintB, LoadErrorB);
|
||||||
if (!BPB) { MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("blueprintB: %s"), *LoadErrorB)); return; }
|
if (!BPB) { MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("blueprintB: %s"), *LoadErrorB)); return; }
|
||||||
|
|
||||||
// Helper to gather graphs from a Blueprint
|
// Helper to gather graphs from a Blueprint
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -28,7 +29,7 @@ void FBlueprintMCPServer::HandleGetPinInfo(const FJsonObject* Json, FJsonObject*
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -133,7 +134,7 @@ void FBlueprintMCPServer::HandleCheckPinCompatibility(const FJsonObject* Json, F
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -27,7 +28,7 @@ void FBlueprintMCPServer::HandleAddEventDispatcher(const FJsonObject* Json, FJso
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -172,7 +173,7 @@ void FBlueprintMCPServer::HandleListEventDispatchers(const FJsonObject* Json, FJ
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -32,7 +33,7 @@ void FBlueprintMCPServer::HandleReparentBlueprint(const FJsonObject* Json, FJson
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -58,7 +59,7 @@ void FBlueprintMCPServer::HandleReparentBlueprint(const FJsonObject* Json, FJson
|
|||||||
if (!NewParentClass)
|
if (!NewParentClass)
|
||||||
{
|
{
|
||||||
FString ParentLoadError;
|
FString ParentLoadError;
|
||||||
UBlueprint* ParentBP = LoadBlueprintByName(NewParentName, ParentLoadError);
|
UBlueprint* ParentBP = UMCPAssetFinder::LoadBlueprintByName(NewParentName, ParentLoadError);
|
||||||
if (ParentBP && ParentBP->GeneratedClass)
|
if (ParentBP && ParentBP->GeneratedClass)
|
||||||
{
|
{
|
||||||
NewParentClass = ParentBP->GeneratedClass;
|
NewParentClass = ParentBP->GeneratedClass;
|
||||||
@@ -133,7 +134,7 @@ void FBlueprintMCPServer::HandleCreateBlueprint(const FJsonObject* Json, FJsonOb
|
|||||||
|
|
||||||
// Check if asset already exists
|
// Check if asset already exists
|
||||||
FString FullAssetPath = PackagePath / BlueprintName;
|
FString FullAssetPath = PackagePath / BlueprintName;
|
||||||
if (FindBlueprintAsset(BlueprintName) || FindBlueprintAsset(FullAssetPath))
|
if (UMCPAssetFinder::FindBlueprintAsset(BlueprintName) || UMCPAssetFinder::FindBlueprintAsset(FullAssetPath))
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
||||||
TEXT("Blueprint '%s' already exists. Use a different name or delete the existing asset first."),
|
TEXT("Blueprint '%s' already exists. Use a different name or delete the existing asset first."),
|
||||||
@@ -155,7 +156,7 @@ void FBlueprintMCPServer::HandleCreateBlueprint(const FJsonObject* Json, FJsonOb
|
|||||||
if (!ParentClass)
|
if (!ParentClass)
|
||||||
{
|
{
|
||||||
FString ParentLoadError;
|
FString ParentLoadError;
|
||||||
UBlueprint* ParentBP = LoadBlueprintByName(ParentClassName, ParentLoadError);
|
UBlueprint* ParentBP = UMCPAssetFinder::LoadBlueprintByName(ParentClassName, ParentLoadError);
|
||||||
if (ParentBP && ParentBP->GeneratedClass)
|
if (ParentBP && ParentBP->GeneratedClass)
|
||||||
{
|
{
|
||||||
ParentClass = ParentBP->GeneratedClass;
|
ParentClass = ParentBP->GeneratedClass;
|
||||||
@@ -232,10 +233,6 @@ void FBlueprintMCPServer::HandleCreateBlueprint(const FJsonObject* Json, FJsonOb
|
|||||||
// Save
|
// Save
|
||||||
bool bSaved = MCPUtils::SaveBlueprintPackage(NewBP);
|
bool bSaved = MCPUtils::SaveBlueprintPackage(NewBP);
|
||||||
|
|
||||||
// Refresh asset cache
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
AllBlueprintAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), AllBlueprintAssets, true);
|
|
||||||
|
|
||||||
// Collect graph names
|
// Collect graph names
|
||||||
TArray<TSharedPtr<FJsonValue>> GraphNames;
|
TArray<TSharedPtr<FJsonValue>> GraphNames;
|
||||||
@@ -288,7 +285,7 @@ void FBlueprintMCPServer::HandleCreateGraph(const FJsonObject* Json, FJsonObject
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -407,7 +404,7 @@ void FBlueprintMCPServer::HandleDeleteGraph(const FJsonObject* Json, FJsonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -493,7 +490,7 @@ void FBlueprintMCPServer::HandleRenameGraph(const FJsonObject* Json, FJsonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "BlueprintMCPHandlers_Interfaces.h"
|
#include "BlueprintMCPHandlers_Interfaces.h"
|
||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -12,10 +13,9 @@
|
|||||||
|
|
||||||
void UMCPHandler_ListBlueprintInterfaces::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_ListBlueprintInterfaces::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -57,10 +57,9 @@ void UMCPHandler_ListBlueprintInterfaces::Handle(const FJsonObject* Json, FJsonO
|
|||||||
|
|
||||||
void UMCPHandler_AddBlueprintInterface::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_AddBlueprintInterface::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -101,7 +100,7 @@ void UMCPHandler_AddBlueprintInterface::Handle(const FJsonObject* Json, FJsonObj
|
|||||||
if (!InterfaceClass)
|
if (!InterfaceClass)
|
||||||
{
|
{
|
||||||
FString IfaceLoadError;
|
FString IfaceLoadError;
|
||||||
UBlueprint* IfaceBP = Helper->LoadBlueprintByName(InterfaceName, IfaceLoadError);
|
UBlueprint* IfaceBP = UMCPAssetFinder::LoadBlueprintByName(InterfaceName, IfaceLoadError);
|
||||||
if (IfaceBP && IfaceBP->GeneratedClass && IfaceBP->GeneratedClass->IsChildOf(UInterface::StaticClass()))
|
if (IfaceBP && IfaceBP->GeneratedClass && IfaceBP->GeneratedClass->IsChildOf(UInterface::StaticClass()))
|
||||||
{
|
{
|
||||||
InterfaceClass = IfaceBP->GeneratedClass;
|
InterfaceClass = IfaceBP->GeneratedClass;
|
||||||
@@ -181,10 +180,9 @@ void UMCPHandler_AddBlueprintInterface::Handle(const FJsonObject* Json, FJsonObj
|
|||||||
|
|
||||||
void UMCPHandler_RemoveBlueprintInterface::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_RemoveBlueprintInterface::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
@@ -40,7 +41,7 @@ void FBlueprintMCPServer::HandleCreateMaterialInstance(const FJsonObject* Json,
|
|||||||
|
|
||||||
// Check if asset already exists
|
// Check if asset already exists
|
||||||
FString FullAssetPath = PackagePath / Name;
|
FString FullAssetPath = PackagePath / Name;
|
||||||
if (FindMaterialInstanceAsset(Name) || FindMaterialInstanceAsset(FullAssetPath))
|
if (UMCPAssetFinder::FindMaterialInstanceAsset(Name) || UMCPAssetFinder::FindMaterialInstanceAsset(FullAssetPath))
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
||||||
TEXT("Material Instance '%s' already exists. Use a different name or delete the existing asset first."),
|
TEXT("Material Instance '%s' already exists. Use a different name or delete the existing asset first."),
|
||||||
@@ -51,7 +52,7 @@ void FBlueprintMCPServer::HandleCreateMaterialInstance(const FJsonObject* Json,
|
|||||||
UMaterialInterface* ParentMaterial = nullptr;
|
UMaterialInterface* ParentMaterial = nullptr;
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* ParentMat = LoadMaterialByName(ParentMaterialName, LoadError);
|
UMaterial* ParentMat = UMCPAssetFinder::LoadMaterialByName(ParentMaterialName, LoadError);
|
||||||
if (ParentMat)
|
if (ParentMat)
|
||||||
{
|
{
|
||||||
ParentMaterial = ParentMat;
|
ParentMaterial = ParentMat;
|
||||||
@@ -59,7 +60,7 @@ void FBlueprintMCPServer::HandleCreateMaterialInstance(const FJsonObject* Json,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString MILoadError;
|
FString MILoadError;
|
||||||
UMaterialInstanceConstant* ParentMI = LoadMaterialInstanceByName(ParentMaterialName, MILoadError);
|
UMaterialInstanceConstant* ParentMI = UMCPAssetFinder::LoadMaterialInstanceByName(ParentMaterialName, MILoadError);
|
||||||
if (ParentMI)
|
if (ParentMI)
|
||||||
{
|
{
|
||||||
ParentMaterial = ParentMI;
|
ParentMaterial = ParentMI;
|
||||||
@@ -107,10 +108,6 @@ void FBlueprintMCPServer::HandleCreateMaterialInstance(const FJsonObject* Json,
|
|||||||
// Save
|
// Save
|
||||||
bool bSaved = MCPUtils::SaveGenericPackage(MI);
|
bool bSaved = MCPUtils::SaveGenericPackage(MI);
|
||||||
|
|
||||||
// Refresh asset cache
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
AllMaterialInstanceAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialInstanceConstant::StaticClass()->GetClassPathName(), AllMaterialInstanceAssets, false);
|
|
||||||
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Created Material Instance '%s' with parent '%s' (saved: %s)"),
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Created Material Instance '%s' with parent '%s' (saved: %s)"),
|
||||||
*Name, *ParentMaterial->GetName(), bSaved ? TEXT("true") : TEXT("false"));
|
*Name, *ParentMaterial->GetName(), bSaved ? TEXT("true") : TEXT("false"));
|
||||||
@@ -149,7 +146,7 @@ void FBlueprintMCPServer::HandleSetMaterialInstanceParameter(const FJsonObject*
|
|||||||
|
|
||||||
// Load the Material Instance
|
// Load the Material Instance
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterialInstanceConstant* MI = LoadMaterialInstanceByName(MIName, LoadError);
|
UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(MIName, LoadError);
|
||||||
if (!MI)
|
if (!MI)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -370,7 +367,7 @@ void FBlueprintMCPServer::HandleGetMaterialInstanceParameters(const FJsonObject*
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterialInstanceConstant* MI = LoadMaterialInstanceByName(NameParam, LoadError);
|
UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(NameParam, LoadError);
|
||||||
if (!MI)
|
if (!MI)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -618,7 +615,7 @@ void FBlueprintMCPServer::HandleReparentMaterialInstance(const FJsonObject* Json
|
|||||||
|
|
||||||
// Load the Material Instance
|
// Load the Material Instance
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterialInstanceConstant* MI = LoadMaterialInstanceByName(MIName, LoadError);
|
UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(MIName, LoadError);
|
||||||
if (!MI)
|
if (!MI)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -631,7 +628,7 @@ void FBlueprintMCPServer::HandleReparentMaterialInstance(const FJsonObject* Json
|
|||||||
UMaterialInterface* NewParent = nullptr;
|
UMaterialInterface* NewParent = nullptr;
|
||||||
{
|
{
|
||||||
FString MatLoadError;
|
FString MatLoadError;
|
||||||
UMaterial* NewParentMat = LoadMaterialByName(NewParentName, MatLoadError);
|
UMaterial* NewParentMat = UMCPAssetFinder::LoadMaterialByName(NewParentName, MatLoadError);
|
||||||
if (NewParentMat)
|
if (NewParentMat)
|
||||||
{
|
{
|
||||||
NewParent = NewParentMat;
|
NewParent = NewParentMat;
|
||||||
@@ -639,7 +636,7 @@ void FBlueprintMCPServer::HandleReparentMaterialInstance(const FJsonObject* Json
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString MILoadError;
|
FString MILoadError;
|
||||||
UMaterialInstanceConstant* NewParentMI = LoadMaterialInstanceByName(NewParentName, MILoadError);
|
UMaterialInstanceConstant* NewParentMI = UMCPAssetFinder::LoadMaterialInstanceByName(NewParentName, MILoadError);
|
||||||
if (NewParentMI)
|
if (NewParentMI)
|
||||||
{
|
{
|
||||||
NewParent = NewParentMI;
|
NewParent = NewParentMI;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
@@ -74,7 +75,7 @@ void FBlueprintMCPServer::HandleCreateMaterial(const FJsonObject* Json, FJsonObj
|
|||||||
|
|
||||||
// Check if asset already exists
|
// Check if asset already exists
|
||||||
FString FullAssetPath = PackagePath / Name;
|
FString FullAssetPath = PackagePath / Name;
|
||||||
if (FindMaterialAsset(Name) || FindMaterialAsset(FullAssetPath))
|
if (UMCPAssetFinder::FindMaterialAsset(Name) || UMCPAssetFinder::FindMaterialAsset(FullAssetPath))
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
||||||
TEXT("Material '%s' already exists. Use a different name or delete the existing asset first."),
|
TEXT("Material '%s' already exists. Use a different name or delete the existing asset first."),
|
||||||
@@ -153,10 +154,6 @@ void FBlueprintMCPServer::HandleCreateMaterial(const FJsonObject* Json, FJsonObj
|
|||||||
// Save
|
// Save
|
||||||
bool bSaved = MCPUtils::SaveMaterialPackage(Material);
|
bool bSaved = MCPUtils::SaveMaterialPackage(Material);
|
||||||
|
|
||||||
// Refresh asset cache
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
AllMaterialAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterial::StaticClass()->GetClassPathName(), AllMaterialAssets, false);
|
|
||||||
|
|
||||||
// Map domain back to string for response
|
// Map domain back to string for response
|
||||||
auto DomainToString = [](EMaterialDomain Domain) -> FString
|
auto DomainToString = [](EMaterialDomain Domain) -> FString
|
||||||
@@ -222,7 +219,7 @@ void FBlueprintMCPServer::HandleSetMaterialProperty(const FJsonObject* Json, FJs
|
|||||||
|
|
||||||
// Load material
|
// Load material
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(MaterialName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material)
|
if (!Material)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -566,7 +563,7 @@ void FBlueprintMCPServer::HandleAddMaterialExpression(const FJsonObject* Json, F
|
|||||||
return MCPUtils::MakeErrorJson(Result, TEXT("Specify either 'material' or 'materialFunction', not both"));
|
return MCPUtils::MakeErrorJson(Result, TEXT("Specify either 'material' or 'materialFunction', not both"));
|
||||||
}
|
}
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
MatFunc = LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
||||||
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
Owner = MatFunc;
|
Owner = MatFunc;
|
||||||
AssetDisplayName = MatFunc->GetName();
|
AssetDisplayName = MatFunc->GetName();
|
||||||
@@ -574,7 +571,7 @@ void FBlueprintMCPServer::HandleAddMaterialExpression(const FJsonObject* Json, F
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
Material = LoadMaterialByName(MaterialName, LoadError);
|
Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
Owner = Material;
|
Owner = Material;
|
||||||
AssetDisplayName = Material->GetName();
|
AssetDisplayName = Material->GetName();
|
||||||
@@ -704,14 +701,14 @@ void FBlueprintMCPServer::HandleDeleteMaterialExpression(const FJsonObject* Json
|
|||||||
if (!MaterialFunctionName.IsEmpty())
|
if (!MaterialFunctionName.IsEmpty())
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
MatFunc = LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
||||||
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = MatFunc->GetName();
|
AssetDisplayName = MatFunc->GetName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
Material = LoadMaterialByName(MaterialName, LoadError);
|
Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = Material->GetName();
|
AssetDisplayName = Material->GetName();
|
||||||
}
|
}
|
||||||
@@ -831,14 +828,14 @@ void FBlueprintMCPServer::HandleConnectMaterialPins(const FJsonObject* Json, FJs
|
|||||||
if (!MaterialFunctionName.IsEmpty())
|
if (!MaterialFunctionName.IsEmpty())
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
MatFunc = LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
||||||
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = MatFunc->GetName();
|
AssetDisplayName = MatFunc->GetName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
Material = LoadMaterialByName(MaterialName, LoadError);
|
Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = Material->GetName();
|
AssetDisplayName = Material->GetName();
|
||||||
}
|
}
|
||||||
@@ -982,14 +979,14 @@ void FBlueprintMCPServer::HandleDisconnectMaterialPin(const FJsonObject* Json, F
|
|||||||
if (!MaterialFunctionName.IsEmpty())
|
if (!MaterialFunctionName.IsEmpty())
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
MatFunc = LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
||||||
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = MatFunc->GetName();
|
AssetDisplayName = MatFunc->GetName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
Material = LoadMaterialByName(MaterialName, LoadError);
|
Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = Material->GetName();
|
AssetDisplayName = Material->GetName();
|
||||||
}
|
}
|
||||||
@@ -1104,14 +1101,14 @@ void FBlueprintMCPServer::HandleSetExpressionValue(const FJsonObject* Json, FJso
|
|||||||
if (!MaterialFunctionName.IsEmpty())
|
if (!MaterialFunctionName.IsEmpty())
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
MatFunc = LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
||||||
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = MatFunc->GetName();
|
AssetDisplayName = MatFunc->GetName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
Material = LoadMaterialByName(MaterialName, LoadError);
|
Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = Material->GetName();
|
AssetDisplayName = Material->GetName();
|
||||||
}
|
}
|
||||||
@@ -1381,14 +1378,14 @@ void FBlueprintMCPServer::HandleMoveMaterialExpression(const FJsonObject* Json,
|
|||||||
if (!MaterialFunctionName.IsEmpty())
|
if (!MaterialFunctionName.IsEmpty())
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
MatFunc = LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
MatFunc = UMCPAssetFinder::LoadMaterialFunctionByName(MaterialFunctionName, LoadError);
|
||||||
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!MatFunc) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = MatFunc->GetName();
|
AssetDisplayName = MatFunc->GetName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
Material = LoadMaterialByName(MaterialName, LoadError);
|
Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
if (!Material) { MCPUtils::MakeErrorJson(Result, LoadError); return; }
|
||||||
AssetDisplayName = Material->GetName();
|
AssetDisplayName = Material->GetName();
|
||||||
}
|
}
|
||||||
@@ -1485,7 +1482,7 @@ void FBlueprintMCPServer::HandleCreateMaterialFunction(const FJsonObject* Json,
|
|||||||
|
|
||||||
// Check if asset already exists
|
// Check if asset already exists
|
||||||
FString FullAssetPath = PackagePath / Name;
|
FString FullAssetPath = PackagePath / Name;
|
||||||
if (FindMaterialFunctionAsset(Name) || FindMaterialFunctionAsset(FullAssetPath))
|
if (UMCPAssetFinder::FindMaterialFunctionAsset(Name) || UMCPAssetFinder::FindMaterialFunctionAsset(FullAssetPath))
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
return MCPUtils::MakeErrorJson(Result, FString::Printf(
|
||||||
TEXT("Material Function '%s' already exists. Use a different name or delete the existing asset first."),
|
TEXT("Material Function '%s' already exists. Use a different name or delete the existing asset first."),
|
||||||
@@ -1522,10 +1519,6 @@ void FBlueprintMCPServer::HandleCreateMaterialFunction(const FJsonObject* Json,
|
|||||||
// Save
|
// Save
|
||||||
bool bSaved = MCPUtils::SaveGenericPackage(MF);
|
bool bSaved = MCPUtils::SaveGenericPackage(MF);
|
||||||
|
|
||||||
// Refresh asset cache
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
AllMaterialFunctionAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialFunction::StaticClass()->GetClassPathName(), AllMaterialFunctionAssets, false);
|
|
||||||
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Created Material Function '%s' (saved: %s)"),
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Created Material Function '%s' (saved: %s)"),
|
||||||
*Name, bSaved ? TEXT("true") : TEXT("false"));
|
*Name, bSaved ? TEXT("true") : TEXT("false"));
|
||||||
@@ -1558,7 +1551,7 @@ void FBlueprintMCPServer::HandleSnapshotMaterialGraph(const FJsonObject* Json, F
|
|||||||
|
|
||||||
// Load material
|
// Load material
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(MaterialName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material)
|
if (!Material)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1657,7 +1650,7 @@ void FBlueprintMCPServer::HandleDiffMaterialGraph(const FJsonObject* Json, FJson
|
|||||||
|
|
||||||
// Load material
|
// Load material
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(MaterialName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material)
|
if (!Material)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1823,7 +1816,7 @@ void FBlueprintMCPServer::HandleRestoreMaterialGraph(const FJsonObject* Json, FJ
|
|||||||
|
|
||||||
// Load material
|
// Load material
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(MaterialName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material)
|
if (!Material)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
@@ -47,7 +48,7 @@ void FBlueprintMCPServer::HandleListMaterials(const FJsonObject* Json, FJsonObje
|
|||||||
|
|
||||||
if (bIncludeMaterials)
|
if (bIncludeMaterials)
|
||||||
{
|
{
|
||||||
for (const FAssetData& Asset : AllMaterialAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialAssets())
|
||||||
{
|
{
|
||||||
FString Name = Asset.AssetName.ToString();
|
FString Name = Asset.AssetName.ToString();
|
||||||
FString Path = Asset.PackageName.ToString();
|
FString Path = Asset.PackageName.ToString();
|
||||||
@@ -71,7 +72,7 @@ void FBlueprintMCPServer::HandleListMaterials(const FJsonObject* Json, FJsonObje
|
|||||||
|
|
||||||
if (bIncludeInstances)
|
if (bIncludeInstances)
|
||||||
{
|
{
|
||||||
for (const FAssetData& Asset : AllMaterialInstanceAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialInstanceAssets())
|
||||||
{
|
{
|
||||||
FString Name = Asset.AssetName.ToString();
|
FString Name = Asset.AssetName.ToString();
|
||||||
FString Path = Asset.PackageName.ToString();
|
FString Path = Asset.PackageName.ToString();
|
||||||
@@ -93,7 +94,7 @@ void FBlueprintMCPServer::HandleListMaterials(const FJsonObject* Json, FJsonObje
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 Total = AllMaterialAssets.Num() + AllMaterialInstanceAssets.Num();
|
int32 Total = UMCPAssetFinder::GetMaterialAssets().Num() + UMCPAssetFinder::GetMaterialInstanceAssets().Num();
|
||||||
|
|
||||||
Result->SetNumberField(TEXT("count"), Entries.Num());
|
Result->SetNumberField(TEXT("count"), Entries.Num());
|
||||||
Result->SetNumberField(TEXT("total"), Total);
|
Result->SetNumberField(TEXT("total"), Total);
|
||||||
@@ -116,7 +117,7 @@ void FBlueprintMCPServer::HandleGetMaterial(const FJsonObject* Json, FJsonObject
|
|||||||
|
|
||||||
// Try loading as UMaterial first
|
// Try loading as UMaterial first
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(DecodedName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(DecodedName, LoadError);
|
||||||
if (Material)
|
if (Material)
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: GetMaterial — loaded material '%s'"), *Material->GetName());
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: GetMaterial — loaded material '%s'"), *Material->GetName());
|
||||||
@@ -271,7 +272,7 @@ void FBlueprintMCPServer::HandleGetMaterial(const FJsonObject* Json, FJsonObject
|
|||||||
|
|
||||||
// Try loading as MaterialInstance
|
// Try loading as MaterialInstance
|
||||||
FString MILoadError;
|
FString MILoadError;
|
||||||
UMaterialInstanceConstant* MI = LoadMaterialInstanceByName(DecodedName, MILoadError);
|
UMaterialInstanceConstant* MI = UMCPAssetFinder::LoadMaterialInstanceByName(DecodedName, MILoadError);
|
||||||
if (MI)
|
if (MI)
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: GetMaterial — loaded material instance '%s'"), *MI->GetName());
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: GetMaterial — loaded material instance '%s'"), *MI->GetName());
|
||||||
@@ -361,7 +362,7 @@ void FBlueprintMCPServer::HandleGetMaterialGraph(const FJsonObject* Json, FJsonO
|
|||||||
FString DecodedName = MCPUtils::UrlDecode(Name);
|
FString DecodedName = MCPUtils::UrlDecode(Name);
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(DecodedName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(DecodedName, LoadError);
|
||||||
if (!Material)
|
if (!Material)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -411,7 +412,7 @@ void FBlueprintMCPServer::HandleDescribeMaterial(const FJsonObject* Json, FJsonO
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(MaterialName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material)
|
if (!Material)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -623,7 +624,7 @@ void FBlueprintMCPServer::HandleSearchMaterials(const FJsonObject* Json, FJsonOb
|
|||||||
|
|
||||||
TArray<TSharedPtr<FJsonValue>> Results;
|
TArray<TSharedPtr<FJsonValue>> Results;
|
||||||
|
|
||||||
for (const FAssetData& Asset : AllMaterialAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialAssets())
|
||||||
{
|
{
|
||||||
if (Results.Num() >= MaxResults) break;
|
if (Results.Num() >= MaxResults) break;
|
||||||
|
|
||||||
@@ -705,7 +706,7 @@ void FBlueprintMCPServer::HandleFindMaterialReferences(const FJsonObject* Json,
|
|||||||
|
|
||||||
// Try to find the material's package path
|
// Try to find the material's package path
|
||||||
FString PackagePath;
|
FString PackagePath;
|
||||||
FAssetData* MatAsset = FindMaterialAsset(MaterialName);
|
FAssetData* MatAsset = UMCPAssetFinder::FindMaterialAsset(MaterialName);
|
||||||
if (MatAsset)
|
if (MatAsset)
|
||||||
{
|
{
|
||||||
PackagePath = MatAsset->PackageName.ToString();
|
PackagePath = MatAsset->PackageName.ToString();
|
||||||
@@ -713,7 +714,7 @@ void FBlueprintMCPServer::HandleFindMaterialReferences(const FJsonObject* Json,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Try material instance
|
// Try material instance
|
||||||
FAssetData* MIAsset = FindMaterialInstanceAsset(MaterialName);
|
FAssetData* MIAsset = UMCPAssetFinder::FindMaterialInstanceAsset(MaterialName);
|
||||||
if (MIAsset)
|
if (MIAsset)
|
||||||
{
|
{
|
||||||
PackagePath = MIAsset->PackageName.ToString();
|
PackagePath = MIAsset->PackageName.ToString();
|
||||||
@@ -758,7 +759,7 @@ void FBlueprintMCPServer::HandleListMaterialFunctions(const FJsonObject* Json, F
|
|||||||
|
|
||||||
TArray<TSharedPtr<FJsonValue>> Entries;
|
TArray<TSharedPtr<FJsonValue>> Entries;
|
||||||
|
|
||||||
for (const FAssetData& Asset : AllMaterialFunctionAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetMaterialFunctionAssets())
|
||||||
{
|
{
|
||||||
FString Name = Asset.AssetName.ToString();
|
FString Name = Asset.AssetName.ToString();
|
||||||
FString Path = Asset.PackageName.ToString();
|
FString Path = Asset.PackageName.ToString();
|
||||||
@@ -779,7 +780,7 @@ void FBlueprintMCPServer::HandleListMaterialFunctions(const FJsonObject* Json, F
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result->SetNumberField(TEXT("count"), Entries.Num());
|
Result->SetNumberField(TEXT("count"), Entries.Num());
|
||||||
Result->SetNumberField(TEXT("total"), AllMaterialFunctionAssets.Num());
|
Result->SetNumberField(TEXT("total"), UMCPAssetFinder::GetMaterialFunctionAssets().Num());
|
||||||
Result->SetArrayField(TEXT("functions"), Entries);
|
Result->SetArrayField(TEXT("functions"), Entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,7 +799,7 @@ void FBlueprintMCPServer::HandleGetMaterialFunction(const FJsonObject* Json, FJs
|
|||||||
FString DecodedName = MCPUtils::UrlDecode(Name);
|
FString DecodedName = MCPUtils::UrlDecode(Name);
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterialFunction* MF = LoadMaterialFunctionByName(DecodedName, LoadError);
|
UMaterialFunction* MF = UMCPAssetFinder::LoadMaterialFunctionByName(DecodedName, LoadError);
|
||||||
if (!MF)
|
if (!MF)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -882,7 +883,7 @@ void FBlueprintMCPServer::HandleValidateMaterial(const FJsonObject* Json, FJsonO
|
|||||||
|
|
||||||
// Load material
|
// Load material
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UMaterial* Material = LoadMaterialByName(MaterialName, LoadError);
|
UMaterial* Material = UMCPAssetFinder::LoadMaterialByName(MaterialName, LoadError);
|
||||||
if (!Material)
|
if (!Material)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "BlueprintMCPHandlers_Mutation.h"
|
#include "BlueprintMCPHandlers_Mutation.h"
|
||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -52,11 +53,10 @@
|
|||||||
|
|
||||||
void UMCPHandler_ReplaceFunctionCallsInBlueprint::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_ReplaceFunctionCallsInBlueprint::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -289,7 +289,6 @@ void UMCPHandler_ReplaceFunctionCallsInBlueprint::Handle(const FJsonObject* Json
|
|||||||
|
|
||||||
void UMCPHandler_DeleteAsset::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_DeleteAsset::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
// Check if asset file exists on disk
|
// Check if asset file exists on disk
|
||||||
FString PackageFilename = FPackageName::LongPackageNameToFilename(
|
FString PackageFilename = FPackageName::LongPackageNameToFilename(
|
||||||
@@ -391,11 +390,6 @@ void UMCPHandler_DeleteAsset::Handle(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
|
|
||||||
if (bDeleted)
|
if (bDeleted)
|
||||||
{
|
{
|
||||||
// Remove from our cached asset list if present
|
|
||||||
Helper->AllBlueprintAssets.RemoveAll([this](const FAssetData& Asset) {
|
|
||||||
return Asset.PackageName.ToString() == AssetPath;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trigger an asset registry rescan so it notices the deletion
|
// Trigger an asset registry rescan so it notices the deletion
|
||||||
TArray<FString> PathsToScan;
|
TArray<FString> PathsToScan;
|
||||||
int32 LastSlash;
|
int32 LastSlash;
|
||||||
@@ -431,10 +425,9 @@ void UMCPHandler_DeleteAsset::Handle(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
|
|
||||||
void UMCPHandler_ConnectBlueprintPins::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_ConnectBlueprintPins::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -534,10 +527,9 @@ void UMCPHandler_ConnectBlueprintPins::Handle(const FJsonObject* Json, FJsonObje
|
|||||||
|
|
||||||
void UMCPHandler_DisconnectBlueprintPins::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_DisconnectBlueprintPins::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -641,11 +633,10 @@ void UMCPHandler_DisconnectBlueprintPins::Handle(const FJsonObject* Json, FJsonO
|
|||||||
|
|
||||||
void UMCPHandler_RefreshAllNodesInGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_RefreshAllNodesInGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -748,7 +739,6 @@ void UMCPHandler_RefreshAllNodesInGraph::Handle(const FJsonObject* Json, FJsonOb
|
|||||||
|
|
||||||
void UMCPHandler_SetPinDefaultValues::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_SetPinDefaultValues::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
TArray<TSharedPtr<FJsonValue>> Results;
|
TArray<TSharedPtr<FJsonValue>> Results;
|
||||||
int32 SuccessCount = 0;
|
int32 SuccessCount = 0;
|
||||||
@@ -773,7 +763,7 @@ void UMCPHandler_SetPinDefaultValues::Handle(const FJsonObject* Json, FJsonObjec
|
|||||||
EntryResult->SetStringField(TEXT("pinName"), Entry.PinName);
|
EntryResult->SetStringField(TEXT("pinName"), Entry.PinName);
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Entry.Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Entry.Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
EntryResult->SetStringField(TEXT("error"), LoadError);
|
EntryResult->SetStringField(TEXT("error"), LoadError);
|
||||||
@@ -849,11 +839,10 @@ void UMCPHandler_SetPinDefaultValues::Handle(const FJsonObject* Json, FJsonObjec
|
|||||||
|
|
||||||
void UMCPHandler_ChangeStructNodeType::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_ChangeStructNodeType::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1063,10 +1052,9 @@ void UMCPHandler_ChangeStructNodeType::Handle(const FJsonObject* Json, FJsonObje
|
|||||||
|
|
||||||
void UMCPHandler_DeleteNodeFromGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_DeleteNodeFromGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1139,7 +1127,6 @@ void UMCPHandler_DeleteNodeFromGraph::Handle(const FJsonObject* Json, FJsonObjec
|
|||||||
|
|
||||||
void UMCPHandler_RenameAsset::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_RenameAsset::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Renaming asset '%s' -> '%s'"), *AssetPath, *NewPath);
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Renaming asset '%s' -> '%s'"), *AssetPath, *NewPath);
|
||||||
|
|
||||||
@@ -1151,7 +1138,7 @@ void UMCPHandler_RenameAsset::Handle(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
TArray<FAssetRenameData> RenameData;
|
TArray<FAssetRenameData> RenameData;
|
||||||
|
|
||||||
// We need to load the asset to get the object
|
// We need to load the asset to get the object
|
||||||
FAssetData* FoundAsset = Helper->FindAnyAsset(AssetPath);
|
FAssetData* FoundAsset = UMCPAssetFinder::FindAnyAsset(AssetPath);
|
||||||
if (!FoundAsset)
|
if (!FoundAsset)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("Asset '%s' not found. Checked Blueprints, Materials, Material Instances, and Material Functions."), *AssetPath));
|
return MCPUtils::MakeErrorJson(Result, FString::Printf(TEXT("Asset '%s' not found. Checked Blueprints, Materials, Material Instances, and Material Functions."), *AssetPath));
|
||||||
@@ -1190,16 +1177,6 @@ void UMCPHandler_RenameAsset::Handle(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
|
|
||||||
if (bSuccess)
|
if (bSuccess)
|
||||||
{
|
{
|
||||||
// Update all cached asset lists — re-scan to pick up the new path
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
Helper->AllBlueprintAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), Helper->AllBlueprintAssets, true);
|
|
||||||
Helper->AllMaterialAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterial::StaticClass()->GetClassPathName(), Helper->AllMaterialAssets, true);
|
|
||||||
Helper->AllMaterialInstanceAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialInstanceConstant::StaticClass()->GetClassPathName(), Helper->AllMaterialInstanceAssets, true);
|
|
||||||
Helper->AllMaterialFunctionAssets.Empty();
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialFunction::StaticClass()->GetClassPathName(), Helper->AllMaterialFunctionAssets, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Rename %s"), bSuccess ? TEXT("succeeded") : TEXT("failed"));
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Rename %s"), bSuccess ? TEXT("succeeded") : TEXT("failed"));
|
||||||
@@ -1221,11 +1198,10 @@ void UMCPHandler_RenameAsset::Handle(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
|
|
||||||
void UMCPHandler_SetClassDefaultValue::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_SetClassDefaultValue::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1277,7 +1253,7 @@ void UMCPHandler_SetClassDefaultValue::Handle(const FJsonObject* Json, FJsonObje
|
|||||||
if (!ResolvedClass)
|
if (!ResolvedClass)
|
||||||
{
|
{
|
||||||
FString BPLoadError;
|
FString BPLoadError;
|
||||||
UBlueprint* ValueBP = Helper->LoadBlueprintByName(Value, BPLoadError);
|
UBlueprint* ValueBP = UMCPAssetFinder::LoadBlueprintByName(Value, BPLoadError);
|
||||||
if (ValueBP && ValueBP->GeneratedClass)
|
if (ValueBP && ValueBP->GeneratedClass)
|
||||||
{
|
{
|
||||||
ResolvedClass = ValueBP->GeneratedClass;
|
ResolvedClass = ValueBP->GeneratedClass;
|
||||||
@@ -1317,7 +1293,7 @@ void UMCPHandler_SetClassDefaultValue::Handle(const FJsonObject* Json, FJsonObje
|
|||||||
|
|
||||||
// Try loading as a Blueprint asset
|
// Try loading as a Blueprint asset
|
||||||
FString ObjLoadError;
|
FString ObjLoadError;
|
||||||
UBlueprint* ValueBP = Helper->LoadBlueprintByName(Value, ObjLoadError);
|
UBlueprint* ValueBP = UMCPAssetFinder::LoadBlueprintByName(Value, ObjLoadError);
|
||||||
if (ValueBP && ValueBP->GeneratedClass)
|
if (ValueBP && ValueBP->GeneratedClass)
|
||||||
{
|
{
|
||||||
ResolvedObj = ValueBP->GeneratedClass->GetDefaultObject();
|
ResolvedObj = ValueBP->GeneratedClass->GetDefaultObject();
|
||||||
@@ -1379,10 +1355,9 @@ void UMCPHandler_SetClassDefaultValue::Handle(const FJsonObject* Json, FJsonObje
|
|||||||
|
|
||||||
void UMCPHandler_SetNodePositions::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_SetNodePositions::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1443,10 +1418,9 @@ void UMCPHandler_SetNodePositions::Handle(const FJsonObject* Json, FJsonObject*
|
|||||||
|
|
||||||
void UMCPHandler_DuplicateNodesInGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_DuplicateNodesInGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1582,10 +1556,9 @@ void UMCPHandler_DuplicateNodesInGraph::Handle(const FJsonObject* Json, FJsonObj
|
|||||||
|
|
||||||
void UMCPHandler_GetNodeComment::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_GetNodeComment::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1612,10 +1585,9 @@ void UMCPHandler_GetNodeComment::Handle(const FJsonObject* Json, FJsonObject* Re
|
|||||||
|
|
||||||
void UMCPHandler_SetNodeComment::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_SetNodeComment::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -1680,11 +1652,10 @@ void UMCPHandler_SearchSpawnableNodeTypes::Handle(const FJsonObject* Json, FJson
|
|||||||
|
|
||||||
void UMCPHandler_SpawnNodesInGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
void UMCPHandler_SpawnNodesInGraph::Handle(const FJsonObject* Json, FJsonObject* Result)
|
||||||
{
|
{
|
||||||
MCPHelper* Helper = MCPHelper::Get();
|
|
||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = Helper->LoadBlueprintByName(Blueprint, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Blueprint, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -28,7 +29,7 @@ void FBlueprintMCPServer::HandleChangeFunctionParamType(const FJsonObject* Json,
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -246,7 +247,7 @@ void FBlueprintMCPServer::HandleRemoveFunctionParameter(const FJsonObject* Json,
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -407,7 +408,7 @@ void FBlueprintMCPServer::HandleAddFunctionParameter(const FJsonObject* Json, FJ
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -36,7 +37,7 @@ void FBlueprintMCPServer::HandleList(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
|
|
||||||
TArray<TSharedPtr<FJsonValue>> Entries;
|
TArray<TSharedPtr<FJsonValue>> Entries;
|
||||||
if (bIncludeRegular)
|
if (bIncludeRegular)
|
||||||
for (const FAssetData& Asset : AllBlueprintAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets())
|
||||||
{
|
{
|
||||||
FString Name = Asset.AssetName.ToString();
|
FString Name = Asset.AssetName.ToString();
|
||||||
FString Path = Asset.PackageName.ToString();
|
FString Path = Asset.PackageName.ToString();
|
||||||
@@ -76,7 +77,7 @@ void FBlueprintMCPServer::HandleList(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
|
|
||||||
// Also include level blueprints from maps
|
// Also include level blueprints from maps
|
||||||
if (bIncludeLevel)
|
if (bIncludeLevel)
|
||||||
for (const FAssetData& Asset : AllMapAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetMapAssets())
|
||||||
{
|
{
|
||||||
FString Name = Asset.AssetName.ToString();
|
FString Name = Asset.AssetName.ToString();
|
||||||
FString Path = Asset.PackageName.ToString();
|
FString Path = Asset.PackageName.ToString();
|
||||||
@@ -108,7 +109,7 @@ void FBlueprintMCPServer::HandleList(const FJsonObject* Json, FJsonObject* Resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result->SetNumberField(TEXT("count"), Entries.Num());
|
Result->SetNumberField(TEXT("count"), Entries.Num());
|
||||||
Result->SetNumberField(TEXT("total"), AllBlueprintAssets.Num() + AllMapAssets.Num());
|
Result->SetNumberField(TEXT("total"), UMCPAssetFinder::GetBlueprintAssets().Num() + UMCPAssetFinder::GetMapAssets().Num());
|
||||||
Result->SetArrayField(TEXT("blueprints"), Entries);
|
Result->SetArrayField(TEXT("blueprints"), Entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +122,7 @@ void FBlueprintMCPServer::HandleGetBlueprint(const FJsonObject* Json, FJsonObjec
|
|||||||
}
|
}
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(Name, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Name, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -144,7 +145,7 @@ void FBlueprintMCPServer::HandleGetGraph(const FJsonObject* Json, FJsonObject* R
|
|||||||
FString DecodedGraphName = MCPUtils::UrlDecode(GraphName);
|
FString DecodedGraphName = MCPUtils::UrlDecode(GraphName);
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(Name, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Name, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -256,7 +257,7 @@ void FBlueprintMCPServer::HandleSearch(const FJsonObject* Json, FJsonObject* Res
|
|||||||
};
|
};
|
||||||
|
|
||||||
TArray<TSharedPtr<FJsonValue>> Results;
|
TArray<TSharedPtr<FJsonValue>> Results;
|
||||||
for (const FAssetData& Asset : AllBlueprintAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets())
|
||||||
{
|
{
|
||||||
if (Results.Num() >= MaxResults) break;
|
if (Results.Num() >= MaxResults) break;
|
||||||
|
|
||||||
@@ -273,7 +274,7 @@ void FBlueprintMCPServer::HandleSearch(const FJsonObject* Json, FJsonObject* Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Also search level blueprints
|
// Also search level blueprints
|
||||||
for (FAssetData& MapAsset : AllMapAssets)
|
for (const FAssetData& MapAsset : UMCPAssetFinder::GetMapAssets())
|
||||||
{
|
{
|
||||||
if (Results.Num() >= MaxResults) break;
|
if (Results.Num() >= MaxResults) break;
|
||||||
|
|
||||||
@@ -317,7 +318,7 @@ void FBlueprintMCPServer::HandleTestSave(const FJsonObject* Json, FJsonObject* R
|
|||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: test-save requested for '%s'"), *Name);
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: test-save requested for '%s'"), *Name);
|
||||||
|
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(Name, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Name, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -355,7 +356,7 @@ void FBlueprintMCPServer::HandleFindReferences(const FJsonObject* Json, FJsonObj
|
|||||||
|
|
||||||
// Build set of known Blueprint package names for filtering
|
// Build set of known Blueprint package names for filtering
|
||||||
TSet<FString> BlueprintPackages;
|
TSet<FString> BlueprintPackages;
|
||||||
for (const FAssetData& Asset : AllBlueprintAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets())
|
||||||
{
|
{
|
||||||
BlueprintPackages.Add(Asset.PackageName.ToString());
|
BlueprintPackages.Add(Asset.PackageName.ToString());
|
||||||
}
|
}
|
||||||
@@ -586,7 +587,7 @@ void FBlueprintMCPServer::HandleSearchByType(const FJsonObject* Json, FJsonObjec
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Search regular blueprints
|
// Search regular blueprints
|
||||||
for (const FAssetData& Asset : AllBlueprintAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets())
|
||||||
{
|
{
|
||||||
if (Results.Num() >= MaxResults) break;
|
if (Results.Num() >= MaxResults) break;
|
||||||
|
|
||||||
@@ -606,7 +607,7 @@ void FBlueprintMCPServer::HandleSearchByType(const FJsonObject* Json, FJsonObjec
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search level blueprints from maps
|
// Search level blueprints from maps
|
||||||
for (FAssetData& MapAsset : AllMapAssets)
|
for (const FAssetData& MapAsset : UMCPAssetFinder::GetMapAssets())
|
||||||
{
|
{
|
||||||
if (Results.Num() >= MaxResults) break;
|
if (Results.Num() >= MaxResults) break;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -268,7 +269,7 @@ void FBlueprintMCPServer::HandleSnapshotGraph(const FJsonObject* Json, FJsonObje
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -368,7 +369,7 @@ void FBlueprintMCPServer::HandleDiffGraph(const FJsonObject* Json, FJsonObject*
|
|||||||
|
|
||||||
// Load the current blueprint
|
// Load the current blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -587,7 +588,7 @@ void FBlueprintMCPServer::HandleRestoreGraph(const FJsonObject* Json, FJsonObjec
|
|||||||
|
|
||||||
// Load the current blueprint
|
// Load the current blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -820,7 +821,7 @@ void FBlueprintMCPServer::HandleFindDisconnectedPins(const FJsonObject* Json, FJ
|
|||||||
}
|
}
|
||||||
else if (!PathFilter.IsEmpty())
|
else if (!PathFilter.IsEmpty())
|
||||||
{
|
{
|
||||||
for (const FAssetData& Asset : AllBlueprintAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets())
|
||||||
{
|
{
|
||||||
if (Asset.PackageName.ToString().Contains(PathFilter) || Asset.AssetName.ToString().Contains(PathFilter))
|
if (Asset.PackageName.ToString().Contains(PathFilter) || Asset.AssetName.ToString().Contains(PathFilter))
|
||||||
{
|
{
|
||||||
@@ -844,7 +845,7 @@ void FBlueprintMCPServer::HandleFindDisconnectedPins(const FJsonObject* Json, FJ
|
|||||||
for (const FString& BPName : BlueprintsToScan)
|
for (const FString& BPName : BlueprintsToScan)
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BPName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BPName, LoadError);
|
||||||
if (!BP) continue;
|
if (!BP) continue;
|
||||||
BlueprintsScanned++;
|
BlueprintsScanned++;
|
||||||
|
|
||||||
@@ -1205,10 +1206,10 @@ void FBlueprintMCPServer::HandleAnalyzeRebuildImpact(const FJsonObject* Json, FJ
|
|||||||
int32 TotalBreakMakeNodes = 0;
|
int32 TotalBreakMakeNodes = 0;
|
||||||
int32 TotalConnectionsAtRisk = 0;
|
int32 TotalConnectionsAtRisk = 0;
|
||||||
|
|
||||||
for (const FAssetData& Asset : AllBlueprintAssets)
|
for (const FAssetData& Asset : UMCPAssetFinder::GetBlueprintAssets())
|
||||||
{
|
{
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(Asset.AssetName.ToString(), LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(Asset.AssetName.ToString(), LoadError);
|
||||||
if (!BP) continue;
|
if (!BP) continue;
|
||||||
|
|
||||||
FBlueprintImpact Impact;
|
FBlueprintImpact Impact;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -186,7 +187,7 @@ void FBlueprintMCPServer::HandleValidateBlueprint(const FJsonObject* Json, FJson
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -211,9 +212,9 @@ void FBlueprintMCPServer::HandleValidateAllBlueprints(const FJsonObject* Json, F
|
|||||||
|
|
||||||
// First pass: collect matching asset indices (string comparisons only, no GetAsset())
|
// First pass: collect matching asset indices (string comparisons only, no GetAsset())
|
||||||
TArray<int32> MatchingIndices;
|
TArray<int32> MatchingIndices;
|
||||||
for (int32 i = 0; i < AllBlueprintAssets.Num(); i++)
|
for (int32 i = 0; i < UMCPAssetFinder::GetBlueprintAssets().Num(); i++)
|
||||||
{
|
{
|
||||||
const FAssetData& Asset = AllBlueprintAssets[i];
|
const FAssetData& Asset = UMCPAssetFinder::GetBlueprintAssets()[i];
|
||||||
if (!Filter.IsEmpty())
|
if (!Filter.IsEmpty())
|
||||||
{
|
{
|
||||||
FString AssetName = Asset.AssetName.ToString();
|
FString AssetName = Asset.AssetName.ToString();
|
||||||
@@ -254,7 +255,7 @@ void FBlueprintMCPServer::HandleValidateAllBlueprints(const FJsonObject* Json, F
|
|||||||
|
|
||||||
for (int32 Idx = StartIdx; Idx < EndIdx; Idx++)
|
for (int32 Idx = StartIdx; Idx < EndIdx; Idx++)
|
||||||
{
|
{
|
||||||
const FAssetData& Asset = AllBlueprintAssets[MatchingIndices[Idx]];
|
const FAssetData& Asset = UMCPAssetFinder::GetBlueprintAssets()[MatchingIndices[Idx]];
|
||||||
FString AssetName = Asset.AssetName.ToString();
|
FString AssetName = Asset.AssetName.ToString();
|
||||||
FString PackagePath = Asset.PackageName.ToString();
|
FString PackagePath = Asset.PackageName.ToString();
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -34,7 +35,7 @@ void FBlueprintMCPServer::HandleChangeVariableType(const FJsonObject* Json, FJso
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -250,7 +251,7 @@ void FBlueprintMCPServer::HandleAddVariable(const FJsonObject* Json, FJsonObject
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -332,7 +333,7 @@ void FBlueprintMCPServer::HandleRemoveVariable(const FJsonObject* Json, FJsonObj
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
@@ -400,7 +401,7 @@ void FBlueprintMCPServer::HandleSetVariableMetadata(const FJsonObject* Json, FJs
|
|||||||
|
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
FString LoadError;
|
FString LoadError;
|
||||||
UBlueprint* BP = LoadBlueprintByName(BlueprintName, LoadError);
|
UBlueprint* BP = UMCPAssetFinder::LoadBlueprintByName(BlueprintName, LoadError);
|
||||||
if (!BP)
|
if (!BP)
|
||||||
{
|
{
|
||||||
return MCPUtils::MakeErrorJson(Result, LoadError);
|
return MCPUtils::MakeErrorJson(Result, LoadError);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "BlueprintMCPServer.h"
|
#include "BlueprintMCPServer.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPAssetFinder.h"
|
||||||
#include "UObject/StrongObjectPtr.h"
|
#include "UObject/StrongObjectPtr.h"
|
||||||
#include "Materials/MaterialExpression.h"
|
#include "Materials/MaterialExpression.h"
|
||||||
#include "AssetRegistry/AssetRegistryModule.h"
|
#include "AssetRegistry/AssetRegistryModule.h"
|
||||||
@@ -112,164 +113,6 @@ FBlueprintMCPServer* FBlueprintMCPServer::Get()
|
|||||||
return Sub ? Sub->GetServer() : nullptr;
|
return Sub ? Sub->GetServer() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
// Helpers
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
FAssetData* FBlueprintMCPServer::FindAnyAsset(const FString& NameOrPath)
|
|
||||||
{
|
|
||||||
FAssetData* Asset = FindBlueprintAsset(NameOrPath);
|
|
||||||
if (!Asset)
|
|
||||||
Asset = FindMaterialAsset(NameOrPath);
|
|
||||||
if (!Asset)
|
|
||||||
Asset = FindMaterialInstanceAsset(NameOrPath);
|
|
||||||
if (!Asset)
|
|
||||||
Asset = FindMaterialFunctionAsset(NameOrPath);
|
|
||||||
return Asset;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAssetData* FBlueprintMCPServer::FindBlueprintAsset(const FString& NameOrPath)
|
|
||||||
{
|
|
||||||
for (FAssetData& Asset : AllBlueprintAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString() == NameOrPath || Asset.PackageName.ToString() == NameOrPath)
|
|
||||||
{
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Case-insensitive fallback
|
|
||||||
for (FAssetData& Asset : AllBlueprintAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase) ||
|
|
||||||
Asset.PackageName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase))
|
|
||||||
{
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAssetData* FBlueprintMCPServer::FindMapAsset(const FString& NameOrPath)
|
|
||||||
{
|
|
||||||
for (FAssetData& Asset : AllMapAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString() == NameOrPath || Asset.PackageName.ToString() == NameOrPath)
|
|
||||||
{
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Case-insensitive fallback
|
|
||||||
for (FAssetData& Asset : AllMapAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase) ||
|
|
||||||
Asset.PackageName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase))
|
|
||||||
{
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
UBlueprint* FBlueprintMCPServer::LoadBlueprintByName(const FString& NameOrPath, FString& OutError)
|
|
||||||
{
|
|
||||||
// Strategy 1: Try as a regular Blueprint asset
|
|
||||||
FAssetData* Asset = FindBlueprintAsset(NameOrPath);
|
|
||||||
if (Asset)
|
|
||||||
{
|
|
||||||
UBlueprint* BP = Cast<UBlueprint>(Asset->GetAsset());
|
|
||||||
if (BP) return BP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strategy 2: Try as a level blueprint (from a .umap)
|
|
||||||
FAssetData* MapAsset = FindMapAsset(NameOrPath);
|
|
||||||
if (MapAsset)
|
|
||||||
{
|
|
||||||
UWorld* World = Cast<UWorld>(MapAsset->GetAsset());
|
|
||||||
if (World && World->PersistentLevel)
|
|
||||||
{
|
|
||||||
ULevelScriptBlueprint* LevelBP = World->PersistentLevel->GetLevelScriptBlueprint(true);
|
|
||||||
if (LevelBP)
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Loaded level blueprint from map '%s'"),
|
|
||||||
*NameOrPath);
|
|
||||||
return LevelBP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OutError = FString::Printf(TEXT("Map '%s' loaded but its level blueprint could not be retrieved. The map may not contain a level blueprint."), *NameOrPath);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
OutError = FString::Printf(TEXT("Blueprint or map '%s' not found. Use list_blueprints to see available assets. Level blueprints are referenced by their map name (e.g. 'MAP_Ward')."), *NameOrPath);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
UMaterial* FBlueprintMCPServer::LoadMaterialByName(const FString& NameOrPath, FString& OutError)
|
|
||||||
{
|
|
||||||
FAssetData* Asset = FindMaterialAsset(NameOrPath);
|
|
||||||
if (Asset)
|
|
||||||
{
|
|
||||||
UMaterial* Mat = Cast<UMaterial>(Asset->GetAsset());
|
|
||||||
if (Mat) return Mat;
|
|
||||||
}
|
|
||||||
OutError = FString::Printf(TEXT("Material '%s' not found. Use list_materials to see available assets."), *NameOrPath);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAssetData* FBlueprintMCPServer::FindMaterialInstanceAsset(const FString& NameOrPath)
|
|
||||||
{
|
|
||||||
for (FAssetData& Asset : AllMaterialInstanceAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString() == NameOrPath || Asset.PackageName.ToString() == NameOrPath)
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
for (FAssetData& Asset : AllMaterialInstanceAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase) ||
|
|
||||||
Asset.PackageName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase))
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
UMaterialInstanceConstant* FBlueprintMCPServer::LoadMaterialInstanceByName(const FString& NameOrPath, FString& OutError)
|
|
||||||
{
|
|
||||||
FAssetData* Asset = FindMaterialInstanceAsset(NameOrPath);
|
|
||||||
if (Asset)
|
|
||||||
{
|
|
||||||
UMaterialInstanceConstant* MI = Cast<UMaterialInstanceConstant>(Asset->GetAsset());
|
|
||||||
if (MI) return MI;
|
|
||||||
}
|
|
||||||
OutError = FString::Printf(TEXT("Material Instance '%s' not found. Use list_materials to see available assets."), *NameOrPath);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAssetData* FBlueprintMCPServer::FindMaterialFunctionAsset(const FString& NameOrPath)
|
|
||||||
{
|
|
||||||
for (FAssetData& Asset : AllMaterialFunctionAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString() == NameOrPath || Asset.PackageName.ToString() == NameOrPath)
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
for (FAssetData& Asset : AllMaterialFunctionAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase) ||
|
|
||||||
Asset.PackageName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase))
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
UMaterialFunction* FBlueprintMCPServer::LoadMaterialFunctionByName(const FString& NameOrPath, FString& OutError)
|
|
||||||
{
|
|
||||||
FAssetData* Asset = FindMaterialFunctionAsset(NameOrPath);
|
|
||||||
if (Asset)
|
|
||||||
{
|
|
||||||
UMaterialFunction* MF = Cast<UMaterialFunction>(Asset->GetAsset());
|
|
||||||
if (MF) return MF;
|
|
||||||
}
|
|
||||||
OutError = FString::Printf(TEXT("Material Function '%s' not found. Use list_material_functions to see available assets."), *NameOrPath);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// SEH wrappers for crash-safe compilation and saving.
|
// SEH wrappers for crash-safe compilation and saving.
|
||||||
@@ -415,29 +258,6 @@ bool FBlueprintMCPServer::Start(int32 InPort, bool bEditorMode)
|
|||||||
Port = InPort;
|
Port = InPort;
|
||||||
bIsEditor = bEditorMode;
|
bIsEditor = bEditorMode;
|
||||||
|
|
||||||
// Scan asset registry
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Scanning asset registry..."));
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
ARM.Get().SearchAllAssets(true);
|
|
||||||
ARM.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), AllBlueprintAssets, true);
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Found %d Blueprint assets."), AllBlueprintAssets.Num());
|
|
||||||
|
|
||||||
// Also scan for map assets (level blueprints live inside .umap packages)
|
|
||||||
ARM.Get().GetAssetsByClass(UWorld::StaticClass()->GetClassPathName(), AllMapAssets, false);
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Found %d Map assets (potential level blueprints)."), AllMapAssets.Num());
|
|
||||||
|
|
||||||
// Scan for Material assets
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterial::StaticClass()->GetClassPathName(), AllMaterialAssets, false);
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Found %d Material assets."), AllMaterialAssets.Num());
|
|
||||||
|
|
||||||
// Scan for Material Instance assets
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialInstanceConstant::StaticClass()->GetClassPathName(), AllMaterialInstanceAssets, false);
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Found %d Material Instance assets."), AllMaterialInstanceAssets.Num());
|
|
||||||
|
|
||||||
// Scan for Material Function assets
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialFunction::StaticClass()->GetClassPathName(), AllMaterialFunctionAssets, false);
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Found %d Material Function assets."), AllMaterialFunctionAssets.Num());
|
|
||||||
|
|
||||||
// Start HTTP server
|
// Start HTTP server
|
||||||
FHttpServerModule& HttpModule = FModuleManager::LoadModuleChecked<FHttpServerModule>("HTTPServer");
|
FHttpServerModule& HttpModule = FModuleManager::LoadModuleChecked<FHttpServerModule>("HTTPServer");
|
||||||
TSharedPtr<IHttpRouter> Router = HttpModule.GetHttpRouter(Port);
|
TSharedPtr<IHttpRouter> Router = HttpModule.GetHttpRouter(Port);
|
||||||
@@ -477,11 +297,11 @@ bool FBlueprintMCPServer::Start(int32 InPort, bool bEditorMode)
|
|||||||
TSharedRef<FJsonObject> J = MakeShared<FJsonObject>();
|
TSharedRef<FJsonObject> J = MakeShared<FJsonObject>();
|
||||||
J->SetStringField(TEXT("status"), TEXT("ok"));
|
J->SetStringField(TEXT("status"), TEXT("ok"));
|
||||||
J->SetStringField(TEXT("mode"), bIsEditor ? TEXT("editor") : TEXT("commandlet"));
|
J->SetStringField(TEXT("mode"), bIsEditor ? TEXT("editor") : TEXT("commandlet"));
|
||||||
J->SetNumberField(TEXT("blueprintCount"), AllBlueprintAssets.Num());
|
J->SetNumberField(TEXT("blueprintCount"), UMCPAssetFinder::GetBlueprintAssets().Num());
|
||||||
J->SetNumberField(TEXT("mapCount"), AllMapAssets.Num());
|
J->SetNumberField(TEXT("mapCount"), UMCPAssetFinder::GetMapAssets().Num());
|
||||||
J->SetNumberField(TEXT("materialCount"), AllMaterialAssets.Num());
|
J->SetNumberField(TEXT("materialCount"), UMCPAssetFinder::GetMaterialAssets().Num());
|
||||||
J->SetNumberField(TEXT("materialInstanceCount"), AllMaterialInstanceAssets.Num());
|
J->SetNumberField(TEXT("materialInstanceCount"), UMCPAssetFinder::GetMaterialInstanceAssets().Num());
|
||||||
J->SetNumberField(TEXT("materialFunctionCount"), AllMaterialFunctionAssets.Num());
|
J->SetNumberField(TEXT("materialFunctionCount"), UMCPAssetFinder::GetMaterialFunctionAssets().Num());
|
||||||
TUniquePtr<FHttpServerResponse> R = FHttpServerResponse::Create(
|
TUniquePtr<FHttpServerResponse> R = FHttpServerResponse::Create(
|
||||||
MCPUtils::JsonToString(J), TEXT("application/json"));
|
MCPUtils::JsonToString(J), TEXT("application/json"));
|
||||||
OnComplete(MoveTemp(R));
|
OnComplete(MoveTemp(R));
|
||||||
@@ -509,9 +329,6 @@ bool FBlueprintMCPServer::Start(int32 InPort, bool bEditorMode)
|
|||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// /api/rescan — re-scan asset registry and refresh cached asset lists (game thread)
|
|
||||||
Router->BindRoute(FHttpPath(TEXT("/api/rescan_asset_registry")), EHttpServerRequestVerbs::VERB_POST,
|
|
||||||
QueuedHandler(TEXT("rescan_asset_registry")));
|
|
||||||
|
|
||||||
// /api/list — answered directly (only reads immutable asset list)
|
// /api/list — answered directly (only reads immutable asset list)
|
||||||
Router->BindRoute(FHttpPath(TEXT("/api/list_blueprint_assets")), EHttpServerRequestVerbs::VERB_GET,
|
Router->BindRoute(FHttpPath(TEXT("/api/list_blueprint_assets")), EHttpServerRequestVerbs::VERB_GET,
|
||||||
@@ -937,7 +754,6 @@ void FBlueprintMCPServer::RegisterHandlers()
|
|||||||
HandlerMap.Add(Name, [this, Fn](const FJsonObject* Json, FJsonObject* Result) { (this->*Fn)(Json, Result); });
|
HandlerMap.Add(Name, [this, Fn](const FJsonObject* Json, FJsonObject* Result) { (this->*Fn)(Json, Result); });
|
||||||
};
|
};
|
||||||
|
|
||||||
H(TEXT("rescan_asset_registry"), &FBlueprintMCPServer::HandleRescan);
|
|
||||||
H(TEXT("dump_blueprint"), &FBlueprintMCPServer::HandleGetBlueprint);
|
H(TEXT("dump_blueprint"), &FBlueprintMCPServer::HandleGetBlueprint);
|
||||||
H(TEXT("dump_blueprint_graph"), &FBlueprintMCPServer::HandleGetGraph);
|
H(TEXT("dump_blueprint_graph"), &FBlueprintMCPServer::HandleGetGraph);
|
||||||
H(TEXT("search_within_blueprints"), &FBlueprintMCPServer::HandleSearch);
|
H(TEXT("search_within_blueprints"), &FBlueprintMCPServer::HandleSearch);
|
||||||
@@ -1046,79 +862,4 @@ void FBlueprintMCPServer::BuildMCPHandlerRegistry()
|
|||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: %d new-style handlers registered."), MCPHandlerRegistry.Num());
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: %d new-style handlers registered."), MCPHandlerRegistry.Num());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
// HandleRescan — refresh cached asset lists from asset registry
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
void FBlueprintMCPServer::HandleRescan(const FJsonObject* Json, FJsonObject* Result)
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Rescanning asset registry..."));
|
|
||||||
|
|
||||||
FAssetRegistryModule& ARM = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
|
||||||
ARM.Get().SearchAllAssets(true);
|
|
||||||
|
|
||||||
int32 OldBP = AllBlueprintAssets.Num();
|
|
||||||
int32 OldMap = AllMapAssets.Num();
|
|
||||||
int32 OldMat = AllMaterialAssets.Num();
|
|
||||||
int32 OldMI = AllMaterialInstanceAssets.Num();
|
|
||||||
int32 OldMF = AllMaterialFunctionAssets.Num();
|
|
||||||
|
|
||||||
AllBlueprintAssets.Empty();
|
|
||||||
AllMapAssets.Empty();
|
|
||||||
AllMaterialAssets.Empty();
|
|
||||||
AllMaterialInstanceAssets.Empty();
|
|
||||||
AllMaterialFunctionAssets.Empty();
|
|
||||||
|
|
||||||
ARM.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), AllBlueprintAssets, true);
|
|
||||||
ARM.Get().GetAssetsByClass(UWorld::StaticClass()->GetClassPathName(), AllMapAssets, false);
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterial::StaticClass()->GetClassPathName(), AllMaterialAssets, false);
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialInstanceConstant::StaticClass()->GetClassPathName(), AllMaterialInstanceAssets, false);
|
|
||||||
ARM.Get().GetAssetsByClass(UMaterialFunction::StaticClass()->GetClassPathName(), AllMaterialFunctionAssets, false);
|
|
||||||
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Rescan complete — BP %d→%d, Map %d→%d, Mat %d→%d, MI %d→%d, MF %d→%d"),
|
|
||||||
OldBP, AllBlueprintAssets.Num(),
|
|
||||||
OldMap, AllMapAssets.Num(),
|
|
||||||
OldMat, AllMaterialAssets.Num(),
|
|
||||||
OldMI, AllMaterialInstanceAssets.Num(),
|
|
||||||
OldMF, AllMaterialFunctionAssets.Num());
|
|
||||||
|
|
||||||
Result->SetStringField(TEXT("status"), TEXT("ok"));
|
|
||||||
Result->SetNumberField(TEXT("blueprintCount"), AllBlueprintAssets.Num());
|
|
||||||
Result->SetNumberField(TEXT("mapCount"), AllMapAssets.Num());
|
|
||||||
Result->SetNumberField(TEXT("materialCount"), AllMaterialAssets.Num());
|
|
||||||
Result->SetNumberField(TEXT("materialInstanceCount"), AllMaterialInstanceAssets.Num());
|
|
||||||
Result->SetNumberField(TEXT("materialFunctionCount"), AllMaterialFunctionAssets.Num());
|
|
||||||
|
|
||||||
TSharedRef<FJsonObject> Delta = MakeShared<FJsonObject>();
|
|
||||||
Delta->SetNumberField(TEXT("blueprints"), AllBlueprintAssets.Num() - OldBP);
|
|
||||||
Delta->SetNumberField(TEXT("maps"), AllMapAssets.Num() - OldMap);
|
|
||||||
Delta->SetNumberField(TEXT("materials"), AllMaterialAssets.Num() - OldMat);
|
|
||||||
Delta->SetNumberField(TEXT("materialInstances"), AllMaterialInstanceAssets.Num() - OldMI);
|
|
||||||
Delta->SetNumberField(TEXT("materialFunctions"), AllMaterialFunctionAssets.Num() - OldMF);
|
|
||||||
Result->SetObjectField(TEXT("delta"), Delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
// (SerializeBlueprint, SerializeGraph, SerializeNode, SerializePin moved to MCPUtils.cpp)
|
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
// Material helpers
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
FAssetData* FBlueprintMCPServer::FindMaterialAsset(const FString& NameOrPath)
|
|
||||||
{
|
|
||||||
for (FAssetData& Asset : AllMaterialAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString() == NameOrPath || Asset.PackageName.ToString() == NameOrPath)
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
for (FAssetData& Asset : AllMaterialAssets)
|
|
||||||
{
|
|
||||||
if (Asset.AssetName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase) ||
|
|
||||||
Asset.PackageName.ToString().Equals(NameOrPath, ESearchCase::IgnoreCase))
|
|
||||||
return &Asset;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,259 @@
|
|||||||
|
#include "MCPAssetFinder.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "Engine/Blueprint.h"
|
||||||
|
#include "Engine/World.h"
|
||||||
|
#include "Engine/Level.h"
|
||||||
|
#include "Engine/LevelScriptBlueprint.h"
|
||||||
|
#include "Materials/Material.h"
|
||||||
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
|
#include "Materials/MaterialFunction.h"
|
||||||
|
#include "AssetRegistry/AssetRegistryModule.h"
|
||||||
|
#include "AssetRegistry/IAssetRegistry.h"
|
||||||
|
|
||||||
|
const TArray<FAssetData> UMCPAssetFinder::EmptyAssetArray;
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Initialize / Deinitialize — subscribe to asset registry events
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
void UMCPAssetFinder::Initialize(FSubsystemCollectionBase& Collection)
|
||||||
|
{
|
||||||
|
Super::Initialize(Collection);
|
||||||
|
|
||||||
|
IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
|
||||||
|
AR.OnAssetAdded().AddUObject(this, &UMCPAssetFinder::OnAssetEvent);
|
||||||
|
AR.OnAssetRemoved().AddUObject(this, &UMCPAssetFinder::OnAssetEvent);
|
||||||
|
AR.OnAssetUpdated().AddUObject(this, &UMCPAssetFinder::OnAssetEvent);
|
||||||
|
AR.OnAssetRenamed().AddUObject(this, &UMCPAssetFinder::OnAssetRenamed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMCPAssetFinder::Deinitialize()
|
||||||
|
{
|
||||||
|
IAssetRegistry* AR = IAssetRegistry::Get();
|
||||||
|
if (AR)
|
||||||
|
{
|
||||||
|
AR->OnAssetAdded().RemoveAll(this);
|
||||||
|
AR->OnAssetRemoved().RemoveAll(this);
|
||||||
|
AR->OnAssetUpdated().RemoveAll(this);
|
||||||
|
AR->OnAssetRenamed().RemoveAll(this);
|
||||||
|
}
|
||||||
|
Super::Deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// GetUpdatedAssets — the gateway for all static API
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
UMCPAssetFinder* UMCPAssetFinder::GetUpdatedAssets()
|
||||||
|
{
|
||||||
|
checkf(IsInGameThread(), TEXT("MCPAssetFinder must only be accessed from the game thread"));
|
||||||
|
if (!GEngine) return nullptr;
|
||||||
|
UMCPAssetFinder* Self = GEngine->GetEngineSubsystem<UMCPAssetFinder>();
|
||||||
|
if (!Self) return nullptr;
|
||||||
|
|
||||||
|
IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
|
||||||
|
|
||||||
|
while (AR.IsLoadingAssets()) FPlatformProcess::Sleep(0.1f);
|
||||||
|
|
||||||
|
if (!Self->bDirty) return Self;
|
||||||
|
|
||||||
|
Self->AllBlueprintAssets.Empty();
|
||||||
|
Self->AllMapAssets.Empty();
|
||||||
|
Self->AllMaterialAssets.Empty();
|
||||||
|
Self->AllMaterialInstanceAssets.Empty();
|
||||||
|
Self->AllMaterialFunctionAssets.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);
|
||||||
|
|
||||||
|
Self->bDirty = false;
|
||||||
|
|
||||||
|
UE_LOG(LogTemp, Display, TEXT("MCPAssetFinder: Refreshed — BP %d, Map %d, Mat %d, MI %d, MF %d"),
|
||||||
|
Self->AllBlueprintAssets.Num(), Self->AllMapAssets.Num(), Self->AllMaterialAssets.Num(),
|
||||||
|
Self->AllMaterialInstanceAssets.Num(), Self->AllMaterialFunctionAssets.Num());
|
||||||
|
|
||||||
|
return Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Static asset list accessors
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
const TArray<FAssetData>& UMCPAssetFinder::GetBlueprintAssets()
|
||||||
|
{
|
||||||
|
UMCPAssetFinder* Self = GetUpdatedAssets();
|
||||||
|
return Self ? Self->AllBlueprintAssets : EmptyAssetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TArray<FAssetData>& UMCPAssetFinder::GetMapAssets()
|
||||||
|
{
|
||||||
|
UMCPAssetFinder* Self = GetUpdatedAssets();
|
||||||
|
return Self ? Self->AllMapAssets : EmptyAssetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TArray<FAssetData>& UMCPAssetFinder::GetMaterialAssets()
|
||||||
|
{
|
||||||
|
UMCPAssetFinder* Self = GetUpdatedAssets();
|
||||||
|
return Self ? Self->AllMaterialAssets : EmptyAssetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TArray<FAssetData>& UMCPAssetFinder::GetMaterialInstanceAssets()
|
||||||
|
{
|
||||||
|
UMCPAssetFinder* Self = GetUpdatedAssets();
|
||||||
|
return Self ? Self->AllMaterialInstanceAssets : EmptyAssetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TArray<FAssetData>& UMCPAssetFinder::GetMaterialFunctionAssets()
|
||||||
|
{
|
||||||
|
UMCPAssetFinder* Self = GetUpdatedAssets();
|
||||||
|
return Self ? Self->AllMaterialFunctionAssets : EmptyAssetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Find helpers (search cached lists by name or path)
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
FAssetData* FindInList(const TArray<FAssetData>& List, const FString& NameOrPath, FString* OutError)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Found = const_cast<FAssetData*>(&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;
|
||||||
|
}
|
||||||
|
return Found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FAssetData* UMCPAssetFinder::FindBlueprintAsset(const FString& NameOrPath, FString* OutError)
|
||||||
|
{
|
||||||
|
return FindInList(GetBlueprintAssets(), NameOrPath, OutError);
|
||||||
|
}
|
||||||
|
|
||||||
|
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::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Load helpers
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
UBlueprint* UMCPAssetFinder::LoadBlueprintByName(const FString& NameOrPath, FString& OutError)
|
||||||
|
{
|
||||||
|
// Strategy 1: Try as a regular Blueprint asset
|
||||||
|
FAssetData* Asset = FindBlueprintAsset(NameOrPath, &OutError);
|
||||||
|
if (Asset)
|
||||||
|
{
|
||||||
|
UBlueprint* BP = Cast<UBlueprint>(Asset->GetAsset());
|
||||||
|
if (BP) return BP;
|
||||||
|
}
|
||||||
|
if (!OutError.IsEmpty()) return nullptr;
|
||||||
|
|
||||||
|
// Strategy 2: Try as a level blueprint (from a .umap)
|
||||||
|
FAssetData* MapAsset = FindMapAsset(NameOrPath, &OutError);
|
||||||
|
if (MapAsset)
|
||||||
|
{
|
||||||
|
UWorld* World = Cast<UWorld>(MapAsset->GetAsset());
|
||||||
|
if (World && World->PersistentLevel)
|
||||||
|
{
|
||||||
|
ULevelScriptBlueprint* LevelBP = World->PersistentLevel->GetLevelScriptBlueprint(true);
|
||||||
|
if (LevelBP)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Display, TEXT("MCPAssetFinder: Loaded level blueprint from map '%s'"),
|
||||||
|
*NameOrPath);
|
||||||
|
return LevelBP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OutError = FString::Printf(TEXT("Map '%s' loaded but its level blueprint could not be retrieved. The map may not contain a level blueprint."), *NameOrPath);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (!OutError.IsEmpty()) return nullptr;
|
||||||
|
|
||||||
|
OutError = FString::Printf(TEXT("Blueprint or map '%s' not found. Use list_blueprints to see available assets. Level blueprints are referenced by their map name (e.g. 'MAP_Ward')."), *NameOrPath);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UMaterial* UMCPAssetFinder::LoadMaterialByName(const FString& NameOrPath, FString& OutError)
|
||||||
|
{
|
||||||
|
FAssetData* Asset = FindMaterialAsset(NameOrPath, &OutError);
|
||||||
|
if (Asset)
|
||||||
|
{
|
||||||
|
UMaterial* Mat = Cast<UMaterial>(Asset->GetAsset());
|
||||||
|
if (Mat) return Mat;
|
||||||
|
}
|
||||||
|
if (OutError.IsEmpty())
|
||||||
|
OutError = FString::Printf(TEXT("Material '%s' not found. Use list_materials to see available assets."), *NameOrPath);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UMaterialInstanceConstant* UMCPAssetFinder::LoadMaterialInstanceByName(const FString& NameOrPath, FString& OutError)
|
||||||
|
{
|
||||||
|
FAssetData* Asset = FindMaterialInstanceAsset(NameOrPath, &OutError);
|
||||||
|
if (Asset)
|
||||||
|
{
|
||||||
|
UMaterialInstanceConstant* MI = Cast<UMaterialInstanceConstant>(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<UMaterialFunction>(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;
|
||||||
|
}
|
||||||
@@ -2,53 +2,11 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Dom/JsonObject.h"
|
#include "Dom/JsonObject.h"
|
||||||
#include "AssetRegistry/AssetData.h"
|
|
||||||
#include "HttpResultCallback.h"
|
#include "HttpResultCallback.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "MCPUtils.h"
|
||||||
|
|
||||||
class UEdGraph;
|
|
||||||
class UEdGraphNode;
|
|
||||||
class UEdGraphPin;
|
|
||||||
class UBlueprint;
|
|
||||||
class UMaterial;
|
|
||||||
class UMaterialInstanceConstant;
|
|
||||||
class UMaterialFunction;
|
|
||||||
class UMaterialExpression;
|
|
||||||
class IMCPHandler;
|
class IMCPHandler;
|
||||||
|
|
||||||
// ----- Snapshot data structures -----
|
|
||||||
|
|
||||||
struct FPinConnectionRecord
|
|
||||||
{
|
|
||||||
FString SourceNodeGuid;
|
|
||||||
FString SourcePinName;
|
|
||||||
FString TargetNodeGuid;
|
|
||||||
FString TargetPinName;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FNodeRecord
|
|
||||||
{
|
|
||||||
FString NodeGuid;
|
|
||||||
FString NodeClass;
|
|
||||||
FString NodeTitle;
|
|
||||||
FString StructType; // for Break/Make nodes
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FGraphSnapshotData
|
|
||||||
{
|
|
||||||
TArray<FNodeRecord> Nodes;
|
|
||||||
TArray<FPinConnectionRecord> Connections;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FGraphSnapshot
|
|
||||||
{
|
|
||||||
FString SnapshotId;
|
|
||||||
FString BlueprintName;
|
|
||||||
FString BlueprintPath;
|
|
||||||
FDateTime CreatedAt;
|
|
||||||
TMap<FString, FGraphSnapshotData> Graphs; // graphName -> data
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FBlueprintMCPServer — plain C++ class (not a UCLASS) that owns all HTTP
|
* FBlueprintMCPServer — plain C++ class (not a UCLASS) that owns all HTTP
|
||||||
* serving logic for the Blueprint MCP protocol.
|
* serving logic for the Blueprint MCP protocol.
|
||||||
@@ -85,24 +43,6 @@ public:
|
|||||||
/** Port the server is listening on. */
|
/** Port the server is listening on. */
|
||||||
int32 GetPort() const { return Port; }
|
int32 GetPort() const { return Port; }
|
||||||
|
|
||||||
/** Number of indexed Blueprint assets. */
|
|
||||||
int32 GetBlueprintCount() const { return AllBlueprintAssets.Num(); }
|
|
||||||
|
|
||||||
/** Number of indexed Map assets. */
|
|
||||||
int32 GetMapCount() const { return AllMapAssets.Num(); }
|
|
||||||
|
|
||||||
/** Number of indexed Material assets. */
|
|
||||||
int32 GetMaterialCount() const { return AllMaterialAssets.Num(); }
|
|
||||||
|
|
||||||
/** Number of indexed Material Instance assets. */
|
|
||||||
int32 GetMaterialInstanceCount() const { return AllMaterialInstanceAssets.Num(); }
|
|
||||||
|
|
||||||
// ----- Cached asset lists (accessed by handlers) -----
|
|
||||||
TArray<FAssetData> AllBlueprintAssets;
|
|
||||||
TArray<FAssetData> AllMapAssets;
|
|
||||||
TArray<FAssetData> AllMaterialAssets;
|
|
||||||
TArray<FAssetData> AllMaterialInstanceAssets;
|
|
||||||
TArray<FAssetData> AllMaterialFunctionAssets;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ----- Request dispatch -----
|
// ----- Request dispatch -----
|
||||||
@@ -126,9 +66,6 @@ private:
|
|||||||
bool bRunning = false;
|
bool bRunning = false;
|
||||||
bool bIsEditor = false;
|
bool bIsEditor = false;
|
||||||
|
|
||||||
// ----- Asset registry rescan -----
|
|
||||||
void HandleRescan(const FJsonObject* Json, FJsonObject* Result);
|
|
||||||
|
|
||||||
// ----- Request handlers (read-only) -----
|
// ----- Request handlers (read-only) -----
|
||||||
void HandleList(const FJsonObject* Json, FJsonObject* Result);
|
void HandleList(const FJsonObject* Json, FJsonObject* Result);
|
||||||
void HandleGetBlueprint(const FJsonObject* Json, FJsonObject* Result);
|
void HandleGetBlueprint(const FJsonObject* Json, FJsonObject* Result);
|
||||||
@@ -254,19 +191,6 @@ private:
|
|||||||
void HandleSetStateBlendSpace(const FJsonObject* Json, FJsonObject* Result);
|
void HandleSetStateBlendSpace(const FJsonObject* Json, FJsonObject* Result);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// ----- Helpers (stateful — use cached asset lists) -----
|
|
||||||
FAssetData* FindAnyAsset(const FString& NameOrPath);
|
|
||||||
FAssetData* FindBlueprintAsset(const FString& NameOrPath);
|
|
||||||
FAssetData* FindMapAsset(const FString& NameOrPath);
|
|
||||||
UBlueprint* LoadBlueprintByName(const FString& NameOrPath, FString& OutError);
|
|
||||||
|
|
||||||
// ----- Material helpers (stateful — use cached asset lists) -----
|
|
||||||
FAssetData* FindMaterialAsset(const FString& NameOrPath);
|
|
||||||
UMaterial* LoadMaterialByName(const FString& NameOrPath, FString& OutError);
|
|
||||||
FAssetData* FindMaterialInstanceAsset(const FString& NameOrPath);
|
|
||||||
UMaterialInstanceConstant* LoadMaterialInstanceByName(const FString& NameOrPath, FString& OutError);
|
|
||||||
FAssetData* FindMaterialFunctionAsset(const FString& NameOrPath);
|
|
||||||
UMaterialFunction* LoadMaterialFunctionByName(const FString& NameOrPath, FString& OutError);
|
|
||||||
|
|
||||||
// ----- Snapshot storage -----
|
// ----- Snapshot storage -----
|
||||||
TMap<FString, FGraphSnapshot> Snapshots;
|
TMap<FString, FGraphSnapshot> Snapshots;
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Subsystems/EngineSubsystem.h"
|
||||||
|
#include "AssetRegistry/AssetData.h"
|
||||||
|
#include "MCPAssetFinder.generated.h"
|
||||||
|
|
||||||
|
class UBlueprint;
|
||||||
|
class UMaterial;
|
||||||
|
class UMaterialInstanceConstant;
|
||||||
|
class UMaterialFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Engine subsystem that caches asset registry data for the BlueprintMCP server.
|
||||||
|
* All public API is static — callers never need to fetch the subsystem directly.
|
||||||
|
* Asset lists are auto-refreshed when the asset registry signals changes.
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class UMCPAssetFinder : public UEngineSubsystem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||||
|
virtual void Deinitialize() override;
|
||||||
|
// --- Static API: asset lists ---
|
||||||
|
static const TArray<FAssetData>& GetBlueprintAssets();
|
||||||
|
static const TArray<FAssetData>& GetMapAssets();
|
||||||
|
static const TArray<FAssetData>& GetMaterialAssets();
|
||||||
|
static const TArray<FAssetData>& GetMaterialInstanceAssets();
|
||||||
|
static const TArray<FAssetData>& GetMaterialFunctionAssets();
|
||||||
|
|
||||||
|
// --- 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);
|
||||||
|
static FAssetData* FindMapAsset(const FString& NameOrPath, FString* OutError = nullptr);
|
||||||
|
static UBlueprint* LoadBlueprintByName(const FString& NameOrPath, FString& OutError);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Get the subsystem, refreshing asset caches if stale. Returns nullptr if engine is not initialized. */
|
||||||
|
static UMCPAssetFinder* GetUpdatedAssets();
|
||||||
|
|
||||||
|
// Cached asset lists
|
||||||
|
TArray<FAssetData> AllBlueprintAssets;
|
||||||
|
TArray<FAssetData> AllMapAssets;
|
||||||
|
TArray<FAssetData> AllMaterialAssets;
|
||||||
|
TArray<FAssetData> AllMaterialInstanceAssets;
|
||||||
|
TArray<FAssetData> AllMaterialFunctionAssets;
|
||||||
|
|
||||||
|
// Change detection — set true by asset registry delegates
|
||||||
|
bool bDirty = true;
|
||||||
|
void OnAssetEvent(const FAssetData&) { bDirty = true; }
|
||||||
|
void OnAssetRenamed(const FAssetData&, const FString&) { bDirty = true; }
|
||||||
|
|
||||||
|
// Empty array returned when subsystem is unavailable
|
||||||
|
static const TArray<FAssetData> EmptyAssetArray;
|
||||||
|
};
|
||||||
@@ -15,6 +15,39 @@ class UAnimationStateMachineGraph;
|
|||||||
class UAnimStateNode;
|
class UAnimStateNode;
|
||||||
class UAnimStateTransitionNode;
|
class UAnimStateTransitionNode;
|
||||||
|
|
||||||
|
// ----- Snapshot data structures -----
|
||||||
|
|
||||||
|
struct FPinConnectionRecord
|
||||||
|
{
|
||||||
|
FString SourceNodeGuid;
|
||||||
|
FString SourcePinName;
|
||||||
|
FString TargetNodeGuid;
|
||||||
|
FString TargetPinName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FNodeRecord
|
||||||
|
{
|
||||||
|
FString NodeGuid;
|
||||||
|
FString NodeClass;
|
||||||
|
FString NodeTitle;
|
||||||
|
FString StructType; // for Break/Make nodes
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FGraphSnapshotData
|
||||||
|
{
|
||||||
|
TArray<FNodeRecord> Nodes;
|
||||||
|
TArray<FPinConnectionRecord> Connections;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FGraphSnapshot
|
||||||
|
{
|
||||||
|
FString SnapshotId;
|
||||||
|
FString BlueprintName;
|
||||||
|
FString BlueprintPath;
|
||||||
|
FDateTime CreatedAt;
|
||||||
|
TMap<FString, FGraphSnapshotData> Graphs; // graphName -> data
|
||||||
|
};
|
||||||
|
|
||||||
// Stateless utility functions used by MCP handlers and the MCP server.
|
// Stateless utility functions used by MCP handlers and the MCP server.
|
||||||
// This is effectively a namespace — all methods are static.
|
// This is effectively a namespace — all methods are static.
|
||||||
class MCPUtils
|
class MCPUtils
|
||||||
|
|||||||
Reference in New Issue
Block a user