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