145 lines
4.1 KiB
C++
145 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "MCPHandler.h"
|
|
#include "MCPAssetFinder.h"
|
|
#include "MCPUtils.h"
|
|
#include "Engine/Blueprint.h"
|
|
#include "Engine/World.h"
|
|
#include "EdGraph/EdGraph.h"
|
|
#include "EdGraph/EdGraphNode.h"
|
|
#include "EdGraph/EdGraphPin.h"
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
|
#include "UMCPHandler_DisconnectBlueprintPins.generated.h"
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
|
|
USTRUCT()
|
|
struct FDisconnectPinEntry
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY()
|
|
FString Node;
|
|
|
|
UPROPERTY()
|
|
FString PinName;
|
|
|
|
UPROPERTY(meta=(Optional))
|
|
FString TargetNode;
|
|
|
|
UPROPERTY(meta=(Optional))
|
|
FString TargetPinName;
|
|
};
|
|
|
|
|
|
UCLASS()
|
|
class UMCPHandler_DisconnectBlueprintPins : public UObject, public IMCPHandler
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
FString Blueprint;
|
|
|
|
UPROPERTY(meta=(Description="Array of {node, pinName, targetNode?, targetPinName?} objects. If target is omitted, all connections on the pin are broken."))
|
|
FMCPJsonArray Disconnections;
|
|
|
|
virtual FString GetDescription() const override
|
|
{
|
|
return TEXT("Disconnect pins in a Blueprint graph. "
|
|
"Can disconnect a specific link or all links on a pin.");
|
|
}
|
|
|
|
virtual void Handle(const FJsonObject* Json, FJsonObject* Result) override
|
|
{
|
|
|
|
MCPAssets<UBlueprint> Assets;
|
|
if (!Assets.Exact(Blueprint).Errors(Result).ENone().ETwo().Load()) return;
|
|
UBlueprint* BP = Assets.Object();
|
|
|
|
TArray<TSharedPtr<FJsonValue>> Results;
|
|
int32 SuccessCount = 0;
|
|
int32 TotalDisconnected = 0;
|
|
|
|
for (const TSharedPtr<FJsonValue>& DiscVal : Disconnections.Array)
|
|
{
|
|
TSharedRef<FJsonObject> EntryResult = MakeShared<FJsonObject>();
|
|
Results.Add(MakeShared<FJsonValueObject>(EntryResult));
|
|
|
|
FDisconnectPinEntry Entry;
|
|
if (!MCPUtils::PopulateFromJson(FDisconnectPinEntry::StaticStruct(), &Entry, DiscVal, &*EntryResult)) continue;
|
|
|
|
UEdGraphNode* Node = MCPUtils::FindNodeByGuid(BP, Entry.Node);
|
|
if (!Node)
|
|
{
|
|
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Node '%s' not found"), *Entry.Node));
|
|
continue;
|
|
}
|
|
|
|
UEdGraphPin* Pin = Node->FindPin(FName(*Entry.PinName));
|
|
if (!Pin)
|
|
{
|
|
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Pin '%s' not found on node '%s'"), *Entry.PinName, *Entry.Node));
|
|
continue;
|
|
}
|
|
|
|
int32 DisconnectedCount = 0;
|
|
|
|
if (!Entry.TargetNode.IsEmpty() && !Entry.TargetPinName.IsEmpty())
|
|
{
|
|
UEdGraphNode* TargetNode = MCPUtils::FindNodeByGuid(BP, Entry.TargetNode);
|
|
if (!TargetNode)
|
|
{
|
|
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Target node '%s' not found"), *Entry.TargetNode));
|
|
continue;
|
|
}
|
|
|
|
UEdGraphPin* TargetPin = TargetNode->FindPin(FName(*Entry.TargetPinName));
|
|
if (!TargetPin)
|
|
{
|
|
EntryResult->SetStringField(TEXT("error"), FString::Printf(TEXT("Target pin '%s' not found on node '%s'"), *Entry.TargetPinName, *Entry.TargetNode));
|
|
continue;
|
|
}
|
|
|
|
if (!Pin->LinkedTo.Contains(TargetPin))
|
|
{
|
|
EntryResult->SetStringField(TEXT("error"), TEXT("The specified pins are not connected to each other"));
|
|
continue;
|
|
}
|
|
|
|
Pin->BreakLinkTo(TargetPin);
|
|
DisconnectedCount = 1;
|
|
}
|
|
else
|
|
{
|
|
DisconnectedCount = Pin->LinkedTo.Num();
|
|
if (DisconnectedCount > 0)
|
|
{
|
|
Pin->BreakAllPinLinks(true);
|
|
}
|
|
}
|
|
|
|
EntryResult->SetNumberField(TEXT("disconnectedCount"), DisconnectedCount);
|
|
SuccessCount++;
|
|
TotalDisconnected += DisconnectedCount;
|
|
}
|
|
|
|
if (TotalDisconnected > 0)
|
|
{
|
|
FBlueprintEditorUtils::MarkBlueprintAsModified(BP);
|
|
}
|
|
|
|
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: DisconnectPin — %d/%d succeeded, %d links broken in '%s'"),
|
|
SuccessCount, Disconnections.Array.Num(), TotalDisconnected, *Blueprint);
|
|
|
|
Result->SetNumberField(TEXT("successCount"), SuccessCount);
|
|
Result->SetNumberField(TEXT("totalCount"), Disconnections.Array.Num());
|
|
Result->SetNumberField(TEXT("totalDisconnected"), TotalDisconnected);
|
|
Result->SetArrayField(TEXT("results"), Results);
|
|
}
|
|
};
|