More handler wokr
This commit is contained in:
@@ -1,66 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "EdGraph/EdGraphPin.h"
|
||||
#include "GraphPin_GetDetails.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// ============================================================
|
||||
// HandleGetPinInfo — detailed information about a specific pin
|
||||
// ============================================================
|
||||
|
||||
UCLASS()
|
||||
class UMCP_GraphPin_GetDetails : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Path to the pin, e.g. /Game/Widgets/WB_Hotkeys,node:MyNode,pin:Result"))
|
||||
FString Pin;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Get detailed information about a specific pin on a blueprint node, "
|
||||
"including type, connections, and default values.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
MCPFetcher F(Result);
|
||||
UEdGraphPin* P = F.Walk(Pin).Cast<UEdGraphPin>();
|
||||
if (!P) return;
|
||||
|
||||
Result.Appendf(TEXT("Direction: %s\n"), P->Direction == EGPD_Input ? TEXT("Input") : TEXT("Output"));
|
||||
Result.Appendf(TEXT("Type: %s\n"), *MCPUtils::FormatPinType(P));
|
||||
|
||||
if (P->PinType.IsArray()) Result.Append(TEXT("Container: Array\n"));
|
||||
else if (P->PinType.IsSet()) Result.Append(TEXT("Container: Set\n"));
|
||||
else if (P->PinType.IsMap()) Result.Append(TEXT("Container: Map\n"));
|
||||
|
||||
if (P->PinType.bIsReference) Result.Append(TEXT("IsReference: true\n"));
|
||||
if (P->PinType.bIsConst) Result.Append(TEXT("IsConst: true\n"));
|
||||
|
||||
if (!P->DefaultValue.IsEmpty())
|
||||
Result.Appendf(TEXT("DefaultValue: %s\n"), *P->DefaultValue);
|
||||
if (!P->DefaultTextValue.IsEmpty())
|
||||
Result.Appendf(TEXT("DefaultTextValue: %s\n"), *P->DefaultTextValue.ToString());
|
||||
if (P->DefaultObject)
|
||||
Result.Appendf(TEXT("DefaultObject: %s\n"), *P->DefaultObject->GetPathName());
|
||||
|
||||
// Connected pins
|
||||
for (UEdGraphPin* Linked : P->LinkedTo)
|
||||
{
|
||||
if (!Linked || !Linked->GetOwningNode()) continue;
|
||||
Result.Appendf(TEXT("Connection: %s :: %s\n"),
|
||||
*MCPUtils::FormatName(Linked->GetOwningNode()),
|
||||
*MCPUtils::FormatName(Linked));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "EdGraph/EdGraphPin.h"
|
||||
#include "EdGraphSchema_K2.h"
|
||||
#include "GraphPin_SetDefault.generated.h"
|
||||
|
||||
|
||||
@@ -17,6 +18,9 @@ struct FSetPinDefaultEntry
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
FString Node;
|
||||
|
||||
UPROPERTY()
|
||||
FString Pin;
|
||||
|
||||
@@ -31,7 +35,10 @@ class UMCP_GraphPin_SetDefault : public UObject, public IMCPHandler
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Array of {pin, value} objects. Pin is a path like /Game/Foo,graph:EventGraph,node:MyNode,pin:InputPin"))
|
||||
UPROPERTY(meta=(Description="Graph path, e.g. /Game/Foo,graph:EventGraph"))
|
||||
FString Graph;
|
||||
|
||||
UPROPERTY(meta=(Description="Array of {node, pin, value} objects"))
|
||||
FMCPJsonArray Pins;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
@@ -41,18 +48,24 @@ public:
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
// Fetch the graph once.
|
||||
MCPFetcher GraphFetcher(Result);
|
||||
UEdGraph* GraphObj = GraphFetcher.Walk(Graph).Cast<UEdGraph>();
|
||||
if (!GraphObj) return;
|
||||
|
||||
int32 SuccessCount = 0;
|
||||
int32 TotalCount = Pins.Array.Num();
|
||||
TSet<UEdGraphNode*> ModifiedNodes;
|
||||
|
||||
GraphFetcher.PreEdit();
|
||||
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
|
||||
{
|
||||
FSetPinDefaultEntry Entry;
|
||||
if (!MCPUtils::PopulateFromJson(FSetPinDefaultEntry::StaticStruct(), &Entry, PinVal, Result))
|
||||
continue;
|
||||
|
||||
MCPFetcher F(Result);
|
||||
UEdGraphPin* Pin = F.Walk(Entry.Pin).Cast<UEdGraphPin>();
|
||||
MCPFetcher F(Result, GraphObj);
|
||||
UEdGraphPin* Pin = F.Node(Entry.Node).Pin(Entry.Pin).Cast<UEdGraphPin>();
|
||||
if (!Pin) continue;
|
||||
|
||||
UEdGraphNode* Node = Pin->GetOwningNode();
|
||||
@@ -63,21 +76,33 @@ public:
|
||||
continue;
|
||||
}
|
||||
|
||||
const UEdGraphSchema* Schema = Node->GetGraph()->GetSchema();
|
||||
if (Schema)
|
||||
const UEdGraphSchema_K2* Schema = Cast<UEdGraphSchema_K2>(Node->GetGraph()->GetSchema());
|
||||
check(Schema);
|
||||
|
||||
// Parse and validate the value before applying.
|
||||
FString UseDefaultValue;
|
||||
TObjectPtr<UObject> UseDefaultObject = nullptr;
|
||||
FText UseDefaultText;
|
||||
Schema->GetPinDefaultValuesFromString(Pin->PinType, Node, Entry.Value, UseDefaultValue, UseDefaultObject, UseDefaultText, false);
|
||||
FString Error = Schema->IsPinDefaultValid(Pin, UseDefaultValue, UseDefaultObject, UseDefaultText);
|
||||
if (!Error.IsEmpty())
|
||||
{
|
||||
Result.Appendf(TEXT("error: %s: %s\n"), *MCPUtils::FormatName(Pin), *Error);
|
||||
continue;
|
||||
}
|
||||
|
||||
Pin->Modify();
|
||||
Schema->TrySetDefaultValue(*Pin, Entry.Value);
|
||||
else
|
||||
Pin->DefaultValue = Entry.Value;
|
||||
|
||||
SuccessCount++;
|
||||
ModifiedNodes.Add(Node);
|
||||
F.PostEdit();
|
||||
}
|
||||
|
||||
for (UEdGraphNode* Node : ModifiedNodes)
|
||||
{
|
||||
Node->ReconstructNode();
|
||||
}
|
||||
GraphFetcher.PostEdit();
|
||||
|
||||
Result.Appendf(TEXT("Set %d/%d pin defaults.\n"), SuccessCount, TotalCount);
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "MaterialDomain.h"
|
||||
#include "Material_DumpProperties.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
class UMCP_Material_DumpProperties : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Material path"))
|
||||
FString Path;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("List top-level material properties such as domain, blend mode, shading model, and usage flags.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
MCPFetcher F(Result);
|
||||
UMaterial* Mat = F.Asset(Path).Cast<UMaterial>();
|
||||
if (!Mat) return;
|
||||
|
||||
Result.Appendf(TEXT("Material: %s\n"), *MCPUtils::FormatName(Mat));
|
||||
Result.Appendf(TEXT(" domain = %s\n"), *MCPUtils::EnumToString(Mat->MaterialDomain, TEXT("MD_")));
|
||||
Result.Appendf(TEXT(" blendMode = %s\n"), *MCPUtils::EnumToString(Mat->BlendMode, TEXT("BLEND_")));
|
||||
Result.Appendf(TEXT(" shadingModel = %s\n"), *MCPUtils::EnumToString(Mat->GetShadingModels().GetFirstShadingModel(), TEXT("MSM_")));
|
||||
Result.Appendf(TEXT(" opacityMaskClipValue = %g\n"), Mat->OpacityMaskClipValue);
|
||||
Result.Appendf(TEXT(" twoSided = %s\n"), Mat->TwoSided ? TEXT("true") : TEXT("false"));
|
||||
Result.Appendf(TEXT(" bUsedWithSkeletalMesh = %s\n"), Mat->bUsedWithSkeletalMesh ? TEXT("true") : TEXT("false"));
|
||||
Result.Appendf(TEXT(" bUsedWithMorphTargets = %s\n"), Mat->bUsedWithMorphTargets ? TEXT("true") : TEXT("false"));
|
||||
Result.Appendf(TEXT(" bUsedWithNiagaraSprites = %s\n"), Mat->bUsedWithNiagaraSprites ? TEXT("true") : TEXT("false"));
|
||||
Result.Appendf(TEXT(" ditheredLODTransition = %s\n"), Mat->DitheredLODTransition ? TEXT("true") : TEXT("false"));
|
||||
Result.Appendf(TEXT(" bAllowNegativeEmissiveColor = %s\n"), Mat->bAllowNegativeEmissiveColor ? TEXT("true") : TEXT("false"));
|
||||
}
|
||||
};
|
||||
@@ -1,114 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "MaterialDomain.h"
|
||||
#include "Material_SetProperty.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
class UMCP_Material_SetProperty : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Material path"))
|
||||
FString Path;
|
||||
|
||||
UPROPERTY(meta=(Description="Property name to set (domain, blendMode, twoSided, shadingModel, opacity, opacityMaskClipValue, bUsedWithSkeletalMesh, bUsedWithMorphTargets, bUsedWithNiagaraSprites, ditheredLODTransition, bAllowNegativeEmissiveColor)"))
|
||||
FString Property;
|
||||
|
||||
UPROPERTY(meta=(Description="Value to set"))
|
||||
FString Value;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Set a top-level material property such as domain, blend mode, shading model, or usage flags.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
MCPFetcher F(Result);
|
||||
UMaterial* Mat = F.Asset(Path).Cast<UMaterial>();
|
||||
if (!Mat) return;
|
||||
|
||||
// Parse value and build setter. Validation happens here so we can bail before PreEdit.
|
||||
TFunction<void()> Setter;
|
||||
|
||||
if (Property == TEXT("domain"))
|
||||
{
|
||||
EMaterialDomain NewDomain;
|
||||
if (!MCPUtils::StringToEnum(Value, NewDomain, Result, TEXT("MD_"))) return;
|
||||
Setter = [Mat, NewDomain]() { Mat->MaterialDomain = NewDomain; };
|
||||
}
|
||||
else if (Property == TEXT("blendMode"))
|
||||
{
|
||||
EBlendMode NewBlend;
|
||||
if (!MCPUtils::StringToEnum(Value, NewBlend, Result, TEXT("BLEND_"))) return;
|
||||
Setter = [Mat, NewBlend]() { Mat->BlendMode = NewBlend; };
|
||||
}
|
||||
else if (Property == TEXT("shadingModel"))
|
||||
{
|
||||
EMaterialShadingModel NewModel;
|
||||
if (!MCPUtils::StringToEnum(Value, NewModel, Result, TEXT("MSM_"))) return;
|
||||
Setter = [Mat, NewModel]() { Mat->SetShadingModel(NewModel); };
|
||||
}
|
||||
else if (Property == TEXT("opacity") || Property == TEXT("opacityMaskClipValue"))
|
||||
{
|
||||
float FloatVal = FCString::Atof(*Value);
|
||||
Setter = [Mat, FloatVal]() { Mat->OpacityMaskClipValue = FloatVal; };
|
||||
}
|
||||
else if (Property == TEXT("twoSided"))
|
||||
{
|
||||
bool bVal; if (!MCPUtils::StringToBool(Value, bVal, Result)) return;
|
||||
Setter = [Mat, bVal]() { Mat->TwoSided = bVal ? 1 : 0; };
|
||||
}
|
||||
else if (Property == TEXT("bUsedWithSkeletalMesh"))
|
||||
{
|
||||
bool bVal; if (!MCPUtils::StringToBool(Value, bVal, Result)) return;
|
||||
Setter = [Mat, bVal]() { Mat->bUsedWithSkeletalMesh = bVal ? 1 : 0; };
|
||||
}
|
||||
else if (Property == TEXT("bUsedWithMorphTargets"))
|
||||
{
|
||||
bool bVal; if (!MCPUtils::StringToBool(Value, bVal, Result)) return;
|
||||
Setter = [Mat, bVal]() { Mat->bUsedWithMorphTargets = bVal ? 1 : 0; };
|
||||
}
|
||||
else if (Property == TEXT("bUsedWithNiagaraSprites"))
|
||||
{
|
||||
bool bVal; if (!MCPUtils::StringToBool(Value, bVal, Result)) return;
|
||||
Setter = [Mat, bVal]() { Mat->bUsedWithNiagaraSprites = bVal ? 1 : 0; };
|
||||
}
|
||||
else if (Property == TEXT("ditheredLODTransition") || Property == TEXT("DitheredLODTransition"))
|
||||
{
|
||||
bool bVal; if (!MCPUtils::StringToBool(Value, bVal, Result)) return;
|
||||
Setter = [Mat, bVal]() { Mat->DitheredLODTransition = bVal ? 1 : 0; };
|
||||
}
|
||||
else if (Property == TEXT("bAllowNegativeEmissiveColor"))
|
||||
{
|
||||
bool bVal; if (!MCPUtils::StringToBool(Value, bVal, Result)) return;
|
||||
Setter = [Mat, bVal]() { Mat->bAllowNegativeEmissiveColor = bVal ? 1 : 0; };
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Unknown property '%s'. Valid: domain, blendMode, twoSided, shadingModel, "
|
||||
"opacity, opacityMaskClipValue, bUsedWithSkeletalMesh, bUsedWithMorphTargets, "
|
||||
"bUsedWithNiagaraSprites, ditheredLODTransition, bAllowNegativeEmissiveColor\n"), *Property);
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply the change between PreEdit/PostEdit.
|
||||
F.PreEdit();
|
||||
Setter();
|
||||
F.PostEdit();
|
||||
MCPUtils::SaveMaterialPackage(Mat);
|
||||
|
||||
Result.Appendf(TEXT("Set %s on %s\n"), *Property, *MCPUtils::FormatName(Mat));
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user