Lots of refactoring
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "Materials/MaterialInterface.h"
|
#include "Materials/MaterialInterface.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "Materials/MaterialFunction.h"
|
#include "Materials/MaterialFunction.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "Materials/MaterialFunction.h"
|
#include "Materials/MaterialFunction.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "Materials/MaterialExpression.h"
|
#include "Materials/MaterialExpression.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "Materials/MaterialExpression.h"
|
#include "Materials/MaterialExpression.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "MaterialDomain.h"
|
#include "MaterialDomain.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/MaterialFunction.h"
|
#include "Materials/MaterialFunction.h"
|
||||||
#include "Materials/MaterialExpression.h"
|
#include "Materials/MaterialExpression.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "Materials/MaterialExpression.h"
|
#include "Materials/MaterialExpression.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "MCPPackageMaker.h"
|
#include "MCPPackageMaker.h"
|
||||||
#include "Animation/AnimBlueprint.h"
|
#include "Animation/AnimBlueprint.h"
|
||||||
@@ -39,14 +39,12 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback CB(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, CB);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
// Resolve skeleton
|
// Resolve skeleton
|
||||||
MCPAssets<USkeleton> SkeletonAssets;
|
MCPAssets<USkeleton> SkeletonAssets;
|
||||||
if (!SkeletonAssets.Exact(Skeleton).Errors(CB).ENone().ETwo().Load()) return;
|
if (!SkeletonAssets.Exact(Skeleton).ENone().ETwo().Load()) return;
|
||||||
USkeleton* SkeletonObj = SkeletonAssets.Object();
|
USkeleton* SkeletonObj = SkeletonAssets.Object();
|
||||||
|
|
||||||
// Resolve parent class (default: UAnimInstance)
|
// Resolve parent class (default: UAnimInstance)
|
||||||
@@ -64,7 +62,8 @@ public:
|
|||||||
}
|
}
|
||||||
if (!Found)
|
if (!Found)
|
||||||
{
|
{
|
||||||
return CB.SetError(FString::Printf(TEXT("Parent class '%s' not found (must derive from AnimInstance)"), *ParentClass));
|
UMCPServer::Printf(TEXT("ERROR: Parent class '%s' not found (must derive from AnimInstance)\n"), *ParentClass);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ParentClassObj = Found;
|
ParentClassObj = Found;
|
||||||
}
|
}
|
||||||
@@ -84,7 +83,8 @@ public:
|
|||||||
|
|
||||||
if (!NewAnimBP)
|
if (!NewAnimBP)
|
||||||
{
|
{
|
||||||
return CB.SetError(TEXT("FKismetEditorUtilities::CreateBlueprint returned null"));
|
UMCPServer::Print(TEXT("ERROR: FKismetEditorUtilities::CreateBlueprint returned null\n"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set target skeleton
|
// Set target skeleton
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Animation/AnimBlueprint.h"
|
#include "Animation/AnimBlueprint.h"
|
||||||
#include "AnimGraphNode_Base.h"
|
#include "AnimGraphNode_Base.h"
|
||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UAnimBlueprint> Assets;
|
MCPAssets<UAnimBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UAnimBlueprint* AnimBP = Assets.Object();
|
UAnimBlueprint* AnimBP = Assets.Object();
|
||||||
|
|
||||||
// Walk all anim nodes to collect slot names
|
// Walk all anim nodes to collect slot names
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Animation/AnimSequence.h"
|
#include "Animation/AnimSequence.h"
|
||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
{
|
{
|
||||||
// Load the blend space
|
// Load the blend space
|
||||||
MCPAssets<UBlendSpace> Assets;
|
MCPAssets<UBlendSpace> Assets;
|
||||||
if (!Assets.Exact(BlendSpace).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(BlendSpace).ENone().ETwo().Load()) return;
|
||||||
UBlendSpace* BS = Assets.Object();
|
UBlendSpace* BS = Assets.Object();
|
||||||
|
|
||||||
// Set axis parameters
|
// Set axis parameters
|
||||||
@@ -101,13 +101,13 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& SampleVal : Samples.Array)
|
for (const TSharedPtr<FJsonValue>& SampleVal : Samples.Array)
|
||||||
{
|
{
|
||||||
FBlendSpaceSampleEntry Entry;
|
FBlendSpaceSampleEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FBlendSpaceSampleEntry::StaticStruct(), &Entry, SampleVal, Result)) return;
|
if (!MCPUtils::PopulateFromJson(FBlendSpaceSampleEntry::StaticStruct(), &Entry, SampleVal)) return;
|
||||||
|
|
||||||
UAnimSequence* AnimSeq = nullptr;
|
UAnimSequence* AnimSeq = nullptr;
|
||||||
if (!Entry.AnimationAsset.IsEmpty())
|
if (!Entry.AnimationAsset.IsEmpty())
|
||||||
{
|
{
|
||||||
MCPAssets<UAnimSequence> AnimAssets;
|
MCPAssets<UAnimSequence> AnimAssets;
|
||||||
if (!AnimAssets.Exact(Entry.AnimationAsset).Errors(Result).ENone().Load()) return;
|
if (!AnimAssets.Exact(Entry.AnimationAsset).ENone().Load()) return;
|
||||||
AnimSeq = AnimAssets.Object();
|
AnimSeq = AnimAssets.Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Misc/PackageName.h"
|
#include "Misc/PackageName.h"
|
||||||
#include "AssetRegistry/AssetRegistryModule.h"
|
#include "AssetRegistry/AssetRegistryModule.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "AssetToolsModule.h"
|
#include "AssetToolsModule.h"
|
||||||
#include "IAssetTools.h"
|
#include "IAssetTools.h"
|
||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
{
|
{
|
||||||
// Load the asset
|
// Load the asset
|
||||||
MCPAssets<UObject> Assets;
|
MCPAssets<UObject> Assets;
|
||||||
if (!Assets.Exact(AssetPath).AllContent().Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(AssetPath).AllContent().ENone().ETwo().Load()) return;
|
||||||
UObject* AssetObj = Assets.Object();
|
UObject* AssetObj = Assets.Object();
|
||||||
|
|
||||||
// Parse new path into package path and asset name
|
// Parse new path into package path and asset name
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Asset_Search.generated.h"
|
#include "Asset_Search.generated.h"
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
Assets.Substring(Query);
|
Assets.Substring(Query);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assets.AllContent().Limit(Limit).Errors(Result).Info();
|
Assets.AllContent().Limit(Limit).Info();
|
||||||
|
|
||||||
const TArray<FAssetData>& AllData = Assets.AllData();
|
const TArray<FAssetData>& AllData = Assets.AllData();
|
||||||
for (const FAssetData& Data : AllData)
|
for (const FAssetData& Data : AllData)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "MCPPackageMaker.h"
|
#include "MCPPackageMaker.h"
|
||||||
#include "Animation/Skeleton.h"
|
#include "Animation/Skeleton.h"
|
||||||
@@ -33,14 +33,12 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback CB(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, CB);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
// Resolve skeleton.
|
// Resolve skeleton.
|
||||||
MCPAssets<USkeleton> SkeletonAssets;
|
MCPAssets<USkeleton> SkeletonAssets;
|
||||||
if (!SkeletonAssets.Exact(Skeleton).Errors(CB).ENone().ETwo().Load()) return;
|
if (!SkeletonAssets.Exact(Skeleton).ENone().ETwo().Load()) return;
|
||||||
USkeleton* SkeletonObj = SkeletonAssets.Object();
|
USkeleton* SkeletonObj = SkeletonAssets.Object();
|
||||||
|
|
||||||
// Create the package and Blend Space.
|
// Create the package and Blend Space.
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Engine/SimpleConstructionScript.h"
|
#include "Engine/SimpleConstructionScript.h"
|
||||||
#include "Engine/SCS_Node.h"
|
#include "Engine/SCS_Node.h"
|
||||||
@@ -42,15 +43,14 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
|
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
|
||||||
if (!SCS)
|
if (!SCS)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Blueprint '%s' does not have a SimpleConstructionScript (not an Actor Blueprint)\n"),
|
||||||
TEXT("Blueprint '%s' does not have a SimpleConstructionScript (not an Actor Blueprint)"),
|
*MCPUtils::FormatName(BP));
|
||||||
*MCPUtils::FormatName(BP)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,9 +61,8 @@ public:
|
|||||||
if (Existing && Existing->ComponentTemplate &&
|
if (Existing && Existing->ComponentTemplate &&
|
||||||
MCPUtils::Identifies(Component, Existing->ComponentTemplate))
|
MCPUtils::Identifies(Component, Existing->ComponentTemplate))
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: A component named '%s' already exists in Blueprint '%s'\n"),
|
||||||
TEXT("A component named '%s' already exists in Blueprint '%s'"),
|
*Component, *MCPUtils::FormatName(BP));
|
||||||
*Component, *MCPUtils::FormatName(BP)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,13 +71,12 @@ public:
|
|||||||
UClass* ComponentClassObj = MCPUtils::FindClassByName(ComponentClass);
|
UClass* ComponentClassObj = MCPUtils::FindClassByName(ComponentClass);
|
||||||
if (!ComponentClassObj || !ComponentClassObj->IsChildOf(UActorComponent::StaticClass()))
|
if (!ComponentClassObj || !ComponentClassObj->IsChildOf(UActorComponent::StaticClass()))
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Component class '%s' not found or is not a subclass of UActorComponent. "
|
||||||
TEXT("Component class '%s' not found or is not a subclass of UActorComponent. "
|
"Common classes: StaticMeshComponent, SkeletalMeshComponent, AudioComponent, "
|
||||||
"Common classes: StaticMeshComponent, SkeletalMeshComponent, AudioComponent, "
|
"SceneComponent, BoxCollisionComponent, SphereCollisionComponent, CapsuleComponent, "
|
||||||
"SceneComponent, BoxCollisionComponent, SphereCollisionComponent, CapsuleComponent, "
|
"ArrowComponent, ChildActorComponent, SpotLightComponent, PointLightComponent, "
|
||||||
"ArrowComponent, ChildActorComponent, SpotLightComponent, PointLightComponent, "
|
"WidgetComponent, BillboardComponent\n"),
|
||||||
"WidgetComponent, BillboardComponent"),
|
*ComponentClass);
|
||||||
*ComponentClass));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,9 +96,8 @@ public:
|
|||||||
|
|
||||||
if (!ParentSCSNode)
|
if (!ParentSCSNode)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Parent component '%s' not found in Blueprint '%s'\n"),
|
||||||
TEXT("Parent component '%s' not found in Blueprint '%s'"),
|
*ParentComponent, *MCPUtils::FormatName(BP));
|
||||||
*ParentComponent, *MCPUtils::FormatName(BP)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,9 +106,8 @@ public:
|
|||||||
USCS_Node* NewNode = SCS->CreateNode(ComponentClassObj, FName(*Component));
|
USCS_Node* NewNode = SCS->CreateNode(ComponentClassObj, FName(*Component));
|
||||||
if (!NewNode)
|
if (!NewNode)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Failed to create SCS node for component '%s' with class '%s'\n"),
|
||||||
TEXT("Failed to create SCS node for component '%s' with class '%s'"),
|
*Component, *MCPUtils::FormatName(ComponentClassObj));
|
||||||
*Component, *MCPUtils::FormatName(ComponentClassObj)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,11 +123,11 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& ParamVal : Parameters.Array)
|
for (const TSharedPtr<FJsonValue>& ParamVal : Parameters.Array)
|
||||||
{
|
{
|
||||||
FDispatcherParamEntry Entry;
|
FDispatcherParamEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FDispatcherParamEntry::StaticStruct(), &Entry, ParamVal, Result)) return;
|
if (!MCPUtils::PopulateFromJson(FDispatcherParamEntry::StaticStruct(), &Entry, ParamVal)) return;
|
||||||
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
|
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
|
||||||
|
|
||||||
FEdGraphPinType PinType;
|
FEdGraphPinType PinType;
|
||||||
if (!MCPUtils::ResolveTypeFromString(Entry.Type, PinType, Result))
|
if (!MCPUtils::ResolveTypeFromString(Entry.Type, PinType))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EntryNode->CreateUserDefinedPin(FName(*Entry.Name), PinType, EGPD_Output);
|
EntryNode->CreateUserDefinedPin(FName(*Entry.Name), PinType, EGPD_Output);
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "EdGraph/EdGraphPin.h"
|
||||||
@@ -44,12 +45,12 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
// Resolve param type
|
// Resolve param type
|
||||||
FEdGraphPinType PinType;
|
FEdGraphPinType PinType;
|
||||||
if (!MCPUtils::ResolveTypeFromString(ParamType, PinType, Result))
|
if (!MCPUtils::ResolveTypeFromString(ParamType, PinType))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Find the entry node using 3 strategies
|
// Find the entry node using 3 strategies
|
||||||
@@ -101,22 +102,21 @@ public:
|
|||||||
if (!EntryNode)
|
if (!EntryNode)
|
||||||
{
|
{
|
||||||
// Build a helpful error listing available functions, events, and dispatchers
|
// Build a helpful error listing available functions, events, and dispatchers
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Function/event/dispatcher '%s' not found. Available:\n"), *FunctionName);
|
||||||
TEXT("Function/event/dispatcher '%s' not found. Available:\n"), *FunctionName));
|
|
||||||
|
|
||||||
for (UEdGraph* Graph : BP->FunctionGraphs)
|
for (UEdGraph* Graph : BP->FunctionGraphs)
|
||||||
{
|
{
|
||||||
if (Graph) Result.Appendf(TEXT(" function: %s\n"), *MCPUtils::FormatName(Graph));
|
if (Graph) UMCPServer::Printf(TEXT(" function: %s\n"), *MCPUtils::FormatName(Graph));
|
||||||
}
|
}
|
||||||
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
|
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
|
||||||
{
|
{
|
||||||
Result.Appendf(TEXT(" custom event: %s\n"), *CE->CustomFunctionName.ToString());
|
UMCPServer::Printf(TEXT(" custom event: %s\n"), *CE->CustomFunctionName.ToString());
|
||||||
}
|
}
|
||||||
TSet<FName> DelegateNames;
|
TSet<FName> DelegateNames;
|
||||||
FBlueprintEditorUtils::GetDelegateNameList(BP, DelegateNames);
|
FBlueprintEditorUtils::GetDelegateNameList(BP, DelegateNames);
|
||||||
for (const FName& DN : DelegateNames)
|
for (const FName& DN : DelegateNames)
|
||||||
{
|
{
|
||||||
Result.Appendf(TEXT(" dispatcher: %s\n"), *DN.ToString());
|
UMCPServer::Printf(TEXT(" dispatcher: %s\n"), *DN.ToString());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -126,8 +126,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (Existing.IsValid() && Existing->PinName.ToString().Equals(ParamName, ESearchCase::IgnoreCase))
|
if (Existing.IsValid() && Existing->PinName.ToString().Equals(ParamName, ESearchCase::IgnoreCase))
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Parameter '%s' already exists on '%s'\n"), *ParamName, *FunctionName);
|
||||||
TEXT("Parameter '%s' already exists on '%s'"), *ParamName, *FunctionName));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
#include "UObject/UObjectIterator.h"
|
#include "UObject/UObjectIterator.h"
|
||||||
@@ -35,7 +36,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
// Resolve the interface class
|
// Resolve the interface class
|
||||||
@@ -47,9 +48,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (IfaceDesc.Interface == InterfaceClass)
|
if (IfaceDesc.Interface == InterfaceClass)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Interface '%s' is already implemented by this Blueprint.\n"),
|
||||||
TEXT("Interface '%s' is already implemented by this Blueprint."),
|
*MCPUtils::FormatName(InterfaceClass));
|
||||||
*MCPUtils::FormatName(InterfaceClass)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,9 +58,8 @@ public:
|
|||||||
bool bAdded = FBlueprintEditorUtils::ImplementNewInterface(BP, InterfacePath);
|
bool bAdded = FBlueprintEditorUtils::ImplementNewInterface(BP, InterfacePath);
|
||||||
if (!bAdded)
|
if (!bAdded)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: ImplementNewInterface failed for '%s'.\n"),
|
||||||
TEXT("ImplementNewInterface failed for '%s'."),
|
*MCPUtils::FormatName(InterfaceClass));
|
||||||
*MCPUtils::FormatName(InterfaceClass)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +94,7 @@ private:
|
|||||||
|
|
||||||
// Strategy 2: Try loading as a Blueprint Interface asset
|
// Strategy 2: Try loading as a Blueprint Interface asset
|
||||||
MCPAssets<UBlueprint> IfaceAssets;
|
MCPAssets<UBlueprint> IfaceAssets;
|
||||||
if (!IfaceAssets.Exact(Name).AllContent().Errors(Result).ETwo().Load()) return nullptr;
|
if (!IfaceAssets.Exact(Name).AllContent().ETwo().Load()) return nullptr;
|
||||||
if (!IfaceAssets.Objects().IsEmpty())
|
if (!IfaceAssets.Objects().IsEmpty())
|
||||||
{
|
{
|
||||||
UClass* GenClass = IfaceAssets.Object()->GeneratedClass;
|
UClass* GenClass = IfaceAssets.Object()->GeneratedClass;
|
||||||
@@ -103,9 +102,8 @@ private:
|
|||||||
return GenClass;
|
return GenClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Interface '%s' not found. Provide a Blueprint Interface asset name (e.g. 'BPI_MyInterface') or a native UInterface class name.\n"),
|
||||||
TEXT("Interface '%s' not found. Provide a Blueprint Interface asset name (e.g. 'BPI_MyInterface') or a native UInterface class name."),
|
*Name);
|
||||||
*Name));
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
#include "Blueprint_AddVariable.generated.h"
|
#include "Blueprint_AddVariable.generated.h"
|
||||||
@@ -45,7 +46,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
// Check for duplicate variable name
|
// Check for duplicate variable name
|
||||||
@@ -54,15 +55,14 @@ public:
|
|||||||
{
|
{
|
||||||
if (Var.VarName == VarFName)
|
if (Var.VarName == VarFName)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Variable '%s' already exists in %s\n"), *VariableName, *MCPUtils::FormatName(BP));
|
||||||
TEXT("Variable '%s' already exists in %s"), *VariableName, *MCPUtils::FormatName(BP)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the type
|
// Resolve the type
|
||||||
FEdGraphPinType PinType;
|
FEdGraphPinType PinType;
|
||||||
if (!MCPUtils::ResolveTypeFromString(VariableType, PinType, Result))
|
if (!MCPUtils::ResolveTypeFromString(VariableType, PinType))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IsArray)
|
if (IsArray)
|
||||||
@@ -71,8 +71,7 @@ public:
|
|||||||
// Add the variable
|
// Add the variable
|
||||||
if (!FBlueprintEditorUtils::AddMemberVariable(BP, VarFName, PinType, DefaultValue))
|
if (!FBlueprintEditorUtils::AddMemberVariable(BP, VarFName, PinType, DefaultValue))
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Failed to add variable '%s' to %s\n"), *VariableName, *MCPUtils::FormatName(BP));
|
||||||
TEXT("Failed to add variable '%s' to %s"), *VariableName, *MCPUtils::FormatName(BP)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "EdGraph/EdGraphPin.h"
|
||||||
@@ -47,12 +48,12 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
// Resolve the new type using the shared resolver (supports primitives, structs, enums, and object references)
|
// Resolve the new type using the shared resolver (supports primitives, structs, enums, and object references)
|
||||||
FEdGraphPinType NewPinType;
|
FEdGraphPinType NewPinType;
|
||||||
if (!MCPUtils::ResolveTypeFromString(NewType, NewPinType, Result))
|
if (!MCPUtils::ResolveTypeFromString(NewType, NewPinType))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Find the entry node: K2Node_FunctionEntry in a function graph,
|
// Find the entry node: K2Node_FunctionEntry in a function graph,
|
||||||
@@ -84,12 +85,11 @@ public:
|
|||||||
|
|
||||||
if (!EntryNode)
|
if (!EntryNode)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Function or custom event '%s' not found. Available:\n"), *FunctionName);
|
||||||
TEXT("Function or custom event '%s' not found. Available:"), *FunctionName));
|
|
||||||
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
|
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
|
||||||
Result.Appendf(TEXT(" function: %s\n"), *MCPUtils::FormatName(FE->GetGraph()));
|
UMCPServer::Printf(TEXT(" function: %s\n"), *MCPUtils::FormatName(FE->GetGraph()));
|
||||||
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
|
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
|
||||||
Result.Appendf(TEXT(" event: %s\n"), *MCPUtils::FormatName(static_cast<UEdGraphNode*>(CE)));
|
UMCPServer::Printf(TEXT(" event: %s\n"), *MCPUtils::FormatName(static_cast<UEdGraphNode*>(CE)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,11 +106,10 @@ public:
|
|||||||
|
|
||||||
if (!FoundPinInfo)
|
if (!FoundPinInfo)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Parameter '%s' not found. Available:\n"), *ParamName);
|
||||||
TEXT("Parameter '%s' not found. Available:"), *ParamName));
|
|
||||||
for (const TSharedPtr<FUserPinInfo>& PinInfo : EntryNode->UserDefinedPins)
|
for (const TSharedPtr<FUserPinInfo>& PinInfo : EntryNode->UserDefinedPins)
|
||||||
if (PinInfo.IsValid())
|
if (PinInfo.IsValid())
|
||||||
Result.Appendf(TEXT(" %s\n"), *PinInfo->PinName.ToString());
|
UMCPServer::Printf(TEXT(" %s\n"), *PinInfo->PinName.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraphPin.h"
|
#include "EdGraph/EdGraphPin.h"
|
||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
ResolveInput = TypeCategory + TEXT(":") + NewType;
|
ResolveInput = TypeCategory + TEXT(":") + NewType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MCPUtils::ResolveTypeFromString(ResolveInput, NewPinType, Result))
|
if (!MCPUtils::ResolveTypeFromString(ResolveInput, NewPinType))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// List affected nodes (get/set nodes for this variable)
|
// List affected nodes (get/set nodes for this variable)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
#include "Kismet2/KismetEditorUtilities.h"
|
||||||
@@ -88,7 +88,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Finder;
|
MCPAssets<UBlueprint> Finder;
|
||||||
Finder.Scan<UBlueprint>().Scan<UWorld>().Errors(Result);
|
Finder.Scan<UBlueprint>().Scan<UWorld>();
|
||||||
if (!Blueprint.IsEmpty())
|
if (!Blueprint.IsEmpty())
|
||||||
{
|
{
|
||||||
if (!Finder.Exact(Blueprint).ENone().ETwo().Info()) return;
|
if (!Finder.Exact(Blueprint).ENone().ETwo().Info()) return;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "MCPPackageMaker.h"
|
#include "MCPPackageMaker.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -36,9 +36,7 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback Error(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, Error);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
// Resolve parent class — try C++ class first, then Blueprint asset
|
// Resolve parent class — try C++ class first, then Blueprint asset
|
||||||
@@ -47,23 +45,23 @@ public:
|
|||||||
if (!ParentClassObj)
|
if (!ParentClassObj)
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> ParentAssets;
|
MCPAssets<UBlueprint> ParentAssets;
|
||||||
if (!ParentAssets.Exact(ParentClass).AllContent().Errors(Error).ETwo().Load()) return;
|
if (!ParentAssets.Exact(ParentClass).AllContent().ETwo().Load()) return;
|
||||||
if (!ParentAssets.Objects().IsEmpty() && ParentAssets.Object()->GeneratedClass)
|
if (!ParentAssets.Objects().IsEmpty() && ParentAssets.Object()->GeneratedClass)
|
||||||
ParentClassObj = ParentAssets.Object()->GeneratedClass;
|
ParentClassObj = ParentAssets.Object()->GeneratedClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ParentClassObj)
|
if (!ParentClassObj)
|
||||||
{
|
{
|
||||||
return Error.SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Could not find parent class '%s'. Provide a C++ class name (e.g. 'Actor', 'Pawn') or Blueprint name.\n"),
|
||||||
TEXT("Could not find parent class '%s'. Provide a C++ class name (e.g. 'Actor', 'Pawn') or Blueprint name."),
|
*ParentClass);
|
||||||
*ParentClass));
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map blueprintType string to EBlueprintType
|
// Map blueprintType string to EBlueprintType
|
||||||
EBlueprintType BlueprintTypeEnum = BPTYPE_Normal;
|
EBlueprintType BlueprintTypeEnum = BPTYPE_Normal;
|
||||||
if (!BlueprintType.IsEmpty())
|
if (!BlueprintType.IsEmpty())
|
||||||
{
|
{
|
||||||
if (!MCPUtils::StringToEnum(BlueprintType, BlueprintTypeEnum, Error, TEXT("BPTYPE_"))) return;
|
if (!MCPUtils::StringToEnum(BlueprintType, BlueprintTypeEnum, TEXT("BPTYPE_"))) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Interface type, parent must be UInterface
|
// For Interface type, parent must be UInterface
|
||||||
@@ -86,7 +84,8 @@ public:
|
|||||||
|
|
||||||
if (!NewBP)
|
if (!NewBP)
|
||||||
{
|
{
|
||||||
return Error.SetError(TEXT("FKismetEditorUtilities::CreateBlueprint returned null"));
|
UMCPServer::Print(TEXT("ERROR: FKismetEditorUtilities::CreateBlueprint returned null\n"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile and save
|
// Compile and save
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
@@ -41,11 +41,11 @@ public:
|
|||||||
{
|
{
|
||||||
// Load both blueprints
|
// Load both blueprints
|
||||||
MCPAssets<UBlueprint> AssetsA;
|
MCPAssets<UBlueprint> AssetsA;
|
||||||
if (!AssetsA.Exact(BlueprintA).Errors(Result).ENone().ETwo().Load()) return;
|
if (!AssetsA.Exact(BlueprintA).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BPA = AssetsA.Object();
|
UBlueprint* BPA = AssetsA.Object();
|
||||||
|
|
||||||
MCPAssets<UBlueprint> AssetsB;
|
MCPAssets<UBlueprint> AssetsB;
|
||||||
if (!AssetsB.Exact(BlueprintB).Errors(Result).ENone().ETwo().Load()) return;
|
if (!AssetsB.Exact(BlueprintB).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BPB = AssetsB.Object();
|
UBlueprint* BPB = AssetsB.Object();
|
||||||
|
|
||||||
// Gather graphs, optionally filtering by name
|
// Gather graphs, optionally filtering by name
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
{
|
{
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
int32 GraphCount = MCPUtils::AllGraphs(BP).Num();
|
int32 GraphCount = MCPUtils::AllGraphs(BP).Num();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "K2Node_FunctionEntry.h"
|
#include "K2Node_FunctionEntry.h"
|
||||||
#include "K2Node_CustomEvent.h"
|
#include "K2Node_CustomEvent.h"
|
||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
// Find the entry node (function entry or custom event)
|
// Find the entry node (function entry or custom event)
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
#include "Blueprint_RemoveInterface.generated.h"
|
#include "Blueprint_RemoveInterface.generated.h"
|
||||||
@@ -37,7 +38,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
// Find the interface by name
|
// Find the interface by name
|
||||||
@@ -54,12 +55,11 @@ public:
|
|||||||
|
|
||||||
if (!FoundInterface)
|
if (!FoundInterface)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Interface '%s' not found. Implemented interfaces:\n"), *InterfaceName);
|
||||||
TEXT("Interface '%s' not found. Implemented interfaces: "), *InterfaceName));
|
|
||||||
for (const FBPInterfaceDescription& IfaceDesc : BP->ImplementedInterfaces)
|
for (const FBPInterfaceDescription& IfaceDesc : BP->ImplementedInterfaces)
|
||||||
{
|
{
|
||||||
if (IfaceDesc.Interface)
|
if (IfaceDesc.Interface)
|
||||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(IfaceDesc.Interface));
|
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(IfaceDesc.Interface));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
#include "Kismet2/KismetEditorUtilities.h"
|
||||||
@@ -36,7 +37,7 @@ public:
|
|||||||
{
|
{
|
||||||
// Load Blueprint
|
// Load Blueprint
|
||||||
MCPAssets<UBlueprint> Assets;
|
MCPAssets<UBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UBlueprint* BP = Assets.Object();
|
UBlueprint* BP = Assets.Object();
|
||||||
|
|
||||||
FString OldParentName = BP->ParentClass ? MCPUtils::FormatName(BP->ParentClass) : TEXT("None");
|
FString OldParentName = BP->ParentClass ? MCPUtils::FormatName(BP->ParentClass) : TEXT("None");
|
||||||
@@ -47,16 +48,15 @@ public:
|
|||||||
if (!NewParentClassObj)
|
if (!NewParentClassObj)
|
||||||
{
|
{
|
||||||
MCPAssets<UBlueprint> ParentAssets;
|
MCPAssets<UBlueprint> ParentAssets;
|
||||||
if (!ParentAssets.Exact(NewParentClass).AllContent().Errors(Result).ETwo().Load()) return;
|
if (!ParentAssets.Exact(NewParentClass).AllContent().ETwo().Load()) return;
|
||||||
if (!ParentAssets.Objects().IsEmpty() && ParentAssets.Object()->GeneratedClass)
|
if (!ParentAssets.Objects().IsEmpty() && ParentAssets.Object()->GeneratedClass)
|
||||||
NewParentClassObj = ParentAssets.Object()->GeneratedClass;
|
NewParentClassObj = ParentAssets.Object()->GeneratedClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NewParentClassObj)
|
if (!NewParentClassObj)
|
||||||
{
|
{
|
||||||
MCPErrorCallback(Result).SetError(FString::Printf(
|
UMCPServer::Printf(TEXT("ERROR: Could not find class '%s'. Provide a C++ class name or Blueprint name.\n"),
|
||||||
TEXT("Could not find class '%s'. Provide a C++ class name or Blueprint name."),
|
*NewParentClass);
|
||||||
*NewParentClass));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UObject> Assets;
|
MCPAssets<UObject> Assets;
|
||||||
Assets.NoScans().Substring(Query).Limit(500).Errors(Result);
|
Assets.NoScans().Substring(Query).Limit(500);
|
||||||
if (IncludeRegular) Assets.Scan<UBlueprint>();
|
if (IncludeRegular) Assets.Scan<UBlueprint>();
|
||||||
if (IncludeLevel) Assets.Scan<UWorld>();
|
if (IncludeLevel) Assets.Scan<UWorld>();
|
||||||
Assets.Info();
|
Assets.Info();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Engine/UserDefinedEnum.h"
|
#include "Engine/UserDefinedEnum.h"
|
||||||
#include "Kismet2/EnumEditorUtils.h"
|
#include "Kismet2/EnumEditorUtils.h"
|
||||||
@@ -34,9 +34,7 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback Error(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, Error);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
TArray<FString> EnumValues;
|
TArray<FString> EnumValues;
|
||||||
@@ -47,7 +45,8 @@ public:
|
|||||||
}
|
}
|
||||||
if (EnumValues.Num() == 0)
|
if (EnumValues.Num() == 0)
|
||||||
{
|
{
|
||||||
return Error.SetError(TEXT("Values must be a non-empty array of strings"));
|
UMCPServer::Print(TEXT("ERROR: Values must be a non-empty array of strings\n"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the enum using AssetTools.
|
// Create the enum using AssetTools.
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& NodeVal : Nodes.Array)
|
for (const TSharedPtr<FJsonValue>& NodeVal : Nodes.Array)
|
||||||
{
|
{
|
||||||
FSpawnNodeEntry Entry;
|
FSpawnNodeEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FSpawnNodeEntry::StaticStruct(), &Entry, NodeVal, Result))
|
if (!MCPUtils::PopulateFromJson(FSpawnNodeEntry::StaticStruct(), &Entry, NodeVal))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Find the action by exact full name
|
// Find the action by exact full name
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
#include "EdGraph/EdGraphNode.h"
|
#include "EdGraph/EdGraphNode.h"
|
||||||
#include "MaterialGraph/MaterialGraphNode.h"
|
#include "MaterialGraph/MaterialGraphNode.h"
|
||||||
@@ -43,10 +44,9 @@ public:
|
|||||||
|
|
||||||
if (!FoundNode->CanUserDeleteNode())
|
if (!FoundNode->CanUserDeleteNode())
|
||||||
{
|
{
|
||||||
MCPErrorCallback Error(Result);
|
UMCPServer::Printf(TEXT("ERROR: Cannot delete node '%s' in graph '%s' — it is not deletable.\n"),
|
||||||
return Error.SetError(FString::Printf(
|
*NodeTitle, *GraphName);
|
||||||
TEXT("Cannot delete node '%s' in graph '%s' — it is not deletable."),
|
return;
|
||||||
*NodeTitle, *GraphName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cast<UMaterialGraphNode>(FoundNode))
|
if (Cast<UMaterialGraphNode>(FoundNode))
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ public:
|
|||||||
UEdGraphNode* Node = F.Node(Entry.Node).Cast<UEdGraphNode>();
|
UEdGraphNode* Node = F.Node(Entry.Node).Cast<UEdGraphNode>();
|
||||||
if (!Node) return;
|
if (!Node) return;
|
||||||
|
|
||||||
MCPProperty P = MCPProperty::GetOneExactMatch(Node, CPF_Edit, Entry.Name, Result);
|
MCPProperty P = MCPProperty::GetOneExactMatch(Node, CPF_Edit, Entry.Name);
|
||||||
if (!P) return;
|
if (!P) return;
|
||||||
|
|
||||||
UMCPServer::AddTouchedObject(Node);
|
UMCPServer::AddTouchedObject(Node);
|
||||||
|
|
||||||
if (!P.SetText(Entry.Value, Result))
|
if (!P.SetText(Entry.Value))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
|
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
|
||||||
{
|
{
|
||||||
FSetNodeDefaultEntry Entry;
|
FSetNodeDefaultEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FSetNodeDefaultEntry::StaticStruct(), &Entry, PinVal, Result))
|
if (!MCPUtils::PopulateFromJson(FSetNodeDefaultEntry::StaticStruct(), &Entry, PinVal))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (K2Schema)
|
if (K2Schema)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& NodeVal : Nodes.Array)
|
for (const TSharedPtr<FJsonValue>& NodeVal : Nodes.Array)
|
||||||
{
|
{
|
||||||
FMoveNodeEntry Entry;
|
FMoveNodeEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FMoveNodeEntry::StaticStruct(), &Entry, NodeVal, Result)) continue;
|
if (!MCPUtils::PopulateFromJson(FMoveNodeEntry::StaticStruct(), &Entry, NodeVal)) continue;
|
||||||
|
|
||||||
MCPFetcher FN(BP);
|
MCPFetcher FN(BP);
|
||||||
UEdGraphNode* Node = FN.Node(Entry.Node).Cast<UEdGraphNode>();
|
UEdGraphNode* Node = FN.Node(Entry.Node).Cast<UEdGraphNode>();
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& ConnVal : Connections.Array)
|
for (const TSharedPtr<FJsonValue>& ConnVal : Connections.Array)
|
||||||
{
|
{
|
||||||
FConnectPinsEntry Entry;
|
FConnectPinsEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FConnectPinsEntry::StaticStruct(), &Entry, ConnVal, Result))
|
if (!MCPUtils::PopulateFromJson(FConnectPinsEntry::StaticStruct(), &Entry, ConnVal))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MCPFetcher FS(G);
|
MCPFetcher FS(G);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& DiscVal : Disconnections.Array)
|
for (const TSharedPtr<FJsonValue>& DiscVal : Disconnections.Array)
|
||||||
{
|
{
|
||||||
FDisconnectPinEntry Entry;
|
FDisconnectPinEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FDisconnectPinEntry::StaticStruct(), &Entry, DiscVal, Result)) continue;
|
if (!MCPUtils::PopulateFromJson(FDisconnectPinEntry::StaticStruct(), &Entry, DiscVal)) continue;
|
||||||
|
|
||||||
MCPFetcher FP(G);
|
MCPFetcher FP(G);
|
||||||
UEdGraphPin* Pin = FP.Walk(Entry.Pin).Cast<UEdGraphPin>();
|
UEdGraphPin* Pin = FP.Walk(Entry.Pin).Cast<UEdGraphPin>();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/MaterialFunction.h"
|
#include "Materials/MaterialFunction.h"
|
||||||
#include "Factories/MaterialFunctionFactoryNew.h"
|
#include "Factories/MaterialFunctionFactoryNew.h"
|
||||||
@@ -33,9 +33,7 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback Error(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, Error);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
// Create via IAssetTools + factory.
|
// Create via IAssetTools + factory.
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
|
|
||||||
// Parse the association string.
|
// Parse the association string.
|
||||||
EMaterialParameterAssociation Association;
|
EMaterialParameterAssociation Association;
|
||||||
if (!MCPUtils::ParseMaterialParameterAssociation(ParameterAssociation, Association, Result))
|
if (!MCPUtils::ParseMaterialParameterAssociation(ParameterAssociation, Association))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
|
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "Materials/MaterialInterface.h"
|
#include "Materials/MaterialInterface.h"
|
||||||
@@ -35,9 +35,7 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback Error(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, Error);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
// Load parent material -- try as Material first, then as Material Instance.
|
// Load parent material -- try as Material first, then as Material Instance.
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public:
|
|||||||
|
|
||||||
// Parse the association string.
|
// Parse the association string.
|
||||||
EMaterialParameterAssociation Association;
|
EMaterialParameterAssociation Association;
|
||||||
if (!MCPUtils::ParseMaterialParameterAssociation(ParameterAssociation, Association, Result))
|
if (!MCPUtils::ParseMaterialParameterAssociation(ParameterAssociation, Association))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Build the parameter ID to look up.
|
// Build the parameter ID to look up.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "Materials/Material.h"
|
||||||
#include "MaterialDomain.h"
|
#include "MaterialDomain.h"
|
||||||
@@ -40,23 +40,21 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback Error(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, Error);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
// Parse optional enum properties before creating the asset.
|
// Parse optional enum properties before creating the asset.
|
||||||
EMaterialDomain ParsedDomain = MD_Surface;
|
EMaterialDomain ParsedDomain = MD_Surface;
|
||||||
if (!Domain.IsEmpty())
|
if (!Domain.IsEmpty())
|
||||||
{
|
{
|
||||||
if (!MCPUtils::StringToEnum(Domain, ParsedDomain, Error, TEXT("MD_")))
|
if (!MCPUtils::StringToEnum(Domain, ParsedDomain, TEXT("MD_")))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EBlendMode ParsedBlendMode = BLEND_Opaque;
|
EBlendMode ParsedBlendMode = BLEND_Opaque;
|
||||||
if (!BlendMode.IsEmpty())
|
if (!BlendMode.IsEmpty())
|
||||||
{
|
{
|
||||||
if (!MCPUtils::StringToEnum(BlendMode, ParsedBlendMode, Error, TEXT("BLEND_")))
|
if (!MCPUtils::StringToEnum(BlendMode, ParsedBlendMode, TEXT("BLEND_")))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
UObject* Template = F.Walk(Path).Template().Cast<UObject>();
|
UObject* Template = F.Walk(Path).Template().Cast<UObject>();
|
||||||
if (!Template) return;
|
if (!Template) return;
|
||||||
|
|
||||||
MCPProperty P = MCPProperty::GetOneExactMatch(Template, CPF_Edit, Property, Result);
|
MCPProperty P = MCPProperty::GetOneExactMatch(Template, CPF_Edit, Property);
|
||||||
if (!P) return;
|
if (!P) return;
|
||||||
|
|
||||||
Result.Append(P.GetText());
|
Result.Append(P.GetText());
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
TArray<TPair<MCPProperty, FString>> Resolved;
|
TArray<TPair<MCPProperty, FString>> Resolved;
|
||||||
for (const auto& Pair : Properties.Json->Values)
|
for (const auto& Pair : Properties.Json->Values)
|
||||||
{
|
{
|
||||||
MCPProperty P = MCPProperty::GetOneExactMatch(Template, CPF_Edit, Pair.Key, Result);
|
MCPProperty P = MCPProperty::GetOneExactMatch(Template, CPF_Edit, Pair.Key);
|
||||||
if (!P) return;
|
if (!P) return;
|
||||||
|
|
||||||
FString ValueStr;
|
FString ValueStr;
|
||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
int32 SuccessCount = 0;
|
int32 SuccessCount = 0;
|
||||||
for (auto& [P, ValueStr] : Resolved)
|
for (auto& [P, ValueStr] : Resolved)
|
||||||
{
|
{
|
||||||
if (!P.SetText(ValueStr, Result))
|
if (!P.SetText(ValueStr))
|
||||||
continue;
|
continue;
|
||||||
SuccessCount++;
|
SuccessCount++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
@@ -65,7 +65,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for duplicate state name
|
// Check for duplicate state name
|
||||||
if (MCPUtils::FindStateByName(SMGraph, StateName, nullptr))
|
if (MCPUtils::FindStateByName(SMGraph, StateName))
|
||||||
{
|
{
|
||||||
Result.Appendf(TEXT("ERROR: State '%s' already exists in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
|
Result.Appendf(TEXT("ERROR: State '%s' already exists in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
|
||||||
return;
|
return;
|
||||||
@@ -94,7 +94,7 @@ public:
|
|||||||
if (!AnimationAsset.IsEmpty() && NewState->GetBoundGraph())
|
if (!AnimationAsset.IsEmpty() && NewState->GetBoundGraph())
|
||||||
{
|
{
|
||||||
MCPAssets<UAnimSequence> AnimAssets;
|
MCPAssets<UAnimSequence> AnimAssets;
|
||||||
if (!AnimAssets.Exact(AnimationAsset).Errors(Result).ENone().ETwo().Load()) return;
|
if (!AnimAssets.Exact(AnimationAsset).ENone().ETwo().Load()) return;
|
||||||
|
|
||||||
UAnimGraphNode_SequencePlayer* SeqNode = NewObject<UAnimGraphNode_SequencePlayer>(NewState->GetBoundGraph());
|
UAnimGraphNode_SequencePlayer* SeqNode = NewObject<UAnimGraphNode_SequencePlayer>(NewState->GetBoundGraph());
|
||||||
SeqNode->CreateNewGuid();
|
SeqNode->CreateNewGuid();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
#include "Kismet2/KismetEditorUtilities.h"
|
||||||
#include "Animation/AnimBlueprint.h"
|
#include "Animation/AnimBlueprint.h"
|
||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UAnimBlueprint> Assets;
|
MCPAssets<UAnimBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UAnimBlueprint* AnimBP = Assets.Object();
|
UAnimBlueprint* AnimBP = Assets.Object();
|
||||||
|
|
||||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||||
@@ -61,10 +61,10 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UAnimStateNode* FromStateNode = MCPUtils::FindStateByName(SMGraph, FromState, Result);
|
UAnimStateNode* FromStateNode = MCPUtils::FindStateByName(SMGraph, FromState);
|
||||||
if (!FromStateNode) return;
|
if (!FromStateNode) return;
|
||||||
|
|
||||||
UAnimStateNode* ToStateNode = MCPUtils::FindStateByName(SMGraph, ToState, Result);
|
UAnimStateNode* ToStateNode = MCPUtils::FindStateByName(SMGraph, ToState);
|
||||||
if (!ToStateNode) return;
|
if (!ToStateNode) return;
|
||||||
|
|
||||||
// Create transition node
|
// Create transition node
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the state node
|
// Find the state node
|
||||||
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName, Result);
|
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName);
|
||||||
if (!StateNode) return;
|
if (!StateNode) return;
|
||||||
|
|
||||||
// Collect and remove transitions connected to this state
|
// Collect and remove transitions connected to this state
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the target state
|
// Find the target state
|
||||||
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName, Result);
|
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName);
|
||||||
if (!StateNode) return;
|
if (!StateNode) return;
|
||||||
|
|
||||||
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
|
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
|
||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
|
|
||||||
// Find the animation asset
|
// Find the animation asset
|
||||||
MCPAssets<UAnimSequence> AnimAssets;
|
MCPAssets<UAnimSequence> AnimAssets;
|
||||||
if (!AnimAssets.Exact(AnimationAsset).Errors(Result).ENone().ETwo().Load()) return;
|
if (!AnimAssets.Exact(AnimationAsset).ENone().ETwo().Load()) return;
|
||||||
UAnimSequence* AnimSeq = AnimAssets.Object();
|
UAnimSequence* AnimSeq = AnimAssets.Object();
|
||||||
|
|
||||||
// Find existing SequencePlayer or create one
|
// Find existing SequencePlayer or create one
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "EdGraph/EdGraph.h"
|
#include "EdGraph/EdGraph.h"
|
||||||
@@ -57,14 +57,14 @@ public:
|
|||||||
{
|
{
|
||||||
// Load the anim blueprint
|
// Load the anim blueprint
|
||||||
MCPAssets<UAnimBlueprint> Assets;
|
MCPAssets<UAnimBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UAnimBlueprint* AnimBP = Assets.Object();
|
UAnimBlueprint* AnimBP = Assets.Object();
|
||||||
|
|
||||||
// Find the state machine graph and state
|
// Find the state machine graph and state
|
||||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||||
if (!SMGraph) { Result.Appendf(TEXT("ERROR: State machine graph '%s' not found\n"), *Graph); return; }
|
if (!SMGraph) { Result.Appendf(TEXT("ERROR: State machine graph '%s' not found\n"), *Graph); return; }
|
||||||
|
|
||||||
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName, Result);
|
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName);
|
||||||
if (!StateNode) return;
|
if (!StateNode) return;
|
||||||
|
|
||||||
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
|
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
|
||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
|
|
||||||
// Load the blend space asset
|
// Load the blend space asset
|
||||||
MCPAssets<UBlendSpace> BlendSpaceAssets;
|
MCPAssets<UBlendSpace> BlendSpaceAssets;
|
||||||
if (!BlendSpaceAssets.Exact(BlendSpace).Errors(Result).ENone().ETwo().Load()) return;
|
if (!BlendSpaceAssets.Exact(BlendSpace).ENone().ETwo().Load()) return;
|
||||||
UBlendSpace* BlendSpaceAsset = BlendSpaceAssets.Object();
|
UBlendSpace* BlendSpaceAsset = BlendSpaceAssets.Object();
|
||||||
|
|
||||||
// Find existing BlendSpacePlayer or create one
|
// Find existing BlendSpacePlayer or create one
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
#include "Kismet2/KismetEditorUtilities.h"
|
||||||
#include "Animation/AnimBlueprint.h"
|
#include "Animation/AnimBlueprint.h"
|
||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPAssets<UAnimBlueprint> Assets;
|
MCPAssets<UAnimBlueprint> Assets;
|
||||||
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||||
UAnimBlueprint* AnimBP = Assets.Object();
|
UAnimBlueprint* AnimBP = Assets.Object();
|
||||||
|
|
||||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "StructUtils/UserDefinedStruct.h"
|
#include "StructUtils/UserDefinedStruct.h"
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
@@ -47,9 +47,7 @@ public:
|
|||||||
|
|
||||||
virtual void Handle(FStringBuilderBase& Result) override
|
virtual void Handle(FStringBuilderBase& Result) override
|
||||||
{
|
{
|
||||||
MCPErrorCallback Error(Result);
|
MCPPackageMaker Maker(AssetPath);
|
||||||
|
|
||||||
MCPPackageMaker Maker(AssetPath, Error);
|
|
||||||
if (!Maker.Ok()) return;
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
// Create the struct using the AssetTools factory.
|
// Create the struct using the AssetTools factory.
|
||||||
@@ -61,11 +59,11 @@ public:
|
|||||||
for (const TSharedPtr<FJsonValue>& PropVal : Properties.Array)
|
for (const TSharedPtr<FJsonValue>& PropVal : Properties.Array)
|
||||||
{
|
{
|
||||||
FStructPropertyEntry Entry;
|
FStructPropertyEntry Entry;
|
||||||
if (!MCPUtils::PopulateFromJson(FStructPropertyEntry::StaticStruct(), &Entry, PropVal, Result)) return;
|
if (!MCPUtils::PopulateFromJson(FStructPropertyEntry::StaticStruct(), &Entry, PropVal)) return;
|
||||||
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
|
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
|
||||||
|
|
||||||
FEdGraphPinType PinType;
|
FEdGraphPinType PinType;
|
||||||
if (!MCPUtils::ResolveTypeFromString(Entry.Type, PinType, Result))
|
if (!MCPUtils::ResolveTypeFromString(Entry.Type, PinType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Snapshot existing GUIDs so we can find the newly added one.
|
// Snapshot existing GUIDs so we can find the newly added one.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
#include "Engine/Level.h"
|
#include "Engine/Level.h"
|
||||||
@@ -46,12 +47,6 @@ MCPAssetsBase& MCPAssetsBase::AllContent()
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCPAssetsBase& MCPAssetsBase::Errors(MCPErrorCallback InCB)
|
|
||||||
{
|
|
||||||
ErrorCB = InCB;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool MCPAssetsBase::Info()
|
bool MCPAssetsBase::Info()
|
||||||
{
|
{
|
||||||
@@ -171,5 +166,5 @@ void MCPAssetsBase::SetError(const FString &Msg)
|
|||||||
{
|
{
|
||||||
AssetResults.Empty();
|
AssetResults.Empty();
|
||||||
UObjectResults.Empty();
|
UObjectResults.Empty();
|
||||||
ErrorCB.SetError(Msg);
|
UMCPServer::Printf(TEXT("ERROR: %s\n"), *Msg);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "MCPProperty.h"
|
#include "MCPProperty.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "Materials/MaterialExpression.h"
|
#include "Materials/MaterialExpression.h"
|
||||||
#include "MaterialGraph/MaterialGraphNode.h"
|
#include "MaterialGraph/MaterialGraphNode.h"
|
||||||
|
|
||||||
@@ -14,14 +15,14 @@ FString MCPProperty::GetText() const
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCPProperty::SetText(const FString& Value, MCPErrorCallback Error)
|
bool MCPProperty::SetText(const FString& Value)
|
||||||
{
|
{
|
||||||
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
||||||
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, nullptr, PPF_None);
|
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, nullptr, PPF_None);
|
||||||
if (!ImportResult)
|
if (!ImportResult)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Failed to parse '%s' for property '%s' (type: %s)"),
|
UMCPServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
|
||||||
*Value, *MCPUtils::FormatName(Prop), *Prop->GetCPPType()));
|
*Value, *MCPUtils::FormatName(Prop), *Prop->GetCPPType());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,19 +83,19 @@ TArray<MCPProperty> MCPProperty::GetAllExactMatch(UObject* Obj, EPropertyFlags F
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCPProperty MCPProperty::GetOneExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name, MCPErrorCallback Error)
|
MCPProperty MCPProperty::GetOneExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name)
|
||||||
{
|
{
|
||||||
TArray<MCPProperty> Matches = GetAllExactMatch(Obj, Flags, Name);
|
TArray<MCPProperty> Matches = GetAllExactMatch(Obj, Flags, Name);
|
||||||
if (Matches.Num() == 0)
|
if (Matches.Num() == 0)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Property '%s' not found on %s"),
|
UMCPServer::Printf(TEXT("ERROR: Property '%s' not found on %s\n"),
|
||||||
*Name, *MCPUtils::FormatName(Obj->GetClass())));
|
*Name, *MCPUtils::FormatName(Obj->GetClass()));
|
||||||
return MCPProperty();
|
return MCPProperty();
|
||||||
}
|
}
|
||||||
if (Matches.Num() > 1)
|
if (Matches.Num() > 1)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Ambiguous property '%s' on %s"),
|
UMCPServer::Printf(TEXT("ERROR: Ambiguous property '%s' on %s\n"),
|
||||||
*Name, *MCPUtils::FormatName(Obj->GetClass())));
|
*Name, *MCPUtils::FormatName(Obj->GetClass()));
|
||||||
return MCPProperty();
|
return MCPProperty();
|
||||||
}
|
}
|
||||||
return Matches[0];
|
return Matches[0];
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "LogCapture.h"
|
#include "LogCapture.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "MCPAssetFinder.h"
|
#include "MCPAssets.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"
|
||||||
@@ -289,12 +289,14 @@ FString UMCPServer::HandleRequest(const FString& Line)
|
|||||||
IMCPHandler* Handler = Cast<IMCPHandler>(HandlerObj.Get());
|
IMCPHandler* Handler = Cast<IMCPHandler>(HandlerObj.Get());
|
||||||
|
|
||||||
// Populate the handler object with the request parameters.
|
// Populate the handler object with the request parameters.
|
||||||
TStringBuilder<4096> PopulateError;
|
HandlerOutput.Reset();
|
||||||
if (!MCPUtils::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request, PopulateError))
|
if (!MCPUtils::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
||||||
{
|
{
|
||||||
PopulateError.Append(TEXT("\nUsage:\n"));
|
HandlerOutput.Append(TEXT("\nUsage:\n"));
|
||||||
MCPUtils::FormatCommandHelp(*HandlerClass, PopulateError);
|
MCPUtils::FormatCommandHelp(*HandlerClass, HandlerOutput);
|
||||||
return PopulateError.ToString();
|
FString Result = HandlerOutput.ToString();
|
||||||
|
HandlerOutput.Reset();
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the handler with log capture.
|
// Invoke the handler with log capture.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "Dom/JsonValue.h"
|
#include "Dom/JsonValue.h"
|
||||||
#include "Serialization/JsonReader.h"
|
#include "Serialization/JsonReader.h"
|
||||||
@@ -90,22 +91,6 @@ extern int32 TrySavePackageSEH(
|
|||||||
FSavePackageArgs* SaveArgs, ESavePackageResult* OutResult);
|
FSavePackageArgs* SaveArgs, ESavePackageResult* OutResult);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
// MCPErrorCallback
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
MCPErrorCallback::MCPErrorCallback(std::nullptr_t)
|
|
||||||
: Func([](const FString&) {})
|
|
||||||
{}
|
|
||||||
|
|
||||||
MCPErrorCallback::MCPErrorCallback(FString& OutError)
|
|
||||||
: Func([&OutError](const FString& Msg) { OutError = Msg; })
|
|
||||||
{}
|
|
||||||
|
|
||||||
MCPErrorCallback::MCPErrorCallback(FStringBuilderBase& OutResult)
|
|
||||||
: Func([&OutResult](const FString& Msg) { OutResult.Appendf(TEXT("ERROR: %s\n"), *Msg); })
|
|
||||||
{}
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Name Formatting
|
// Name Formatting
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -343,12 +328,12 @@ FString MCPUtils::EnumToString(UEnum* Enum, int64 Value, const FString& Prefix)
|
|||||||
return Full;
|
return Full;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCPUtils::StringToEnum(UEnum* Enum, const FString& Str, int64& OutValue, MCPErrorCallback Error, const FString& Prefix)
|
bool MCPUtils::StringToEnum(UEnum* Enum, const FString& Str, int64& OutValue, const FString& Prefix)
|
||||||
{
|
{
|
||||||
OutValue = Enum->GetValueByNameString(Prefix + Str);
|
OutValue = Enum->GetValueByNameString(Prefix + Str);
|
||||||
if (OutValue == INDEX_NONE)
|
if (OutValue == INDEX_NONE)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Invalid value '%s' for %s"), *Str, *Enum->GetName()));
|
UMCPServer::Printf(TEXT("ERROR: Invalid value '%s' for %s\n"), *Str, *Enum->GetName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -541,7 +526,7 @@ UClass* MCPUtils::FindClassByName(const FString& ClassName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MCPUtils::ResolveTypeFromString(
|
bool MCPUtils::ResolveTypeFromString(
|
||||||
const FString& TypeName, FEdGraphPinType& OutPinType, MCPErrorCallback Error)
|
const FString& TypeName, FEdGraphPinType& OutPinType)
|
||||||
{
|
{
|
||||||
FString TypeLower = TypeName.ToLower();
|
FString TypeLower = TypeName.ToLower();
|
||||||
|
|
||||||
@@ -614,7 +599,7 @@ bool MCPUtils::ResolveTypeFromString(
|
|||||||
UClass* FoundClass = FindClassByName(ClassName);
|
UClass* FoundClass = FindClassByName(ClassName);
|
||||||
if (!FoundClass)
|
if (!FoundClass)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Class '%s' not found for object reference type"), *ClassName));
|
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for object reference type\n"), *ClassName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Object;
|
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Object;
|
||||||
@@ -626,7 +611,7 @@ bool MCPUtils::ResolveTypeFromString(
|
|||||||
UClass* FoundClass = FindClassByName(ClassName);
|
UClass* FoundClass = FindClassByName(ClassName);
|
||||||
if (!FoundClass)
|
if (!FoundClass)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Class '%s' not found for soft object reference type"), *ClassName));
|
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for soft object reference type\n"), *ClassName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_SoftObject;
|
OutPinType.PinCategory = UEdGraphSchema_K2::PC_SoftObject;
|
||||||
@@ -638,7 +623,7 @@ bool MCPUtils::ResolveTypeFromString(
|
|||||||
UClass* FoundClass = FindClassByName(ClassName);
|
UClass* FoundClass = FindClassByName(ClassName);
|
||||||
if (!FoundClass)
|
if (!FoundClass)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Class '%s' not found for class reference type (TSubclassOf)"), *ClassName));
|
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for class reference type (TSubclassOf)\n"), *ClassName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Class;
|
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Class;
|
||||||
@@ -650,7 +635,7 @@ bool MCPUtils::ResolveTypeFromString(
|
|||||||
UClass* FoundClass = FindClassByName(ClassName);
|
UClass* FoundClass = FindClassByName(ClassName);
|
||||||
if (!FoundClass)
|
if (!FoundClass)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Class '%s' not found for soft class reference type"), *ClassName));
|
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for soft class reference type\n"), *ClassName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_SoftClass;
|
OutPinType.PinCategory = UEdGraphSchema_K2::PC_SoftClass;
|
||||||
@@ -662,7 +647,7 @@ bool MCPUtils::ResolveTypeFromString(
|
|||||||
UClass* FoundClass = FindClassByName(ClassName);
|
UClass* FoundClass = FindClassByName(ClassName);
|
||||||
if (!FoundClass)
|
if (!FoundClass)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Class '%s' not found for interface reference type"), *ClassName));
|
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found for interface reference type\n"), *ClassName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Interface;
|
OutPinType.PinCategory = UEdGraphSchema_K2::PC_Interface;
|
||||||
@@ -738,9 +723,9 @@ bool MCPUtils::ResolveTypeFromString(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(
|
UMCPServer::Printf(
|
||||||
TEXT("Unknown type '%s'. Use: bool, int, float, string, name, text, byte, vector, rotator, transform, object, a struct/enum name (e.g. FVector, EMyEnum), or colon syntax for references (object:Actor, softobject:Actor, class:Actor, softclass:Actor, interface:MyInterface)"),
|
TEXT("ERROR: Unknown type '%s'. Use: bool, int, float, string, name, text, byte, vector, rotator, transform, object, a struct/enum name (e.g. FVector, EMyEnum), or colon syntax for references (object:Actor, softobject:Actor, class:Actor, softclass:Actor, interface:MyInterface)\n"),
|
||||||
*TypeName));
|
*TypeName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -798,54 +783,6 @@ UMaterial* MCPUtils::ReplaceMaterialWithTransientCopy(UMaterial* Material)
|
|||||||
return Material;
|
return Material;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
// PreEdit / PostEdit
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
void MCPUtils::PreEdit(const TArray<UObject*>& Objects)
|
|
||||||
{
|
|
||||||
for (UObject* Obj : Objects)
|
|
||||||
Obj->PreEditChange(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MCPUtils::PostEdit(const TArray<UObject*>& Objects)
|
|
||||||
{
|
|
||||||
TSet<UEdGraphNode*> Nodes;
|
|
||||||
TSet<UEdGraph*> Graphs;
|
|
||||||
TSet<UMaterial*> Materials;
|
|
||||||
TSet<UBlueprint*> Blueprints;
|
|
||||||
for (int32 i = Objects.Num() - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
UObject* Obj = Objects[i];
|
|
||||||
Obj->PostEditChange();
|
|
||||||
Obj->MarkPackageDirty();
|
|
||||||
|
|
||||||
if (UEdGraphNode* Node = Cast<UEdGraphNode>(Obj))
|
|
||||||
Nodes.Add(Node);
|
|
||||||
|
|
||||||
if (UEdGraph* Graph = Cast<UEdGraph>(Obj))
|
|
||||||
Graphs.Add(Graph);
|
|
||||||
|
|
||||||
if (UBlueprint* BP = Cast<UBlueprint>(Obj))
|
|
||||||
Blueprints.Add(BP);
|
|
||||||
|
|
||||||
if (UMaterialInterface* MatIface = Cast<UMaterialInterface>(Obj))
|
|
||||||
if (UMaterial* BaseMat = MatIface->GetMaterial())
|
|
||||||
Materials.Add(BaseMat);
|
|
||||||
}
|
|
||||||
for (UEdGraphNode* Node : Nodes)
|
|
||||||
Node->ReconstructNode();
|
|
||||||
for (UEdGraph* Graph : Graphs)
|
|
||||||
Graph->NotifyGraphChanged();
|
|
||||||
for (UMaterial *Material : Materials)
|
|
||||||
UMaterialEditingLibrary::RebuildMaterialInstanceEditors(Material);
|
|
||||||
for (UBlueprint *Blueprint : Blueprints)
|
|
||||||
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(Blueprint);
|
|
||||||
|
|
||||||
if (GEditor)
|
|
||||||
GEditor->RedrawAllViewports();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> MCPUtils::GetMaterialParameters(UMaterialInterface* Material)
|
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> MCPUtils::GetMaterialParameters(UMaterialInterface* Material)
|
||||||
{
|
{
|
||||||
@@ -860,7 +797,7 @@ TMap<FMaterialParameterInfo, FMaterialParameterMetadata> MCPUtils::GetMaterialPa
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCPUtils::ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation, MCPErrorCallback Error)
|
bool MCPUtils::ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation)
|
||||||
{
|
{
|
||||||
if (Str.Equals(TEXT("Global"), ESearchCase::IgnoreCase))
|
if (Str.Equals(TEXT("Global"), ESearchCase::IgnoreCase))
|
||||||
OutAssociation = GlobalParameter;
|
OutAssociation = GlobalParameter;
|
||||||
@@ -870,7 +807,7 @@ bool MCPUtils::ParseMaterialParameterAssociation(const FString& Str, EMaterialPa
|
|||||||
OutAssociation = BlendParameter;
|
OutAssociation = BlendParameter;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Invalid ParameterAssociation '%s' (expected 'Global', 'Layer', or 'Blend')"), *Str));
|
UMCPServer::Printf(TEXT("ERROR: Invalid ParameterAssociation '%s' (expected 'Global', 'Layer', or 'Blend')\n"), *Str);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -984,7 +921,7 @@ UAnimationStateMachineGraph* MCPUtils::FindStateMachineGraph(UBlueprint* BP, con
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
UAnimStateNode* MCPUtils::FindStateByName(UAnimationStateMachineGraph* SMGraph, const FString& StateName, MCPErrorCallback Error)
|
UAnimStateNode* MCPUtils::FindStateByName(UAnimationStateMachineGraph* SMGraph, const FString& StateName)
|
||||||
{
|
{
|
||||||
for (UEdGraphNode* Node : SMGraph->Nodes)
|
for (UEdGraphNode* Node : SMGraph->Nodes)
|
||||||
{
|
{
|
||||||
@@ -996,7 +933,7 @@ UAnimStateNode* MCPUtils::FindStateByName(UAnimationStateMachineGraph* SMGraph,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Error.SetError(FString::Printf(TEXT("State '%s' not found in graph '%s'"), *StateName, *SMGraph->GetName()));
|
UMCPServer::Printf(TEXT("ERROR: State '%s' not found in graph '%s'\n"), *StateName, *SMGraph->GetName());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1229,22 +1166,20 @@ FString MCPUtils::SetPropertyFromJson(
|
|||||||
bool MCPUtils::PopulateFromJson(
|
bool MCPUtils::PopulateFromJson(
|
||||||
UStruct* StructType,
|
UStruct* StructType,
|
||||||
void* Container,
|
void* Container,
|
||||||
const TSharedPtr<FJsonValue>& JsonValue,
|
const TSharedPtr<FJsonValue>& JsonValue)
|
||||||
MCPErrorCallback Error)
|
|
||||||
{
|
{
|
||||||
if (!JsonValue.IsValid() || (JsonValue->Type != EJson::Object))
|
if (!JsonValue.IsValid() || (JsonValue->Type != EJson::Object))
|
||||||
{
|
{
|
||||||
Error.SetError(TEXT("Expected a JSON object"));
|
UMCPServer::Print(TEXT("ERROR: Expected a JSON object\n"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return PopulateFromJson(StructType, Container, JsonValue->AsObject().Get(), Error);
|
return PopulateFromJson(StructType, Container, JsonValue->AsObject().Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCPUtils::PopulateFromJson(
|
bool MCPUtils::PopulateFromJson(
|
||||||
UStruct* StructType,
|
UStruct* StructType,
|
||||||
void* Container,
|
void* Container,
|
||||||
const FJsonObject* Json,
|
const FJsonObject* Json)
|
||||||
MCPErrorCallback Error)
|
|
||||||
{
|
{
|
||||||
// Build a set of known property names (as JSON keys) for the unknown-field check.
|
// Build a set of known property names (as JSON keys) for the unknown-field check.
|
||||||
TSet<FString> KnownKeys;
|
TSet<FString> KnownKeys;
|
||||||
@@ -1262,7 +1197,7 @@ bool MCPUtils::PopulateFromJson(
|
|||||||
{
|
{
|
||||||
if (!KnownKeys.Contains(KV.Key))
|
if (!KnownKeys.Contains(KV.Key))
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Unknown parameter '%s'"), *KV.Key));
|
UMCPServer::Printf(TEXT("ERROR: Unknown parameter '%s'\n"), *KV.Key);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1277,7 +1212,7 @@ bool MCPUtils::PopulateFromJson(
|
|||||||
{
|
{
|
||||||
if (!bOptional)
|
if (!bOptional)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Missing required parameter '%s'"), *JsonKey));
|
UMCPServer::Printf(TEXT("ERROR: Missing required parameter '%s'\n"), *JsonKey);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -1286,7 +1221,7 @@ bool MCPUtils::PopulateFromJson(
|
|||||||
FString PropError = SetPropertyFromJson(Container, Prop, JsonKey, Json);
|
FString PropError = SetPropertyFromJson(Container, Prop, JsonKey, Json);
|
||||||
if (!PropError.IsEmpty())
|
if (!PropError.IsEmpty())
|
||||||
{
|
{
|
||||||
Error.SetError(PropError);
|
UMCPServer::Printf(TEXT("ERROR: %s\n"), *PropError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1369,11 +1304,11 @@ FString MCPUtils::FormatPropertyType(FProperty* Prop)
|
|||||||
// FindPropertyByName
|
// FindPropertyByName
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
FProperty* MCPUtils::FindPropertyByName(UObject* Obj, const FString& Name, MCPErrorCallback Error)
|
FProperty* MCPUtils::FindPropertyByName(UObject* Obj, const FString& Name)
|
||||||
{
|
{
|
||||||
if (!Obj)
|
if (!Obj)
|
||||||
{
|
{
|
||||||
Error.SetError(TEXT("Object is null"));
|
UMCPServer::Print(TEXT("ERROR: Object is null\n"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1383,14 +1318,14 @@ FProperty* MCPUtils::FindPropertyByName(UObject* Obj, const FString& Name, MCPEr
|
|||||||
if (!Identifies(Name, *PropIt)) continue;
|
if (!Identifies(Name, *PropIt)) continue;
|
||||||
if (Found)
|
if (Found)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Ambiguous property '%s' on %s"), *Name, *FormatName(Obj->GetClass())));
|
UMCPServer::Printf(TEXT("ERROR: Ambiguous property '%s' on %s\n"), *Name, *FormatName(Obj->GetClass()));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Found = *PropIt;
|
Found = *PropIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Found)
|
if (!Found)
|
||||||
Error.SetError(FString::Printf(TEXT("Property '%s' not found on %s"), *Name, *FormatName(Obj->GetClass())));
|
UMCPServer::Printf(TEXT("ERROR: Property '%s' not found on %s\n"), *Name, *FormatName(Obj->GetClass()));
|
||||||
|
|
||||||
return Found;
|
return Found;
|
||||||
}
|
}
|
||||||
@@ -1411,27 +1346,27 @@ FString MCPUtils::GetPropertyValueText(UObject* Container, FProperty* Prop)
|
|||||||
// SetPropertyValueText
|
// SetPropertyValueText
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
bool MCPUtils::SetPropertyValueText(UObject* Container, FProperty* Prop, const FString& Value, MCPErrorCallback Error)
|
bool MCPUtils::SetPropertyValueText(UObject* Container, FProperty* Prop, const FString& Value)
|
||||||
{
|
{
|
||||||
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
||||||
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, Container, PPF_None);
|
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, Container, PPF_None);
|
||||||
if (!ImportResult)
|
if (!ImportResult)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Failed to parse '%s' for property '%s' (type: %s)"),
|
UMCPServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
|
||||||
*Value, *FormatName(Prop), *Prop->GetCPPType()));
|
*Value, *FormatName(Prop), *Prop->GetCPPType());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCPUtils::SetPropertyValueText(void* Container, FProperty* Prop, const FString& Value, UObject* Owner, MCPErrorCallback Error)
|
bool MCPUtils::SetPropertyValueText(void* Container, FProperty* Prop, const FString& Value, UObject* Owner)
|
||||||
{
|
{
|
||||||
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
||||||
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, Owner, PPF_None);
|
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, Owner, PPF_None);
|
||||||
if (!ImportResult)
|
if (!ImportResult)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Failed to parse '%s' for property '%s' (type: %s)"),
|
UMCPServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
|
||||||
*Value, *FormatName(Prop), *Prop->GetCPPType()));
|
*Value, *FormatName(Prop), *Prop->GetCPPType());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -60,12 +60,7 @@ struct FARFilter;
|
|||||||
// Assets.EAny() - it's an error if anything is found
|
// Assets.EAny() - it's an error if anything is found
|
||||||
// Assets.ETwo() - it's an error if two or more are found
|
// Assets.ETwo() - it's an error if two or more are found
|
||||||
//
|
//
|
||||||
// Errors can be stored in variables, or in string builders,
|
// Errors are reported via UMCPServer::Printf.
|
||||||
// or in json trees. This example tells it to put error
|
|
||||||
// messages into a string variable:
|
|
||||||
//
|
|
||||||
// FString ErrorMessage;
|
|
||||||
// Assets.Errors(ErrorMessage)
|
|
||||||
//
|
//
|
||||||
// Once the Assets object is configured, it's time to scan
|
// Once the Assets object is configured, it's time to scan
|
||||||
// the assets. Use 'Info' if you just want to see
|
// the assets. Use 'Info' if you just want to see
|
||||||
@@ -87,7 +82,7 @@ struct FARFilter;
|
|||||||
//
|
//
|
||||||
// MCPAssets configuration methods can be chained:
|
// MCPAssets configuration methods can be chained:
|
||||||
//
|
//
|
||||||
// Assets.Limit(100).Errors(ErrMsg).ENone().ETwo();
|
// Assets.Limit(100).ENone().ETwo();
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -102,7 +97,6 @@ public:
|
|||||||
MCPAssetsBase& Limit(int32 Count) { MaxResults = Count; return *this; }
|
MCPAssetsBase& Limit(int32 Count) { MaxResults = Count; return *this; }
|
||||||
MCPAssetsBase& NoDerived();
|
MCPAssetsBase& NoDerived();
|
||||||
MCPAssetsBase& AllContent();
|
MCPAssetsBase& AllContent();
|
||||||
MCPAssetsBase& Errors(MCPErrorCallback InCB);
|
|
||||||
MCPAssetsBase& EAny() { bErrorIfAny = true; return *this; }
|
MCPAssetsBase& EAny() { bErrorIfAny = true; return *this; }
|
||||||
MCPAssetsBase& ENone() { bErrorIfNone = true; return *this; }
|
MCPAssetsBase& ENone() { bErrorIfNone = true; return *this; }
|
||||||
MCPAssetsBase& ETwo() { bErrorIfTwo = true; return *this; }
|
MCPAssetsBase& ETwo() { bErrorIfTwo = true; return *this; }
|
||||||
@@ -135,7 +129,6 @@ protected:
|
|||||||
bool bErrorIfNone = false;
|
bool bErrorIfNone = false;
|
||||||
bool bErrorIfTwo = false;
|
bool bErrorIfTwo = false;
|
||||||
int32 MaxResults = 50;
|
int32 MaxResults = 50;
|
||||||
MCPErrorCallback ErrorCB = MCPErrorCallback(nullptr);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPServer.h"
|
||||||
#include "UObject/Package.h"
|
#include "UObject/Package.h"
|
||||||
#include "AssetToolsModule.h"
|
#include "AssetToolsModule.h"
|
||||||
#include "IAssetTools.h"
|
#include "IAssetTools.h"
|
||||||
@@ -12,14 +12,13 @@
|
|||||||
class MCPPackageMaker
|
class MCPPackageMaker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MCPPackageMaker(const FString& InFullPath, MCPErrorCallback InError)
|
MCPPackageMaker(const FString& InFullPath)
|
||||||
: FullPath(InFullPath)
|
: FullPath(InFullPath)
|
||||||
, Error(InError)
|
|
||||||
{
|
{
|
||||||
// Path must start with /Game.
|
// Path must start with /Game.
|
||||||
if (!FullPath.StartsWith(TEXT("/Game")))
|
if (!FullPath.StartsWith(TEXT("/Game")))
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Package path '%s' must start with '/Game'"), *FullPath));
|
UMCPServer::Printf(TEXT("ERROR: Package path '%s' must start with '/Game'\n"), *FullPath);
|
||||||
bError = true;
|
bError = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -27,7 +26,7 @@ public:
|
|||||||
// Check for an existing asset at this path.
|
// Check for an existing asset at this path.
|
||||||
if (FindObject<UPackage>(nullptr, *FullPath))
|
if (FindObject<UPackage>(nullptr, *FullPath))
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("An asset already exists at '%s'"), *FullPath));
|
UMCPServer::Printf(TEXT("ERROR: An asset already exists at '%s'\n"), *FullPath);
|
||||||
bError = true;
|
bError = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -41,7 +40,7 @@ public:
|
|||||||
Pkg = CreatePackage(*FullPath);
|
Pkg = CreatePackage(*FullPath);
|
||||||
if (!Pkg)
|
if (!Pkg)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Failed to create package at '%s'"), *FullPath));
|
UMCPServer::Printf(TEXT("ERROR: Failed to create package at '%s'\n"), *FullPath);
|
||||||
bError = true;
|
bError = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -63,7 +62,7 @@ public:
|
|||||||
AssetClass* Result = Cast<AssetClass>(NewAsset);
|
AssetClass* Result = Cast<AssetClass>(NewAsset);
|
||||||
if (!Result)
|
if (!Result)
|
||||||
{
|
{
|
||||||
Error.SetError(FString::Printf(TEXT("Failed to create asset at '%s'"), *FullPath));
|
UMCPServer::Printf(TEXT("ERROR: Failed to create asset at '%s'\n"), *FullPath);
|
||||||
bError = true;
|
bError = true;
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
@@ -71,7 +70,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
FString FullPath;
|
FString FullPath;
|
||||||
MCPErrorCallback Error;
|
|
||||||
UPackage* Pkg = nullptr;
|
UPackage* Pkg = nullptr;
|
||||||
bool bError = false;
|
bool bError = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ struct MCPProperty
|
|||||||
MCPProperty(FProperty* InProp, void* Container);
|
MCPProperty(FProperty* InProp, void* Container);
|
||||||
|
|
||||||
FString GetText() const;
|
FString GetText() const;
|
||||||
bool SetText(const FString& Value, MCPErrorCallback Error = nullptr);
|
bool SetText(const FString& Value);
|
||||||
|
|
||||||
explicit operator bool() const { return Prop != nullptr; }
|
explicit operator bool() const { return Prop != nullptr; }
|
||||||
FProperty* operator->() const { return Prop; }
|
FProperty* operator->() const { return Prop; }
|
||||||
@@ -22,5 +22,5 @@ struct MCPProperty
|
|||||||
static TArray<MCPProperty> GetAll(UObject* Obj, EPropertyFlags Flags);
|
static TArray<MCPProperty> GetAll(UObject* Obj, EPropertyFlags Flags);
|
||||||
static TArray<MCPProperty> GetAllSubstring(UObject* Obj, EPropertyFlags Flags, const FString& Substring);
|
static TArray<MCPProperty> GetAllSubstring(UObject* Obj, EPropertyFlags Flags, const FString& Substring);
|
||||||
static TArray<MCPProperty> GetAllExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name);
|
static TArray<MCPProperty> GetAllExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name);
|
||||||
static MCPProperty GetOneExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name, MCPErrorCallback Error);
|
static MCPProperty GetOneExactMatch(UObject* Obj, EPropertyFlags Flags, const FString& Name);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,12 +39,12 @@ public:
|
|||||||
|
|
||||||
// FTickableEditorObject
|
// FTickableEditorObject
|
||||||
virtual void Tick(float DeltaTime) override;
|
virtual void Tick(float DeltaTime) override;
|
||||||
|
|
||||||
/** Static entry point for commandlet mode (no FTickableEditorObject). */
|
|
||||||
static void TickServer(float DeltaTime);
|
|
||||||
virtual bool IsTickable() const override;
|
virtual bool IsTickable() const override;
|
||||||
virtual TStatId GetStatId() const override;
|
virtual TStatId GetStatId() const override;
|
||||||
|
|
||||||
|
/** Tick entry point for commandlet mode (no FTickableEditorObject). */
|
||||||
|
static void TickServer(float DeltaTime);
|
||||||
|
|
||||||
/** Track an object that has been modified by the current handler. */
|
/** Track an object that has been modified by the current handler. */
|
||||||
static void AddTouchedObject(UObject* Obj) { GMCPServer->Notifier.AddTouchedObject(Obj); }
|
static void AddTouchedObject(UObject* Obj) { GMCPServer->Notifier.AddTouchedObject(Obj); }
|
||||||
|
|
||||||
|
|||||||
@@ -30,20 +30,6 @@ class UEnum;
|
|||||||
struct FMemberReference;
|
struct FMemberReference;
|
||||||
struct FBPVariableDescription;
|
struct FBPVariableDescription;
|
||||||
|
|
||||||
// ----- Error callback -----
|
|
||||||
|
|
||||||
struct MCPErrorCallback
|
|
||||||
{
|
|
||||||
TFunction<void(const FString&)> Func;
|
|
||||||
|
|
||||||
|
|
||||||
MCPErrorCallback(std::nullptr_t);
|
|
||||||
MCPErrorCallback(FString& OutError);
|
|
||||||
MCPErrorCallback(FStringBuilderBase& OutResult);
|
|
||||||
|
|
||||||
void SetError(const FString& Msg) const { Func(Msg); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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
|
||||||
@@ -113,7 +99,7 @@ public:
|
|||||||
|
|
||||||
// ----- Enum helpers -----
|
// ----- Enum helpers -----
|
||||||
static FString EnumToString(UEnum* Enum, int64 Value, const FString& Prefix = FString());
|
static FString EnumToString(UEnum* Enum, int64 Value, const FString& Prefix = FString());
|
||||||
static bool StringToEnum(UEnum* Enum, const FString& Str, int64& OutValue, MCPErrorCallback Error, const FString& Prefix = FString());
|
static bool StringToEnum(UEnum* Enum, const FString& Str, int64& OutValue, const FString& Prefix = FString());
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static FString EnumToString(TEnumAsByte<T> Value, const FString& Prefix = FString())
|
static FString EnumToString(TEnumAsByte<T> Value, const FString& Prefix = FString())
|
||||||
@@ -124,8 +110,8 @@ public:
|
|||||||
{ return EnumToString(StaticEnum<T>(), (int64)Value, Prefix); }
|
{ return EnumToString(StaticEnum<T>(), (int64)Value, Prefix); }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool StringToEnum(const FString& Str, T& OutValue, MCPErrorCallback Error, const FString& Prefix = FString())
|
static bool StringToEnum(const FString& Str, T& OutValue, const FString& Prefix = FString())
|
||||||
{ int64 V; if (!StringToEnum(StaticEnum<T>(), Str, V, Error, Prefix)) return false; OutValue = (T)V; return true; }
|
{ int64 V; if (!StringToEnum(StaticEnum<T>(), Str, V, Prefix)) return false; OutValue = (T)V; return true; }
|
||||||
|
|
||||||
// ----- Blueprint helpers -----
|
// ----- Blueprint helpers -----
|
||||||
static TArray<UEdGraph*> AllGraphs(UBlueprint* BP);
|
static TArray<UEdGraph*> AllGraphs(UBlueprint* BP);
|
||||||
@@ -152,7 +138,7 @@ public:
|
|||||||
|
|
||||||
// ----- Type resolution -----
|
// ----- Type resolution -----
|
||||||
static UClass* FindClassByName(const FString& ClassName);
|
static UClass* FindClassByName(const FString& ClassName);
|
||||||
static bool ResolveTypeFromString(const FString& TypeName, FEdGraphPinType& OutPinType, MCPErrorCallback Error);
|
static bool ResolveTypeFromString(const FString& TypeName, FEdGraphPinType& OutPinType);
|
||||||
static FString FormatPropertyType(FProperty* Prop);
|
static FString FormatPropertyType(FProperty* Prop);
|
||||||
|
|
||||||
// ----- Material helpers -----
|
// ----- Material helpers -----
|
||||||
@@ -166,36 +152,29 @@ public:
|
|||||||
|
|
||||||
// ----- Anim blueprint helpers -----
|
// ----- Anim blueprint helpers -----
|
||||||
static UAnimationStateMachineGraph* FindStateMachineGraph(UBlueprint* BP, const FString& GraphName);
|
static UAnimationStateMachineGraph* FindStateMachineGraph(UBlueprint* BP, const FString& GraphName);
|
||||||
static UAnimStateNode* FindStateByName(UAnimationStateMachineGraph* SMGraph, const FString& StateName, MCPErrorCallback Error);
|
static UAnimStateNode* FindStateByName(UAnimationStateMachineGraph* SMGraph, const FString& StateName);
|
||||||
static UAnimStateTransitionNode* FindTransition(UAnimationStateMachineGraph* SMGraph, const FString& FromStateName, const FString& ToStateName);
|
static UAnimStateTransitionNode* FindTransition(UAnimationStateMachineGraph* SMGraph, const FString& FromStateName, const FString& ToStateName);
|
||||||
|
|
||||||
// ----- Graph actions (node spawning) -----
|
// ----- Graph actions (node spawning) -----
|
||||||
static FString ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action);
|
static FString ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action);
|
||||||
static TArray<TSharedPtr<FEdGraphSchemaAction>> SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults = 0, bool ExactMatch = false);
|
static TArray<TSharedPtr<FEdGraphSchemaAction>> SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults = 0, bool ExactMatch = false);
|
||||||
|
|
||||||
// ----- Pre/Post edit -----
|
|
||||||
// Call before and after modifying objects. Walks the list looking for
|
|
||||||
// known parent types (UMaterial, UBlueprint, etc.) and issues the
|
|
||||||
// appropriate notifications.
|
|
||||||
static void PreEdit(const TArray<UObject*>& Objects);
|
|
||||||
static void PostEdit(const TArray<UObject*>& Objects);
|
|
||||||
|
|
||||||
// ----- Material Parameters -----
|
// ----- Material Parameters -----
|
||||||
static TMap<FMaterialParameterInfo, FMaterialParameterMetadata> GetMaterialParameters(UMaterialInterface* Material);
|
static TMap<FMaterialParameterInfo, FMaterialParameterMetadata> GetMaterialParameters(UMaterialInterface* Material);
|
||||||
static bool ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation, MCPErrorCallback Error = nullptr);
|
static bool ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation);
|
||||||
static void FormatMaterialParameter(FStringBuilderBase& Result, const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta);
|
static void FormatMaterialParameter(FStringBuilderBase& Result, const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta);
|
||||||
|
|
||||||
// ----- Editable template -----
|
// ----- Editable template -----
|
||||||
static TArray<FProperty*> SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal);
|
static TArray<FProperty*> SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal);
|
||||||
static FProperty* FindPropertyByName(UObject* Obj, const FString& Name, MCPErrorCallback Error = nullptr);
|
static FProperty* FindPropertyByName(UObject* Obj, const FString& Name);
|
||||||
static FString GetPropertyValueText(UObject* Container, FProperty* Prop);
|
static FString GetPropertyValueText(UObject* Container, FProperty* Prop);
|
||||||
static bool SetPropertyValueText(UObject* Container, FProperty* Prop, const FString& Value, MCPErrorCallback Error = nullptr);
|
static bool SetPropertyValueText(UObject* Container, FProperty* Prop, const FString& Value);
|
||||||
static bool SetPropertyValueText(void* Container, FProperty* Prop, const FString& Value, UObject* Owner, MCPErrorCallback Error = nullptr);
|
static bool SetPropertyValueText(void* Container, FProperty* Prop, const FString& Value, UObject* Owner);
|
||||||
|
|
||||||
// ----- JSON helpers -----
|
// ----- JSON helpers -----
|
||||||
static FString PropertyNameToJsonKey(const FString& PropName);
|
static FString PropertyNameToJsonKey(const FString& PropName);
|
||||||
static bool PopulateFromJson(UStruct* StructType, void* Container, const TSharedPtr<FJsonValue>& JsonValue, MCPErrorCallback Error);
|
static bool PopulateFromJson(UStruct* StructType, void* Container, const TSharedPtr<FJsonValue>& JsonValue);
|
||||||
static bool PopulateFromJson(UStruct* StructType, void* Container, const FJsonObject* Json, MCPErrorCallback Error);
|
static bool PopulateFromJson(UStruct* StructType, void* Container, const FJsonObject* Json);
|
||||||
|
|
||||||
// ----- Text formatting -----
|
// ----- Text formatting -----
|
||||||
static FString WrapText(const FString& Text, int32 ColLimit, const FString& Prefix);
|
static FString WrapText(const FString& Text, int32 ColLimit, const FString& Prefix);
|
||||||
|
|||||||
Reference in New Issue
Block a user