Renaming to UE Wingman begins

This commit is contained in:
2026-03-18 10:17:58 -04:00
parent 42fb0a8453
commit d910f9f14a
111 changed files with 1519 additions and 1871 deletions

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPPackageMaker.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingPackageMaker.h"
#include "Animation/AnimBlueprint.h"
#include "Animation/AnimBlueprintGeneratedClass.h"
#include "Animation/AnimInstance.h"
@@ -19,7 +19,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_AnimBlueprint_Create : public UObject, public IMCPHandler
class UWing_AnimBlueprint_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -40,11 +40,11 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(AssetPath);
WingPackageMaker Maker(AssetPath);
if (!Maker.Ok()) return;
// Resolve skeleton
MCPFetcher SkeletonFetcher;
WingFetcher SkeletonFetcher;
USkeleton* SkeletonObj = SkeletonFetcher.Asset(Skeleton).Cast<USkeleton>();
if (!SkeletonObj) return;
@@ -55,7 +55,7 @@ public:
UClass* Found = nullptr;
for (TObjectIterator<UClass> It; It; ++It)
{
if (It->IsChildOf(UAnimInstance::StaticClass()) && MCPUtils::Identifies(ParentClass, *It))
if (It->IsChildOf(UAnimInstance::StaticClass()) && WingUtils::Identifies(ParentClass, *It))
{
Found = *It;
break;
@@ -63,7 +63,7 @@ public:
}
if (!Found)
{
UMCPServer::Printf(TEXT("ERROR: Parent class '%s' not found (must derive from AnimInstance)\n"), *ParentClass);
UWingServer::Printf(TEXT("ERROR: Parent class '%s' not found (must derive from AnimInstance)\n"), *ParentClass);
return;
}
ParentClassObj = Found;
@@ -84,7 +84,7 @@ public:
if (!NewAnimBP)
{
UMCPServer::Print(TEXT("ERROR: FKismetEditorUtilities::CreateBlueprint returned null\n"));
UWingServer::Print(TEXT("ERROR: FKismetEditorUtilities::CreateBlueprint returned null\n"));
return;
}
@@ -93,16 +93,16 @@ public:
// Compile and save
FKismetEditorUtilities::CompileBlueprint(NewAnimBP);
bool bSaved = MCPUtils::SaveBlueprintPackage(NewAnimBP);
bool bSaved = WingUtils::SaveBlueprintPackage(NewAnimBP);
UMCPServer::Printf(TEXT("Created: %s\n"), *AssetPath);
UMCPServer::Printf(TEXT("ParentClass: %s\n"), *MCPUtils::FormatName(ParentClassObj));
UMCPServer::Printf(TEXT("Saved: %s\n"), bSaved ? TEXT("true") : TEXT("false"));
UWingServer::Printf(TEXT("Created: %s\n"), *AssetPath);
UWingServer::Printf(TEXT("ParentClass: %s\n"), *WingUtils::FormatName(ParentClassObj));
UWingServer::Printf(TEXT("Saved: %s\n"), bSaved ? TEXT("true") : TEXT("false"));
TArray<UEdGraph*> Graphs = MCPUtils::AllGraphs(NewAnimBP);
TArray<UEdGraph*> Graphs = WingUtils::AllGraphs(NewAnimBP);
for (UEdGraph* Graph : Graphs)
{
UMCPServer::Printf(TEXT("Graph: %s\n"), *MCPUtils::FormatName(Graph));
UWingServer::Printf(TEXT("Graph: %s\n"), *WingUtils::FormatName(Graph));
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Animation/AnimBlueprint.h"
#include "AnimGraphNode_Base.h"
#include "AnimBlueprint_ListSlotNames.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_AnimBlueprint_ListSlotNames : public UObject, public IMCPHandler
class UWing_AnimBlueprint_ListSlotNames : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -30,13 +30,13 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UAnimBlueprint* AnimBP = F.Asset(Blueprint).Cast<UAnimBlueprint>();
if (!AnimBP) return;
// Walk all anim nodes to collect slot names
TSet<FString> SlotNames;
for (UAnimGraphNode_Base* AnimNode : MCPUtils::AllNodes<UAnimGraphNode_Base>(AnimBP))
for (UAnimGraphNode_Base* AnimNode : WingUtils::AllNodes<UAnimGraphNode_Base>(AnimBP))
{
for (TFieldIterator<FNameProperty> PropIt(AnimNode->GetClass()); PropIt; ++PropIt)
{
@@ -53,12 +53,12 @@ public:
for (const FString& Slot : SlotNames)
{
UMCPServer::Printf(TEXT("%s\n"), *Slot);
UWingServer::Printf(TEXT("%s\n"), *Slot);
}
if (SlotNames.Num() == 0)
{
UMCPServer::Print(TEXT("No animation slot names found.\n"));
UWingServer::Print(TEXT("No animation slot names found.\n"));
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Animation/AnimBlueprint.h"
#include "AnimGraphNode_Base.h"
#include "AnimBlueprint_ListSyncGroups.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_AnimBlueprint_ListSyncGroups : public UObject, public IMCPHandler
class UWing_AnimBlueprint_ListSyncGroups : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -30,13 +30,13 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UAnimBlueprint* AnimBP = F.Walk(Blueprint).Cast<UAnimBlueprint>();
if (!AnimBP) return;
// Walk all anim nodes to collect sync group names
TSet<FString> SyncGroupNames;
for (UAnimGraphNode_Base* AnimNode : MCPUtils::AllNodes<UAnimGraphNode_Base>(AnimBP))
for (UAnimGraphNode_Base* AnimNode : WingUtils::AllNodes<UAnimGraphNode_Base>(AnimBP))
{
for (TFieldIterator<FNameProperty> PropIt(AnimNode->GetClass()); PropIt; ++PropIt)
{
@@ -53,13 +53,13 @@ public:
if (SyncGroupNames.Num() == 0)
{
UMCPServer::Print(TEXT("No sync groups found.\n"));
UWingServer::Print(TEXT("No sync groups found.\n"));
return;
}
for (const FString& Group : SyncGroupNames)
{
UMCPServer::Printf(TEXT("%s\n"), *Group);
UWingServer::Printf(TEXT("%s\n"), *Group);
}
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "Animation/AnimSequence.h"
#include "Animation/BlendSpace.h"
#include "AnimBlueprint_SetBlendSpaceSamples.generated.h"
@@ -31,7 +31,7 @@ struct FBlendSpaceSampleEntry
};
UCLASS()
class UMCP_AnimBlueprint_SetBlendSpaceSamples : public UObject, public IMCPHandler
class UWing_AnimBlueprint_SetBlendSpaceSamples : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -58,7 +58,7 @@ public:
float AxisYMax = 0.0f;
UPROPERTY(meta=(Optional, Description="Array of sample points, each with animationAsset, x, y"))
FMCPJsonArray Samples;
FWingJsonArray Samples;
virtual FString GetDescription() const override
{
@@ -69,7 +69,7 @@ public:
virtual void Handle() override
{
// Load the blend space
MCPFetcher F;
WingFetcher F;
UBlendSpace* BS = F.Asset(BlendSpace).Cast<UBlendSpace>();
if (!BS) return;
@@ -102,12 +102,12 @@ public:
for (const TSharedPtr<FJsonValue>& SampleVal : Samples.Array)
{
FBlendSpaceSampleEntry Entry;
if (!MCPJson::PopulateFromJson(FBlendSpaceSampleEntry::StaticStruct(), &Entry, SampleVal)) return;
if (!WingJson::PopulateFromJson(FBlendSpaceSampleEntry::StaticStruct(), &Entry, SampleVal)) return;
UAnimSequence* AnimSeq = nullptr;
if (!Entry.AnimationAsset.IsEmpty())
{
MCPFetcher F2;
WingFetcher F2;
AnimSeq = F2.Asset(Entry.AnimationAsset).Cast<UAnimSequence>();
if (!AnimSeq) return;
}
@@ -127,12 +127,12 @@ public:
BS->ValidateSampleData();
// Save
bool bSaved = MCPUtils::SaveGenericPackage(BS);
bool bSaved = WingUtils::SaveGenericPackage(BS);
UMCPServer::Printf(TEXT("Set %d samples on %s\n"), SamplesSet, *MCPUtils::FormatName(BS));
UWingServer::Printf(TEXT("Set %d samples on %s\n"), SamplesSet, *WingUtils::FormatName(BS));
if (!bSaved)
{
UMCPServer::Print(TEXT("WARNING: package save failed\n"));
UWingServer::Print(TEXT("WARNING: package save failed\n"));
}
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPPackageMaker.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingPackageMaker.h"
#include "Animation/Skeleton.h"
#include "Animation/BlendSpace.h"
#include "BlendSpace_Create.generated.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlendSpace_Create : public UObject, public IMCPHandler
class UWing_BlendSpace_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,11 +34,11 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(AssetPath);
WingPackageMaker Maker(AssetPath);
if (!Maker.Ok()) return;
// Resolve skeleton.
MCPFetcher SkeletonFetcher;
WingFetcher SkeletonFetcher;
USkeleton* SkeletonObj = SkeletonFetcher.Asset(Skeleton).Cast<USkeleton>();
if (!SkeletonObj) return;
@@ -47,7 +47,7 @@ public:
UBlendSpace* NewBS = NewObject<UBlendSpace>(Maker.Package(), FName(*Maker.Name()), RF_Public | RF_Standalone);
if (!NewBS)
{
UMCPServer::Print(TEXT("ERROR: Failed to create Blend Space object\n"));
UWingServer::Print(TEXT("ERROR: Failed to create Blend Space object\n"));
return;
}
@@ -55,11 +55,11 @@ public:
NewBS->SetSkeleton(SkeletonObj);
NewBS->MarkPackageDirty();
bool bSaved = MCPUtils::SaveGenericPackage(NewBS);
bool bSaved = WingUtils::SaveGenericPackage(NewBS);
UMCPServer::Printf(TEXT("Created %s\n"), *NewBS->GetPathName());
UMCPServer::Printf(TEXT("Skeleton: %s\n"), *SkeletonObj->GetPathName());
UWingServer::Printf(TEXT("Created %s\n"), *NewBS->GetPathName());
UWingServer::Printf(TEXT("Skeleton: %s\n"), *SkeletonObj->GetPathName());
if (!bSaved)
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
UWingServer::Print(TEXT("WARNING: Package save failed\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
@@ -19,7 +19,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlueprintGraph_Create : public UObject, public IMCPHandler
class UWing_BlueprintGraph_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -42,29 +42,29 @@ public:
{
if (GraphType != TEXT("function") && GraphType != TEXT("macro") && GraphType != TEXT("customEvent"))
{
UMCPServer::Printf(TEXT("ERROR: Invalid GraphType '%s'. Valid values: function, macro, customEvent\n"), *GraphType);
UWingServer::Printf(TEXT("ERROR: Invalid GraphType '%s'. Valid values: function, macro, customEvent\n"), *GraphType);
return;
}
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
// Check graph name uniqueness
if (!MCPUtils::AllGraphsNamed(BP, Graph).IsEmpty())
if (!WingUtils::AllGraphsNamed(BP, Graph).IsEmpty())
{
UMCPServer::Printf(TEXT("ERROR: A graph named '%s' already exists in %s\n"), *Graph, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: A graph named '%s' already exists in %s\n"), *Graph, *WingUtils::FormatName(BP));
return;
}
// For custom events, also check for existing custom events with the same name
if (GraphType == TEXT("customEvent"))
{
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
for (UK2Node_CustomEvent* CE : WingUtils::AllNodes<UK2Node_CustomEvent>(BP))
{
if (CE->CustomFunctionName == FName(*Graph))
{
UMCPServer::Printf(TEXT("ERROR: A custom event named '%s' already exists in %s\n"), *Graph, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: A custom event named '%s' already exists in %s\n"), *Graph, *WingUtils::FormatName(BP));
return;
}
}
@@ -76,11 +76,11 @@ public:
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
if (!NewGraph)
{
UMCPServer::Print(TEXT("ERROR: Failed to create function graph\n"));
UWingServer::Print(TEXT("ERROR: Failed to create function graph\n"));
return;
}
FBlueprintEditorUtils::AddFunctionGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromObject=*/static_cast<UClass*>(nullptr));
UMCPServer::Printf(TEXT("Created function graph: %s\n"), *MCPUtils::FormatName(NewGraph));
UWingServer::Printf(TEXT("Created function graph: %s\n"), *WingUtils::FormatName(NewGraph));
}
else if (GraphType == TEXT("macro"))
{
@@ -88,11 +88,11 @@ public:
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
if (!NewGraph)
{
UMCPServer::Print(TEXT("ERROR: Failed to create macro graph\n"));
UWingServer::Print(TEXT("ERROR: Failed to create macro graph\n"));
return;
}
FBlueprintEditorUtils::AddMacroGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromClass=*/nullptr);
UMCPServer::Printf(TEXT("Created macro graph: %s\n"), *MCPUtils::FormatName(NewGraph));
UWingServer::Printf(TEXT("Created macro graph: %s\n"), *WingUtils::FormatName(NewGraph));
}
else // customEvent
{
@@ -101,7 +101,7 @@ public:
EventGraph = BP->UbergraphPages[0];
if (!EventGraph)
{
UMCPServer::Print(TEXT("ERROR: Blueprint has no EventGraph to add a custom event to\n"));
UWingServer::Print(TEXT("ERROR: Blueprint has no EventGraph to add a custom event to\n"));
return;
}
@@ -112,9 +112,9 @@ public:
NewEvent->CreateNewGuid();
NewEvent->PostPlacedNewNode();
NewEvent->AllocateDefaultPins();
UMCPServer::Printf(TEXT("Created custom event: %s\n"), *MCPUtils::FormatName(NewEvent));
UWingServer::Printf(TEXT("Created custom event: %s\n"), *WingUtils::FormatName(NewEvent));
}
MCPUtils::SaveBlueprintPackage(BP);
WingUtils::SaveBlueprintPackage(BP);
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "Kismet2/BlueprintEditorUtils.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlueprintGraph_Delete : public UObject, public IMCPHandler
class UWing_BlueprintGraph_Delete : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,7 +34,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
F.Walk(Blueprint);
if (!F.Ok()) return;
@@ -47,7 +47,7 @@ public:
for (UEdGraph* G : BP->FunctionGraphs)
{
if (G && MCPUtils::Identifies(Graph, G))
if (G && WingUtils::Identifies(Graph, G))
{
TargetGraph = G;
GraphType = TEXT("function");
@@ -58,7 +58,7 @@ public:
{
for (UEdGraph* G : BP->MacroGraphs)
{
if (G && MCPUtils::Identifies(Graph, G))
if (G && WingUtils::Identifies(Graph, G))
{
TargetGraph = G;
GraphType = TEXT("macro");
@@ -72,25 +72,25 @@ public:
{
for (UEdGraph* G : BP->UbergraphPages)
{
if (G && MCPUtils::Identifies(Graph, G))
if (G && WingUtils::Identifies(Graph, G))
{
UMCPServer::Printf(TEXT("ERROR: Cannot delete UbergraphPage '%s'. EventGraph pages cannot be deleted.\n"),
*MCPUtils::FormatName(G));
UWingServer::Printf(TEXT("ERROR: Cannot delete UbergraphPage '%s'. EventGraph pages cannot be deleted.\n"),
*WingUtils::FormatName(G));
return;
}
}
UMCPServer::Printf(TEXT("ERROR: Graph '%s' not found in blueprint %s\n"),
*Graph, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: Graph '%s' not found in blueprint %s\n"),
*Graph, *WingUtils::FormatName(BP));
return;
}
// Remove the graph
FString GraphName = MCPUtils::FormatName(TargetGraph);
FString GraphName = WingUtils::FormatName(TargetGraph);
FBlueprintEditorUtils::RemoveGraph(BP, TargetGraph, EGraphRemoveFlags::Default);
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
bool bSaved = WingUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Deleted %s graph %s\n"), *GraphType, *GraphName);
UWingServer::Printf(TEXT("Deleted %s graph %s\n"), *GraphType, *GraphName);
if (!bSaved)
UMCPServer::Print(TEXT("WARNING: Package save failed.\n"));
UWingServer::Print(TEXT("WARNING: Package save failed.\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "Kismet2/BlueprintEditorUtils.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlueprintGraph_Rename : public UObject, public IMCPHandler
class UWing_BlueprintGraph_Rename : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,22 +34,22 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
if (!TargetGraph) return;
UBlueprint* BP = Cast<UBlueprint>(TargetGraph->GetOuter());
if (!BP)
{
UMCPServer::Printf(TEXT("Error: Graph '%s' is not owned by a Blueprint.\n"), *Graph);
UWingServer::Printf(TEXT("Error: Graph '%s' is not owned by a Blueprint.\n"), *Graph);
return;
}
// Check if it's an UbergraphPage -- disallow rename
if (BP->UbergraphPages.Contains(TargetGraph))
{
UMCPServer::Printf(TEXT("Error: Cannot rename UbergraphPage '%s'. EventGraph pages cannot be renamed.\n"),
*MCPUtils::FormatName(TargetGraph));
UWingServer::Printf(TEXT("Error: Cannot rename UbergraphPage '%s'. EventGraph pages cannot be renamed.\n"),
*WingUtils::FormatName(TargetGraph));
return;
}
@@ -58,27 +58,27 @@ public:
bool bIsMacro = BP->MacroGraphs.Contains(TargetGraph);
if (!bIsFunction && !bIsMacro)
{
UMCPServer::Printf(TEXT("Error: Graph '%s' is not a function or macro graph.\n"),
*MCPUtils::FormatName(TargetGraph));
UWingServer::Printf(TEXT("Error: Graph '%s' is not a function or macro graph.\n"),
*WingUtils::FormatName(TargetGraph));
return;
}
// Check for name collision
for (UEdGraph* Existing : MCPUtils::AllGraphsNamed(BP, NewName))
for (UEdGraph* Existing : WingUtils::AllGraphsNamed(BP, NewName))
{
if (Existing != TargetGraph)
{
UMCPServer::Printf(TEXT("Error: A graph named '%s' already exists in '%s'.\n"),
*NewName, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("Error: A graph named '%s' already exists in '%s'.\n"),
*NewName, *WingUtils::FormatName(BP));
return;
}
}
FBlueprintEditorUtils::RenameGraph(TargetGraph, NewName);
MCPUtils::SaveBlueprintPackage(BP);
WingUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Renamed to %s %s\n"),
UWingServer::Printf(TEXT("Renamed to %s %s\n"),
bIsFunction ? TEXT("function") : TEXT("macro"),
*MCPUtils::FormatName(TargetGraph));
*WingUtils::FormatName(TargetGraph));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "Engine/Blueprint.h"
#include "Engine/SimpleConstructionScript.h"
#include "Engine/SCS_Node.h"
@@ -17,7 +17,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_AddComponent : public UObject, public IMCPHandler
class UWing_Blueprint_AddComponent : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -42,15 +42,15 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
if (!SCS)
{
UMCPServer::Printf(TEXT("ERROR: Blueprint '%s' does not have a SimpleConstructionScript (not an Actor Blueprint)\n"),
*MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: Blueprint '%s' does not have a SimpleConstructionScript (not an Actor Blueprint)\n"),
*WingUtils::FormatName(BP));
return;
}
@@ -59,19 +59,19 @@ public:
for (USCS_Node* Existing : ExistingNodes)
{
if (Existing && Existing->ComponentTemplate &&
MCPUtils::Identifies(Component, Existing->ComponentTemplate))
WingUtils::Identifies(Component, Existing->ComponentTemplate))
{
UMCPServer::Printf(TEXT("ERROR: A component named '%s' already exists in Blueprint '%s'\n"),
*Component, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: A component named '%s' already exists in Blueprint '%s'\n"),
*Component, *WingUtils::FormatName(BP));
return;
}
}
// Resolve the component class by name
UClass* ComponentClassObj = MCPUtils::FindClassByName(ComponentClass);
UClass* ComponentClassObj = WingUtils::FindClassByName(ComponentClass);
if (!ComponentClassObj || !ComponentClassObj->IsChildOf(UActorComponent::StaticClass()))
{
UMCPServer::Printf(TEXT("ERROR: Component class '%s' not found or is not a subclass of UActorComponent. "
UWingServer::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, "
@@ -87,7 +87,7 @@ public:
for (USCS_Node* Node : ExistingNodes)
{
if (Node && Node->ComponentTemplate &&
MCPUtils::Identifies(ParentComponent, Node->ComponentTemplate))
WingUtils::Identifies(ParentComponent, Node->ComponentTemplate))
{
ParentSCSNode = Node;
break;
@@ -96,8 +96,8 @@ public:
if (!ParentSCSNode)
{
UMCPServer::Printf(TEXT("ERROR: Parent component '%s' not found in Blueprint '%s'\n"),
*ParentComponent, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: Parent component '%s' not found in Blueprint '%s'\n"),
*ParentComponent, *WingUtils::FormatName(BP));
return;
}
}
@@ -106,8 +106,8 @@ public:
USCS_Node* NewNode = SCS->CreateNode(ComponentClassObj, FName(*Component));
if (!NewNode)
{
UMCPServer::Printf(TEXT("ERROR: Failed to create SCS node for component '%s' with class '%s'\n"),
*Component, *MCPUtils::FormatName(ComponentClassObj));
UWingServer::Printf(TEXT("ERROR: Failed to create SCS node for component '%s' with class '%s'\n"),
*Component, *WingUtils::FormatName(ComponentClassObj));
return;
}
@@ -121,15 +121,15 @@ public:
SCS->AddNode(NewNode);
}
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
bool bSaved = WingUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Added component %s (%s)"),
*MCPUtils::FormatName(NewNode->ComponentTemplate),
*MCPUtils::FormatName(ComponentClassObj));
UWingServer::Printf(TEXT("Added component %s (%s)"),
*WingUtils::FormatName(NewNode->ComponentTemplate),
*WingUtils::FormatName(ComponentClassObj));
if (ParentSCSNode)
{
UMCPServer::Printf(TEXT(" under %s"), *MCPUtils::FormatName(ParentSCSNode->ComponentTemplate));
UWingServer::Printf(TEXT(" under %s"), *WingUtils::FormatName(ParentSCSNode->ComponentTemplate));
}
UMCPServer::Printf(TEXT("\nSaved: %s\n"), bSaved ? TEXT("true") : TEXT("false"));
UWingServer::Printf(TEXT("\nSaved: %s\n"), bSaved ? TEXT("true") : TEXT("false"));
}
};

View File

@@ -1,12 +1,12 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPTypes.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingTypes.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphPin.h"
@@ -33,7 +33,7 @@ struct FDispatcherParamEntry
};
UCLASS()
class UMCP_Blueprint_AddEventDispatcher : public UObject, public IMCPHandler
class UWing_Blueprint_AddEventDispatcher : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -45,7 +45,7 @@ public:
FString DispatcherName;
UPROPERTY(meta=(Optional, Description="Array of parameter objects, each with 'name' and 'type' fields"))
FMCPJsonArray Parameters;
FWingJsonArray Parameters;
virtual FString GetDescription() const override
{
@@ -54,7 +54,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
@@ -65,15 +65,15 @@ public:
{
if (Var.VarName == DispatcherFName)
{
UMCPServer::Printf(TEXT("Error: A variable or dispatcher named '%s' already exists.\n"), *DispatcherName);
UWingServer::Printf(TEXT("Error: A variable or dispatcher named '%s' already exists.\n"), *DispatcherName);
return;
}
}
// Check against existing graphs (functions, macros, etc.)
if (!MCPUtils::AllGraphsNamed(BP, DispatcherName).IsEmpty())
if (!WingUtils::AllGraphsNamed(BP, DispatcherName).IsEmpty())
{
UMCPServer::Printf(TEXT("Error: A graph named '%s' already exists.\n"), *DispatcherName);
UWingServer::Printf(TEXT("Error: A graph named '%s' already exists.\n"), *DispatcherName);
return;
}
@@ -82,7 +82,7 @@ public:
DelegateType.PinCategory = UEdGraphSchema_K2::PC_MCDelegate;
if (!FBlueprintEditorUtils::AddMemberVariable(BP, DispatcherFName, DelegateType))
{
UMCPServer::Printf(TEXT("Error: Failed to add delegate variable for '%s'.\n"), *DispatcherName);
UWingServer::Printf(TEXT("Error: Failed to add delegate variable for '%s'.\n"), *DispatcherName);
return;
}
@@ -93,7 +93,7 @@ public:
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
if (!SigGraph)
{
UMCPServer::Print(TEXT("Error: Failed to create delegate signature graph.\n"));
UWingServer::Print(TEXT("Error: Failed to create delegate signature graph.\n"));
return;
}
@@ -110,7 +110,7 @@ public:
if (Parameters.Array.Num() > 0)
{
UK2Node_EditablePinBase* EntryNode = nullptr;
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(SigGraph))
for (UK2Node_FunctionEntry* FE : WingUtils::AllNodes<UK2Node_FunctionEntry>(SigGraph))
{
EntryNode = FE;
break;
@@ -118,19 +118,19 @@ public:
if (!EntryNode)
{
MCPUtils::SaveBlueprintPackage(BP);
UMCPServer::Print(TEXT("Error: Event dispatcher created but entry node not found — parameters could not be added.\n"));
WingUtils::SaveBlueprintPackage(BP);
UWingServer::Print(TEXT("Error: Event dispatcher created but entry node not found — parameters could not be added.\n"));
return;
}
for (const TSharedPtr<FJsonValue>& ParamVal : Parameters.Array)
{
FDispatcherParamEntry Entry;
if (!MCPJson::PopulateFromJson(FDispatcherParamEntry::StaticStruct(), &Entry, ParamVal)) return;
if (!WingJson::PopulateFromJson(FDispatcherParamEntry::StaticStruct(), &Entry, ParamVal)) return;
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
FEdGraphPinType PinType;
if (!UMCPTypes::TextToType(Entry.Type, PinType))
if (!UWingTypes::TextToType(Entry.Type, PinType))
return;
EntryNode->CreateUserDefinedPin(FName(*Entry.Name), PinType, EGPD_Output);
@@ -138,11 +138,11 @@ public:
}
}
MCPUtils::SaveBlueprintPackage(BP);
WingUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Created event dispatcher '%s'"), *DispatcherName);
UWingServer::Printf(TEXT("Created event dispatcher '%s'"), *DispatcherName);
if (ParamCount > 0)
UMCPServer::Printf(TEXT(" with %d parameter(s)"), ParamCount);
UMCPServer::Print(TEXT(".\n"));
UWingServer::Printf(TEXT(" with %d parameter(s)"), ParamCount);
UWingServer::Print(TEXT(".\n"));
}
};

View File

@@ -1,143 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPTypes.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphPin.h"
#include "K2Node_FunctionEntry.h"
#include "K2Node_CustomEvent.h"
#include "K2Node_EditablePinBase.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "Blueprint_AddFunctionParameter.generated.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_AddFunctionParameter : public UObject, public IMCPHandler
{
GENERATED_BODY()
public:
UPROPERTY(meta=(Description="Blueprint package path"))
FString Blueprint;
UPROPERTY(meta=(Description="Name of the function, custom event, or event dispatcher"))
FString FunctionName;
UPROPERTY(meta=(Description="Name for the new parameter"))
FString ParamName;
UPROPERTY(meta=(Description="Type for the new parameter (e.g. 'Float', 'Vector', 'MyStruct')"))
FString ParamType;
virtual FString GetDescription() const override
{
return TEXT("Add a new parameter to a function, custom event, or event dispatcher in a Blueprint.");
}
virtual void Handle() override
{
MCPFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
// Resolve param type
FEdGraphPinType PinType;
if (!UMCPTypes::TextToType(ParamType, PinType))
return;
// Find the entry node using 3 strategies
UK2Node_EditablePinBase* EntryNode = nullptr;
FString NodeType;
// Strategy 1: K2Node_FunctionEntry in function graphs
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
{
UEdGraph* FEGraph = FE->GetGraph();
if (!MCPUtils::Identifies(FunctionName, FEGraph)) continue;
// Skip delegate signature graphs (handled in Strategy 3)
if (BP->DelegateSignatureGraphs.Contains(FEGraph)) continue;
EntryNode = FE;
NodeType = TEXT("FunctionEntry");
break;
}
// Strategy 2: K2Node_CustomEvent with matching CustomFunctionName
if (!EntryNode)
{
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
{
if (CE->CustomFunctionName.ToString().Equals(FunctionName, ESearchCase::IgnoreCase))
{
EntryNode = CE;
NodeType = TEXT("CustomEvent");
break;
}
}
}
// Strategy 3: K2Node_FunctionEntry in DelegateSignatureGraphs
if (!EntryNode)
{
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
{
UEdGraph* FEGraph = FE->GetGraph();
if (!MCPUtils::Identifies(FunctionName, FEGraph)) continue;
if (!BP->DelegateSignatureGraphs.Contains(FEGraph)) continue;
EntryNode = FE;
NodeType = TEXT("EventDispatcher");
break;
}
}
if (!EntryNode)
{
// Build a helpful error listing available functions, events, and dispatchers
UMCPServer::Printf(TEXT("ERROR: Function/event/dispatcher '%s' not found. Available:\n"), *FunctionName);
for (UEdGraph* Graph : BP->FunctionGraphs)
{
if (Graph) UMCPServer::Printf(TEXT(" function: %s\n"), *MCPUtils::FormatName(Graph));
}
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
{
UMCPServer::Printf(TEXT(" custom event: %s\n"), *CE->CustomFunctionName.ToString());
}
TSet<FName> DelegateNames;
FBlueprintEditorUtils::GetDelegateNameList(BP, DelegateNames);
for (const FName& DN : DelegateNames)
{
UMCPServer::Printf(TEXT(" dispatcher: %s\n"), *DN.ToString());
}
return;
}
// Check for duplicate parameter name
for (const TSharedPtr<FUserPinInfo>& Existing : EntryNode->UserDefinedPins)
{
if (Existing.IsValid() && Existing->PinName.ToString().Equals(ParamName, ESearchCase::IgnoreCase))
{
UMCPServer::Printf(TEXT("ERROR: Parameter '%s' already exists on '%s'\n"), *ParamName, *FunctionName);
return;
}
}
// Add the parameter pin (EGPD_Output on entry = input to callers)
EntryNode->CreateUserDefinedPin(FName(*ParamName), PinType, EGPD_Output);
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Added %s parameter '%s' to %s '%s'%s\n"),
*ParamType, *ParamName, *NodeType, *FunctionName,
bSaved ? TEXT("") : TEXT(" (WARNING: save failed)"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "Engine/Blueprint.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "UObject/UObjectIterator.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_AddInterface : public UObject, public IMCPHandler
class UWing_Blueprint_AddInterface : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,7 +35,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
@@ -48,8 +48,8 @@ public:
{
if (IfaceDesc.Interface == InterfaceClass)
{
UMCPServer::Printf(TEXT("ERROR: Interface '%s' is already implemented by this Blueprint.\n"),
*MCPUtils::FormatName(InterfaceClass));
UWingServer::Printf(TEXT("ERROR: Interface '%s' is already implemented by this Blueprint.\n"),
*WingUtils::FormatName(InterfaceClass));
return;
}
}
@@ -58,21 +58,21 @@ public:
bool bAdded = FBlueprintEditorUtils::ImplementNewInterface(BP, InterfacePath);
if (!bAdded)
{
UMCPServer::Printf(TEXT("ERROR: ImplementNewInterface failed for '%s'.\n"),
*MCPUtils::FormatName(InterfaceClass));
UWingServer::Printf(TEXT("ERROR: ImplementNewInterface failed for '%s'.\n"),
*WingUtils::FormatName(InterfaceClass));
return;
}
// Collect stub function graph names from the newly added interface entry
UMCPServer::Printf(TEXT("Added interface %s\n"), *MCPUtils::FormatName(InterfaceClass));
UMCPServer::Printf(TEXT("Function stubs:\n"));
UWingServer::Printf(TEXT("Added interface %s\n"), *WingUtils::FormatName(InterfaceClass));
UWingServer::Printf(TEXT("Function stubs:\n"));
for (const FBPInterfaceDescription& IfaceDesc : BP->ImplementedInterfaces)
{
if (IfaceDesc.Interface != InterfaceClass) continue;
for (const UEdGraph* Graph : IfaceDesc.Graphs)
{
if (Graph)
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
UWingServer::Printf(TEXT(" %s\n"), *WingUtils::FormatName(Graph));
}
break;
}
@@ -88,17 +88,17 @@ private:
for (TObjectIterator<UClass> It; It; ++It)
{
if (!It->IsChildOf(UInterface::StaticClass())) continue;
if (MCPUtils::Identifies(Name, *It))
if (WingUtils::Identifies(Name, *It))
return *It;
}
// Strategy 2: Try loading as a Blueprint Interface asset by package path
MCPFetcher F;
WingFetcher F;
UBlueprint* IfaceBP = F.Asset(Name).Cast<UBlueprint>();
if (IfaceBP && IfaceBP->GeneratedClass && IfaceBP->GeneratedClass->IsChildOf(UInterface::StaticClass()))
return IfaceBP->GeneratedClass;
UMCPServer::Printf(TEXT("ERROR: Interface '%s' not found. Provide a native UInterface class name or Blueprint Interface package path.\n"),
UWingServer::Printf(TEXT("ERROR: Interface '%s' not found. Provide a native UInterface class name or Blueprint Interface package path.\n"),
*Name);
return nullptr;
}

View File

@@ -1,160 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "MCPTypes.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphPin.h"
#include "K2Node_FunctionEntry.h"
#include "K2Node_CustomEvent.h"
#include "K2Node_EditablePinBase.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "Blueprint_ChangeFunctionParameterType.generated.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_ChangeFunctionParameterType : public UObject, public IMCPHandler
{
GENERATED_BODY()
public:
UPROPERTY(meta=(Description="Blueprint package path"))
FString Blueprint;
UPROPERTY(meta=(Description="Name of the function or custom event"))
FString FunctionName;
UPROPERTY(meta=(Description="Name of the parameter to change"))
FString ParamName;
UPROPERTY(meta=(Description="New type for the parameter (e.g. 'Float', 'Vector', 'MyStruct')"))
FString NewType;
UPROPERTY(meta=(Optional, Description="If true, analyze impact without making changes"))
bool DryRun = false;
virtual FString GetDescription() const override
{
return TEXT("Change the type of an existing parameter on a function or custom event in a Blueprint.");
}
virtual void Handle() override
{
MCPFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
// Resolve the new type using the shared resolver (supports primitives, structs, enums, and object references)
FEdGraphPinType NewPinType;
if (!UMCPTypes::TextToType(NewType, NewPinType))
return;
// Find the entry node: K2Node_FunctionEntry in a function graph,
// or K2Node_CustomEvent in any graph
UK2Node_EditablePinBase* EntryNode = nullptr;
// Strategy 1: Look for a K2Node_FunctionEntry in a function graph matching the name
for (UK2Node_FunctionEntry* FuncEntry : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
{
if (MCPUtils::Identifies(FunctionName, FuncEntry->GetGraph()))
{
EntryNode = FuncEntry;
break;
}
}
// Strategy 2: Search for a K2Node_CustomEvent with matching name
if (!EntryNode)
{
for (UK2Node_CustomEvent* CustomEvent : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
{
if (MCPUtils::Identifies(FunctionName, static_cast<UEdGraphNode*>(CustomEvent)))
{
EntryNode = CustomEvent;
break;
}
}
}
if (!EntryNode)
{
UMCPServer::Printf(TEXT("ERROR: Function or custom event '%s' not found. Available:\n"), *FunctionName);
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
UMCPServer::Printf(TEXT(" function: %s\n"), *MCPUtils::FormatName(FE->GetGraph()));
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
UMCPServer::Printf(TEXT(" event: %s\n"), *MCPUtils::FormatName(static_cast<UEdGraphNode*>(CE)));
return;
}
// Find the UserDefinedPin matching ParamName
TSharedPtr<FUserPinInfo>* FoundPinInfo = nullptr;
for (TSharedPtr<FUserPinInfo>& PinInfo : EntryNode->UserDefinedPins)
{
if (PinInfo.IsValid() && PinInfo->PinName.ToString().Equals(ParamName, ESearchCase::IgnoreCase))
{
FoundPinInfo = &PinInfo;
break;
}
}
if (!FoundPinInfo)
{
UMCPServer::Printf(TEXT("ERROR: Parameter '%s' not found. Available:\n"), *ParamName);
for (const TSharedPtr<FUserPinInfo>& PinInfo : EntryNode->UserDefinedPins)
if (PinInfo.IsValid())
UMCPServer::Printf(TEXT(" %s\n"), *PinInfo->PinName.ToString());
return;
}
// Dry run: report connected pins that may disconnect
if (DryRun)
{
int32 AtRisk = 0;
for (UEdGraphPin* Pin : EntryNode->Pins)
{
if (!Pin || !MCPUtils::Identifies(ParamName, Pin)) continue;
for (UEdGraphPin* Linked : Pin->LinkedTo)
{
if (!Linked || !Linked->GetOwningNode()) continue;
UMCPServer::Printf(TEXT("Connection at risk: %s -> %s on %s\n"),
*MCPUtils::FormatName(Pin),
*MCPUtils::FormatName(Linked),
*MCPUtils::FormatName(Linked->GetOwningNode()));
AtRisk++;
}
}
UMCPServer::Printf(TEXT("Dry run: %d connection(s) at risk.\n"), AtRisk);
return;
}
// Apply the type change (PreEdit/PostEdit on the node itself, not the BP —
// MCPUtils::PreEdit/PostEdit operates at BP level, not node level)
EntryNode->PreEditChange(nullptr);
(*FoundPinInfo)->PinType = NewPinType;
EntryNode->PostEditChange();
// Reconstruct the node to update output pins with the new type
if (UEdGraph* OwningGraph = EntryNode->GetGraph())
{
if (const UEdGraphSchema* Schema = OwningGraph->GetSchema())
{
Schema->ReconstructNode(*EntryNode);
}
}
// Save
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Changed '%s' to %s. Save %s.\n"),
*ParamName, *UMCPTypes::TypeToText(NewPinType),
bSaved ? TEXT("succeeded") : TEXT("failed"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "Kismet2/KismetEditorUtilities.h"
#include "Blueprint_Compile.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_Compile : public UObject, public IMCPHandler
class UWing_Blueprint_Compile : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -30,7 +30,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint *BP = F.Walk(Blueprint).Cast<UBlueprint>();
EBlueprintCompileOptions CompileOpts =
@@ -41,14 +41,14 @@ public:
FKismetEditorUtilities::CompileBlueprint(BP, CompileOpts, nullptr);
// Collect compiler messages from nodes
for (UEdGraphNode* Node : MCPUtils::AllNodes(BP))
for (UEdGraphNode* Node : WingUtils::AllNodes(BP))
{
if (!Node->bHasCompilerMessage) continue;
UMCPServer::Printf(TEXT("%s %s: %s\n"),
*MCPUtils::FormatName(Node->GetGraph()),
*MCPUtils::FormatName(Node),
UWingServer::Printf(TEXT("%s %s: %s\n"),
*WingUtils::FormatName(Node->GetGraph()),
*WingUtils::FormatName(Node),
*Node->ErrorMsg);
}
UMCPServer::Printf(TEXT("Compilation Done.\n"));
UWingServer::Printf(TEXT("Compilation Done.\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
@@ -17,7 +17,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_Diff : public UObject, public IMCPHandler
class UWing_Blueprint_Diff : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -41,11 +41,11 @@ public:
virtual void Handle() override
{
// Load both blueprints
MCPFetcher FA;
WingFetcher FA;
UBlueprint* BPA = FA.Asset(BlueprintA).Cast<UBlueprint>();
if (!BPA) return;
MCPFetcher FB;
WingFetcher FB;
UBlueprint* BPB = FB.Asset(BlueprintB).Cast<UBlueprint>();
if (!BPB) return;
@@ -56,13 +56,13 @@ public:
for (UEdGraph* G : BP->UbergraphPages)
{
if (!G) continue;
if (!Graph.IsEmpty() && !MCPUtils::Identifies(Graph, G)) continue;
if (!Graph.IsEmpty() && !WingUtils::Identifies(Graph, G)) continue;
Graphs.Add(G);
}
for (UEdGraph* G : BP->FunctionGraphs)
{
if (!G) continue;
if (!Graph.IsEmpty() && !MCPUtils::Identifies(Graph, G)) continue;
if (!Graph.IsEmpty() && !WingUtils::Identifies(Graph, G)) continue;
Graphs.Add(G);
}
return Graphs;
@@ -73,8 +73,8 @@ public:
// Build graph name maps
TMap<FString, UEdGraph*> GraphMapA, GraphMapB;
for (UEdGraph* G : GraphsA) GraphMapA.Add(MCPUtils::FormatName(G), G);
for (UEdGraph* G : GraphsB) GraphMapB.Add(MCPUtils::FormatName(G), G);
for (UEdGraph* G : GraphsA) GraphMapA.Add(WingUtils::FormatName(G), G);
for (UEdGraph* G : GraphsB) GraphMapB.Add(WingUtils::FormatName(G), G);
// Find all unique graph names
TSet<FString> AllGraphNames;
@@ -90,13 +90,13 @@ public:
if (!pGA)
{
UMCPServer::Printf(TEXT("Graph %s: only in B (%d nodes)\n"), *GraphName, (*pGB)->Nodes.Num());
UWingServer::Printf(TEXT("Graph %s: only in B (%d nodes)\n"), *GraphName, (*pGB)->Nodes.Num());
TotalDiffs++;
continue;
}
if (!pGB)
{
UMCPServer::Printf(TEXT("Graph %s: only in A (%d nodes)\n"), *GraphName, (*pGA)->Nodes.Num());
UWingServer::Printf(TEXT("Graph %s: only in A (%d nodes)\n"), *GraphName, (*pGA)->Nodes.Num());
TotalDiffs++;
continue;
}
@@ -110,12 +110,12 @@ public:
for (UEdGraphNode* N : GA->Nodes)
{
if (!N) continue;
NodesA.FindOrAdd(MCPUtils::FormatName(N)).Add(N);
NodesA.FindOrAdd(WingUtils::FormatName(N)).Add(N);
}
for (UEdGraphNode* N : GB->Nodes)
{
if (!N) continue;
NodesB.FindOrAdd(MCPUtils::FormatName(N)).Add(N);
NodesB.FindOrAdd(WingUtils::FormatName(N)).Add(N);
}
// Nodes only in A
@@ -144,8 +144,8 @@ public:
auto MakeConnKey = [](UEdGraphPin* SrcPin, UEdGraphPin* TgtPin) -> FString
{
return FString::Printf(TEXT("%s|%s|%s|%s"),
*MCPUtils::FormatName(SrcPin->GetOwningNode()), *MCPUtils::FormatName(SrcPin),
*MCPUtils::FormatName(TgtPin->GetOwningNode()), *MCPUtils::FormatName(TgtPin));
*WingUtils::FormatName(SrcPin->GetOwningNode()), *WingUtils::FormatName(SrcPin),
*WingUtils::FormatName(TgtPin->GetOwningNode()), *WingUtils::FormatName(TgtPin));
};
auto GatherConnections = [&MakeConnKey](UEdGraph* G) -> TSet<FString>
@@ -182,39 +182,39 @@ public:
if (bIdentical)
{
UMCPServer::Printf(TEXT("Graph %s: identical (%d nodes)\n"), *GraphName, GA->Nodes.Num());
UWingServer::Printf(TEXT("Graph %s: identical (%d nodes)\n"), *GraphName, GA->Nodes.Num());
continue;
}
TotalDiffs++;
UMCPServer::Printf(TEXT("Graph %s: different (A=%d nodes, B=%d nodes)\n"), *GraphName, GA->Nodes.Num(), GB->Nodes.Num());
UWingServer::Printf(TEXT("Graph %s: different (A=%d nodes, B=%d nodes)\n"), *GraphName, GA->Nodes.Num(), GB->Nodes.Num());
if (!OnlyInA.IsEmpty())
{
UMCPServer::Print(TEXT(" Nodes only in A:\n"));
for (const FString& Line : OnlyInA) UMCPServer::Printf(TEXT(" %s\n"), *Line);
UWingServer::Print(TEXT(" Nodes only in A:\n"));
for (const FString& Line : OnlyInA) UWingServer::Printf(TEXT(" %s\n"), *Line);
}
if (!OnlyInB.IsEmpty())
{
UMCPServer::Print(TEXT(" Nodes only in B:\n"));
for (const FString& Line : OnlyInB) UMCPServer::Printf(TEXT(" %s\n"), *Line);
UWingServer::Print(TEXT(" Nodes only in B:\n"));
for (const FString& Line : OnlyInB) UWingServer::Printf(TEXT(" %s\n"), *Line);
}
if (!ConnsOnlyInA.IsEmpty())
{
UMCPServer::Print(TEXT(" Connections only in A:\n"));
for (const FString& Line : ConnsOnlyInA) UMCPServer::Printf(TEXT(" %s\n"), *Line);
UWingServer::Print(TEXT(" Connections only in A:\n"));
for (const FString& Line : ConnsOnlyInA) UWingServer::Printf(TEXT(" %s\n"), *Line);
}
if (!ConnsOnlyInB.IsEmpty())
{
UMCPServer::Print(TEXT(" Connections only in B:\n"));
for (const FString& Line : ConnsOnlyInB) UMCPServer::Printf(TEXT(" %s\n"), *Line);
UWingServer::Print(TEXT(" Connections only in B:\n"));
for (const FString& Line : ConnsOnlyInB) UWingServer::Printf(TEXT(" %s\n"), *Line);
}
}
// Compare variables
TSet<FString> VarNamesA, VarNamesB;
for (const FBPVariableDescription& V : BPA->NewVariables) VarNamesA.Add(MCPUtils::FormatName(V));
for (const FBPVariableDescription& V : BPB->NewVariables) VarNamesB.Add(MCPUtils::FormatName(V));
for (const FBPVariableDescription& V : BPA->NewVariables) VarNamesA.Add(WingUtils::FormatName(V));
for (const FBPVariableDescription& V : BPB->NewVariables) VarNamesB.Add(WingUtils::FormatName(V));
TArray<FString> VarsOnlyInA, VarsOnlyInB;
for (const FString& Name : VarNamesA)
@@ -226,17 +226,17 @@ public:
if (!VarsOnlyInA.IsEmpty())
{
UMCPServer::Print(TEXT("Variables only in A:\n"));
for (const FString& Name : VarsOnlyInA) UMCPServer::Printf(TEXT(" %s\n"), *Name);
UWingServer::Print(TEXT("Variables only in A:\n"));
for (const FString& Name : VarsOnlyInA) UWingServer::Printf(TEXT(" %s\n"), *Name);
TotalDiffs += VarsOnlyInA.Num();
}
if (!VarsOnlyInB.IsEmpty())
{
UMCPServer::Print(TEXT("Variables only in B:\n"));
for (const FString& Name : VarsOnlyInB) UMCPServer::Printf(TEXT(" %s\n"), *Name);
UWingServer::Print(TEXT("Variables only in B:\n"));
for (const FString& Name : VarsOnlyInB) UWingServer::Printf(TEXT(" %s\n"), *Name);
TotalDiffs += VarsOnlyInB.Num();
}
UMCPServer::Printf(TEXT("Total differences: %d\n"), TotalDiffs);
UWingServer::Printf(TEXT("Total differences: %d\n"), TotalDiffs);
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPTypes.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingTypes.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "Animation/AnimBlueprint.h"
#include "Animation/Skeleton.h"
@@ -19,7 +19,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_Dump : public UObject, public IMCPHandler
class UWing_Blueprint_Dump : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,44 +35,43 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
// Header
UMCPServer::Printf(TEXT("Blueprint: %s\n"), *MCPUtils::FormatName(BP));
UMCPServer::Printf(TEXT("Parent: %s\n"), BP->ParentClass ? *MCPUtils::FormatName(BP->ParentClass) : TEXT("None"));
UMCPServer::Printf(TEXT("Type: %s\n"),
*MCPUtils::EnumToString(BP->BlueprintType));
UWingServer::Printf(TEXT("Blueprint: %s\n"), *WingUtils::FormatName(BP));
UWingServer::Printf(TEXT("Parent: %s\n"), BP->ParentClass ? *WingUtils::FormatName(BP->ParentClass) : TEXT("None"));
UWingServer::Printf(TEXT("Type: %s\n"), *WingUtils::EnumToString(BP->BlueprintType));
// Animation Blueprint
if (UAnimBlueprint* AnimBP = Cast<UAnimBlueprint>(BP))
{
if (AnimBP->TargetSkeleton)
UMCPServer::Printf(TEXT("TargetSkeleton: %s\n"), *AnimBP->TargetSkeleton->GetPathName());
UWingServer::Printf(TEXT("TargetSkeleton: %s\n"), *AnimBP->TargetSkeleton->GetPathName());
}
// Interfaces
for (const FBPInterfaceDescription& I : BP->ImplementedInterfaces)
{
if (I.Interface)
UMCPServer::Printf(TEXT("Interface: %s\n"), *MCPUtils::FormatName(I.Interface));
UWingServer::Printf(TEXT("Interface: %s\n"), *WingUtils::FormatName(I.Interface));
}
// Variables
if (!BP->NewVariables.IsEmpty())
{
UMCPServer::Print(TEXT("\nVariables:\n"));
UWingServer::Print(TEXT("\nVariables:\n"));
for (const FBPVariableDescription& V : BP->NewVariables)
{
UMCPServer::Printf(TEXT(" %s %s"),
*UMCPTypes::TypeToText(V.VarType),
*MCPUtils::FormatName(V));
UWingServer::Printf(TEXT(" %s %s"),
*UWingTypes::TypeToText(V.VarType),
*WingUtils::FormatName(V));
if (!V.DefaultValue.IsEmpty())
UMCPServer::Printf(TEXT(" = %s"), *V.DefaultValue);
UWingServer::Printf(TEXT(" = %s"), *V.DefaultValue);
if (!V.Category.IsEmpty() && V.Category.ToString() != TEXT("Default"))
UMCPServer::Printf(TEXT(" [%s]"), *V.Category.ToString());
UMCPServer::Print(TEXT("\n"));
UWingServer::Printf(TEXT(" [%s]"), *V.Category.ToString());
UWingServer::Print(TEXT("\n"));
}
}
@@ -82,27 +81,27 @@ public:
const TArray<USCS_Node*>& AllNodes = SCS->GetAllNodes();
if (!AllNodes.IsEmpty())
{
UMCPServer::Print(TEXT("\nComponents:\n"));
UWingServer::Print(TEXT("\nComponents:\n"));
for (USCS_Node* Node : AllNodes)
{
if (!Node || !Node->ComponentTemplate) continue;
UMCPServer::Printf(TEXT(" %s (%s)"),
*MCPUtils::FormatName(Node->ComponentTemplate),
*MCPUtils::FormatName(Node->ComponentClass));
UWingServer::Printf(TEXT(" %s (%s)"),
*WingUtils::FormatName(Node->ComponentTemplate),
*WingUtils::FormatName(Node->ComponentClass));
if (Node->ParentComponentOrVariableName != NAME_None)
UMCPServer::Printf(TEXT(" parent=%s"), *Node->ParentComponentOrVariableName.ToString());
UMCPServer::Print(TEXT("\n"));
UWingServer::Printf(TEXT(" parent=%s"), *Node->ParentComponentOrVariableName.ToString());
UWingServer::Print(TEXT("\n"));
}
}
}
// Graph names (without contents)
TArray<UEdGraph*> Graphs = MCPUtils::AllGraphs(BP);
TArray<UEdGraph*> Graphs = WingUtils::AllGraphs(BP);
if (!Graphs.IsEmpty())
{
UMCPServer::Print(TEXT("\nGraphs:\n"));
UWingServer::Print(TEXT("\nGraphs:\n"));
for (UEdGraph* Graph : Graphs)
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
UWingServer::Printf(TEXT(" %s\n"), *WingUtils::FormatName(Graph));
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "Engine/SimpleConstructionScript.h"
#include "Engine/SCS_Node.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_ListComponents : public UObject, public IMCPHandler
class UWing_Blueprint_ListComponents : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -32,7 +32,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
F.Walk(Blueprint);
if (!F.Ok()) return;
@@ -42,7 +42,7 @@ public:
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
if (!SCS)
{
UMCPServer::Print(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript)\n"));
UWingServer::Print(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript)\n"));
return;
}
@@ -51,11 +51,11 @@ public:
if (AllNodes.Num() == 0)
{
UMCPServer::Print(TEXT("No components.\n"));
UWingServer::Print(TEXT("No components.\n"));
return;
}
UMCPServer::Print(TEXT("WARNING: This only lists components added in this blueprint's SCS. "
UWingServer::Print(TEXT("WARNING: This only lists components added in this blueprint's SCS. "
"It does not include inherited components from C++ parent classes "
"(available via the CDO's OwnedComponents) or from parent blueprint SCS nodes.\n"));
@@ -72,20 +72,20 @@ private:
{
// Indent to show hierarchy
for (int32 i = 0; i < Depth; i++)
UMCPServer::Print(TEXT(" "));
UWingServer::Print(TEXT(" "));
FString ClassName = Node->ComponentClass
? MCPUtils::FormatName(Node->ComponentClass)
? WingUtils::FormatName(Node->ComponentClass)
: TEXT("None");
UMCPServer::Printf(TEXT("%s %s"),
UWingServer::Printf(TEXT("%s %s"),
*ClassName,
*MCPUtils::FormatName(Node->ComponentTemplate));
*WingUtils::FormatName(Node->ComponentTemplate));
if (bIsSceneRoot && Depth == 0)
UMCPServer::Print(TEXT(" [SceneRoot]"));
UWingServer::Print(TEXT(" [SceneRoot]"));
UMCPServer::Print(TEXT("\n"));
UWingServer::Print(TEXT("\n"));
for (USCS_Node* Child : Node->GetChildNodes())
{

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPTypes.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingTypes.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphPin.h"
@@ -20,7 +20,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_ListEventDispatchers : public UObject, public IMCPHandler
class UWing_Blueprint_ListEventDispatchers : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,7 +35,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
@@ -44,33 +44,33 @@ public:
for (const FName& DelegateName : DelegateNameSet)
{
UMCPServer::Printf(TEXT("%s("), *DelegateName.ToString());
UWingServer::Printf(TEXT("%s("), *DelegateName.ToString());
UEdGraph* SigGraph = FBlueprintEditorUtils::GetDelegateSignatureGraphByName(BP, DelegateName);
if (SigGraph)
{
bool bFirst = true;
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(SigGraph))
for (UK2Node_FunctionEntry* FE : WingUtils::AllNodes<UK2Node_FunctionEntry>(SigGraph))
{
for (const TSharedPtr<FUserPinInfo>& PinInfo : FE->UserDefinedPins)
{
if (!PinInfo.IsValid()) continue;
if (!bFirst) UMCPServer::Print(TEXT(", "));
if (!bFirst) UWingServer::Print(TEXT(", "));
bFirst = false;
UMCPServer::Printf(TEXT("%s %s"),
*UMCPTypes::TypeToText(PinInfo->PinType),
UWingServer::Printf(TEXT("%s %s"),
*UWingTypes::TypeToText(PinInfo->PinType),
*PinInfo->PinName.ToString());
}
break; // only need the first entry node
}
}
UMCPServer::Print(TEXT(")\n"));
UWingServer::Print(TEXT(")\n"));
}
if (DelegateNameSet.Num() == 0)
{
UMCPServer::Print(TEXT("No event dispatchers found.\n"));
UWingServer::Print(TEXT("No event dispatchers found.\n"));
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "Blueprint_ListInterfaces.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_ListInterfaces : public UObject, public IMCPHandler
class UWing_Blueprint_ListInterfaces : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -30,7 +30,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
F.Walk(Blueprint);
if (!F.Ok()) return;
UBlueprint* BP = F.Cast<UBlueprint>();
@@ -42,17 +42,17 @@ public:
if (!IfaceDesc.Interface) continue;
bAny = true;
UMCPServer::Printf(TEXT("Interface: %s\n"), *MCPUtils::FormatName(IfaceDesc.Interface));
UWingServer::Printf(TEXT("Interface: %s\n"), *WingUtils::FormatName(IfaceDesc.Interface));
for (const UEdGraph* Graph : IfaceDesc.Graphs)
{
if (!Graph) continue;
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
UWingServer::Printf(TEXT(" %s\n"), *WingUtils::FormatName(Graph));
}
}
if (!bAny)
{
UMCPServer::Print(TEXT("No interfaces implemented.\n"));
UWingServer::Print(TEXT("No interfaces implemented.\n"));
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_RefreshAllNodes : public UObject, public IMCPHandler
class UWing_Blueprint_RefreshAllNodes : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,19 +35,19 @@ public:
virtual void Handle() override
{
// Load Blueprint
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
int32 GraphCount = MCPUtils::AllGraphs(BP).Num();
int32 NodeCount = MCPUtils::AllNodes(BP).Num();
int32 GraphCount = WingUtils::AllGraphs(BP).Num();
int32 NodeCount = WingUtils::AllNodes(BP).Num();
// Refresh all nodes
FBlueprintEditorUtils::RefreshAllNodes(BP);
// Remove orphaned pins from all nodes
int32 OrphanedPinsRemoved = 0;
for (UEdGraphNode* Node : MCPUtils::AllNodes(BP))
for (UEdGraphNode* Node : WingUtils::AllNodes(BP))
{
for (int32 i = Node->Pins.Num() - 1; i >= 0; --i)
{
@@ -62,26 +62,26 @@ public:
}
// Summary
UMCPServer::Printf(TEXT("Refreshed %s: %d graphs, %d nodes"), *MCPUtils::FormatName(BP), GraphCount, NodeCount);
UWingServer::Printf(TEXT("Refreshed %s: %d graphs, %d nodes"), *WingUtils::FormatName(BP), GraphCount, NodeCount);
if (OrphanedPinsRemoved > 0)
{
UMCPServer::Printf(TEXT(", %d orphaned pins removed"), OrphanedPinsRemoved);
UWingServer::Printf(TEXT(", %d orphaned pins removed"), OrphanedPinsRemoved);
}
UMCPServer::Print(TEXT("\n"));
UWingServer::Print(TEXT("\n"));
// Collect compiler warnings and errors
if (BP->Status == BS_Error)
{
UMCPServer::Print(TEXT("ERROR: Blueprint has compiler errors after refresh\n"));
UWingServer::Print(TEXT("ERROR: Blueprint has compiler errors after refresh\n"));
}
for (UEdGraphNode* Node : MCPUtils::AllNodes(BP))
for (UEdGraphNode* Node : WingUtils::AllNodes(BP))
{
if (!Node->bHasCompilerMessage) continue;
const TCHAR* Prefix = (Node->ErrorType == EMessageSeverity::Error) ? TEXT("ERROR") : TEXT("WARNING");
UMCPServer::Printf(TEXT("%s: [%s] %s: %s\n"),
Prefix, *MCPUtils::FormatName(Node->GetGraph()),
*MCPUtils::FormatName(Node), *Node->ErrorMsg);
UWingServer::Printf(TEXT("%s: [%s] %s: %s\n"),
Prefix, *WingUtils::FormatName(Node->GetGraph()),
*WingUtils::FormatName(Node), *Node->ErrorMsg);
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "Engine/SimpleConstructionScript.h"
#include "Engine/SCS_Node.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_RemoveComponent : public UObject, public IMCPHandler
class UWing_Blueprint_RemoveComponent : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,14 +34,14 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
if (!SCS)
{
UMCPServer::Print(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript).\n"));
UWingServer::Print(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript).\n"));
return;
}
@@ -51,7 +51,7 @@ public:
for (USCS_Node* Node : AllNodes)
{
if (Node && Node->ComponentTemplate &&
MCPUtils::Identifies(Component, Node->ComponentTemplate))
WingUtils::Identifies(Component, Node->ComponentTemplate))
{
NodeToRemove = Node;
break;
@@ -60,12 +60,12 @@ public:
if (!NodeToRemove)
{
UMCPServer::Printf(TEXT("ERROR: Component '%s' not found.\nAvailable components:\n"),
UWingServer::Printf(TEXT("ERROR: Component '%s' not found.\nAvailable components:\n"),
*Component);
for (USCS_Node* Node : AllNodes)
{
if (Node && Node->ComponentTemplate)
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Node->ComponentTemplate));
UWingServer::Printf(TEXT(" %s\n"), *WingUtils::FormatName(Node->ComponentTemplate));
}
return;
}
@@ -74,21 +74,21 @@ public:
const TArray<USCS_Node*>& RootNodes = SCS->GetRootNodes();
if (RootNodes.Contains(NodeToRemove) && NodeToRemove->GetChildNodes().Num() > 0)
{
UMCPServer::Printf(TEXT("ERROR: Cannot remove '%s' — it is a root component with %d child(ren). "
UWingServer::Printf(TEXT("ERROR: Cannot remove '%s' — it is a root component with %d child(ren). "
"Remove or re-parent the children first.\n"),
*MCPUtils::FormatName(NodeToRemove->ComponentTemplate),
*WingUtils::FormatName(NodeToRemove->ComponentTemplate),
NodeToRemove->GetChildNodes().Num());
return;
}
FString RemovedName = MCPUtils::FormatName(NodeToRemove->ComponentTemplate);
FString RemovedName = WingUtils::FormatName(NodeToRemove->ComponentTemplate);
// Remove the node (promotes children to parent if it has any — but we've guarded root above)
SCS->RemoveNodeAndPromoteChildren(NodeToRemove);
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
bool bSaved = WingUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Removed component %s.%s\n"),
UWingServer::Printf(TEXT("Removed component %s.%s\n"),
*RemovedName,
bSaved ? TEXT("") : TEXT(" WARNING: save failed."));
}

View File

@@ -1,115 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "K2Node_FunctionEntry.h"
#include "K2Node_CustomEvent.h"
#include "K2Node_EditablePinBase.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "Blueprint_RemoveFunctionParameter.generated.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_RemoveFunctionParameter : public UObject, public IMCPHandler
{
GENERATED_BODY()
public:
UPROPERTY(meta=(Description="Blueprint package path"))
FString Blueprint;
UPROPERTY(meta=(Description="Name of the function or custom event"))
FString FunctionName;
UPROPERTY(meta=(Description="Name of the parameter to remove"))
FString ParamName;
virtual FString GetDescription() const override
{
return TEXT("Remove a parameter from a function or custom event in a Blueprint.");
}
virtual void Handle() override
{
MCPFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
// Find the entry node (function entry or custom event)
UK2Node_EditablePinBase* EntryNode = nullptr;
for (UK2Node_FunctionEntry* FuncEntry : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
{
if (MCPUtils::Identifies(FunctionName, FuncEntry->GetGraph()))
{
EntryNode = FuncEntry;
break;
}
}
if (!EntryNode)
{
for (UK2Node_CustomEvent* CustomEvent : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
{
if (CustomEvent->CustomFunctionName.ToString().Equals(FunctionName, ESearchCase::IgnoreCase))
{
EntryNode = CustomEvent;
break;
}
}
}
if (!EntryNode)
{
UMCPServer::Printf(TEXT("Error: Function or event '%s' not found.\nAvailable:\n"), *FunctionName);
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
UMCPServer::Printf(TEXT(" function: %s\n"), *MCPUtils::FormatName(FE->GetGraph()));
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
UMCPServer::Printf(TEXT(" event: %s\n"), *MCPUtils::FormatName(CE));
return;
}
// Find the parameter to remove
int32 RemovedIndex = INDEX_NONE;
for (int32 i = 0; i < EntryNode->UserDefinedPins.Num(); ++i)
{
if (EntryNode->UserDefinedPins[i].IsValid() &&
EntryNode->UserDefinedPins[i]->PinName.ToString().Equals(ParamName, ESearchCase::IgnoreCase))
{
RemovedIndex = i;
break;
}
}
if (RemovedIndex == INDEX_NONE)
{
UMCPServer::Printf(TEXT("Error: Parameter '%s' not found on %s.\nAvailable:\n"),
*ParamName, *MCPUtils::FormatName(EntryNode));
for (const TSharedPtr<FUserPinInfo>& PinInfo : EntryNode->UserDefinedPins)
if (PinInfo.IsValid())
UMCPServer::Printf(TEXT(" %s\n"), *PinInfo->PinName.ToString());
return;
}
// Remove the pin
EntryNode->UserDefinedPins.RemoveAt(RemovedIndex);
// Reconstruct the node to update output pins
if (UEdGraph* OwningGraph = EntryNode->GetGraph())
if (const UEdGraphSchema* Schema = OwningGraph->GetSchema())
Schema->ReconstructNode(*EntryNode);
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Removed parameter '%s' from %s.\n"), *ParamName, *MCPUtils::FormatName(EntryNode));
if (!bSaved)
UMCPServer::Print(TEXT("Warning: save failed.\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "Engine/Blueprint.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "Blueprint_RemoveInterface.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_RemoveInterface : public UObject, public IMCPHandler
class UWing_Blueprint_RemoveInterface : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -37,7 +37,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
@@ -46,7 +46,7 @@ public:
for (const FBPInterfaceDescription& IfaceDesc : BP->ImplementedInterfaces)
{
if (!IfaceDesc.Interface) continue;
if (MCPUtils::Identifies(InterfaceName, IfaceDesc.Interface))
if (WingUtils::Identifies(InterfaceName, IfaceDesc.Interface))
{
FoundInterface = IfaceDesc.Interface;
break;
@@ -55,11 +55,11 @@ public:
if (!FoundInterface)
{
UMCPServer::Printf(TEXT("ERROR: Interface '%s' not found. Implemented interfaces:\n"), *InterfaceName);
UWingServer::Printf(TEXT("ERROR: Interface '%s' not found. Implemented interfaces:\n"), *InterfaceName);
for (const FBPInterfaceDescription& IfaceDesc : BP->ImplementedInterfaces)
{
if (IfaceDesc.Interface)
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(IfaceDesc.Interface));
UWingServer::Printf(TEXT(" %s\n"), *WingUtils::FormatName(IfaceDesc.Interface));
}
return;
}
@@ -67,8 +67,8 @@ public:
FTopLevelAssetPath InterfacePath = FoundInterface->GetClassPathName();
FBlueprintEditorUtils::RemoveInterface(BP, InterfacePath, PreserveFunctions);
UMCPServer::Printf(TEXT("Removed interface %s\n"), *MCPUtils::FormatName(FoundInterface));
UWingServer::Printf(TEXT("Removed interface %s\n"), *WingUtils::FormatName(FoundInterface));
if (PreserveFunctions)
UMCPServer::Print(TEXT("Function graphs preserved as regular functions.\n"));
UWingServer::Print(TEXT("Function graphs preserved as regular functions.\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "Engine/Blueprint.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "Kismet2/KismetEditorUtilities.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_Reparent : public UObject, public IMCPHandler
class UWing_Blueprint_Reparent : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,18 +35,18 @@ public:
virtual void Handle() override
{
// Load Blueprint
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Asset(Blueprint).Cast<UBlueprint>();
if (!BP) return;
FString OldParentName = BP->ParentClass ? MCPUtils::FormatName(BP->ParentClass) : TEXT("None");
FString OldParentName = BP->ParentClass ? WingUtils::FormatName(BP->ParentClass) : TEXT("None");
// Find the new parent class: try C++ classes first, then Blueprint package path
UClass* NewParentClassObj = MCPUtils::FindClassByName(NewParentClass);
UClass* NewParentClassObj = WingUtils::FindClassByName(NewParentClass);
if (!NewParentClassObj)
{
MCPFetcher F2;
WingFetcher F2;
UBlueprint* ParentBP = F2.Asset(NewParentClass).Cast<UBlueprint>();
if (ParentBP && ParentBP->GeneratedClass)
NewParentClassObj = ParentBP->GeneratedClass;
@@ -54,7 +54,7 @@ public:
if (!NewParentClassObj)
{
UMCPServer::Printf(TEXT("ERROR: Could not find class '%s'. Provide a C++ class name or Blueprint package path.\n"),
UWingServer::Printf(TEXT("ERROR: Could not find class '%s'. Provide a C++ class name or Blueprint package path.\n"),
*NewParentClass);
return;
}
@@ -63,11 +63,11 @@ public:
BP->ParentClass = NewParentClassObj;
FBlueprintEditorUtils::RefreshAllNodes(BP);
FKismetEditorUtilities::CompileBlueprint(BP);
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
bool bSaved = WingUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Reparented %s: %s -> %s\n"),
*MCPUtils::FormatName(BP), *OldParentName, *MCPUtils::FormatName(NewParentClassObj));
UWingServer::Printf(TEXT("Reparented %s: %s -> %s\n"),
*WingUtils::FormatName(BP), *OldParentName, *WingUtils::FormatName(NewParentClassObj));
if (!bSaved)
UMCPServer::Print(TEXT("Warning: save failed\n"));
UWingServer::Print(TEXT("Warning: save failed\n"));
}
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "UObject/UObjectIterator.h"
#include "Class_Search.generated.h"
@@ -17,7 +17,7 @@
// ============================================================
UCLASS()
class UMCP_Class_Search : public UObject, public IMCPHandler
class UWing_Class_Search : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -46,7 +46,7 @@ public:
{
for (TObjectIterator<UClass> It; It; ++It)
{
if (MCPUtils::Identifies(ParentClass, *It))
if (WingUtils::Identifies(ParentClass, *It))
{
ParentClassObj = *It;
break;
@@ -54,7 +54,7 @@ public:
}
if (!ParentClassObj)
{
UMCPServer::Printf(TEXT("Error: Parent class '%s' not found\n"), *ParentClass);
UWingServer::Printf(TEXT("Error: Parent class '%s' not found\n"), *ParentClass);
return;
}
}
@@ -69,7 +69,7 @@ public:
if (Class->HasAnyClassFlags(CLASS_Deprecated | CLASS_NewerVersionExists)) continue;
if (ParentClassObj && !Class->IsChildOf(ParentClassObj)) continue;
FString ClassName = MCPUtils::FormatName(Class);
FString ClassName = WingUtils::FormatName(Class);
if (!Query.IsEmpty() && !ClassName.Contains(Query, ESearchCase::IgnoreCase)) continue;
TotalMatched++;
@@ -79,16 +79,16 @@ public:
}
}
UMCPServer::Printf(TEXT("Found %d classes"), TotalMatched);
UWingServer::Printf(TEXT("Found %d classes"), TotalMatched);
if (TotalMatched > Limit)
{
UMCPServer::Printf(TEXT(" (showing %d)"), Limit);
UWingServer::Printf(TEXT(" (showing %d)"), Limit);
}
UMCPServer::Print(TEXT("\n"));
UWingServer::Print(TEXT("\n"));
for (UClass* Class : Matches)
{
UMCPServer::Printf(TEXT(" %s"), *MCPUtils::FormatName(Class));
UWingServer::Printf(TEXT(" %s"), *WingUtils::FormatName(Class));
// Flags
TStringBuilder<64> Flags;
@@ -98,15 +98,15 @@ public:
if (Class->ClassGeneratedBy) Flags.Append(TEXT(" Blueprint"));
if (Flags.Len() > 0)
{
UMCPServer::Printf(TEXT(" [%s]"), Flags.ToString() + 1); // skip leading space
UWingServer::Printf(TEXT(" [%s]"), Flags.ToString() + 1); // skip leading space
}
if (Class->GetSuperClass())
{
UMCPServer::Printf(TEXT(" : %s"), *MCPUtils::FormatName(Class->GetSuperClass()));
UWingServer::Printf(TEXT(" : %s"), *WingUtils::FormatName(Class->GetSuperClass()));
}
UMCPServer::Print(TEXT("\n"));
UWingServer::Print(TEXT("\n"));
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPTypes.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingTypes.h"
#include "WingUtils.h"
#include "Class_ShowProperties.generated.h"
@@ -13,7 +13,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Class_ShowProperties : public UObject, public IMCPHandler
class UWing_Class_ShowProperties : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -31,14 +31,14 @@ public:
virtual void Handle() override
{
UClass* FoundClass = MCPUtils::FindClassByName(ClassName);
UClass* FoundClass = WingUtils::FindClassByName(ClassName);
if (!FoundClass)
{
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found\n"), *ClassName);
UWingServer::Printf(TEXT("ERROR: Class '%s' not found\n"), *ClassName);
return;
}
UMCPServer::Printf(TEXT("Properties of %s:\n"), *MCPUtils::FormatName(FoundClass));
UWingServer::Printf(TEXT("Properties of %s:\n"), *WingUtils::FormatName(FoundClass));
int32 Count = 0;
for (TFieldIterator<FProperty> PropIt(FoundClass); PropIt; ++PropIt)
@@ -63,18 +63,18 @@ public:
if (Prop->HasAnyPropertyFlags(CPF_RepNotify)) Flags.Append(TEXT(" RepNotify"));
UClass* OwnerClass = Prop->GetOwnerClass();
UMCPServer::Printf(TEXT(" %s %s"), *UMCPTypes::TypeToText(Prop), *PropName);
UWingServer::Printf(TEXT(" %s %s"), *UWingTypes::TypeToText(Prop), *PropName);
if (OwnerClass && OwnerClass != FoundClass)
UMCPServer::Printf(TEXT(" [%s]"), *MCPUtils::FormatName(OwnerClass));
UWingServer::Printf(TEXT(" [%s]"), *WingUtils::FormatName(OwnerClass));
if (Flags.Len() > 0)
UMCPServer::Printf(TEXT(" (%s)"), Flags.ToString() + 1); // skip leading space
UMCPServer::Print(TEXT("\n"));
UWingServer::Printf(TEXT(" (%s)"), Flags.ToString() + 1); // skip leading space
UWingServer::Print(TEXT("\n"));
Count++;
}
if (Count == 0)
{
UMCPServer::Print(TEXT("No properties found.\n"));
UWingServer::Print(TEXT("No properties found.\n"));
}
}
};

View File

@@ -1,13 +1,13 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "Engine/UserDefinedEnum.h"
#include "Kismet2/EnumEditorUtils.h"
#include "Factories/EnumFactory.h"
#include "MCPPackageMaker.h"
#include "WingPackageMaker.h"
#include "Enum_Create.generated.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Enum_Create : public UObject, public IMCPHandler
class UWing_Enum_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -25,7 +25,7 @@ public:
FString AssetPath;
UPROPERTY(meta=(Description="Array of enum value names"))
FMCPJsonArray Values;
FWingJsonArray Values;
virtual FString GetDescription() const override
{
@@ -34,7 +34,7 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(AssetPath);
WingPackageMaker Maker(AssetPath);
if (!Maker.Ok()) return;
TArray<FString> EnumValues;
@@ -45,7 +45,7 @@ public:
}
if (EnumValues.Num() == 0)
{
UMCPServer::Print(TEXT("ERROR: Values must be a non-empty array of strings\n"));
UWingServer::Print(TEXT("ERROR: Values must be a non-empty array of strings\n"));
return;
}
@@ -62,10 +62,10 @@ public:
FEnumEditorUtils::SetEnumeratorDisplayName(NewEnum, NewIndex, FText::FromString(EnumValues[i]));
}
bool bSaved = MCPUtils::SaveGenericPackage(NewEnum);
bool bSaved = WingUtils::SaveGenericPackage(NewEnum);
UMCPServer::Printf(TEXT("Created %s with %d values\n"), *NewEnum->GetPathName(), EnumValues.Num());
UWingServer::Printf(TEXT("Created %s with %d values\n"), *NewEnum->GetPathName(), EnumValues.Num());
if (!bSaved)
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
UWingServer::Print(TEXT("WARNING: Package save failed\n"));
}
};

View File

@@ -1,12 +1,12 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "Materials/MaterialFunction.h"
#include "Factories/MaterialFunctionFactoryNew.h"
#include "MCPPackageMaker.h"
#include "WingPackageMaker.h"
#include "MaterialFunction_Create.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_MaterialFunction_Create : public UObject, public IMCPHandler
class UWing_MaterialFunction_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -33,7 +33,7 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(AssetPath);
WingPackageMaker Maker(AssetPath);
if (!Maker.Ok()) return;
// Create via IAssetTools + factory.
@@ -44,10 +44,10 @@ public:
if (!Description.IsEmpty())
MF->Description = Description;
bool bSaved = MCPUtils::SaveGenericPackage(MF);
bool bSaved = WingUtils::SaveGenericPackage(MF);
UMCPServer::Printf(TEXT("Created %s\n"), *MF->GetPathName());
UWingServer::Printf(TEXT("Created %s\n"), *MF->GetPathName());
if (!bSaved)
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
UWingServer::Print(TEXT("WARNING: Package save failed\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "EdGraph/EdGraph.h"
#include "Kismet2/KismetEditorUtilities.h"
#include "Animation/AnimBlueprint.h"
@@ -20,7 +20,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_StateMachine_AddState : public UObject, public IMCPHandler
class UWing_StateMachine_AddState : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -52,22 +52,22 @@ public:
virtual void Handle() override
{
// Resolve the anim blueprint
MCPFetcher F;
WingFetcher F;
UAnimBlueprint* AnimBP = F.Walk(Blueprint).Cast<UAnimBlueprint>();
if (!AnimBP) return;
// Find the state machine graph
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
UAnimationStateMachineGraph* SMGraph = WingUtils::FindStateMachineGraph(AnimBP, Graph);
if (!SMGraph)
{
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *MCPUtils::FormatName(AnimBP));
UWingServer::Printf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *WingUtils::FormatName(AnimBP));
return;
}
// Check for duplicate state name
if (MCPUtils::FindStateByName(SMGraph, StateName))
if (WingUtils::FindStateByName(SMGraph, StateName))
{
UMCPServer::Printf(TEXT("ERROR: State '%s' already exists in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
UWingServer::Printf(TEXT("ERROR: State '%s' already exists in %s\n"), *StateName, *WingUtils::FormatName(SMGraph));
return;
}
@@ -93,7 +93,7 @@ public:
// Optionally set animation asset
if (!AnimationAsset.IsEmpty() && NewState->GetBoundGraph())
{
MCPFetcher F2;
WingFetcher F2;
UAnimSequence* AnimSeq = F2.Asset(AnimationAsset).Cast<UAnimSequence>();
if (!AnimSeq) return;
@@ -109,9 +109,9 @@ public:
// Compile and save
FKismetEditorUtilities::CompileBlueprint(AnimBP);
MCPUtils::SaveBlueprintPackage(AnimBP);
WingUtils::SaveBlueprintPackage(AnimBP);
UMCPServer::Printf(TEXT("Created state '%s' in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
UMCPServer::Printf(TEXT(" node: %s\n"), *MCPUtils::FormatName(NewState));
UWingServer::Printf(TEXT("Created state '%s' in %s\n"), *StateName, *WingUtils::FormatName(SMGraph));
UWingServer::Printf(TEXT(" node: %s\n"), *WingUtils::FormatName(NewState));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Kismet2/KismetEditorUtilities.h"
#include "Animation/AnimBlueprint.h"
#include "AnimStateNode.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_StateMachine_AddTransition : public UObject, public IMCPHandler
class UWing_StateMachine_AddTransition : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -51,21 +51,21 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UAnimBlueprint* AnimBP = F.Asset(Blueprint).Cast<UAnimBlueprint>();
if (!AnimBP) return;
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
UAnimationStateMachineGraph* SMGraph = WingUtils::FindStateMachineGraph(AnimBP, Graph);
if (!SMGraph)
{
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *MCPUtils::FormatName(AnimBP));
UWingServer::Printf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *WingUtils::FormatName(AnimBP));
return;
}
UAnimStateNode* FromStateNode = MCPUtils::FindStateByName(SMGraph, FromState);
UAnimStateNode* FromStateNode = WingUtils::FindStateByName(SMGraph, FromState);
if (!FromStateNode) return;
UAnimStateNode* ToStateNode = MCPUtils::FindStateByName(SMGraph, ToState);
UAnimStateNode* ToStateNode = WingUtils::FindStateByName(SMGraph, ToState);
if (!ToStateNode) return;
// Create transition node
@@ -91,9 +91,9 @@ public:
// Compile and save
FKismetEditorUtilities::CompileBlueprint(AnimBP);
MCPUtils::SaveBlueprintPackage(AnimBP);
WingUtils::SaveBlueprintPackage(AnimBP);
UMCPServer::Printf(TEXT("Created transition %s -> %s: %s\n"),
*FromState, *ToState, *MCPUtils::FormatName(TransNode));
UWingServer::Printf(TEXT("Created transition %s -> %s: %s\n"),
*FromState, *ToState, *WingUtils::FormatName(TransNode));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Kismet2/KismetEditorUtilities.h"
#include "Animation/AnimBlueprint.h"
#include "AnimStateNode.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_StateMachine_RemoveState : public UObject, public IMCPHandler
class UWing_StateMachine_RemoveState : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -36,8 +36,8 @@ public:
virtual void Handle() override
{
// Fetch the state machine graph via MCPFetcher
MCPFetcher F;
// Fetch the state machine graph via WingFetcher
WingFetcher F;
F.Walk(Graph);
if (!F.Ok()) return;
@@ -48,12 +48,12 @@ public:
UBlueprint* BP = Cast<UBlueprint>(SMGraph->GetOuter()->GetOuter());
if (!BP)
{
UMCPServer::Print(TEXT("ERROR: Could not find owning blueprint.\n"));
UWingServer::Print(TEXT("ERROR: Could not find owning blueprint.\n"));
return;
}
// Find the state node
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName);
UAnimStateNode* StateNode = WingUtils::FindStateByName(SMGraph, StateName);
if (!StateNode) return;
// Collect and remove transitions connected to this state
@@ -74,9 +74,9 @@ public:
// Compile and save
FKismetEditorUtilities::CompileBlueprint(BP);
MCPUtils::SaveBlueprintPackage(BP);
WingUtils::SaveBlueprintPackage(BP);
UMCPServer::Printf(TEXT("Removed state %s and %d transition(s).\n"),
*MCPUtils::FormatName(StateNode), RemovedTransitions);
UWingServer::Printf(TEXT("Removed state %s and %d transition(s).\n"),
*WingUtils::FormatName(StateNode), RemovedTransitions);
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
#include "Kismet2/KismetEditorUtilities.h"
@@ -21,7 +21,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_StateMachine_SetAnimation : public UObject, public IMCPHandler
class UWing_StateMachine_SetAnimation : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -46,31 +46,31 @@ public:
virtual void Handle() override
{
// Resolve the anim blueprint
MCPFetcher F;
WingFetcher F;
UAnimBlueprint* AnimBP = F.Walk(Blueprint).Cast<UAnimBlueprint>();
if (!AnimBP) return;
// Find the state machine graph
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
UAnimationStateMachineGraph* SMGraph = WingUtils::FindStateMachineGraph(AnimBP, Graph);
if (!SMGraph)
{
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *MCPUtils::FormatName(AnimBP));
UWingServer::Printf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *WingUtils::FormatName(AnimBP));
return;
}
// Find the target state
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName);
UAnimStateNode* StateNode = WingUtils::FindStateByName(SMGraph, StateName);
if (!StateNode) return;
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
if (!InnerGraph)
{
UMCPServer::Printf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName);
UWingServer::Printf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName);
return;
}
// Find the animation asset
MCPFetcher F2;
WingFetcher F2;
UAnimSequence* AnimSeq = F2.Asset(AnimationAsset).Cast<UAnimSequence>();
if (!AnimSeq) return;
@@ -99,11 +99,11 @@ public:
// Compile and save
FKismetEditorUtilities::CompileBlueprint(AnimBP);
MCPUtils::SaveBlueprintPackage(AnimBP);
WingUtils::SaveBlueprintPackage(AnimBP);
if (bCreatedNew)
UMCPServer::Printf(TEXT("Created sequence player in state '%s', assigned %s\n"), *StateName, *MCPUtils::FormatName(AnimSeq));
UWingServer::Printf(TEXT("Created sequence player in state '%s', assigned %s\n"), *StateName, *WingUtils::FormatName(AnimSeq));
else
UMCPServer::Printf(TEXT("Updated sequence player in state '%s' to %s\n"), *StateName, *MCPUtils::FormatName(AnimSeq));
UWingServer::Printf(TEXT("Updated sequence player in state '%s' to %s\n"), *StateName, *WingUtils::FormatName(AnimSeq));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
#include "EdGraph/EdGraphPin.h"
@@ -24,7 +24,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_StateMachine_SetBlendSpace : public UObject, public IMCPHandler
class UWing_StateMachine_SetBlendSpace : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -56,22 +56,22 @@ public:
virtual void Handle() override
{
// Load the anim blueprint
MCPFetcher F;
WingFetcher F;
UAnimBlueprint* AnimBP = F.Asset(Blueprint).Cast<UAnimBlueprint>();
if (!AnimBP) return;
// Find the state machine graph and state
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
if (!SMGraph) { UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found\n"), *Graph); return; }
UAnimationStateMachineGraph* SMGraph = WingUtils::FindStateMachineGraph(AnimBP, Graph);
if (!SMGraph) { UWingServer::Printf(TEXT("ERROR: State machine graph '%s' not found\n"), *Graph); return; }
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName);
UAnimStateNode* StateNode = WingUtils::FindStateByName(SMGraph, StateName);
if (!StateNode) return;
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
if (!InnerGraph) { UMCPServer::Printf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName); return; }
if (!InnerGraph) { UWingServer::Printf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName); return; }
// Load the blend space asset
MCPFetcher F2;
WingFetcher F2;
UBlendSpace* BlendSpaceAsset = F2.Asset(BlendSpace).Cast<UBlendSpace>();
if (!BlendSpaceAsset) return;
@@ -105,12 +105,12 @@ public:
// Compile and save
FKismetEditorUtilities::CompileBlueprint(AnimBP);
bool bSaved = MCPUtils::SaveBlueprintPackage(AnimBP);
bool bSaved = WingUtils::SaveBlueprintPackage(AnimBP);
UMCPServer::Printf(TEXT("BlendSpacePlayer %s placed in state %s\n"),
*MCPUtils::FormatName(BSNode), *StateName);
UWingServer::Printf(TEXT("BlendSpacePlayer %s placed in state %s\n"),
*WingUtils::FormatName(BSNode), *StateName);
if (!bSaved)
UMCPServer::Print(TEXT("WARNING: Failed to save package\n"));
UWingServer::Print(TEXT("WARNING: Failed to save package\n"));
}
private:
@@ -185,7 +185,7 @@ private:
}
if (!bVarFound)
{
UMCPServer::Printf(TEXT("WARNING: Variable '%s' not found, skipping %s wire\n"), *VarName, PinName);
UWingServer::Printf(TEXT("WARNING: Variable '%s' not found, skipping %s wire\n"), *VarName, PinName);
return;
}

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Kismet2/KismetEditorUtilities.h"
#include "Animation/AnimBlueprint.h"
#include "AnimStateTransitionNode.h"
@@ -17,7 +17,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_StateMachine_SetTransitionRule : public UObject, public IMCPHandler
class UWing_StateMachine_SetTransitionRule : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -56,21 +56,21 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UAnimBlueprint* AnimBP = F.Asset(Blueprint).Cast<UAnimBlueprint>();
if (!AnimBP) return;
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
UAnimationStateMachineGraph* SMGraph = WingUtils::FindStateMachineGraph(AnimBP, Graph);
if (!SMGraph)
{
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *MCPUtils::FormatName(AnimBP));
UWingServer::Printf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *WingUtils::FormatName(AnimBP));
return;
}
UAnimStateTransitionNode* TransNode = MCPUtils::FindTransition(SMGraph, FromState, ToState);
UAnimStateTransitionNode* TransNode = WingUtils::FindTransition(SMGraph, FromState, ToState);
if (!TransNode)
{
UMCPServer::Printf(TEXT("ERROR: Transition from '%s' to '%s' not found in graph '%s'\n"),
UWingServer::Printf(TEXT("ERROR: Transition from '%s' to '%s' not found in graph '%s'\n"),
*FromState, *ToState, *Graph);
return;
}
@@ -84,9 +84,9 @@ public:
// Compile and save
FKismetEditorUtilities::CompileBlueprint(AnimBP);
MCPUtils::SaveBlueprintPackage(AnimBP);
WingUtils::SaveBlueprintPackage(AnimBP);
UMCPServer::Printf(TEXT("Updated transition %s -> %s: %s\n"),
*FromState, *ToState, *MCPUtils::FormatName(TransNode));
UWingServer::Printf(TEXT("Updated transition %s -> %s: %s\n"),
*FromState, *ToState, *WingUtils::FormatName(TransNode));
}
};

View File

@@ -1,16 +1,16 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPTypes.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingTypes.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "StructUtils/UserDefinedStruct.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "UserDefinedStructure/UserDefinedStructEditorData.h"
#include "Factories/StructureFactory.h"
#include "MCPPackageMaker.h"
#include "WingPackageMaker.h"
#include "Struct_Create.generated.h"
@@ -31,7 +31,7 @@ struct FStructPropertyEntry
};
UCLASS()
class UMCP_Struct_Create : public UObject, public IMCPHandler
class UWing_Struct_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -40,7 +40,7 @@ public:
FString AssetPath;
UPROPERTY(meta=(Optional, Description="Array of initial properties, each with 'name' and 'type' fields"))
FMCPJsonArray Properties;
FWingJsonArray Properties;
virtual FString GetDescription() const override
{
@@ -49,7 +49,7 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(AssetPath);
WingPackageMaker Maker(AssetPath);
if (!Maker.Ok()) return;
// Create the struct using the AssetTools factory.
@@ -61,11 +61,11 @@ public:
for (const TSharedPtr<FJsonValue>& PropVal : Properties.Array)
{
FStructPropertyEntry Entry;
if (!MCPJson::PopulateFromJson(FStructPropertyEntry::StaticStruct(), &Entry, PropVal)) return;
if (!WingJson::PopulateFromJson(FStructPropertyEntry::StaticStruct(), &Entry, PropVal)) return;
if (Entry.Name.IsEmpty() || Entry.Type.IsEmpty()) continue;
FEdGraphPinType PinType;
if (!UMCPTypes::TextToType(Entry.Type, PinType))
if (!UWingTypes::TextToType(Entry.Type, PinType))
continue;
// Snapshot existing GUIDs so we can find the newly added one.
@@ -88,12 +88,12 @@ public:
PropsAdded++;
}
bool bSaved = MCPUtils::SaveGenericPackage(NewStruct);
bool bSaved = WingUtils::SaveGenericPackage(NewStruct);
UMCPServer::Printf(TEXT("Created %s\n"), *NewStruct->GetPathName());
UWingServer::Printf(TEXT("Created %s\n"), *NewStruct->GetPathName());
if (PropsAdded > 0)
UMCPServer::Printf(TEXT("Properties added: %d\n"), PropsAdded);
UWingServer::Printf(TEXT("Properties added: %d\n"), PropsAdded);
if (!bSaved)
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
UWingServer::Print(TEXT("WARNING: Package save failed\n"));
}
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "Misc/Paths.h"
#include "Misc/PackageName.h"
#include "HAL/FileManager.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Asset_Backup : public UObject, public IMCPHandler
class UWing_Asset_Backup : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,7 +35,7 @@ public:
if (!IFileManager::Get().FileExists(*Filename))
{
UMCPServer::Printf(TEXT("ERROR: Asset file not found: %s\n"), *Filename);
UWingServer::Printf(TEXT("ERROR: Asset file not found: %s\n"), *Filename);
return;
}
@@ -43,10 +43,10 @@ public:
uint32 CopyResult = IFileManager::Get().Copy(*BackupFilename, *Filename, true);
if (CopyResult != COPY_OK)
{
UMCPServer::Printf(TEXT("ERROR: Failed to copy %s to %s\n"), *Filename, *BackupFilename);
UWingServer::Printf(TEXT("ERROR: Failed to copy %s to %s\n"), *Filename, *BackupFilename);
return;
}
UMCPServer::Printf(TEXT("Backed up to %s\n"), *BackupFilename);
UWingServer::Printf(TEXT("Backed up to %s\n"), *BackupFilename);
}
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "Misc/PackageName.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Asset_Delete : public UObject, public IMCPHandler
class UWing_Asset_Delete : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -44,7 +44,7 @@ public:
if (!IFileManager::Get().FileExists(*PackageFilename))
{
UMCPServer::Printf(TEXT("ERROR: Asset file not found on disk: %s\n"), *PackageFilename);
UWingServer::Printf(TEXT("ERROR: Asset file not found on disk: %s\n"), *PackageFilename);
return;
}
@@ -60,22 +60,22 @@ public:
if (Referencers.Num() > 0 && !Force)
{
UMCPServer::Printf(TEXT("ERROR: Asset is still referenced by %d package(s):\n"), Referencers.Num());
UWingServer::Printf(TEXT("ERROR: Asset is still referenced by %d package(s):\n"), Referencers.Num());
for (const FName& Ref : Referencers)
{
FString RefStr = Ref.ToString();
UPackage* RefPackage = FindPackage(nullptr, *RefStr);
UMCPServer::Printf(TEXT(" %s%s\n"), *RefStr,
UWingServer::Printf(TEXT(" %s%s\n"), *RefStr,
RefPackage ? TEXT(" (loaded)") : TEXT(" (on-disk only)"));
}
UMCPServer::Print(TEXT("Use force=true to skip the reference check.\n"));
UWingServer::Print(TEXT("Use force=true to skip the reference check.\n"));
return;
}
// Force delete: unload the package from memory first
if (Force && Referencers.Num() > 0)
{
UMCPServer::Printf(TEXT("WARNING: Force-deleting despite %d referencer(s).\n"), Referencers.Num());
UWingServer::Printf(TEXT("WARNING: Force-deleting despite %d referencer(s).\n"), Referencers.Num());
}
// Mark the package, and all the objects in it, as NOT
@@ -109,7 +109,7 @@ public:
if (!bDeleted)
{
UMCPServer::Printf(TEXT("ERROR: Failed to delete file from disk: %s\n"), *PackageFilename);
UWingServer::Printf(TEXT("ERROR: Failed to delete file from disk: %s\n"), *PackageFilename);
return;
}
@@ -122,6 +122,6 @@ public:
Registry.ScanPathsSynchronous({PackageDir}, true);
}
UMCPServer::Printf(TEXT("Deleted %s\n"), *Asset);
UWingServer::Printf(TEXT("Deleted %s\n"), *Asset);
}
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "AssetRegistry/AssetData.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "Asset_FindReferences.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Asset_FindReferences : public UObject, public IMCPHandler
class UWing_Asset_FindReferences : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,7 +35,7 @@ public:
FAssetData AssetData = Registry.GetAssetByObjectPath(FSoftObjectPath(Asset));
if (!AssetData.IsValid())
{
UMCPServer::Printf(TEXT("ERROR: Asset not found: %s\n"), *Asset);
UWingServer::Printf(TEXT("ERROR: Asset not found: %s\n"), *Asset);
return;
}
@@ -44,7 +44,7 @@ public:
if (Referencers.Num() == 0)
{
UMCPServer::Print(TEXT("No referencers found.\n"));
UWingServer::Print(TEXT("No referencers found.\n"));
return;
}
@@ -56,13 +56,13 @@ public:
Registry.GetAssetsByPackageName(Ref, RefAssets);
if (RefAssets.Num() > 0)
{
UMCPServer::Printf(TEXT("%s %s\n"),
*MCPUtils::FormatName(RefAssets[0].GetClass()),
UWingServer::Printf(TEXT("%s %s\n"),
*WingUtils::FormatName(RefAssets[0].GetClass()),
*RefStr);
}
else
{
UMCPServer::Printf(TEXT("Unknown %s\n"), *RefStr);
UWingServer::Printf(TEXT("Unknown %s\n"), *RefStr);
}
}
}

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "AssetToolsModule.h"
#include "IAssetTools.h"
#include "Asset_Rename.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Asset_Rename : public UObject, public IMCPHandler
class UWing_Asset_Rename : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,7 +34,7 @@ public:
virtual void Handle() override
{
// Load the asset
MCPFetcher F;
WingFetcher F;
UObject* AssetObj = F.Asset(Asset).GetObj();
if (!AssetObj) return;
@@ -48,7 +48,7 @@ public:
NewAssetName = NewPath;
if (NewPackagePath.IsEmpty())
{
UMCPServer::Printf(TEXT("ERROR: Cannot determine directory from Asset '%s'\n"), *Asset);
UWingServer::Printf(TEXT("ERROR: Cannot determine directory from Asset '%s'\n"), *Asset);
return;
}
}
@@ -62,10 +62,10 @@ public:
if (!AssetTools.RenameAssets(RenameData))
{
UMCPServer::Print(TEXT("ERROR: Rename failed. The target path may be invalid or a conflicting asset may exist.\n"));
UWingServer::Print(TEXT("ERROR: Rename failed. The target path may be invalid or a conflicting asset may exist.\n"));
return;
}
UMCPServer::Printf(TEXT("Renamed to %s/%s\n"), *NewPackagePath, *NewAssetName);
UWingServer::Printf(TEXT("Renamed to %s/%s\n"), *NewPackagePath, *NewAssetName);
}
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "Misc/PackageName.h"
#include "FileHelpers.h"
#include "HAL/FileManager.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Asset_Restore : public UObject, public IMCPHandler
class UWing_Asset_Restore : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -37,7 +37,7 @@ public:
if (!IFileManager::Get().FileExists(*BackupFilename))
{
UMCPServer::Printf(TEXT("ERROR: Backup file not found: %s\n"), *BackupFilename);
UWingServer::Printf(TEXT("ERROR: Backup file not found: %s\n"), *BackupFilename);
return;
}
@@ -52,7 +52,7 @@ public:
uint32 CopyResult = IFileManager::Get().Copy(*Filename, *BackupFilename, true);
if (CopyResult != COPY_OK)
{
UMCPServer::Printf(TEXT("ERROR: Failed to copy backup over %s\n"), *Asset);
UWingServer::Printf(TEXT("ERROR: Failed to copy backup over %s\n"), *Asset);
return;
}
@@ -64,12 +64,12 @@ public:
UEditorLoadingAndSavingUtils::ReloadPackages({Package}, bReloaded, ErrorMessage, EReloadPackagesInteractionMode::AssumePositive);
if (!bReloaded)
{
UMCPServer::Printf(TEXT("WARNING: Restored %s but reload failed: %s\n"),
UWingServer::Printf(TEXT("WARNING: Restored %s but reload failed: %s\n"),
*Asset, *ErrorMessage.ToString());
return;
}
}
UMCPServer::Printf(TEXT("Restored %s from backup\n"), *Asset);
UWingServer::Printf(TEXT("Restored %s from backup\n"), *Asset);
}
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "Asset_Search.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Asset_Search : public UObject, public IMCPHandler
class UWing_Asset_Search : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -37,7 +37,7 @@ public:
{
if (Query.IsEmpty() && Type.IsEmpty())
{
UMCPServer::Print(TEXT("ERROR: At least one of Query or Type must be specified\n"));
UWingServer::Print(TEXT("ERROR: At least one of Query or Type must be specified\n"));
return;
}
@@ -49,10 +49,10 @@ public:
if (!Type.IsEmpty())
{
UClass* TypeClass = MCPUtils::FindClassByName(Type);
UClass* TypeClass = WingUtils::FindClassByName(Type);
if (!TypeClass)
{
UMCPServer::Printf(TEXT("ERROR: Unknown asset type '%s'\n"), *Type);
UWingServer::Printf(TEXT("ERROR: Unknown asset type '%s'\n"), *Type);
return;
}
Filter.ClassPaths.Add(TypeClass->GetClassPathName());
@@ -79,18 +79,18 @@ public:
for (const FAssetData& Data : Results)
{
UMCPServer::Printf(TEXT("%s %s\n"),
*MCPUtils::FormatName(Data.GetClass()),
UWingServer::Printf(TEXT("%s %s\n"),
*WingUtils::FormatName(Data.GetClass()),
*Data.PackageName.ToString());
}
if (Results.Num() == 0)
{
UMCPServer::Print(TEXT("No assets found.\n"));
UWingServer::Print(TEXT("No assets found.\n"));
}
else if (Results.Num() >= Limit)
{
UMCPServer::Printf(TEXT("WARNING: You reached the limit of %d, to raise it, specify the Limit parameter.\n"), Limit);
UWingServer::Printf(TEXT("WARNING: You reached the limit of %d, to raise it, specify the Limit parameter.\n"), Limit);
}
}
};

View File

@@ -1,14 +1,14 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPProperty.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingProperty.h"
#include "BPVarEditor.h"
#include "MCPUtils.h"
#include "MCPTypes.h"
#include "WingUtils.h"
#include "WingTypes.h"
#include "Engine/Blueprint.h"
#include "EdGraphSchema_K2.h"
#include "Kismet2/BlueprintEditorUtils.h"
@@ -20,7 +20,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlueprintVariable_Create : public UObject, public IMCPHandler
class UWing_BlueprintVariable_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -32,7 +32,7 @@ public:
FString Name;
UPROPERTY(meta=(Optional, Description="Variable configuration: VarType, Category, DefaultValue, InstanceEditable, BlueprintReadOnly, ExposeOnSpawn, Private, ExposeToCinematics, etc."))
FMCPJsonObject Config;
FWingJsonObject Config;
virtual FString GetDescription() const override
{
@@ -41,7 +41,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
@@ -49,7 +49,7 @@ public:
FName VarFName(*Name);
if (FBlueprintEditorUtils::FindNewVariableIndex(BP, VarFName) != INDEX_NONE)
{
UMCPServer::Printf(TEXT("ERROR: Variable '%s' already exists in %s\n"), *Name, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: Variable '%s' already exists in %s\n"), *Name, *WingUtils::FormatName(BP));
return;
}
@@ -58,7 +58,7 @@ public:
DefaultType.PinCategory = UEdGraphSchema_K2::PC_Int;
if (!FBlueprintEditorUtils::AddMemberVariable(BP, VarFName, DefaultType))
{
UMCPServer::Printf(TEXT("ERROR: Failed to add variable '%s' to %s\n"), *Name, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: Failed to add variable '%s' to %s\n"), *Name, *WingUtils::FormatName(BP));
return;
}
@@ -73,7 +73,7 @@ public:
return;
}
UMCPServer::Printf(TEXT("Created variable %s (%s) in %s\n"),
*Name, *UMCPTypes::TypeToText(Editor.Desc->VarType), *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("Created variable %s (%s) in %s\n"),
*Name, *UWingTypes::TypeToText(Editor.Desc->VarType), *WingUtils::FormatName(BP));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "BPVarEditor.h"
#include "Engine/Blueprint.h"
#include "Kismet2/BlueprintEditorUtils.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlueprintVariable_Delete : public UObject, public IMCPHandler
class UWing_BlueprintVariable_Delete : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,7 +34,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
@@ -43,7 +43,7 @@ public:
FBlueprintEditorUtils::RemoveMemberVariable(BP, Editor.Desc->VarName);
UMCPServer::Printf(TEXT("Removed variable %s from %s\n"),
*Variable, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("Removed variable %s from %s\n"),
*Variable, *WingUtils::FormatName(BP));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "BPVarEditor.h"
#include "Engine/Blueprint.h"
#include "Kismet2/BlueprintEditorUtils.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlueprintVariable_Dump : public UObject, public IMCPHandler
class UWing_BlueprintVariable_Dump : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,14 +34,14 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
FBPVarEditor Editor(BP, Variable);
if (Editor.NotFound()) return;
UMCPServer::Printf(TEXT("Variable %s in %s:\n"), *Variable, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("Variable %s in %s:\n"), *Variable, *WingUtils::FormatName(BP));
Editor.Dump();
}
};

View File

@@ -1,14 +1,14 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPProperty.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingProperty.h"
#include "BPVarEditor.h"
#include "MCPUtils.h"
#include "MCPTypes.h"
#include "WingUtils.h"
#include "WingTypes.h"
#include "Engine/Blueprint.h"
#include "Kismet2/BlueprintEditorUtils.h"
#include "BlueprintVariable_Modify.generated.h"
@@ -19,7 +19,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_BlueprintVariable_Modify : public UObject, public IMCPHandler
class UWing_BlueprintVariable_Modify : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -31,7 +31,7 @@ public:
FString Variable;
UPROPERTY(meta=(Description="Properties to change: VarType, Category, DefaultValue, InstanceEditable, BlueprintReadOnly, ExposeOnSpawn, Private, ExposeToCinematics, etc."))
FMCPJsonObject Properties;
FWingJsonObject Properties;
virtual FString GetDescription() const override
{
@@ -40,7 +40,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
if (!BP) return;
@@ -49,14 +49,14 @@ public:
if (!Properties.Json || Properties.Json->Values.Num() == 0)
{
UMCPServer::Print(TEXT("ERROR: No properties specified\n"));
UWingServer::Print(TEXT("ERROR: No properties specified\n"));
return;
}
if (!Editor.ApplyJson(Properties.Json.Get()))
return;
UMCPServer::Printf(TEXT("Modified variable %s (%s) in %s\n"),
*Variable, *UMCPTypes::TypeToText(Editor.Desc->VarType), *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("Modified variable %s (%s) in %s\n"),
*Variable, *UWingTypes::TypeToText(Editor.Desc->VarType), *WingUtils::FormatName(BP));
}
};

View File

@@ -1,12 +1,12 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPTypes.h"
#include "MCPPackageMaker.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingTypes.h"
#include "WingPackageMaker.h"
#include "Engine/Blueprint.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Kismet2/KismetEditorUtilities.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Blueprint_Create : public UObject, public IMCPHandler
class UWing_Blueprint_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -39,7 +39,7 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(AssetPath);
WingPackageMaker Maker(AssetPath);
if (!Maker.Ok()) return;
// Resolve parent class based on blueprint type
@@ -47,11 +47,11 @@ public:
switch (BlueprintType)
{
case BPTYPE_Normal:
ParentClassObj = UMCPTypes::TextToOneObjectType(ParentClass);
ParentClassObj = UWingTypes::TextToOneObjectType(ParentClass);
if (!ParentClassObj) return;
break;
case BPTYPE_MacroLibrary:
ParentClassObj = UMCPTypes::TextToOneObjectType(ParentClass);
ParentClassObj = UWingTypes::TextToOneObjectType(ParentClass);
if (!ParentClassObj) return;
break;
case BPTYPE_Interface:
@@ -61,7 +61,7 @@ public:
ParentClassObj = UBlueprintFunctionLibrary::StaticClass();
break;
default:
UMCPServer::Print(TEXT("ERROR: BlueprintType must be Normal, Interface, FunctionLibrary, or MacroLibrary\n"));
UWingServer::Print(TEXT("ERROR: BlueprintType must be Normal, Interface, FunctionLibrary, or MacroLibrary\n"));
return;
}
@@ -79,16 +79,16 @@ public:
if (!NewBP)
{
UMCPServer::Print(TEXT("ERROR: FKismetEditorUtilities::CreateBlueprint returned null\n"));
UWingServer::Print(TEXT("ERROR: FKismetEditorUtilities::CreateBlueprint returned null\n"));
return;
}
// Compile and save
FKismetEditorUtilities::CompileBlueprint(NewBP);
bool bSaved = MCPUtils::SaveBlueprintPackage(NewBP);
bool bSaved = WingUtils::SaveBlueprintPackage(NewBP);
// Report result
UMCPServer::Printf(TEXT("Created: %s\n"), *MCPUtils::FormatName(NewBP));
if (!bSaved) UMCPServer::Print(TEXT("Warning: save failed\n"));
UWingServer::Printf(TEXT("Created: %s\n"), *WingUtils::FormatName(NewBP));
if (!bSaved) UWingServer::Print(TEXT("Warning: save failed\n"));
}
};

View File

@@ -1,8 +1,8 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "Editor.h"
#include "Subsystems/AssetEditorSubsystem.h"
#include "Editor_ListOpenAssets.generated.h"
@@ -13,7 +13,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Editor_ListOpenAssets : public UObject, public IMCPHandler
class UWing_Editor_ListOpenAssets : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -28,14 +28,14 @@ public:
UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
if (!Sub)
{
UMCPServer::Print(TEXT("Error: AssetEditorSubsystem not available\n"));
UWingServer::Print(TEXT("Error: AssetEditorSubsystem not available\n"));
return;
}
TArray<UObject*> EditedAssets = Sub->GetAllEditedAssets();
if (EditedAssets.IsEmpty())
{
UMCPServer::Print(TEXT("No asset editors are open.\n"));
UWingServer::Print(TEXT("No asset editors are open.\n"));
return;
}
@@ -43,7 +43,7 @@ public:
{
bool bDirty = Asset->GetOutermost()->IsDirty();
UMCPServer::Printf(TEXT(" %s%s\n"),
UWingServer::Printf(TEXT(" %s%s\n"),
bDirty ? TEXT("[unsaved] ") : TEXT(""),
*Asset->GetPathName());
}

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "Editor.h"
#include "Subsystems/AssetEditorSubsystem.h"
#include "Editor_OpenAsset.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Editor_OpenAsset : public UObject, public IMCPHandler
class UWing_Editor_OpenAsset : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -29,20 +29,20 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UObject* Obj = F.Walk(Asset).Cast<UObject>();
if (!Obj) return;
UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
if (!Sub)
{
UMCPServer::Print(TEXT("Error: AssetEditorSubsystem not available\n"));
UWingServer::Print(TEXT("Error: AssetEditorSubsystem not available\n"));
return;
}
if (Sub->OpenEditorForAsset(Obj))
UMCPServer::Printf(TEXT("Opened editor for %s\n"), *Obj->GetPathName());
UWingServer::Printf(TEXT("Opened editor for %s\n"), *Obj->GetPathName());
else
UMCPServer::Printf(TEXT("Error: Could not open editor for %s\n"), *Obj->GetPathName());
UWingServer::Printf(TEXT("Error: Could not open editor for %s\n"), *Obj->GetPathName());
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPToolMenu.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingToolMenu.h"
#include "WingServer.h"
#include "ToolMenus.h"
#include "GraphNode_ChooseMenu.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_ChooseMenu : public UObject, public IMCPHandler
class UWing_GraphNode_ChooseMenu : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -35,29 +35,29 @@ public:
private:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>();
if (!NodeObj) return;
FToolMenuContext Context;
TArray<FToolMenuEntry> Entries = MCPToolMenu::GetMenuItems(NodeObj, Context);
TArray<FToolMenuEntry> Entries = WingToolMenu::GetMenuItems(NodeObj, Context);
for (FToolMenuEntry &Entry : Entries)
{
FString LabelText = Entry.Label.Get().ToString();
if (!LabelText.Equals(Item, ESearchCase::IgnoreCase))
continue;
if (MCPToolMenu::Execute(Entry, Context))
if (WingToolMenu::Execute(Entry, Context))
{
UMCPServer::Printf(TEXT("Executed: %s\n"), *LabelText);
UWingServer::Printf(TEXT("Executed: %s\n"), *LabelText);
}
else
{
UMCPServer::Printf(TEXT("ERROR: Action '%s' cannot execute (greyed out)\n"), *LabelText);
UWingServer::Printf(TEXT("ERROR: Action '%s' cannot execute (greyed out)\n"), *LabelText);
}
return;
}
UMCPServer::Printf(TEXT("ERROR: Menu item '%s' not found. Use GraphNode_ShowMenu to see available items.\n"), *Item);
UWingServer::Printf(TEXT("ERROR: Menu item '%s' not found. Use GraphNode_ShowMenu to see available items.\n"), *Item);
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
#include "EdGraph/EdGraphSchema.h"
@@ -33,7 +33,7 @@ struct FSpawnNodeEntry
UCLASS()
class UMCP_GraphNode_Create : public UObject, public IMCPHandler
class UWing_GraphNode_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -42,7 +42,7 @@ public:
FString Graph;
UPROPERTY(meta=(Description="Array of {Type, posX, posY} objects. Use GraphNode_SearchTypes to find types."))
FMCPJsonArray Nodes;
FWingJsonArray Nodes;
virtual FString GetDescription() const override
{
@@ -52,7 +52,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
if (!TargetGraph) return;
@@ -62,20 +62,20 @@ public:
for (const TSharedPtr<FJsonValue>& NodeVal : Nodes.Array)
{
FSpawnNodeEntry Entry;
if (!MCPJson::PopulateFromJson(FSpawnNodeEntry::StaticStruct(), &Entry, NodeVal))
if (!WingJson::PopulateFromJson(FSpawnNodeEntry::StaticStruct(), &Entry, NodeVal))
continue;
// Find the action by exact full name
TArray<TSharedPtr<FEdGraphSchemaAction>> Matches = MCPUtils::SearchGraphActions(TargetGraph, Entry.ActionName, 0, /*ExactMatch=*/true);
TArray<TSharedPtr<FEdGraphSchemaAction>> Matches = WingUtils::SearchGraphActions(TargetGraph, Entry.ActionName, 0, /*ExactMatch=*/true);
if (Matches.Num() == 0)
{
UMCPServer::Printf(TEXT("ERROR: No action found matching '%s'. Use GraphNodeSearchTypes to find available actions.\n"),
UWingServer::Printf(TEXT("ERROR: No action found matching '%s'. Use GraphNodeSearchTypes to find available actions.\n"),
*Entry.ActionName);
continue;
}
if (Matches.Num() > 1)
{
UMCPServer::Printf(TEXT("ERROR: Ambiguous: %d actions match '%s'.\n"),
UWingServer::Printf(TEXT("ERROR: Ambiguous: %d actions match '%s'.\n"),
Matches.Num(), *Entry.ActionName);
continue;
}
@@ -85,18 +85,18 @@ public:
UEdGraphNode* NewNode = Matches[0]->PerformAction(TargetGraph, nullptr, Location, /*bSelectNewNode=*/false);
if (!NewNode)
{
UMCPServer::Printf(TEXT("ERROR: PerformAction returned null for '%s'.\n"), *Entry.ActionName);
UWingServer::Printf(TEXT("ERROR: PerformAction returned null for '%s'.\n"), *Entry.ActionName);
continue;
}
if (!NewNode->NodeGuid.IsValid())
NewNode->CreateNewGuid();
UMCPServer::Printf(TEXT("Spawned: %s (%s)\n"),
*MCPUtils::FormatName(NewNode), *MCPUtils::FormatName(NewNode->GetClass()));
UWingServer::Printf(TEXT("Spawned: %s (%s)\n"),
*WingUtils::FormatName(NewNode), *WingUtils::FormatName(NewNode->GetClass()));
SuccessCount++;
}
UMCPServer::Printf(TEXT("Spawned %d/%d nodes.\n"), SuccessCount, TotalCount);
UWingServer::Printf(TEXT("Spawned %d/%d nodes.\n"), SuccessCount, TotalCount);
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
#include "MaterialGraph/MaterialGraphNode.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_Delete : public UObject, public IMCPHandler
class UWing_GraphNode_Delete : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -34,17 +34,17 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>();
if (!FoundNode) return;
UEdGraph* Graph = FoundNode->GetGraph();
FString NodeTitle = MCPUtils::FormatName(FoundNode);
FString GraphName = MCPUtils::FormatName(Graph);
FString NodeTitle = WingUtils::FormatName(FoundNode);
FString GraphName = WingUtils::FormatName(Graph);
if (!FoundNode->CanUserDeleteNode())
{
UMCPServer::Printf(TEXT("ERROR: Cannot delete node '%s' in graph '%s' — it is not deletable.\n"),
UWingServer::Printf(TEXT("ERROR: Cannot delete node '%s' in graph '%s' — it is not deletable.\n"),
*NodeTitle, *GraphName);
return;
}
@@ -63,6 +63,6 @@ public:
Graph->RemoveNode(FoundNode);
}
UMCPServer::Printf(TEXT("Deleted node '%s' from graph '%s'.\n"), *NodeTitle, *GraphName);
UWingServer::Printf(TEXT("Deleted node '%s' from graph '%s'.\n"), *NodeTitle, *GraphName);
}
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPServer.h"
#include "MCPFetcher.h"
#include "WingHandler.h"
#include "WingServer.h"
#include "WingFetcher.h"
#include "GraphExport.h"
#include "GraphNode_Dump.generated.h"
@@ -13,7 +13,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_Dump : public UObject, public IMCPHandler
class UWing_GraphNode_Dump : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -29,12 +29,12 @@ public:
private:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>();
if (!NodeObj) return;
MCPGraphExport Exporter(NodeObj);
UMCPServer::Print(*Exporter.GetOutput());
UMCPServer::Print(Exporter.GetDetails());
WingGraphExport Exporter(NodeObj);
UWingServer::Print(*Exporter.GetOutput());
UWingServer::Print(Exporter.GetDetails());
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
#include "EdGraph/EdGraphPin.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_Duplicate : public UObject, public IMCPHandler
class UWing_GraphNode_Duplicate : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -25,7 +25,7 @@ public:
FString Graph;
UPROPERTY(meta=(Description="Array of node names to duplicate (as returned by FormatName)"))
FMCPJsonArray Nodes;
FWingJsonArray Nodes;
UPROPERTY(meta=(Optional, Description="X offset for duplicated nodes"))
int32 OffsetX = 50;
@@ -42,13 +42,13 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
if (!TargetGraph) return;
if (Nodes.Array.Num() == 0)
{
UMCPServer::Print(TEXT("ERROR: Nodes array is empty\n"));
UWingServer::Print(TEXT("ERROR: Nodes array is empty\n"));
return;
}
@@ -60,7 +60,7 @@ public:
UEdGraphNode* Found = nullptr;
for (UEdGraphNode* Node : TargetGraph->Nodes)
{
if (MCPUtils::Identifies(Name, Node))
if (WingUtils::Identifies(Name, Node))
{
Found = Node;
break;
@@ -68,7 +68,7 @@ public:
}
if (!Found)
{
UMCPServer::Printf(TEXT("ERROR: Node '%s' not found in graph\n"), *Name);
UWingServer::Printf(TEXT("ERROR: Node '%s' not found in graph\n"), *Name);
continue;
}
SourceNodes.Add(Found);
@@ -82,7 +82,7 @@ public:
UEdGraphNode* NewNode = DuplicateObject<UEdGraphNode>(SourceNode, TargetGraph);
if (!NewNode)
{
UMCPServer::Printf(TEXT("ERROR: Failed to duplicate %s\n"), *MCPUtils::FormatName(SourceNode));
UWingServer::Printf(TEXT("ERROR: Failed to duplicate %s\n"), *WingUtils::FormatName(SourceNode));
continue;
}
@@ -97,7 +97,7 @@ public:
}
TargetGraph->AddNode(NewNode, false, false);
UMCPServer::Printf(TEXT("Duplicated: %s -> %s\n"), *MCPUtils::FormatName(SourceNode), *MCPUtils::FormatName(NewNode));
UWingServer::Printf(TEXT("Duplicated: %s -> %s\n"), *WingUtils::FormatName(SourceNode), *WingUtils::FormatName(NewNode));
}
}

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "EdGraph/EdGraphNode.h"
#include "GraphNode_GetComment.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_GetComment : public UObject, public IMCPHandler
class UWing_GraphNode_GetComment : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -29,12 +29,12 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>();
if (!FoundNode) return;
UMCPServer::Printf(TEXT("Node: %s\n"), *MCPUtils::FormatName(FoundNode));
UMCPServer::Printf(TEXT("Comment: %s\n"), *FoundNode->NodeComment);
UMCPServer::Printf(TEXT("BubbleVisible: %s\n"), FoundNode->bCommentBubbleVisible ? TEXT("true") : TEXT("false"));
UWingServer::Printf(TEXT("Node: %s\n"), *WingUtils::FormatName(FoundNode));
UWingServer::Printf(TEXT("Comment: %s\n"), *FoundNode->NodeComment);
UWingServer::Printf(TEXT("BubbleVisible: %s\n"), FoundNode->bCommentBubbleVisible ? TEXT("true") : TEXT("false"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphSchema.h"
#include "GraphNode_SearchTypes.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_SearchTypes : public UObject, public IMCPHandler
class UWing_GraphNode_SearchTypes : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -40,24 +40,24 @@ public:
{
int32 ClampedMax = FMath::Clamp(MaxResults, 1, 500);
MCPFetcher F;
WingFetcher F;
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
if (!TargetGraph) return;
TArray<TSharedPtr<FEdGraphSchemaAction>> Actions = MCPUtils::SearchGraphActions(TargetGraph, Query, ClampedMax, /*ExactMatch=*/false);
TArray<TSharedPtr<FEdGraphSchemaAction>> Actions = WingUtils::SearchGraphActions(TargetGraph, Query, ClampedMax, /*ExactMatch=*/false);
for (const TSharedPtr<FEdGraphSchemaAction>& Action : Actions)
{
UMCPServer::Printf(TEXT("%s\n"), *MCPUtils::ActionFullName(Action));
UWingServer::Printf(TEXT("%s\n"), *WingUtils::ActionFullName(Action));
}
if (Actions.Num() == 0)
{
UMCPServer::Print(TEXT("No matching node types found.\n"));
UWingServer::Print(TEXT("No matching node types found.\n"));
}
else if (Actions.Num() >= ClampedMax)
{
UMCPServer::Printf(TEXT("WARNING: Reached limit of %d results. Refine your query or increase MaxResults.\n"), ClampedMax);
UWingServer::Printf(TEXT("WARNING: Reached limit of %d results. Refine your query or increase MaxResults.\n"), ClampedMax);
}
}
};

View File

@@ -1,15 +1,15 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPServer.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingHandler.h"
#include "WingServer.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "FunctionArgs.h"
#include "GraphNode_SetArgs.generated.h"
UCLASS()
class UMCP_GraphNode_SetArgs : public UObject, public IMCPHandler
class UWing_GraphNode_SetArgs : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -27,18 +27,18 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>();
if (!NodeObj) return;
if (!MCPFunctionArgs::HasArgs(NodeObj))
if (!WingFunctionArgs::HasArgs(NodeObj))
{
UMCPServer::Printf(TEXT("ERROR: Node does not support editable args\n"));
UWingServer::Printf(TEXT("ERROR: Node does not support editable args\n"));
return;
}
if (!MCPFunctionArgs::SetArgs(NodeObj, Args)) return;
if (!WingFunctionArgs::SetArgs(NodeObj, Args)) return;
UMCPServer::Printf(TEXT("Args set to: %s\n"), *MCPFunctionArgs::GetArgs(NodeObj));
UWingServer::Printf(TEXT("Args set to: %s\n"), *WingFunctionArgs::GetArgs(NodeObj));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "EdGraph/EdGraphNode.h"
#include "GraphNode_SetComment.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_SetComment : public UObject, public IMCPHandler
class UWing_GraphNode_SetComment : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -33,7 +33,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>();
if (!FoundNode) return;
@@ -41,6 +41,6 @@ public:
FoundNode->bCommentBubbleVisible = !Comment.IsEmpty();
FoundNode->bCommentBubblePinned = !Comment.IsEmpty();
UMCPServer::Printf(TEXT("Comment set on %s\n"), *MCPUtils::FormatName(FoundNode));
UWingServer::Printf(TEXT("Comment set on %s\n"), *WingUtils::FormatName(FoundNode));
}
};

View File

@@ -1,12 +1,12 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPServer.h"
#include "MCPFetcher.h"
#include "MCPProperty.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingHandler.h"
#include "WingServer.h"
#include "WingFetcher.h"
#include "WingProperty.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "EdGraph/EdGraphPin.h"
#include "EdGraphSchema_K2.h"
#include "MaterialGraph/MaterialGraphSchema.h"
@@ -34,7 +34,7 @@ struct FSetNodeDefaultEntry
UCLASS()
class UMCP_GraphNode_SetDefaults : public UObject, public IMCPHandler
class UWing_GraphNode_SetDefaults : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -43,7 +43,7 @@ public:
FString Graph;
UPROPERTY(meta=(Description="Array of {node, name, value} objects"))
FMCPJsonArray Pins;
FWingJsonArray Pins;
virtual FString GetDescription() const override
{
@@ -56,7 +56,7 @@ public:
void HandleK2Entry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj, const UEdGraphSchema_K2* K2Schema)
{
MCPFetcher F(GraphObj);
WingFetcher F(GraphObj);
UEdGraphPin* Pin = F.Node(Entry.Node).Pin(Entry.Name).Cast<UEdGraphPin>();
if (!Pin) return;
@@ -64,7 +64,7 @@ public:
if (Pin->Direction != EGPD_Input)
{
UMCPServer::Printf(TEXT("error: %s is an output pin\n"), *MCPUtils::FormatName(Pin));
UWingServer::Printf(TEXT("error: %s is an output pin\n"), *WingUtils::FormatName(Pin));
return;
}
@@ -77,10 +77,10 @@ public:
FString Error = K2Schema->IsPinDefaultValid(Pin, UseDefaultValue, UseDefaultObject, UseDefaultText);
if (!Error.IsEmpty())
{
UMCPServer::Printf(TEXT("error: %s: %s\n"), *MCPUtils::FormatName(Pin), *Error);
UWingServer::Printf(TEXT("error: %s: %s\n"), *WingUtils::FormatName(Pin), *Error);
return;
}
UMCPServer::AddTouchedObject(Node);
UWingServer::AddTouchedObject(Node);
K2Schema->TrySetDefaultValue(*Pin, Entry.Value);
}
@@ -90,15 +90,15 @@ public:
void HandleMaterialEntry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj)
{
MCPFetcher F(GraphObj);
WingFetcher F(GraphObj);
UEdGraphNode* Node = F.Node(Entry.Node).Cast<UEdGraphNode>();
if (!Node) return;
TArray<MCPProperty> All = MCPProperty::GetAll(Node, CPF_Edit);
MCPProperty P = MCPProperty::FindOneExactMatch(All, Entry.Name);
TArray<WingProperty> All = WingProperty::GetAll(Node, CPF_Edit);
WingProperty P = WingProperty::FindOneExactMatch(All, Entry.Name);
if (!P) return;
UMCPServer::AddTouchedObject(Node);
UWingServer::AddTouchedObject(Node);
if (!P.SetText(Entry.Value))
return;
@@ -109,7 +109,7 @@ public:
virtual void Handle() override
{
// Fetch the graph once.
MCPFetcher GraphFetcher;
WingFetcher GraphFetcher;
UEdGraph* GraphObj = GraphFetcher.Walk(Graph).Cast<UEdGraph>();
if (!GraphObj) return;
@@ -119,14 +119,14 @@ public:
if (!K2Schema && !MGSchema)
{
UMCPServer::Printf(TEXT("error: unsupported graph schema %s\n"), *Schema->GetClass()->GetName());
UWingServer::Printf(TEXT("error: unsupported graph schema %s\n"), *Schema->GetClass()->GetName());
return;
}
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
{
FSetNodeDefaultEntry Entry;
if (!MCPJson::PopulateFromJson(FSetNodeDefaultEntry::StaticStruct(), &Entry, PinVal))
if (!WingJson::PopulateFromJson(FSetNodeDefaultEntry::StaticStruct(), &Entry, PinVal))
continue;
if (K2Schema)
@@ -135,6 +135,6 @@ public:
HandleMaterialEntry(Entry, GraphObj);
}
UMCPServer::Printf(TEXT("Done.\n"));
UWingServer::Printf(TEXT("Done.\n"));
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraphNode.h"
#include "GraphNode_SetPositions.generated.h"
@@ -32,7 +32,7 @@ struct FMoveNodeEntry
UCLASS()
class UMCP_GraphNode_SetPositions : public UObject, public IMCPHandler
class UWing_GraphNode_SetPositions : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -41,7 +41,7 @@ public:
FString Graph;
UPROPERTY(meta=(Description="Array of {node, x, y} objects"))
FMCPJsonArray Nodes;
FWingJsonArray Nodes;
virtual FString GetDescription() const override
{
@@ -50,7 +50,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
if (!TargetGraph) return;
@@ -59,9 +59,9 @@ public:
for (const TSharedPtr<FJsonValue>& NodeVal : Nodes.Array)
{
FMoveNodeEntry Entry;
if (!MCPJson::PopulateFromJson(FMoveNodeEntry::StaticStruct(), &Entry, NodeVal)) continue;
if (!WingJson::PopulateFromJson(FMoveNodeEntry::StaticStruct(), &Entry, NodeVal)) continue;
MCPFetcher FN(TargetGraph);
WingFetcher FN(TargetGraph);
UEdGraphNode* Node = FN.Node(Entry.Node).Cast<UEdGraphNode>();
if (!Node) continue;
@@ -70,6 +70,6 @@ public:
SuccessCount++;
}
UMCPServer::Printf(TEXT("Moved %d/%d nodes.\n"), SuccessCount, Nodes.Array.Num());
UWingServer::Printf(TEXT("Moved %d/%d nodes.\n"), SuccessCount, Nodes.Array.Num());
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPToolMenu.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingToolMenu.h"
#include "WingServer.h"
#include "ToolMenus.h"
#include "MaterialGraph/MaterialGraphNode.h"
#include "GraphNode_ShowMenu.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_GraphNode_ShowMenu : public UObject, public IMCPHandler
class UWing_GraphNode_ShowMenu : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -31,22 +31,22 @@ public:
private:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>();
if (!NodeObj) return;
if (Cast<UMaterialGraphNode>(NodeObj))
{
UMCPServer::Printf(TEXT("Material graph nodes do not have usable context menus."));
UWingServer::Printf(TEXT("Material graph nodes do not have usable context menus."));
return;
}
FToolMenuContext Context;
TArray<FToolMenuEntry> Entries = MCPToolMenu::GetMenuItems(NodeObj, Context);
TArray<FToolMenuEntry> Entries = WingToolMenu::GetMenuItems(NodeObj, Context);
for (FToolMenuEntry &Entry : Entries)
{
FString LabelText = Entry.Label.Get().ToString();
UMCPServer::Printf(TEXT("%s\n"), *LabelText);
UWingServer::Printf(TEXT("%s\n"), *LabelText);
}
if (Entries.IsEmpty()) UMCPServer::Printf(TEXT("No selectable menu entries right now.\n"));
if (Entries.IsEmpty()) UWingServer::Printf(TEXT("No selectable menu entries right now.\n"));
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphPin.h"
@@ -31,7 +31,7 @@ struct FConnectPinsEntry
UCLASS()
class UMCP_GraphPin_Connect : public UObject, public IMCPHandler
class UWing_GraphPin_Connect : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -40,7 +40,7 @@ public:
FString Graph;
UPROPERTY(meta=(Description="Array of {sourcePin, targetPin} objects"))
FMCPJsonArray Connections;
FWingJsonArray Connections;
virtual FString GetDescription() const override
{
@@ -49,7 +49,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
if (!G) return;
@@ -59,14 +59,14 @@ public:
for (const TSharedPtr<FJsonValue>& ConnVal : Connections.Array)
{
FConnectPinsEntry Entry;
if (!MCPJson::PopulateFromJson(FConnectPinsEntry::StaticStruct(), &Entry, ConnVal))
if (!WingJson::PopulateFromJson(FConnectPinsEntry::StaticStruct(), &Entry, ConnVal))
continue;
MCPFetcher FS(G);
WingFetcher FS(G);
UEdGraphPin* SourcePin = FS.Walk(Entry.SourcePin).Cast<UEdGraphPin>();
if (!SourcePin) continue;
MCPFetcher FT(G);
WingFetcher FT(G);
UEdGraphPin* TargetPin = FT.Walk(Entry.TargetPin).Cast<UEdGraphPin>();
if (!TargetPin) continue;
@@ -74,9 +74,9 @@ public:
const FPinConnectionResponse Response = Schema->CanCreateConnection(SourcePin, TargetPin);
if (Response.Response == CONNECT_RESPONSE_DISALLOW)
{
UMCPServer::Printf(TEXT("error: Cannot connect %s.%s to %s.%s: %s\n"),
*MCPUtils::FormatName(SourcePin->GetOwningNode()), *MCPUtils::FormatName(SourcePin),
*MCPUtils::FormatName(TargetPin->GetOwningNode()), *MCPUtils::FormatName(TargetPin),
UWingServer::Printf(TEXT("error: Cannot connect %s.%s to %s.%s: %s\n"),
*WingUtils::FormatName(SourcePin->GetOwningNode()), *WingUtils::FormatName(SourcePin),
*WingUtils::FormatName(TargetPin->GetOwningNode()), *WingUtils::FormatName(TargetPin),
*Response.Message.ToString());
continue;
}
@@ -85,6 +85,6 @@ public:
SuccessCount++;
}
UMCPServer::Printf(TEXT("Connected %d/%d pins.\n"), SuccessCount, TotalCount);
UWingServer::Printf(TEXT("Connected %d/%d pins.\n"), SuccessCount, TotalCount);
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphPin.h"
@@ -30,7 +30,7 @@ struct FDisconnectPinEntry
UCLASS()
class UMCP_GraphPin_Disconnect : public UObject, public IMCPHandler
class UWing_GraphPin_Disconnect : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -39,7 +39,7 @@ public:
FString Graph;
UPROPERTY(meta=(Description="Array of {pin, targetPin?} objects. If targetPin is omitted, all connections on the pin are broken."))
FMCPJsonArray Disconnections;
FWingJsonArray Disconnections;
virtual FString GetDescription() const override
{
@@ -49,7 +49,7 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
if (!G) return;
@@ -59,9 +59,9 @@ public:
for (const TSharedPtr<FJsonValue>& DiscVal : Disconnections.Array)
{
FDisconnectPinEntry Entry;
if (!MCPJson::PopulateFromJson(FDisconnectPinEntry::StaticStruct(), &Entry, DiscVal)) continue;
if (!WingJson::PopulateFromJson(FDisconnectPinEntry::StaticStruct(), &Entry, DiscVal)) continue;
MCPFetcher FP(G);
WingFetcher FP(G);
UEdGraphPin* Pin = FP.Walk(Entry.Pin).Cast<UEdGraphPin>();
if (!Pin) continue;
@@ -69,15 +69,15 @@ public:
if (!Entry.TargetPin.IsEmpty())
{
MCPFetcher FT(G);
WingFetcher FT(G);
UEdGraphPin* Target = FT.Walk(Entry.TargetPin).Cast<UEdGraphPin>();
if (!Target) continue;
if (!Pin->LinkedTo.Contains(Target))
{
UMCPServer::Printf(TEXT("Error: %s.%s is not connected to %s.%s\n"),
*MCPUtils::FormatName(Pin->GetOwningNode()), *MCPUtils::FormatName(Pin),
*MCPUtils::FormatName(Target->GetOwningNode()), *MCPUtils::FormatName(Target));
UWingServer::Printf(TEXT("Error: %s.%s is not connected to %s.%s\n"),
*WingUtils::FormatName(Pin->GetOwningNode()), *WingUtils::FormatName(Pin),
*WingUtils::FormatName(Target->GetOwningNode()), *WingUtils::FormatName(Target));
continue;
}
@@ -93,14 +93,14 @@ public:
}
}
UMCPServer::Printf(TEXT("Disconnected %d link(s) from %s.%s\n"),
UWingServer::Printf(TEXT("Disconnected %d link(s) from %s.%s\n"),
DisconnectedCount,
*MCPUtils::FormatName(Pin->GetOwningNode()), *MCPUtils::FormatName(Pin));
*WingUtils::FormatName(Pin->GetOwningNode()), *WingUtils::FormatName(Pin));
SuccessCount++;
TotalDisconnected += DisconnectedCount;
}
UMCPServer::Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"),
UWingServer::Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"),
SuccessCount, Disconnections.Array.Num(), TotalDisconnected);
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPServer.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingHandler.h"
#include "WingServer.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "GraphExport.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Graph_Dump : public UObject, public IMCPHandler
class UWing_Graph_Dump : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -36,19 +36,19 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UEdGraph *G = F.Walk(Graph).Cast<UEdGraph>();
if (!G) return;
MCPGraphExport Exporter(G);
UMCPServer::Print(*Exporter.GetOutput());
WingGraphExport Exporter(G);
UWingServer::Print(*Exporter.GetOutput());
if (bDetails)
{
UMCPServer::Print(Exporter.GetDetails());
UWingServer::Print(Exporter.GetDetails());
}
else
{
UMCPServer::Printf(TEXT("Note: use bDetails=true to see suppressed details."));
UWingServer::Printf(TEXT("Note: use bDetails=true to see suppressed details."));
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "MaterialParameter.h"
#include "Materials/MaterialInstanceConstant.h"
#include "MaterialTypes.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_MaterialInstance_ClearParameter : public UObject, public IMCPHandler
class UWing_MaterialInstance_ClearParameter : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -40,13 +40,13 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UMaterialInstanceConstant* MI = F.Asset(MaterialInstance).Cast<UMaterialInstanceConstant>();
if (!MI) return;
// Parse the association string.
EMaterialParameterAssociation Association;
if (!MCPMaterialParameter::ParseMaterialParameterAssociation(ParameterAssociation, Association))
if (!WingMaterialParameter::ParseMaterialParameterAssociation(ParameterAssociation, Association))
return;
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
@@ -68,13 +68,13 @@ public:
if (Removed == 0)
{
UMCPServer::Printf(TEXT("No override found for parameter '%s' (association=%s layer=%d) on %s"),
*Parameter, *ParameterAssociation, ParameterLayer, *MCPUtils::FormatName(MI));
UWingServer::Printf(TEXT("No override found for parameter '%s' (association=%s layer=%d) on %s"),
*Parameter, *ParameterAssociation, ParameterLayer, *WingUtils::FormatName(MI));
return;
}
MCPUtils::SaveGenericPackage(MI);
UMCPServer::Printf(TEXT("Cleared override for '%s' on %s\n"),
*Parameter, *MCPUtils::FormatName(MI));
WingUtils::SaveGenericPackage(MI);
UWingServer::Printf(TEXT("Cleared override for '%s' on %s\n"),
*Parameter, *WingUtils::FormatName(MI));
}
};

View File

@@ -1,15 +1,15 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Materials/Material.h"
#include "Materials/MaterialInterface.h"
#include "Materials/MaterialInstanceConstant.h"
#include "Factories/MaterialInstanceConstantFactoryNew.h"
#include "MCPPackageMaker.h"
#include "WingPackageMaker.h"
#include "MaterialInstance_Create.generated.h"
@@ -18,7 +18,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_MaterialInstance_Create : public UObject, public IMCPHandler
class UWing_MaterialInstance_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -36,16 +36,16 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(AssetPath);
WingPackageMaker Maker(AssetPath);
if (!Maker.Ok()) return;
// Load parent material by package path.
MCPFetcher F;
WingFetcher F;
UObject* ParentObj = F.Asset(ParentMaterial).GetObj();
UMaterialInterface* ParentMaterialObj = ParentObj ? Cast<UMaterialInterface>(ParentObj) : nullptr;
if (!ParentMaterialObj)
{
UMCPServer::Printf(TEXT("ERROR: Parent material '%s' not found or not a material\n"), *ParentMaterial);
UWingServer::Printf(TEXT("ERROR: Parent material '%s' not found or not a material\n"), *ParentMaterial);
return;
}
@@ -57,16 +57,16 @@ public:
MI->Parent = ParentMaterialObj;
// Save.
bool bSaved = MCPUtils::SaveGenericPackage(MI);
bool bSaved = WingUtils::SaveGenericPackage(MI);
UMCPServer::Printf(TEXT("Created %s\n"), *MI->GetPathName());
UWingServer::Printf(TEXT("Created %s\n"), *MI->GetPathName());
if (UMaterialInstance* ParentMI = Cast<UMaterialInstance>(ParentMaterialObj))
UMCPServer::Printf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMI));
UWingServer::Printf(TEXT("Parent: %s\n"), *WingUtils::FormatName(ParentMI));
else if (UMaterial* ParentMat = Cast<UMaterial>(ParentMaterialObj))
UMCPServer::Printf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMat));
UWingServer::Printf(TEXT("Parent: %s\n"), *WingUtils::FormatName(ParentMat));
else
UMCPServer::Printf(TEXT("Parent: %s\n"), *ParentMaterialObj->GetPathName());
UWingServer::Printf(TEXT("Parent: %s\n"), *ParentMaterialObj->GetPathName());
if (!bSaved)
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
UWingServer::Print(TEXT("WARNING: Package save failed\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "MaterialParameter.h"
#include "Materials/MaterialInstanceConstant.h"
#include "MaterialTypes.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_MaterialInstance_DumpParameters : public UObject, public IMCPHandler
class UWing_MaterialInstance_DumpParameters : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -31,19 +31,19 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UMaterialInstanceConstant* MI = F.Asset(MaterialInstance).Cast<UMaterialInstanceConstant>();
if (!MI) return;
auto AllParams = MCPMaterialParameter::GetMaterialParameters(MI);
auto AllParams = WingMaterialParameter::GetMaterialParameters(MI);
// Overridden parameters first.
bool bHasOverrides = false;
for (auto& [Info, Meta] : AllParams)
{
if (!Meta.bOverride) continue;
if (!bHasOverrides) { UMCPServer::Print(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
MCPMaterialParameter::FormatMaterialParameter(Info, Meta);
if (!bHasOverrides) { UWingServer::Print(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
WingMaterialParameter::FormatMaterialParameter(Info, Meta);
}
// Inherited (non-overridden) parameters.
@@ -51,8 +51,8 @@ public:
for (auto& [Info, Meta] : AllParams)
{
if (Meta.bOverride) continue;
if (!bHasInherited) { UMCPServer::Print(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
MCPMaterialParameter::FormatMaterialParameter(Info, Meta);
if (!bHasInherited) { UWingServer::Print(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
WingMaterialParameter::FormatMaterialParameter(Info, Meta);
}
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "MaterialParameter.h"
#include "Materials/MaterialInstanceConstant.h"
#include "MaterialTypes.h"
@@ -17,7 +17,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_MaterialInstance_SetParameter : public UObject, public IMCPHandler
class UWing_MaterialInstance_SetParameter : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -44,30 +44,30 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UMaterialInstanceConstant* MI = F.Asset(MaterialInstance).Cast<UMaterialInstanceConstant>();
if (!MI) return;
// Parse the association string.
EMaterialParameterAssociation Association;
if (!MCPMaterialParameter::ParseMaterialParameterAssociation(ParameterAssociation, Association))
if (!WingMaterialParameter::ParseMaterialParameterAssociation(ParameterAssociation, Association))
return;
// Build the parameter ID to look up.
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
// Find it in the material's parameter map.
auto AllParams = MCPMaterialParameter::GetMaterialParameters(MI);
auto AllParams = WingMaterialParameter::GetMaterialParameters(MI);
FMaterialParameterMetadata* Found = AllParams.Find(ParamID);
if (!Found)
{
UMCPServer::Printf(TEXT("No parameter named '%s' with association=%s layer=%d"),
UWingServer::Printf(TEXT("No parameter named '%s' with association=%s layer=%d"),
*Parameter, *ParameterAssociation, ParameterLayer);
return;
}
if (Found->PrimitiveDataIndex != INDEX_NONE)
{
UMCPServer::Printf(TEXT("Parameter '%s' uses custom primitive data and cannot be set on a material instance"), *Parameter);
UWingServer::Printf(TEXT("Parameter '%s' uses custom primitive data and cannot be set on a material instance"), *Parameter);
return;
}
@@ -80,7 +80,7 @@ public:
float ScalarValue;
if (!FDefaultValueHelper::ParseFloat(Value, ScalarValue))
{
UMCPServer::Printf(TEXT("Failed to parse '%s' as a float"), *Value);
UWingServer::Printf(TEXT("Failed to parse '%s' as a float"), *Value);
return;
}
MI->SetScalarParameterValueEditorOnly(ParamID, ScalarValue);
@@ -91,19 +91,19 @@ public:
FLinearColor Color;
if (!Color.InitFromString(Value))
{
UMCPServer::Printf(TEXT("Failed to parse '%s' as a color/vector (expected format: '(R=1,G=0,B=0,A=1)')"), *Value);
UWingServer::Printf(TEXT("Failed to parse '%s' as a color/vector (expected format: '(R=1,G=0,B=0,A=1)')"), *Value);
return;
}
MI->SetVectorParameterValueEditorOnly(ParamID, Color);
break;
}
default:
UMCPServer::Printf(TEXT("Parameters of type %d (see EMaterialParameterType) are not implemented"), (int)Type);
UWingServer::Printf(TEXT("Parameters of type %d (see EMaterialParameterType) are not implemented"), (int)Type);
return;
}
MCPUtils::SaveGenericPackage(MI);
WingUtils::SaveGenericPackage(MI);
UMCPServer::Printf(TEXT("Set '%s' = %s on %s\n"),
*Parameter, *Value, *MCPUtils::FormatName(MI));
UWingServer::Printf(TEXT("Set '%s' = %s on %s\n"),
*Parameter, *Value, *WingUtils::FormatName(MI));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingUtils.h"
#include "Materials/Material.h"
#include "Material_Compile.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Material_Compile : public UObject, public IMCPHandler
class UWing_Material_Compile : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -30,7 +30,7 @@ public:
virtual void Handle() override
{
// Load material
MCPFetcher F;
WingFetcher F;
UMaterial* MaterialObj = F.Asset(Material).Cast<UMaterial>();
if (!MaterialObj) return;
@@ -48,14 +48,14 @@ public:
if (Errors.IsEmpty())
{
UMCPServer::Printf(TEXT("%s compiled successfully.\n"), *MCPUtils::FormatName(MaterialObj));
UWingServer::Printf(TEXT("%s compiled successfully.\n"), *WingUtils::FormatName(MaterialObj));
}
else
{
UMCPServer::Printf(TEXT("%s compiled with %d error(s):\n"), *MCPUtils::FormatName(MaterialObj), Errors.Num());
UWingServer::Printf(TEXT("%s compiled with %d error(s):\n"), *WingUtils::FormatName(MaterialObj), Errors.Num());
for (const FString& Err : Errors)
{
UMCPServer::Printf(TEXT(" %s\n"), *Err);
UWingServer::Printf(TEXT(" %s\n"), *Err);
}
}
}

View File

@@ -1,13 +1,13 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingUtils.h"
#include "Materials/Material.h"
#include "MaterialDomain.h"
#include "Factories/MaterialFactoryNew.h"
#include "MCPPackageMaker.h"
#include "WingPackageMaker.h"
#include "Material_Create.generated.h"
@@ -16,7 +16,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Material_Create : public UObject, public IMCPHandler
class UWing_Material_Create : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -31,15 +31,15 @@ public:
virtual void Handle() override
{
MCPPackageMaker Maker(Material);
WingPackageMaker Maker(Material);
if (!Maker.Ok()) return;
// Create via IAssetTools + factory.
UMaterial* MaterialObj = Maker.CreateAsset<UMaterial, UMaterialFactoryNew>();
if (!MaterialObj) return;
bool bSaved = MCPUtils::SaveGenericPackage(MaterialObj);
UMCPServer::Printf(TEXT("Created %s\n"), *MaterialObj->GetPathName());
if (!bSaved) UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
bool bSaved = WingUtils::SaveGenericPackage(MaterialObj);
UWingServer::Printf(TEXT("Created %s\n"), *MaterialObj->GetPathName());
if (!bSaved) UWingServer::Print(TEXT("WARNING: Package save failed\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPServer.h"
#include "MCPUtils.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingServer.h"
#include "WingUtils.h"
#include "MaterialParameter.h"
#include "MaterialTypes.h"
#include "Material_DumpParameters.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Material_DumpParameters : public UObject, public IMCPHandler
class UWing_Material_DumpParameters : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -30,16 +30,16 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UMaterial* Mat = F.Asset(Material).Cast<UMaterial>();
if (!Mat) return;
auto AllParams = MCPMaterialParameter::GetMaterialParameters(Mat);
auto AllParams = WingMaterialParameter::GetMaterialParameters(Mat);
for (auto& [Info, Meta] : AllParams)
{
MCPMaterialParameter::FormatMaterialParameter(Info, Meta);
WingMaterialParameter::FormatMaterialParameter(Info, Meta);
}
if (AllParams.IsEmpty()) UMCPServer::Printf(TEXT("No material parameters.\n"));
if (AllParams.IsEmpty()) UWingServer::Printf(TEXT("No material parameters.\n"));
}
};

View File

@@ -1,12 +1,12 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPProperty.h"
#include "MCPTypes.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingProperty.h"
#include "WingTypes.h"
#include "WingUtils.h"
#include "Property_Dump.generated.h"
@@ -15,7 +15,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Property_Dump : public UObject, public IMCPHandler
class UWing_Property_Dump : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -40,20 +40,20 @@ public:
virtual void Handle() override
{
// Resolve the path to an object and get its editable template.
MCPFetcher F;
WingFetcher F;
UObject* Template = F.Walk(Object).Cast<UObject>();
if (!Template) return;
TArray<MCPProperty> AllProps = MCPProperty::GetAll(Template, CPF_Edit);
TArray<MCPProperty> Props = MCPProperty::FindAllSubstring(AllProps, Query);
TArray<WingProperty> AllProps = WingProperty::GetAll(Template, CPF_Edit);
TArray<WingProperty> Props = WingProperty::FindAllSubstring(AllProps, Query);
if (Local)
{
UClass* ObjClass = Template->GetClass();
Props.RemoveAll([ObjClass](const MCPProperty& P) { return P->GetOwnerStruct() != ObjClass; });
Props.RemoveAll([ObjClass](const WingProperty& P) { return P->GetOwnerStruct() != ObjClass; });
}
// Group properties by category.
TMap<FString, TArray<MCPProperty>> ByCategory;
for (MCPProperty& P : Props)
TMap<FString, TArray<WingProperty>> ByCategory;
for (WingProperty& P : Props)
{
FString Category = P->HasMetaData(TEXT("Category")) ? P->GetMetaData(TEXT("Category")) : FString();
ByCategory.FindOrAdd(Category).Add(P);
@@ -71,28 +71,28 @@ public:
for (const FString& Category : Categories)
{
if (Category.IsEmpty())
UMCPServer::Print(TEXT("\nUncategorized:\n"));
UWingServer::Print(TEXT("\nUncategorized:\n"));
else
UMCPServer::Printf(TEXT("\n%s:\n"), *Category);
UWingServer::Printf(TEXT("\n%s:\n"), *Category);
for (MCPProperty& P : ByCategory[Category])
for (WingProperty& P : ByCategory[Category])
{
FString PropName = MCPUtils::FormatName(P.Prop);
FString PropName = WingUtils::FormatName(P.Prop);
FString ValueStr = P.GetText();
if (Truncate && (ValueStr.Len() > 80))
ValueStr = ValueStr.Left(80) + TEXT("...");
bool bEditable = !P->HasAnyPropertyFlags(CPF_EditConst);
UMCPServer::Printf(TEXT(" %s %s %s = %s\n"),
UWingServer::Printf(TEXT(" %s %s %s = %s\n"),
bEditable ? TEXT("editable") : TEXT("readonly"),
*UMCPTypes::TypeToText(P.Prop),
*UWingTypes::TypeToText(P.Prop),
*PropName,
*ValueStr);
}
}
if (Props.IsEmpty())
UMCPServer::Print(TEXT(" (no blueprint-visible properties found)\n"));
UWingServer::Print(TEXT(" (no blueprint-visible properties found)\n"));
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPProperty.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingProperty.h"
#include "WingUtils.h"
#include "Property_Get.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Property_Get : public UObject, public IMCPHandler
class UWing_Property_Get : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -32,15 +32,15 @@ public:
virtual void Handle() override
{
MCPFetcher F;
WingFetcher F;
UObject* Obj = F.Walk(Object).Cast<UObject>();
if (!Obj) return;
TArray<MCPProperty> All = MCPProperty::GetAll(Obj, CPF_Edit);
MCPProperty P = MCPProperty::FindOneExactMatch(All, Property);
TArray<WingProperty> All = WingProperty::GetAll(Obj, CPF_Edit);
WingProperty P = WingProperty::FindOneExactMatch(All, Property);
if (!P) return;
UMCPServer::Print(P.GetText());
UMCPServer::Print(TEXT("\n"));
UWingServer::Print(P.GetText());
UWingServer::Print(TEXT("\n"));
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPProperty.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingProperty.h"
#include "WingUtils.h"
#include "Property_Set.generated.h"
@@ -14,7 +14,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Property_Set : public UObject, public IMCPHandler
class UWing_Property_Set : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -23,7 +23,7 @@ public:
FString Object;
UPROPERTY(meta=(Description="Object mapping property names to new values in Unreal text format"))
FMCPJsonObject Properties;
FWingJsonObject Properties;
virtual FString GetDescription() const override
{
@@ -33,28 +33,28 @@ public:
virtual void Handle() override
{
// Resolve the path to an object and get its editable template.
MCPFetcher F;
WingFetcher F;
UObject* Obj = F.Walk(Object).Cast<UObject>();
if (!Obj) return;
if (!Properties.Json || Properties.Json->Values.Num() == 0)
{
UMCPServer::Print(TEXT("Error: No properties specified\n"));
UWingServer::Print(TEXT("Error: No properties specified\n"));
return;
}
// Validation pass — resolve all properties and values before modifying anything.
TArray<MCPProperty> All = MCPProperty::GetAll(Obj, CPF_Edit);
TArray<TPair<MCPProperty, FString>> Resolved;
TArray<WingProperty> All = WingProperty::GetAll(Obj, CPF_Edit);
TArray<TPair<WingProperty, FString>> Resolved;
for (const auto& Pair : Properties.Json->Values)
{
MCPProperty P = MCPProperty::FindOneExactMatch(All, Pair.Key);
WingProperty P = WingProperty::FindOneExactMatch(All, Pair.Key);
if (!P) return;
FString ValueStr;
if (!Pair.Value->TryGetString(ValueStr))
{
UMCPServer::Printf(TEXT("Error: Value for '%s' must be a string\n"), *Pair.Key);
UWingServer::Printf(TEXT("Error: Value for '%s' must be a string\n"), *Pair.Key);
return;
}
Resolved.Emplace(P, ValueStr);
@@ -70,10 +70,10 @@ public:
}
// Save.
bool bSaved = MCPUtils::SaveGenericPackage(Obj);
bool bSaved = WingUtils::SaveGenericPackage(Obj);
UMCPServer::Printf(TEXT("Set %d/%d properties.\n"), SuccessCount, Properties.Json->Values.Num());
UWingServer::Printf(TEXT("Set %d/%d properties.\n"), SuccessCount, Properties.Json->Values.Num());
if (!bSaved)
UMCPServer::Print(TEXT("Warning: Save failed\n"));
UWingServer::Print(TEXT("Warning: Save failed\n"));
}
};

View File

@@ -1,16 +1,16 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPFetcher.h"
#include "MCPServer.h"
#include "MCPTypes.h"
#include "MCPJson.h"
#include "MCPUtils.h"
#include "WingHandler.h"
#include "WingFetcher.h"
#include "WingServer.h"
#include "WingTypes.h"
#include "WingJson.h"
#include "WingUtils.h"
#include "ShowCommands.generated.h"
UCLASS()
class UMCP_ShowCommands : public UObject, public IMCPHandler
class UWing_ShowCommands : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -30,20 +30,20 @@ public:
{
if (Verbose)
{
MCPUtils::FormatCommandHelp(Class);
WingUtils::FormatCommandHelp(Class);
return;
}
UMCPServer::Print(MCPUtils::GetHandlerName(Class));
UMCPServer::Print(TEXT("("));
UWingServer::Print(WingUtils::GetHandlerName(Class));
UWingServer::Print(TEXT("("));
bool bFirst = true;
for (TFieldIterator<FProperty> PropIt(Class, EFieldIterationFlags::None); PropIt; ++PropIt)
{
if (!bFirst) UMCPServer::Print(TEXT(","));
if (!bFirst) UWingServer::Print(TEXT(","));
bFirst = false;
if (PropIt->HasMetaData(TEXT("Optional"))) UMCPServer::Print(TEXT("?"));
UMCPServer::Print(PropIt->GetName());
if (PropIt->HasMetaData(TEXT("Optional"))) UWingServer::Print(TEXT("?"));
UWingServer::Print(PropIt->GetName());
}
UMCPServer::Print(TEXT(")\n"));
UWingServer::Print(TEXT(")\n"));
}
void EmitCommandList(bool bHalfBaked)
@@ -51,22 +51,22 @@ public:
FString QueryLower = Query.ToLower();
FString PrevGroup;
for (UClass* Class : MCPUtils::CollectHandlerClasses())
for (UClass* Class : WingUtils::CollectHandlerClasses())
{
bool bIsHalfBaked = Class->GetMetaData(TEXT("ModuleRelativePath")).StartsWith(TEXT("HalfBaked/"));
if (bIsHalfBaked != bHalfBaked)
continue;
FString ToolName = MCPUtils::GetHandlerName(Class);
FString ToolName = WingUtils::GetHandlerName(Class);
if (!ToolName.ToLower().Contains(QueryLower))
continue;
// Blank line between groups
FString Group = MCPUtils::GetHandlerGroup(Class);
FString Group = WingUtils::GetHandlerGroup(Class);
if (Group != PrevGroup)
{
if (!PrevGroup.IsEmpty())
UMCPServer::Print(TEXT("\n"));
UWingServer::Print(TEXT("\n"));
PrevGroup = Group;
}
@@ -76,10 +76,10 @@ public:
virtual void Handle() override
{
UMCPServer::Printf(TEXT("\n"));
UWingServer::Printf(TEXT("\n"));
EmitCommandList(false);
// UMCPServer::Print(TEXT("\n--- Half-Baked (may have issues) ---\n\n"));
// UWingServer::Print(TEXT("\n--- Half-Baked (may have issues) ---\n\n"));
// EmitCommandList(true);
UMCPServer::Printf(TEXT("\n"));
UWingServer::Printf(TEXT("\n"));
}
};

View File

@@ -1,10 +1,10 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPTypes.h"
#include "MCPUtils.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingTypes.h"
#include "WingUtils.h"
#include "AssetRegistry/AssetData.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "UObject/UObjectIterator.h"
@@ -19,7 +19,7 @@
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_TypeName_Search : public UObject, public IMCPHandler
class UWing_TypeName_Search : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -89,16 +89,16 @@ public:
Kind = TEXT("Struct");
else if (const UClass* Class = Cast<UClass>(Obj))
Kind = Class->IsChildOf(UInterface::StaticClass()) ? TEXT("Interface") : TEXT("Class");
Results.Add(FString::Printf(TEXT("%s %s\n"), Kind, *UMCPTypes::TypeToText(Obj)));
Results.Add(FString::Printf(TEXT("%s %s\n"), Kind, *UWingTypes::TypeToText(Obj)));
}
Results.Sort();
for (const auto &Result : Results)
{
UMCPServer::Print(Result);
UWingServer::Print(Result);
}
if (Results.Num() == Limit)
{
UMCPServer::Printf(TEXT("Search limit reached, raise it with Limit=\n"));
UWingServer::Printf(TEXT("Search limit reached, raise it with Limit=\n"));
}
}
};

View File

@@ -1,12 +1,12 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPServer.h"
#include "WingHandler.h"
#include "WingServer.h"
#include "UserManual.generated.h"
UCLASS()
class UMCP_UserManual : public UObject, public IMCPHandler
class UWing_UserManual : public UObject, public IWingHandler
{
GENERATED_BODY()
@@ -18,7 +18,7 @@ public:
virtual void Handle() override
{
UMCPServer::Print(TEXT(
UWingServer::Print(TEXT(
"\n PATHS:"
"\n"
"\n Most commands require you to specify a path. A path starts"

View File

@@ -1,8 +1,8 @@
#include "BPVarEditor.h"
#include "MCPJson.h"
#include "MCPServer.h"
#include "MCPTypes.h"
#include "MCPUtils.h"
#include "WingJson.h"
#include "WingServer.h"
#include "WingTypes.h"
#include "WingUtils.h"
#include "EdGraphSchema_K2.h"
#include "Kismet2/BlueprintEditorUtils.h"
@@ -12,7 +12,7 @@ FBPVarEditor::FBPVarEditor(UBlueprint* BP, const FString& VarName)
int32 VarIndex = FBlueprintEditorUtils::FindNewVariableIndex(BP, VarFName);
if (VarIndex == INDEX_NONE)
{
UMCPServer::Printf(TEXT("ERROR: Variable '%s' not found in %s\n"), *VarName, *MCPUtils::FormatName(BP));
UWingServer::Printf(TEXT("ERROR: Variable '%s' not found in %s\n"), *VarName, *WingUtils::FormatName(BP));
return;
}
Desc = &BP->NewVariables[VarIndex];
@@ -23,7 +23,7 @@ FBPVarEditor::FBPVarEditor(UBlueprint* BP, const FString& VarName)
UObject* CDO = BP->GeneratedClass->GetDefaultObject();
FProperty* Prop = BP->GeneratedClass->FindPropertyByName(VarFName);
if (CDO && Prop)
DefaultValueProp = MCPProperty(Prop, CDO);
DefaultValueProp = WingProperty(Prop, CDO);
}
}
@@ -31,12 +31,12 @@ void FBPVarEditor::Dump()
{
LoadFlags();
LoadDefault();
TArray<MCPProperty> Props = MergedProperties();
for (MCPProperty& P : Props)
TArray<WingProperty> Props = MergedProperties();
for (WingProperty& P : Props)
{
UMCPServer::Printf(TEXT(" %s %s = %s\n"),
*UMCPTypes::TypeToText(P.Prop),
*MCPUtils::FormatName(P.Prop),
UWingServer::Printf(TEXT(" %s %s = %s\n"),
*UWingTypes::TypeToText(P.Prop),
*WingUtils::FormatName(P.Prop),
*P.GetText());
}
}
@@ -47,7 +47,7 @@ bool FBPVarEditor::ApplyJson(const FJsonObject* Json)
bool bHasType = Json->HasField(TEXT("VarType"));
if (bHasDefault && bHasType)
{
UMCPServer::Print(TEXT(
UWingServer::Print(TEXT(
"ERROR: Cannot set VarType and DefaultValue in the same call.\n"
"Change the type first, then recompile the blueprint,\n"
"then set the default.\n"));
@@ -56,8 +56,8 @@ bool FBPVarEditor::ApplyJson(const FJsonObject* Json)
LoadFlags();
TArray<MCPProperty> Props = MergedProperties();
if (!MCPJson::PopulateFromJson(Props, Json, true))
TArray<WingProperty> Props = MergedProperties();
if (!WingJson::PopulateFromJson(Props, Json, true))
return false;
SaveFlags();
@@ -131,23 +131,23 @@ bool FBPVarEditor::SaveDefault()
return true;
}
TArray<MCPProperty> FBPVarEditor::MergedProperties()
TArray<WingProperty> FBPVarEditor::MergedProperties()
{
TArray<MCPProperty> Props = MCPProperty::GetAll(
TArray<WingProperty> Props = WingProperty::GetAll(
FBPVariableDescription::StaticStruct(), Desc, CPF_Edit);
MCPProperty::Remove(Props, TEXT("PropertyFlags"));
MCPProperty::Remove(Props, TEXT("MetaDataArray"));
MCPProperty::Remove(Props, TEXT("VarName"));
MCPProperty::Remove(Props, TEXT("VarGuid"));
MCPProperty::Remove(Props, TEXT("DefaultValue"));
WingProperty::Remove(Props, TEXT("PropertyFlags"));
WingProperty::Remove(Props, TEXT("MetaDataArray"));
WingProperty::Remove(Props, TEXT("VarName"));
WingProperty::Remove(Props, TEXT("VarGuid"));
WingProperty::Remove(Props, TEXT("DefaultValue"));
Props.Append(MCPProperty::GetAll(
Props.Append(WingProperty::GetAll(
FBPVarEditor::StaticStruct(), this, (EPropertyFlags)0));
// Remove DefaultValue if we don't have a CDO property to back it.
if (!DefaultValueProp)
MCPProperty::Remove(Props, TEXT("DefaultValue"));
WingProperty::Remove(Props, TEXT("DefaultValue"));
return Props;
}

View File

@@ -2,17 +2,17 @@
#include "K2Node_EditablePinBase.h"
#include "K2Node_FunctionResult.h"
#include "K2Node_Tunnel.h"
#include "MCPTypes.h"
#include "MCPServer.h"
#include "WingTypes.h"
#include "WingServer.h"
bool MCPFunctionArgs::HasArgs(UEdGraphNode* Node)
bool WingFunctionArgs::HasArgs(UEdGraphNode* Node)
{
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
if (!Editable) return false;
return Editable->IsEditable();
}
FString MCPFunctionArgs::GetArgs(UEdGraphNode* Node)
FString WingFunctionArgs::GetArgs(UEdGraphNode* Node)
{
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
if (!Editable) return FString();
@@ -21,12 +21,12 @@ FString MCPFunctionArgs::GetArgs(UEdGraphNode* Node)
for (const TSharedPtr<FUserPinInfo>& Pin : Editable->UserDefinedPins)
{
if (SB.Len() > 0) SB << TEXT(", ");
SB << UMCPTypes::TypeToText(Pin->PinType) << TEXT(" ") << Pin->PinName.ToString();
SB << UWingTypes::TypeToText(Pin->PinType) << TEXT(" ") << Pin->PinName.ToString();
}
return FString(SB);
}
EEdGraphPinDirection MCPFunctionArgs::GetPinDirection(UK2Node_EditablePinBase* Node)
EEdGraphPinDirection WingFunctionArgs::GetPinDirection(UK2Node_EditablePinBase* Node)
{
// FunctionResult takes inputs; Tunnel depends on its flags; everything else outputs.
if (Node->IsA<UK2Node_FunctionResult>())
@@ -36,7 +36,7 @@ EEdGraphPinDirection MCPFunctionArgs::GetPinDirection(UK2Node_EditablePinBase* N
return EGPD_Output;
}
bool MCPFunctionArgs::ParseArgs(const FString& Args, TArray<FParsedArg>& OutArgs)
bool WingFunctionArgs::ParseArgs(const FString& Args, TArray<FParsedArg>& OutArgs)
{
FString Trimmed = Args.TrimStartAndEnd();
if (Trimmed.IsEmpty()) return true;
@@ -53,7 +53,7 @@ bool MCPFunctionArgs::ParseArgs(const FString& Args, TArray<FParsedArg>& OutArgs
int32 LastSpace;
if (!Token.FindLastChar(TEXT(' '), LastSpace))
{
UMCPServer::Printf(TEXT("ERROR: Expected 'type name' but got '%s'\n"), *Token);
UWingServer::Printf(TEXT("ERROR: Expected 'type name' but got '%s'\n"), *Token);
return false;
}
@@ -62,24 +62,24 @@ bool MCPFunctionArgs::ParseArgs(const FString& Args, TArray<FParsedArg>& OutArgs
if (TypeStr.IsEmpty() || NameStr.IsEmpty())
{
UMCPServer::Printf(TEXT("ERROR: Expected 'type name' but got '%s'\n"), *Token);
UWingServer::Printf(TEXT("ERROR: Expected 'type name' but got '%s'\n"), *Token);
return false;
}
FParsedArg Arg;
if (!UMCPTypes::TextToType(TypeStr, Arg.PinType)) return false;
if (!UWingTypes::TextToType(TypeStr, Arg.PinType)) return false;
Arg.PinName = FName(*NameStr);
OutArgs.Add(MoveTemp(Arg));
}
return true;
}
bool MCPFunctionArgs::SetArgs(UEdGraphNode* Node, const FString& Args)
bool WingFunctionArgs::SetArgs(UEdGraphNode* Node, const FString& Args)
{
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
if (!Editable || !Editable->IsEditable())
{
UMCPServer::Printf(TEXT("ERROR: Node does not support editable pins\n"));
UWingServer::Printf(TEXT("ERROR: Node does not support editable pins\n"));
return false;
}

View File

@@ -1,6 +1,6 @@
#include "GraphExport.h"
#include "MCPTypes.h"
#include "MCPUtils.h"
#include "WingTypes.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
@@ -14,7 +14,7 @@
#include "FunctionArgs.h"
#include "MaterialGraph/MaterialGraphNode.h"
MCPGraphExport::MCPGraphExport(UEdGraph* InGraph)
WingGraphExport::WingGraphExport(UEdGraph* InGraph)
: Graph(InGraph)
{
SortNodes();
@@ -24,7 +24,7 @@ MCPGraphExport::MCPGraphExport(UEdGraph* InGraph)
EmitComments();
}
MCPGraphExport::MCPGraphExport(UEdGraphNode* InNode)
WingGraphExport::WingGraphExport(UEdGraphNode* InNode)
: Graph(InNode->GetGraph())
{
SortedNodes.Add(InNode);
@@ -41,7 +41,7 @@ MCPGraphExport::MCPGraphExport(UEdGraphNode* InNode)
//
////////////////////////////////////////////////////////
UEdGraphPin* MCPGraphExport::GetLinkedTo(UEdGraphPin* Pin)
UEdGraphPin* WingGraphExport::GetLinkedTo(UEdGraphPin* Pin)
{
while (true)
{
@@ -53,7 +53,7 @@ UEdGraphPin* MCPGraphExport::GetLinkedTo(UEdGraphPin* Pin)
}
}
bool MCPGraphExport::IsDefaultToSelf(UEdGraphPin* Pin)
bool WingGraphExport::IsDefaultToSelf(UEdGraphPin* Pin)
{
// Only valid call-function nodes can have default-to-self.
UK2Node_CallFunction* CallNode = Cast<UK2Node_CallFunction>(Pin->GetOwningNode());
@@ -72,7 +72,7 @@ bool MCPGraphExport::IsDefaultToSelf(UEdGraphPin* Pin)
return Pin->PinName.ToString() == DefaultToSelfPinName;
}
TArray<UEdGraphPin*> MCPGraphExport::FilterPins(UEdGraphNode* Node, EEdGraphPinDirection Direction, FName Category)
TArray<UEdGraphPin*> WingGraphExport::FilterPins(UEdGraphNode* Node, EEdGraphPinDirection Direction, FName Category)
{
TArray<UEdGraphPin*> Result;
for (UEdGraphPin* Pin : Node->Pins)
@@ -84,12 +84,12 @@ TArray<UEdGraphPin*> MCPGraphExport::FilterPins(UEdGraphNode* Node, EEdGraphPinD
return Result;
}
bool MCPGraphExport::HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction)
bool WingGraphExport::HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction)
{
return FilterPins(Node, Direction, UEdGraphSchema_K2::PC_Exec).Num() > 0;
}
UEdGraphPin* MCPGraphExport::FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirection Direction)
UEdGraphPin* WingGraphExport::FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirection Direction)
{
for (UEdGraphPin* Pin : Node->Pins)
{
@@ -105,7 +105,7 @@ UEdGraphPin* MCPGraphExport::FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirecti
//
////////////////////////////////////////////////////////
FString MCPGraphExport::FormatPinSource(UEdGraphPin* Pin)
FString WingGraphExport::FormatPinSource(UEdGraphPin* Pin)
{
// If connected, show source node.pin
UEdGraphPin* LinkedTo = GetLinkedTo(Pin);
@@ -115,10 +115,10 @@ FString MCPGraphExport::FormatPinSource(UEdGraphPin* Pin)
// For variable get nodes, just show the variable name.
if (UK2Node_VariableGet* VarGet = Cast<UK2Node_VariableGet>(LinkedToNode))
return MCPUtils::FormatName(VarGet->VariableReference);
return WingUtils::FormatName(VarGet->VariableReference);
FString PinLabel = MCPUtils::FormatName(LinkedTo);
return FString::Printf(TEXT("%s.%s"), *MCPUtils::FormatName(LinkedToNode), *PinLabel);
FString PinLabel = WingUtils::FormatName(LinkedTo);
return FString::Printf(TEXT("%s.%s"), *WingUtils::FormatName(LinkedToNode), *PinLabel);
}
// String pins: always show in quotes (even if empty).
@@ -156,7 +156,7 @@ FString MCPGraphExport::FormatPinSource(UEdGraphPin* Pin)
}
}
void MCPGraphExport::Traverse(UEdGraphNode* Node)
void WingGraphExport::Traverse(UEdGraphNode* Node)
{
if (Visited.Contains(Node)) return;
Visited.Add(Node);
@@ -177,7 +177,7 @@ void MCPGraphExport::Traverse(UEdGraphNode* Node)
Traverse(LinkedPin->GetOwningNode());
}
void MCPGraphExport::SortNodes()
void WingGraphExport::SortNodes()
{
// Find starter nodes: have exec output but no exec input.
TArray<UEdGraphNode*> Starters;
@@ -208,15 +208,15 @@ void MCPGraphExport::SortNodes()
}
}
void MCPGraphExport::EmitNode(UEdGraphNode* Node)
void WingGraphExport::EmitNode(UEdGraphNode* Node)
{
if (Node->IsA<UEdGraphNode_Comment>()) return;
Output.Appendf(TEXT("\nnode %s: %s\n"), *MCPUtils::FormatName(Node), *MCPUtils::FormatNodeTitle(Node));
Output.Appendf(TEXT("\nnode %s: %s\n"), *WingUtils::FormatName(Node), *WingUtils::FormatNodeTitle(Node));
// Emit function args (if applicable).
if (MCPFunctionArgs::HasArgs(Node))
Output.Appendf(TEXT(" args %s\n"), *MCPFunctionArgs::GetArgs(Node));
if (WingFunctionArgs::HasArgs(Node))
Output.Appendf(TEXT(" args %s\n"), *WingFunctionArgs::GetArgs(Node));
// Emit material expression properties (if applicable).
EmitMaterialProperties(Node, Output, true);
@@ -228,8 +228,8 @@ void MCPGraphExport::EmitNode(UEdGraphNode* Node)
if (Pin->bHidden) continue;
Output.Appendf(TEXT(" input %s %s = %s\n"),
*UMCPTypes::TypeToText(Pin->PinType),
*MCPUtils::FormatName(Pin),
*UWingTypes::TypeToText(Pin->PinType),
*WingUtils::FormatName(Pin),
*FormatPinSource(Pin));
}
@@ -240,7 +240,7 @@ void MCPGraphExport::EmitNode(UEdGraphNode* Node)
if (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) continue;
if (Pin->bHidden) continue;
if (!ReturnPins.IsEmpty()) ReturnPins += TEXT(", ");
ReturnPins += MCPUtils::FormatName(Pin);
ReturnPins += WingUtils::FormatName(Pin);
}
if (!ReturnPins.IsEmpty())
{
@@ -254,18 +254,18 @@ void MCPGraphExport::EmitNode(UEdGraphNode* Node)
UEdGraphPin* LinkedTo = GetLinkedTo(Pin);
if (!LinkedTo) continue;
FString Target = MCPUtils::FormatName(LinkedTo->GetOwningNode());
FString Target = WingUtils::FormatName(LinkedTo->GetOwningNode());
if (ExecOuts.Num() == 1)
Output.Appendf(TEXT(" goto %s\n"), *Target);
else
Output.Appendf(TEXT(" goto-if %s %s\n"), *MCPUtils::FormatName(Pin), *Target);
Output.Appendf(TEXT(" goto-if %s %s\n"), *WingUtils::FormatName(Pin), *Target);
}
}
void MCPGraphExport::EmitMaterialProperty(UMaterialExpression* Expression, FProperty* Prop, FStringBuilderBase& Out)
void WingGraphExport::EmitMaterialProperty(UMaterialExpression* Expression, FProperty* Prop, FStringBuilderBase& Out)
{
FString ValueStr = MCPUtils::GetPropertyValueText(Expression, Prop);
FString ValueStr = WingUtils::GetPropertyValueText(Expression, Prop);
ValueStr.ReplaceInline(TEXT("\r\n"), TEXT(" "));
ValueStr.ReplaceInline(TEXT("\n"), TEXT(" "));
if (ValueStr.Len() > 80)
@@ -274,19 +274,19 @@ void MCPGraphExport::EmitMaterialProperty(UMaterialExpression* Expression, FProp
bool bEditable = !Prop->HasAnyPropertyFlags(CPF_EditConst);
Out.Appendf(TEXT(" %s %s %s = %s\n"),
bEditable ? TEXT("mxeditable") : TEXT("mxreadonly"),
*UMCPTypes::TypeToText(Prop),
*MCPUtils::FormatName(Prop),
*UWingTypes::TypeToText(Prop),
*WingUtils::FormatName(Prop),
*ValueStr);
}
void MCPGraphExport::EmitMaterialProperties(UEdGraphNode* Node, FStringBuilderBase& Out, bool bPrimary)
void WingGraphExport::EmitMaterialProperties(UEdGraphNode* Node, FStringBuilderBase& Out, bool bPrimary)
{
UMaterialGraphNode* MatNode = Cast<UMaterialGraphNode>(Node);
if (!MatNode || !MatNode->MaterialExpression) return;
UMaterialExpression* Expression = MatNode->MaterialExpression;
FString PrimaryCategory = Expression->GetClass()->GetName();
TArray<FProperty*> Props = MCPUtils::SearchProperties(Expression, FString(), CPF_Edit, false);
TArray<FProperty*> Props = WingUtils::SearchProperties(Expression, FString(), CPF_Edit, false);
for (FProperty* Prop : Props)
{
@@ -296,7 +296,7 @@ void MCPGraphExport::EmitMaterialProperties(UEdGraphNode* Node, FStringBuilderBa
}
}
void MCPGraphExport::EmitLocalVariables()
void WingGraphExport::EmitLocalVariables()
{
for (UEdGraphNode* Node : Graph->Nodes)
{
@@ -307,15 +307,15 @@ void MCPGraphExport::EmitLocalVariables()
{
FString Default = Var.DefaultValue.IsEmpty() ? TEXT("<default>") : Var.DefaultValue;
Output.Appendf(TEXT("local %s %s = %s\n"),
*UMCPTypes::TypeToText(Var.VarType),
*MCPUtils::FormatName(Var),
*UWingTypes::TypeToText(Var.VarType),
*WingUtils::FormatName(Var),
*Default);
}
break;
}
}
void MCPGraphExport::EmitGraph()
void WingGraphExport::EmitGraph()
{
for (UEdGraphNode* Node : SortedNodes)
{
@@ -326,21 +326,21 @@ void MCPGraphExport::EmitGraph()
Output.Append(TEXT("\n"));
}
void MCPGraphExport::EmitDetails()
void WingGraphExport::EmitDetails()
{
for (UEdGraphNode* Node : SortedNodes)
{
if (Node->IsA<UK2Node_Knot>()) continue;
if (Node->IsA<UEdGraphNode_Comment>()) continue;
if (Node->IsA<UK2Node_VariableGet>()) continue;
Details.Appendf(TEXT("\ndetails %s\n"), *MCPUtils::FormatName(Node));
Details.Appendf(TEXT("\ndetails %s\n"), *WingUtils::FormatName(Node));
Details.Appendf(TEXT(" pos %d, %d\n"), Node->NodePosX, Node->NodePosY);
EmitMaterialProperties(Node, Details, false);
}
}
void MCPGraphExport::EmitComments()
void WingGraphExport::EmitComments()
{
for (UEdGraphNode* CommentNode : SortedNodes)
{
@@ -352,10 +352,10 @@ void MCPGraphExport::EmitComments()
int32 CH = CommentNode->NodeHeight;
// Emit header.
Output.Appendf(TEXT("\ncomment %s:\n"), *MCPUtils::FormatName(CommentNode));
Output.Appendf(TEXT("\ncomment %s:\n"), *WingUtils::FormatName(CommentNode));
// Emit wrapped, indented body.
Output.Append(MCPUtils::WrapText(CommentNode->NodeComment, 70, TEXT(" - ")));
Output.Append(WingUtils::WrapText(CommentNode->NodeComment, 70, TEXT(" - ")));
Output.Append(TEXT("\n"));
// Find contained nodes.
@@ -366,7 +366,7 @@ void MCPGraphExport::EmitComments()
int32 NX = Node->NodePosX;
int32 NY = Node->NodePosY;
if (NX >= CX && NY >= CY && NX <= CX + CW && NY <= CY + CH)
ContainedNames.Add(MCPUtils::FormatName(Node));
ContainedNames.Add(WingUtils::FormatName(Node));
}
if (ContainedNames.Num() > 0)

View File

@@ -1,10 +1,10 @@
* Command-handlers are classes that implement the MCPHandler
* Command-handlers are classes that implement the WingHandler
interface. The command's json parameters automatically get
injected into the handler's properties using reflection
code. Check out a few handlers to see how this works.
* Class MCPFetcher can precisely and easily retrieve objects
* Class WingFetcher can precisely and easily retrieve objects
of all different kinds using a 'path'. Study the API
of this class, we use it everywhere. It is the best tool
when you need the caller to specify a blueprint, or a
@@ -15,15 +15,15 @@
in a convenient interface. Please study this API.
* The only valid way to get a name for an object is using
MCPUtils::FormatName(obj). We don't allow the use of
WingUtils::FormatName(obj). We don't allow the use of
pin->GetName, or node->GetTitle, or any other name-fetching
routine. Using only MCPUtils::FormatName guarantees
routine. Using only WingUtils::FormatName guarantees
consistency: that means, names output by one tool can
be parsed by a different tool.
* To check whether a string matches an object's name,
there's only one valid way to do that as well: using
bool MCPUtils::Identifies(Name, Obj).
bool WingUtils::Identifies(Name, Obj).
* Concise output is better. The output of these handlers
will primarily be consumed by LLMs with finite context
@@ -35,7 +35,7 @@
consume.
* You can pass the output StringBuilder directly into
MCPFetcher and MCPAssets. If you do, these will automatically
WingFetcher and MCPAssets. If you do, these will automatically
generate good error messages. If either of these classes
returns 'false', you don't need to generate an error
message: it's already been done. Any other routine that
@@ -56,7 +56,7 @@
* When you're going to edit something, it's important to
mark things dirty. There's a very powerful tool for that:
MCPUtils::PreEdit and MCPUtils::PostEdit, which can also
be accessed through MCPFetcher::PreEdit and PostEdit.
WingUtils::PreEdit and WingUtils::PostEdit, which can also
be accessed through WingFetcher::PreEdit and PostEdit.
These routines are very careful about marking everything
dirty, so you don't have to worry about it.

View File

@@ -3,7 +3,7 @@
## Breaking API Changes
Several handlers switched from GUID-based node matching to
`MCPUtils::Identifies()`. Since the only caller is our own MCP
`WingUtils::Identifies()`. Since the only caller is our own MCP
bridge (which uses `FormatName` output from dump commands), this
is actually fine — but it's a one-way door.
@@ -11,7 +11,7 @@ is actually fine — but it's a one-way door.
DeleteMaterialExpression, DisconnectMaterialExpressionPin** —
node param now expects FormatName identifiers, not GUIDs
- **RemoveStructField, AddStructField** — switched from
MCPAssets (accepts bare names) to MCPFetcher (requires full
MCPAssets (accepts bare names) to WingFetcher (requires full
paths)
- **SetPinDefaultValues** — entry struct changed from
`{Blueprint, Node, PinName, Value}` to `{Pin, Value}` where

View File

@@ -1,4 +0,0 @@
#include "MCPModule.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_MODULE(FBlueprintMCPModule, BlueprintMCP);

View File

@@ -1,8 +1,8 @@
#include "MaterialParameter.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "WingUtils.h"
#include "WingServer.h"
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> MCPMaterialParameter::GetMaterialParameters(UMaterialInterface* Material)
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> WingMaterialParameter::GetMaterialParameters(UMaterialInterface* Material)
{
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> Result;
if (!Material) return Result;
@@ -15,7 +15,7 @@ TMap<FMaterialParameterInfo, FMaterialParameterMetadata> MCPMaterialParameter::G
return Result;
}
bool MCPMaterialParameter::ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation)
bool WingMaterialParameter::ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation)
{
if (Str.Equals(TEXT("Global"), ESearchCase::IgnoreCase))
OutAssociation = GlobalParameter;
@@ -25,13 +25,13 @@ bool MCPMaterialParameter::ParseMaterialParameterAssociation(const FString& Str,
OutAssociation = BlendParameter;
else
{
UMCPServer::Printf(TEXT("ERROR: Invalid ParameterAssociation '%s' (expected 'Global', 'Layer', or 'Blend')\n"), *Str);
UWingServer::Printf(TEXT("ERROR: Invalid ParameterAssociation '%s' (expected 'Global', 'Layer', or 'Blend')\n"), *Str);
return false;
}
return true;
}
void MCPMaterialParameter::FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
void WingMaterialParameter::FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
{
// Association prefix for layer/blend parameters.
FString Prefix;
@@ -43,35 +43,35 @@ void MCPMaterialParameter::FormatMaterialParameter(const FMaterialParameterInfo&
switch (Meta.Value.Type)
{
case EMaterialParameterType::Scalar:
UMCPServer::Printf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
UWingServer::Printf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
break;
case EMaterialParameterType::Vector:
{
FLinearColor C = Meta.Value.AsLinearColor();
UMCPServer::Printf(TEXT(" %sVector \"%s\" = (R=%.3f, G=%.3f, B=%.3f, A=%.3f)\n"),
UWingServer::Printf(TEXT(" %sVector \"%s\" = (R=%.3f, G=%.3f, B=%.3f, A=%.3f)\n"),
*Prefix, *Info.Name.ToString(), C.R, C.G, C.B, C.A);
break;
}
case EMaterialParameterType::DoubleVector:
{
FVector4d V = Meta.Value.AsVector4d();
UMCPServer::Printf(TEXT(" %sDoubleVector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
UWingServer::Printf(TEXT(" %sDoubleVector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
*Prefix, *Info.Name.ToString(), V.X, V.Y, V.Z, V.W);
break;
}
case EMaterialParameterType::Texture:
{
UTexture* Tex = Cast<UTexture>(Meta.Value.AsTextureObject());
UMCPServer::Printf(TEXT(" %sTexture \"%s\" = %s\n"),
*Prefix, *Info.Name.ToString(), Tex ? *MCPUtils::FormatName(Tex) : TEXT("None"));
UWingServer::Printf(TEXT(" %sTexture \"%s\" = %s\n"),
*Prefix, *Info.Name.ToString(), Tex ? *WingUtils::FormatName(Tex) : TEXT("None"));
break;
}
case EMaterialParameterType::StaticSwitch:
UMCPServer::Printf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
UWingServer::Printf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
*Prefix, *Info.Name.ToString(), Meta.Value.AsStaticSwitch() ? TEXT("true") : TEXT("false"));
break;
default:
UMCPServer::Printf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
UWingServer::Printf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
break;
}
}

View File

@@ -1,6 +1,6 @@
#include "MCPFetcher.h"
#include "MCPServer.h"
#include "MCPUtils.h"
#include "WingFetcher.h"
#include "WingServer.h"
#include "WingUtils.h"
#include "Engine/Blueprint.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNode.h"
@@ -15,30 +15,30 @@
#include "Engine/LevelScriptBlueprint.h"
#include "Subsystems/AssetEditorSubsystem.h"
MCPFetcher::WalkFunc MCPFetcher::GetWalker(const FString& Step)
WingFetcher::WalkFunc WingFetcher::GetWalker(const FString& Step)
{
if (Step.Equals(TEXT("graph"), ESearchCase::IgnoreCase)) return &MCPFetcher::Graph;
if (Step.Equals(TEXT("node"), ESearchCase::IgnoreCase)) return &MCPFetcher::Node;
if (Step.Equals(TEXT("pin"), ESearchCase::IgnoreCase)) return &MCPFetcher::Pin;
if (Step.Equals(TEXT("component"), ESearchCase::IgnoreCase)) return &MCPFetcher::Component;
if (Step.Equals(TEXT("levelblueprint"), ESearchCase::IgnoreCase)) return &MCPFetcher::LevelBlueprint;
if (Step.Equals(TEXT("graph"), ESearchCase::IgnoreCase)) return &WingFetcher::Graph;
if (Step.Equals(TEXT("node"), ESearchCase::IgnoreCase)) return &WingFetcher::Node;
if (Step.Equals(TEXT("pin"), ESearchCase::IgnoreCase)) return &WingFetcher::Pin;
if (Step.Equals(TEXT("component"), ESearchCase::IgnoreCase)) return &WingFetcher::Component;
if (Step.Equals(TEXT("levelblueprint"), ESearchCase::IgnoreCase)) return &WingFetcher::LevelBlueprint;
return nullptr;
}
void MCPFetcher::SetObj(UObject* InObj)
void WingFetcher::SetObj(UObject* InObj)
{
UMCPServer::AddTouchedObject(InObj);
UWingServer::AddTouchedObject(InObj);
Obj = InObj;
ResultPin = nullptr;
}
void MCPFetcher::SetPin(UEdGraphPin* InPin)
void WingFetcher::SetPin(UEdGraphPin* InPin)
{
ResultPin = InPin;
Obj = nullptr;
}
MCPFetcher& MCPFetcher::SetError()
WingFetcher& WingFetcher::SetError()
{
bError = true;
Obj = nullptr;
@@ -48,30 +48,30 @@ MCPFetcher& MCPFetcher::SetError()
return *this;
}
void MCPFetcher::PathFailed(const TCHAR* Expected)
void WingFetcher::PathFailed(const TCHAR* Expected)
{
SetError();
if (ResultPin)
UMCPServer::Printf(TEXT("ERROR: Path specifies a pin, but expected %s\n"), Expected);
UWingServer::Printf(TEXT("ERROR: Path specifies a pin, but expected %s\n"), Expected);
else if (Obj)
UMCPServer::Printf(TEXT("ERROR: Path specifies a %s, but expected %s\n"), *Obj->GetClass()->GetName(), Expected);
UWingServer::Printf(TEXT("ERROR: Path specifies a %s, but expected %s\n"), *Obj->GetClass()->GetName(), Expected);
else
UMCPServer::Printf(TEXT("ERROR: Path led to a null pointer\n"));
UWingServer::Printf(TEXT("ERROR: Path led to a null pointer\n"));
}
MCPFetcher& MCPFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expected)
WingFetcher& WingFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expected)
{
SetError();
if (ResultPin)
UMCPServer::Printf(TEXT("ERROR: Input to '%s' is a pin, but expected %s\n"), Walker, Expected);
UWingServer::Printf(TEXT("ERROR: Input to '%s' is a pin, but expected %s\n"), Walker, Expected);
else if (Obj)
UMCPServer::Printf(TEXT("ERROR: Input to '%s' is %s, but expected %s\n"), Walker, *Obj->GetClass()->GetName(), Expected);
UWingServer::Printf(TEXT("ERROR: Input to '%s' is %s, but expected %s\n"), Walker, *Obj->GetClass()->GetName(), Expected);
else
UMCPServer::Printf(TEXT("ERROR: Path led to a null pointer\n"));
UWingServer::Printf(TEXT("ERROR: Path led to a null pointer\n"));
return *this;
}
MCPFetcher& MCPFetcher::Walk(const FString& Path)
WingFetcher& WingFetcher::Walk(const FString& Path)
{
if (bError) return *this;
@@ -79,7 +79,7 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
Path.ParseIntoArray(Segments, TEXT(","));
if (Segments.Num() == 0)
{
UMCPServer::Print(TEXT("ERROR: Empty path\n"));
UWingServer::Print(TEXT("ERROR: Empty path\n"));
return SetError();
}
@@ -99,7 +99,7 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
WalkFunc Func = GetWalker(Key);
if (!Func)
{
UMCPServer::Printf(TEXT("ERROR: Unknown path step '%s'\n"), *Key);
UWingServer::Printf(TEXT("ERROR: Unknown path step '%s'\n"), *Key);
return SetError();
}
(this->*Func)(Value);
@@ -109,14 +109,14 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
return *this;
}
MCPFetcher& MCPFetcher::Asset(const FString& PackagePath)
WingFetcher& WingFetcher::Asset(const FString& PackagePath)
{
if (bError) return *this;
SetObj(LoadObject<UObject>(nullptr, *PackagePath));
if (!Obj)
{
UMCPServer::Printf(TEXT("ERROR: Could not load asset '%s'\n"), *PackagePath);
UWingServer::Printf(TEXT("ERROR: Could not load asset '%s'\n"), *PackagePath);
return SetError();
}
@@ -126,13 +126,13 @@ MCPFetcher& MCPFetcher::Asset(const FString& PackagePath)
UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
if (!Sub || !Sub->OpenEditorForAsset(Obj))
{
UMCPServer::Printf(TEXT("ERROR: Could not open editor for '%s'\n"), *PackagePath);
UWingServer::Printf(TEXT("ERROR: Could not open editor for '%s'\n"), *PackagePath);
return SetError();
}
Editor = Sub->FindEditorForAsset(OriginalAsset, false);
if (!Editor)
{
UMCPServer::Printf(TEXT("ERROR: Could not find editor instance for '%s'\n"), *PackagePath);
UWingServer::Printf(TEXT("ERROR: Could not find editor instance for '%s'\n"), *PackagePath);
return SetError();
}
@@ -145,12 +145,12 @@ MCPFetcher& MCPFetcher::Asset(const FString& PackagePath)
return *this;
}
bool MCPFetcher::CheckAssetIsA(UClass* StaticClass)
bool WingFetcher::CheckAssetIsA(UClass* StaticClass)
{
if (bError) return false;
if (!OriginalAsset || !OriginalAsset->IsA(StaticClass))
{
UMCPServer::Printf(TEXT("ERROR: Asset is %s, expected %s\n"),
UWingServer::Printf(TEXT("ERROR: Asset is %s, expected %s\n"),
OriginalAsset ? *OriginalAsset->GetClass()->GetName() : TEXT("null"),
*StaticClass->GetName());
SetError();
@@ -159,7 +159,7 @@ bool MCPFetcher::CheckAssetIsA(UClass* StaticClass)
return true;
}
MCPFetcher& MCPFetcher::Graph(const FString& Value)
WingFetcher& WingFetcher::Graph(const FString& Value)
{
if (bError) return *this;
@@ -168,13 +168,13 @@ MCPFetcher& MCPFetcher::Graph(const FString& Value)
{
if (!Value.IsEmpty())
{
UMCPServer::Printf(TEXT("ERROR: Materials do not have named graphs (got '%s')\n"), *Value);
UWingServer::Printf(TEXT("ERROR: Materials do not have named graphs (got '%s')\n"), *Value);
return SetError();
}
MCPUtils::EnsureMaterialGraph(Mat);
WingUtils::EnsureMaterialGraph(Mat);
if (!Mat->MaterialGraph)
{
UMCPServer::Printf(TEXT("ERROR: Material '%s' has no material graph\n"), *Mat->GetName());
UWingServer::Printf(TEXT("ERROR: Material '%s' has no material graph\n"), *Mat->GetName());
return SetError();
}
SetObj(Mat->MaterialGraph);
@@ -185,15 +185,15 @@ MCPFetcher& MCPFetcher::Graph(const FString& Value)
if (!BP)
return TypeMismatch(TEXT("graph"), TEXT("Blueprint or Material"));
TArray<UEdGraph*> Matches = MCPUtils::AllGraphsNamed(BP, Value);
TArray<UEdGraph*> Matches = WingUtils::AllGraphsNamed(BP, Value);
if (Matches.Num() == 0)
{
UMCPServer::Printf(TEXT("ERROR: Graph '%s' not found in %s\n"), *Value, *BP->GetName());
UWingServer::Printf(TEXT("ERROR: Graph '%s' not found in %s\n"), *Value, *BP->GetName());
return SetError();
}
if (Matches.Num() > 1)
{
UMCPServer::Printf(TEXT("ERROR: Ambiguous graph '%s' in %s — %d matches\n"), *Value, *BP->GetName(), Matches.Num());
UWingServer::Printf(TEXT("ERROR: Ambiguous graph '%s' in %s — %d matches\n"), *Value, *BP->GetName(), Matches.Num());
return SetError();
}
@@ -201,7 +201,7 @@ MCPFetcher& MCPFetcher::Graph(const FString& Value)
return *this;
}
MCPFetcher& MCPFetcher::Node(const FString& Value)
WingFetcher& WingFetcher::Node(const FString& Value)
{
if (bError) return *this;
@@ -211,18 +211,18 @@ MCPFetcher& MCPFetcher::Node(const FString& Value)
UEdGraphNode* Found = nullptr;
for (UEdGraphNode* N : G->Nodes)
{
if (!N || !MCPUtils::Identifies(Value, N))
if (!N || !WingUtils::Identifies(Value, N))
continue;
if (Found)
{
UMCPServer::Printf(TEXT("ERROR: Ambiguous node '%s' in graph %s\n"), *Value, *G->GetName());
UWingServer::Printf(TEXT("ERROR: Ambiguous node '%s' in graph %s\n"), *Value, *G->GetName());
return SetError();
}
Found = N;
}
if (!Found)
{
UMCPServer::Printf(TEXT("ERROR: Node '%s' not found in graph %s\n"), *Value, *G->GetName());
UWingServer::Printf(TEXT("ERROR: Node '%s' not found in graph %s\n"), *Value, *G->GetName());
return SetError();
}
SetObj(Found);
@@ -233,15 +233,15 @@ MCPFetcher& MCPFetcher::Node(const FString& Value)
if (UBlueprint* BP = ::Cast<UBlueprint>(Obj))
{
UEdGraphNode* Found = nullptr;
for (UEdGraph* G : MCPUtils::AllGraphs(BP))
for (UEdGraph* G : WingUtils::AllGraphs(BP))
{
for (UEdGraphNode* N : G->Nodes)
{
if (!N || !MCPUtils::Identifies(Value, N))
if (!N || !WingUtils::Identifies(Value, N))
continue;
if (Found)
{
UMCPServer::Printf(TEXT("ERROR: Ambiguous node '%s' in %s\n"), *Value, *BP->GetName());
UWingServer::Printf(TEXT("ERROR: Ambiguous node '%s' in %s\n"), *Value, *BP->GetName());
return SetError();
}
Found = N;
@@ -249,7 +249,7 @@ MCPFetcher& MCPFetcher::Node(const FString& Value)
}
if (!Found)
{
UMCPServer::Printf(TEXT("ERROR: Node '%s' not found in %s\n"), *Value, *BP->GetName());
UWingServer::Printf(TEXT("ERROR: Node '%s' not found in %s\n"), *Value, *BP->GetName());
return SetError();
}
SetObj(Found);
@@ -259,7 +259,7 @@ MCPFetcher& MCPFetcher::Node(const FString& Value)
return TypeMismatch(TEXT("node"), TEXT("graph or Blueprint"));
}
MCPFetcher& MCPFetcher::Pin(const FString& Value)
WingFetcher& WingFetcher::Pin(const FString& Value)
{
if (bError) return *this;
@@ -269,20 +269,20 @@ MCPFetcher& MCPFetcher::Pin(const FString& Value)
UEdGraphPin* Found = nullptr;
for (UEdGraphPin *P : N->Pins)
{
if (!MCPUtils::Identifies(Value, P))
if (!WingUtils::Identifies(Value, P))
continue;
if (Found)
{
UMCPServer::Printf(TEXT("ERROR: Ambiguous pin '%s' on node %s\n"),
*Value, *MCPUtils::FormatName(N));
UWingServer::Printf(TEXT("ERROR: Ambiguous pin '%s' on node %s\n"),
*Value, *WingUtils::FormatName(N));
return SetError();
}
Found = P;
}
if (!Found)
{
UMCPServer::Printf(TEXT("ERROR: Pin '%s' not found on node %s\n"),
*Value, *MCPUtils::FormatName(N));
UWingServer::Printf(TEXT("ERROR: Pin '%s' not found on node %s\n"),
*Value, *WingUtils::FormatName(N));
return SetError();
}
@@ -290,7 +290,7 @@ MCPFetcher& MCPFetcher::Pin(const FString& Value)
return *this;
}
MCPFetcher& MCPFetcher::Component(const FString& Value)
WingFetcher& WingFetcher::Component(const FString& Value)
{
if (bError) return *this;
@@ -301,7 +301,7 @@ MCPFetcher& MCPFetcher::Component(const FString& Value)
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
if (!SCS)
{
UMCPServer::Printf(TEXT("ERROR: Blueprint %s has no SimpleConstructionScript (not an Actor Blueprint)\n"), *BP->GetName());
UWingServer::Printf(TEXT("ERROR: Blueprint %s has no SimpleConstructionScript (not an Actor Blueprint)\n"), *BP->GetName());
return SetError();
}
@@ -315,11 +315,11 @@ MCPFetcher& MCPFetcher::Component(const FString& Value)
}
}
UMCPServer::Printf(TEXT("ERROR: Component '%s' not found in %s\n"), *Value, *BP->GetName());
UWingServer::Printf(TEXT("ERROR: Component '%s' not found in %s\n"), *Value, *BP->GetName());
return SetError();
}
MCPFetcher& MCPFetcher::LevelBlueprint(const FString& Value)
WingFetcher& WingFetcher::LevelBlueprint(const FString& Value)
{
if (bError) return *this;
@@ -329,14 +329,14 @@ MCPFetcher& MCPFetcher::LevelBlueprint(const FString& Value)
if (!World->PersistentLevel)
{
UMCPServer::Print(TEXT("ERROR: World has no PersistentLevel\n"));
UWingServer::Print(TEXT("ERROR: World has no PersistentLevel\n"));
return SetError();
}
ULevelScriptBlueprint* LevelBP = World->PersistentLevel->GetLevelScriptBlueprint(true);
if (!LevelBP)
{
UMCPServer::Print(TEXT("ERROR: World has no level blueprint\n"));
UWingServer::Print(TEXT("ERROR: World has no level blueprint\n"));
return SetError();
}

View File

@@ -1,12 +1,12 @@
#include "MCPJson.h"
#include "MCPTypes.h"
#include "MCPServer.h"
#include "WingJson.h"
#include "WingTypes.h"
#include "WingServer.h"
#include "UObject/UnrealType.h"
#include "UObject/EnumProperty.h"
#include "Dom/JsonValue.h"
bool MCPJson::PopulateFromJson(MCPProperty& P, const FJsonObject* Json, bool AllOptional)
bool WingJson::PopulateFromJson(WingProperty& P, const FJsonObject* Json, bool AllOptional)
{
FString JsonKey = P.Prop->GetName();
bool bOptional = AllOptional || P.Prop->HasMetaData(TEXT("Optional"));
@@ -15,7 +15,7 @@ bool MCPJson::PopulateFromJson(MCPProperty& P, const FJsonObject* Json, bool All
{
if (!bOptional)
{
UMCPServer::Printf(TEXT("ERROR: Missing required parameter '%s'\n"), *JsonKey);
UWingServer::Printf(TEXT("ERROR: Missing required parameter '%s'\n"), *JsonKey);
return false;
}
return true;
@@ -23,28 +23,28 @@ bool MCPJson::PopulateFromJson(MCPProperty& P, const FJsonObject* Json, bool All
void* ValuePtr = P.Prop->ContainerPtrToValuePtr<void>(P.Container);
// Special handling for FMCPJsonObject and FMCPJsonArray
// Special handling for FWingJsonObject and FWingJsonArray
if (FStructProperty* StructProp = CastField<FStructProperty>(P.Prop))
{
if (StructProp->Struct == FMCPJsonObject::StaticStruct())
if (StructProp->Struct == FWingJsonObject::StaticStruct())
{
if (!Json->HasTypedField<EJson::Object>(JsonKey))
{
UMCPServer::Printf(TEXT("ERROR: '%s' must be an object\n"), *JsonKey);
UWingServer::Printf(TEXT("ERROR: '%s' must be an object\n"), *JsonKey);
return false;
}
static_cast<FMCPJsonObject*>(ValuePtr)->Json = Json->GetObjectField(JsonKey);
static_cast<FWingJsonObject*>(ValuePtr)->Json = Json->GetObjectField(JsonKey);
return true;
}
if (StructProp->Struct == FMCPJsonArray::StaticStruct())
if (StructProp->Struct == FWingJsonArray::StaticStruct())
{
if (!Json->HasTypedField<EJson::Array>(JsonKey))
{
UMCPServer::Printf(TEXT("ERROR: '%s' must be an array\n"), *JsonKey);
UWingServer::Printf(TEXT("ERROR: '%s' must be an array\n"), *JsonKey);
return false;
}
static_cast<FMCPJsonArray*>(ValuePtr)->Array = Json->GetArrayField(JsonKey);
static_cast<FWingJsonArray*>(ValuePtr)->Array = Json->GetArrayField(JsonKey);
return true;
}
}
@@ -63,7 +63,7 @@ bool MCPJson::PopulateFromJson(MCPProperty& P, const FJsonObject* Json, bool All
{ DoubleProp->SetPropertyValue(ValuePtr, D); return true; }
if (FByteProperty* ByteProp = CastField<FByteProperty>(P.Prop))
{ ByteProp->SetPropertyValue(ValuePtr, (uint8)D); return true; }
UMCPServer::Printf(TEXT("ERROR: '%s' received a number but expects %s\n"), *JsonKey, *P.Prop->GetCPPType());
UWingServer::Printf(TEXT("ERROR: '%s' received a number but expects %s\n"), *JsonKey, *P.Prop->GetCPPType());
return false;
}
@@ -71,7 +71,7 @@ bool MCPJson::PopulateFromJson(MCPProperty& P, const FJsonObject* Json, bool All
{
if (FBoolProperty* BoolProp = CastField<FBoolProperty>(P.Prop))
{ BoolProp->SetPropertyValue(ValuePtr, JsonValue->AsBool()); return true; }
UMCPServer::Printf(TEXT("ERROR: '%s' received a boolean but expects %s\n"), *JsonKey, *P.Prop->GetCPPType());
UWingServer::Printf(TEXT("ERROR: '%s' received a boolean but expects %s\n"), *JsonKey, *P.Prop->GetCPPType());
return false;
}
@@ -80,18 +80,18 @@ bool MCPJson::PopulateFromJson(MCPProperty& P, const FJsonObject* Json, bool All
return P.SetText(JsonValue->AsString());
}
UMCPServer::Printf(TEXT("ERROR: '%s' must be a string, number, or boolean\n"), *JsonKey);
UWingServer::Printf(TEXT("ERROR: '%s' must be a string, number, or boolean\n"), *JsonKey);
return false;
}
bool MCPJson::PopulateFromJson(
TArray<MCPProperty>& Props, const FJsonObject* Json, bool AllOptional)
bool WingJson::PopulateFromJson(
TArray<WingProperty>& Props, const FJsonObject* Json, bool AllOptional)
{
bool Ok = true;
// Build a set of known property names for the unknown-field check.
TSet<FString> KnownKeys;
for (const MCPProperty& P : Props)
for (const WingProperty& P : Props)
KnownKeys.Add(P.Prop->GetName());
// Check for unknown fields in the JSON
@@ -99,33 +99,33 @@ bool MCPJson::PopulateFromJson(
{
if (!KnownKeys.Contains(KV.Key))
{
UMCPServer::Printf(TEXT("ERROR: Unknown parameter '%s'\n"), *KV.Key);
UWingServer::Printf(TEXT("ERROR: Unknown parameter '%s'\n"), *KV.Key);
Ok = false;
}
}
// Populate each property from JSON
for (MCPProperty& P : Props)
for (WingProperty& P : Props)
{
if (!PopulateFromJson(P, Json, AllOptional)) Ok = false;
}
return Ok;
}
bool MCPJson::PopulateFromJson(
bool WingJson::PopulateFromJson(
UStruct* StructType, void* Container, const FJsonObject* Json)
{
TArray<MCPProperty> Props = MCPProperty::GetAll(StructType, Container, (EPropertyFlags)0);
TArray<WingProperty> Props = WingProperty::GetAll(StructType, Container, (EPropertyFlags)0);
return PopulateFromJson(Props, Json);
}
bool MCPJson::PopulateFromJson(
bool WingJson::PopulateFromJson(
UStruct* StructType, void* Container,
const TSharedPtr<FJsonValue>& JsonValue)
{
if (!JsonValue.IsValid() || (JsonValue->Type != EJson::Object))
{
UMCPServer::Print(TEXT("ERROR: Expected a JSON object\n"));
UWingServer::Print(TEXT("ERROR: Expected a JSON object\n"));
return false;
}
return PopulateFromJson(StructType, Container, JsonValue->AsObject().Get());

View File

@@ -1,4 +1,4 @@
#include "MCPNotifier.h"
#include "WingNotifier.h"
#include "EdGraph/EdGraphNode.h"
#include "EdGraph/EdGraph.h"
#include "Engine/Blueprint.h"
@@ -6,7 +6,7 @@
#include "Kismet2/BlueprintEditorUtils.h"
#include "MaterialEditingLibrary.h"
void MCPNotifier::AddTouchedObject(UObject* Obj)
void WingNotifier::AddTouchedObject(UObject* Obj)
{
if (!Obj) return;
bool bAlreadyInSet = false;
@@ -16,7 +16,7 @@ void MCPNotifier::AddTouchedObject(UObject* Obj)
Obj->PreEditChange(nullptr);
}
void MCPNotifier::SendNotifications()
void WingNotifier::SendNotifications()
{
TSet<UEdGraphNode*> Nodes;
TSet<UEdGraph*> Graphs;

View File

@@ -1,7 +1,7 @@
#include "MCPProperty.h"
#include "MCPUtils.h"
#include "MCPServer.h"
#include "MCPTypes.h"
#include "WingProperty.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "WingTypes.h"
#include "Engine/Blueprint.h"
#include "Materials/MaterialExpression.h"
#include "MaterialGraph/MaterialGraphNode.h"
@@ -14,20 +14,20 @@ static bool IsPinTypeProperty(FProperty* Prop)
return StructProp && StructProp->Struct == FEdGraphPinType::StaticStruct();
}
MCPProperty::MCPProperty(FProperty* InProp, void* InContainer)
WingProperty::WingProperty(FProperty* InProp, void* InContainer)
: Prop(InProp), Container(InContainer) {}
FString MCPProperty::GetText() const
FString WingProperty::GetText() const
{
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
if (IsPinTypeProperty(Prop))
return UMCPTypes::TypeToText(*static_cast<FEdGraphPinType*>(ValuePtr));
return UWingTypes::TypeToText(*static_cast<FEdGraphPinType*>(ValuePtr));
FString Result;
Prop->ExportTextItem_Direct(Result, ValuePtr, nullptr, nullptr, PPF_None);
return Result;
}
bool MCPProperty::TryParseEnum(UEnum* Enum, const FString& Text, int64 &OutValue)
bool WingProperty::TryParseEnum(UEnum* Enum, const FString& Text, int64 &OutValue)
{
int Index = Enum->GetIndexByNameString(Text);
if (Index == INDEX_NONE)
@@ -40,7 +40,7 @@ bool MCPProperty::TryParseEnum(UEnum* Enum, const FString& Text, int64 &OutValue
}
if (Index == INDEX_NONE)
{
UMCPServer::Printf(TEXT("ERROR: '%s' is not a valid value for %s\n"),
UWingServer::Printf(TEXT("ERROR: '%s' is not a valid value for %s\n"),
*Text, *Enum->GetName());
OutValue = 0;
return false;
@@ -52,13 +52,13 @@ bool MCPProperty::TryParseEnum(UEnum* Enum, const FString& Text, int64 &OutValue
}
}
bool MCPProperty::TrySetText(const FString &Value)
bool WingProperty::TrySetText(const FString &Value)
{
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
// Pin types get parsed by UMCPTypes.
// Pin types get parsed by UWingTypes.
if (IsPinTypeProperty(Prop))
return UMCPTypes::TextToType(Value, *static_cast<FEdGraphPinType*>(ValuePtr));
return UWingTypes::TextToType(Value, *static_cast<FEdGraphPinType*>(ValuePtr));
// Byte Enum types get parsed by TryParseEnum, above.
if (FByteProperty* ByteProp = CastField<FByteProperty>(Prop))
@@ -85,14 +85,14 @@ bool MCPProperty::TrySetText(const FString &Value)
const TCHAR* Result = Prop->ImportText_Direct(*Value, ValuePtr, nullptr, PPF_None);
if (!Result)
{
UMCPServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
*Value, *MCPUtils::FormatName(Prop), *Prop->GetCPPType());
UWingServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
*Value, *WingUtils::FormatName(Prop), *Prop->GetCPPType());
return false;
}
return true;
}
bool MCPProperty::SetText(const FString& Value)
bool WingProperty::SetText(const FString& Value)
{
if (!TrySetText(Value)) return false;
@@ -105,7 +105,7 @@ bool MCPProperty::SetText(const FString& Value)
return true;
}
void MCPProperty::Collect(UStruct* StructType, void* Container, TArray<MCPProperty> &Props, EPropertyFlags Flags)
void WingProperty::Collect(UStruct* StructType, void* Container, TArray<WingProperty> &Props, EPropertyFlags Flags)
{
for (TFieldIterator<FProperty> It(StructType); It; ++It)
{
@@ -114,15 +114,15 @@ void MCPProperty::Collect(UStruct* StructType, void* Container, TArray<MCPProper
}
}
void MCPProperty::Remove(TArray<MCPProperty>& Props, const FString& Name)
void WingProperty::Remove(TArray<WingProperty>& Props, const FString& Name)
{
Props.RemoveAll([&](const MCPProperty& P) { return P.Prop->GetName() == Name; });
Props.RemoveAll([&](const WingProperty& P) { return P.Prop->GetName() == Name; });
}
TArray<MCPProperty> MCPProperty::GetAll(UObject* Obj, EPropertyFlags Flags)
TArray<WingProperty> WingProperty::GetAll(UObject* Obj, EPropertyFlags Flags)
{
if (!Obj) return {};
TArray<MCPProperty> Result;
TArray<WingProperty> Result;
// Blueprints don't have editable properties. So
// instead, we fetch properties from the generated CDO,
@@ -132,7 +132,7 @@ TArray<MCPProperty> MCPProperty::GetAll(UObject* Obj, EPropertyFlags Flags)
{
if (BP->GeneratedClass == nullptr)
{
UMCPServer::Printf(TEXT("ERROR: Blueprint '%s' has no GeneratedClass\n"), *Obj->GetName());
UWingServer::Printf(TEXT("ERROR: Blueprint '%s' has no GeneratedClass\n"), *Obj->GetName());
return {};
}
Obj = BP->GeneratedClass->GetDefaultObject();
@@ -153,42 +153,42 @@ TArray<MCPProperty> MCPProperty::GetAll(UObject* Obj, EPropertyFlags Flags)
return Result;
}
TArray<MCPProperty> MCPProperty::GetAll(UStruct* StructType, void* Container, EPropertyFlags Flags)
TArray<WingProperty> WingProperty::GetAll(UStruct* StructType, void* Container, EPropertyFlags Flags)
{
TArray<MCPProperty> Result;
TArray<WingProperty> Result;
Collect(StructType, Container, Result, Flags);
return Result;
}
TArray<MCPProperty> MCPProperty::FindAllSubstring(const TArray<MCPProperty>& Props, const FString& Substring)
TArray<WingProperty> WingProperty::FindAllSubstring(const TArray<WingProperty>& Props, const FString& Substring)
{
if (Substring.IsEmpty()) return Props;
TArray<MCPProperty> Result;
for (const MCPProperty& P : Props)
TArray<WingProperty> Result;
for (const WingProperty& P : Props)
{
if (MCPUtils::FormatName(P.Prop).Contains(Substring, ESearchCase::IgnoreCase))
if (WingUtils::FormatName(P.Prop).Contains(Substring, ESearchCase::IgnoreCase))
Result.Add(P);
}
return Result;
}
MCPProperty MCPProperty::FindOneExactMatch(const TArray<MCPProperty>& Props, const FString& Name)
WingProperty WingProperty::FindOneExactMatch(const TArray<WingProperty>& Props, const FString& Name)
{
TArray<MCPProperty> Matches;
for (const MCPProperty& P : Props)
TArray<WingProperty> Matches;
for (const WingProperty& P : Props)
{
if (MCPUtils::Identifies(Name, P.Prop))
if (WingUtils::Identifies(Name, P.Prop))
Matches.Add(P);
}
if (Matches.Num() == 0)
{
UMCPServer::Printf(TEXT("ERROR: Property '%s' not found\n"), *Name);
return MCPProperty();
UWingServer::Printf(TEXT("ERROR: Property '%s' not found\n"), *Name);
return WingProperty();
}
if (Matches.Num() > 1)
{
UMCPServer::Printf(TEXT("ERROR: Ambiguous property '%s'\n"), *Name);
return MCPProperty();
UWingServer::Printf(TEXT("ERROR: Ambiguous property '%s'\n"), *Name);
return WingProperty();
}
return Matches[0];
}

View File

@@ -1,8 +1,8 @@
#include "MCPServer.h"
#include "MCPHandler.h"
#include "MCPJson.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "WingJson.h"
#include "LogCapture.h"
#include "MCPUtils.h"
#include "WingUtils.h"
#include "UObject/StrongObjectPtr.h"
#include "Materials/MaterialExpression.h"
#include "AssetRegistry/AssetRegistryModule.h"
@@ -100,20 +100,20 @@
#include "AnimationGraph.h"
#include "AnimationTransitionGraph.h"
UMCPServer* UMCPServer::GMCPServer = nullptr;
UWingServer* UWingServer::GWingServer = nullptr;
// ============================================================
// Initialization and Shutdown
// ============================================================
void UMCPServer::Initialize(FSubsystemCollectionBase& Collection)
void UWingServer::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
GMCPServer = this;
GWingServer = this;
// Create TCP listen socket
ISocketSubsystem* SocketSub = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
ListenSocket = SocketSub->CreateSocket(NAME_Stream, TEXT("MCPServer"), false);
ListenSocket = SocketSub->CreateSocket(NAME_Stream, TEXT("WingServer"), false);
if (!ListenSocket)
{
UE_LOG(LogTemp, Error, TEXT("BlueprintMCP: Failed to create listen socket"));
@@ -144,14 +144,14 @@ void UMCPServer::Initialize(FSubsystemCollectionBase& Collection)
return;
}
BuildMCPHandlerRegistry();
BuildWingHandlerRegistry();
LogCapture.bEnabled = false;
LogCapture.Install();
bRunning = true;
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: MCP server listening on tcp://localhost:%d"), Port);
}
void UMCPServer::Deinitialize()
void UWingServer::Deinitialize()
{
if (!bRunning)
{
@@ -203,7 +203,7 @@ void UMCPServer::Deinitialize()
LogCapture.Uninstall();
bRunning = false;
bShuttingDown = false;
GMCPServer = nullptr;
GWingServer = nullptr;
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Server stopped."));
Super::Deinitialize();
}
@@ -212,7 +212,7 @@ void UMCPServer::Deinitialize()
// FTickableEditorObject interface
// ============================================================
void UMCPServer::Tick(float DeltaTime)
void UWingServer::Tick(float DeltaTime)
{
// Accept new connections (non-blocking)
AcceptNewConnections();
@@ -239,26 +239,26 @@ void UMCPServer::Tick(float DeltaTime)
}
}
void UMCPServer::TickServer(float DeltaTime)
void UWingServer::TickServer(float DeltaTime)
{
if (GMCPServer) GMCPServer->Tick(DeltaTime);
if (GWingServer) GWingServer->Tick(DeltaTime);
}
bool UMCPServer::IsTickable() const
bool UWingServer::IsTickable() const
{
return bRunning;
}
TStatId UMCPServer::GetStatId() const
TStatId UWingServer::GetStatId() const
{
RETURN_QUICK_DECLARE_CYCLE_STAT(UMCPServer, STATGROUP_Tickables);
RETURN_QUICK_DECLARE_CYCLE_STAT(UWingServer, STATGROUP_Tickables);
}
// ============================================================
// HandleRequest — Given a command, execute it.
// ============================================================
FString UMCPServer::HandleRequest(const FString& Line)
FString UWingServer::HandleRequest(const FString& Line)
{
LogCapture.CapturedErrors.Empty();
LogCapture.bEnabled = true;
@@ -270,7 +270,7 @@ FString UMCPServer::HandleRequest(const FString& Line)
LogCapture.bEnabled = false;
for (const FString& Msg : LogCapture.CapturedErrors)
{
UMCPServer::Printf(TEXT("UE_LOG: %s\n"), *Msg);
UWingServer::Printf(TEXT("UE_LOG: %s\n"), *Msg);
}
LogCapture.CapturedErrors.Empty();
FString Result = HandlerOutput.ToString();
@@ -282,7 +282,7 @@ FString UMCPServer::HandleRequest(const FString& Line)
return Result;
}
void UMCPServer::TryCallHandler(const FString &Line)
void UWingServer::TryCallHandler(const FString &Line)
{
// Turn the request string into a JSON tree.
TSharedPtr<FJsonObject> Request;
@@ -290,7 +290,7 @@ void UMCPServer::TryCallHandler(const FString &Line)
FJsonSerializer::Deserialize(Reader, Request);
if (!Request.IsValid())
{
UMCPServer::Printf(TEXT("Request is not valid JSON"));
UWingServer::Printf(TEXT("Request is not valid JSON"));
return;
}
@@ -298,28 +298,28 @@ void UMCPServer::TryCallHandler(const FString &Line)
FString Command;
if (!Request->TryGetStringField(TEXT("command"), Command))
{
UMCPServer::Printf(TEXT("Request does not contain 'command' parameter"));
UWingServer::Printf(TEXT("Request does not contain 'command' parameter"));
return;
}
Request->RemoveField(TEXT("command"));
// Find the handler UClass for the specified command.
UClass** HandlerClass = MCPHandlerRegistry.Find(Command);
UClass** HandlerClass = WingHandlerRegistry.Find(Command);
if (!HandlerClass)
{
UMCPServer::Printf(TEXT("Unknown command: %s"), *Command);
UWingServer::Printf(TEXT("Unknown command: %s"), *Command);
return;
}
// Make an object of the handler class.
TStrongObjectPtr<UObject> HandlerObj(NewObject<UObject>(GetTransientPackage(), *HandlerClass));
IMCPHandler* Handler = Cast<IMCPHandler>(HandlerObj.Get());
IWingHandler* Handler = Cast<IWingHandler>(HandlerObj.Get());
// Populate the handler object with the request parameters.
if (!MCPJson::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
if (!WingJson::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
{
UMCPServer::Printf(TEXT("\nUsage:\n\n"));
MCPUtils::FormatCommandHelp(*HandlerClass);
UWingServer::Printf(TEXT("\nUsage:\n\n"));
WingUtils::FormatCommandHelp(*HandlerClass);
return;
}
@@ -331,7 +331,7 @@ void UMCPServer::TryCallHandler(const FString &Line)
// Connection Maintenance
// ============================================================
void UMCPServer::AcceptNewConnections()
void UWingServer::AcceptNewConnections()
{
if (!ListenSocket) return;
@@ -351,7 +351,7 @@ void UMCPServer::AcceptNewConnections()
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: Client connected."));
}
void UMCPServer::CleanupFinishedClients()
void UWingServer::CleanupFinishedClients()
{
ISocketSubsystem* SocketSub = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
@@ -368,7 +368,7 @@ void UMCPServer::CleanupFinishedClients()
}
}
void UMCPServer::ClientThreadFunc(UMCPServer* Server, TSharedPtr<FClientConnection> Client)
void UWingServer::ClientThreadFunc(UWingServer* Server, TSharedPtr<FClientConnection> Client)
{
FSocket* Socket = Client->Socket;
FString LineBuffer;
@@ -405,7 +405,7 @@ void UMCPServer::ClientThreadFunc(UMCPServer* Server, TSharedPtr<FClientConnecti
}
// Enqueue the line for game-thread processing
TSharedPtr<UMCPServer::FPendingMessage> Msg = MakeShared<UMCPServer::FPendingMessage>();
TSharedPtr<UWingServer::FPendingMessage> Msg = MakeShared<UWingServer::FPendingMessage>();
Msg->Line = Line;
TFuture<FString> Future = Msg->Response.GetFuture();
@@ -435,13 +435,13 @@ void UMCPServer::ClientThreadFunc(UMCPServer* Server, TSharedPtr<FClientConnecti
// ============================================================
// BuildMCPHandlerRegistry
// BuildWingHandlerRegistry
// ============================================================
void UMCPServer::BuildMCPHandlerRegistry()
void UWingServer::BuildWingHandlerRegistry()
{
for (UClass* Class : MCPUtils::CollectHandlerClasses())
for (UClass* Class : WingUtils::CollectHandlerClasses())
{
MCPHandlerRegistry.FindOrAdd(MCPUtils::GetHandlerName(Class)) = Class;
WingHandlerRegistry.FindOrAdd(WingUtils::GetHandlerName(Class)) = Class;
}
}

View File

@@ -1,9 +1,9 @@
#include "MCPToolMenu.h"
#include "WingToolMenu.h"
#include "ToolMenuEntry.h"
#include "ToolMenuDelegates.h"
#include "ToolMenuContext.h"
#include "ToolMenus.h"
#include "MCPUtils.h"
#include "WingUtils.h"
#include "EdGraph/EdGraphSchema.h"
#include "EdGraphSchema_K2.h"
#include "Framework/Commands/UIAction.h"
@@ -16,14 +16,14 @@
// &FToolMenuEntry::Action is legal as a template argument in an
// explicit instantiation, even though Action is private.
//
// The MCPPrivateAccessor template captures the member pointer and exposes it
// The WingPrivateAccessor template captures the member pointer and exposes it
// through a friend function that we can call from normal code.
//
// See: https://bloglitb.blogspot.com/2011/12/access-to-private-members-safer.html
// ============================================================
template<typename Tag, typename Tag::type M>
struct MCPPrivateAccessor
struct WingPrivateAccessor
{
friend typename Tag::type GetPtr(Tag) { return M; }
};
@@ -35,7 +35,7 @@ struct Tag_FToolMenuEntry_Action
using type = FToolUIActionChoice FToolMenuEntry::*;
friend type GetPtr(Tag_FToolMenuEntry_Action);
};
template struct MCPPrivateAccessor<Tag_FToolMenuEntry_Action, &FToolMenuEntry::Action>;
template struct WingPrivateAccessor<Tag_FToolMenuEntry_Action, &FToolMenuEntry::Action>;
static const FToolUIActionChoice& GetAction(const FToolMenuEntry& Entry)
{
@@ -49,7 +49,7 @@ struct Tag_FToolMenuEntry_Command
using type = TSharedPtr<const FUICommandInfo> FToolMenuEntry::*;
friend type GetPtr(Tag_FToolMenuEntry_Command);
};
template struct MCPPrivateAccessor<Tag_FToolMenuEntry_Command, &FToolMenuEntry::Command>;
template struct WingPrivateAccessor<Tag_FToolMenuEntry_Command, &FToolMenuEntry::Command>;
static bool HasCommand(const FToolMenuEntry& Entry)
{
@@ -63,7 +63,7 @@ static bool HasCommand(const FToolMenuEntry& Entry)
// the LLM can easily remember what to type.
// ============================================================
FText MCPToolMenu::MakeBetterLabel(const UEdGraphPin *Pin, const FText &EntryLabel)
FText WingToolMenu::MakeBetterLabel(const UEdGraphPin *Pin, const FText &EntryLabel)
{
FString Sanitized = EntryLabel.ToString();
int32 Dst = 0;
@@ -88,7 +88,7 @@ FText MCPToolMenu::MakeBetterLabel(const UEdGraphPin *Pin, const FText &EntryLab
Sanitized.LeftInline(Dst);
if (Pin)
{
Sanitized = FString::Printf(TEXT("Pin:%s:%s"), *MCPUtils::FormatName(Pin), *Sanitized);
Sanitized = FString::Printf(TEXT("Pin:%s:%s"), *WingUtils::FormatName(Pin), *Sanitized);
}
return FText::FromString(Sanitized);
}
@@ -97,7 +97,7 @@ FText MCPToolMenu::MakeBetterLabel(const UEdGraphPin *Pin, const FText &EntryLab
// Check if an array of entries contains a specific label.
// ============================================================
bool MCPToolMenu::ContainsText(const TArray<FText> &Texts, const FText &Value)
bool WingToolMenu::ContainsText(const TArray<FText> &Texts, const FText &Value)
{
for (const FText &Text : Texts)
{
@@ -113,7 +113,7 @@ bool MCPToolMenu::ContainsText(const TArray<FText> &Texts, const FText &Value)
// AddEntry — create a synthetic menu entry with a direct action.
// ============================================================
void MCPToolMenu::AddEntry(TArray<FToolMenuEntry>& Entries, UEdGraphPin* Pin,
void WingToolMenu::AddEntry(TArray<FToolMenuEntry>& Entries, UEdGraphPin* Pin,
const TCHAR* Label, FCanExecuteAction CanExec, FExecuteAction Exec)
{
if (!CanExec.Execute())
@@ -127,7 +127,7 @@ void MCPToolMenu::AddEntry(TArray<FToolMenuEntry>& Entries, UEdGraphPin* Pin,
Entries.Add(MoveTemp(Entry));
}
void MCPToolMenu::AddSyntheticEntries(TArray<FToolMenuEntry> &Entries, UEdGraphNode *NodePtr)
void WingToolMenu::AddSyntheticEntries(TArray<FToolMenuEntry> &Entries, UEdGraphNode *NodePtr)
{
const UEdGraphSchema_K2 *K2Schema = Cast<UEdGraphSchema_K2>(NodePtr->GetSchema());
if (K2Schema == nullptr) return;
@@ -150,7 +150,7 @@ void MCPToolMenu::AddSyntheticEntries(TArray<FToolMenuEntry> &Entries, UEdGraphN
// do anything with the labels yet.
// ============================================================
TArray<FToolMenuEntry> MCPToolMenu::GetMenuItems(
TArray<FToolMenuEntry> WingToolMenu::GetMenuItems(
UGraphNodeContextMenuContext* GNC, const FToolMenuContext &TMC)
{
TArray<FToolMenuEntry> Result;
@@ -164,7 +164,7 @@ TArray<FToolMenuEntry> MCPToolMenu::GetMenuItems(
return Result;
}
TArray<FToolMenuEntry> MCPToolMenu::GetMenuItems(UEdGraphNode *Node, const FToolMenuContext &Context)
TArray<FToolMenuEntry> WingToolMenu::GetMenuItems(UEdGraphNode *Node, const FToolMenuContext &Context)
{
// Create the two context objects.
TArray<FToolMenuEntry> Result;
@@ -192,7 +192,7 @@ TArray<FToolMenuEntry> MCPToolMenu::GetMenuItems(UEdGraphNode *Node, const FTool
for (const UEdGraphPin *Pin : Node->Pins)
{
if (Pin->bHidden) continue;
FString PinName = MCPUtils::FormatName(Pin);
FString PinName = WingUtils::FormatName(Pin);
GNC->Init(Node->GetGraph(), Node, Pin, false);
TArray<FToolMenuEntry> PinEntries = GetMenuItems(GNC, Context);
for (FToolMenuEntry &PinEntry : PinEntries)
@@ -225,7 +225,7 @@ TArray<FToolMenuEntry> MCPToolMenu::GetMenuItems(UEdGraphNode *Node, const FTool
// selection/focus state which we can't reliably provide.
// ============================================================
bool MCPToolMenu::CanExecute(const FToolMenuEntry& Entry, const FToolMenuContext& Context)
bool WingToolMenu::CanExecute(const FToolMenuEntry& Entry, const FToolMenuContext& Context)
{
if (HasCommand(Entry))
return false;
@@ -252,7 +252,7 @@ bool MCPToolMenu::CanExecute(const FToolMenuEntry& Entry, const FToolMenuContext
return false;
}
bool MCPToolMenu::Execute(const FToolMenuEntry& Entry, const FToolMenuContext& Context)
bool WingToolMenu::Execute(const FToolMenuEntry& Entry, const FToolMenuContext& Context)
{
if (HasCommand(Entry))
return false;

View File

@@ -1,5 +1,5 @@
#include "MCPTypes.h"
#include "MCPServer.h"
#include "WingTypes.h"
#include "WingServer.h"
#include "Editor.h"
#include "EdGraphSchema_K2.h"
#include "Engine/Blueprint.h"
@@ -9,7 +9,7 @@
// Choose Short Name
// ---------------------------------------------------------------------------
FString UMCPTypes::GetNameWithoutUnderscoreC(const UObject *Obj)
FString UWingTypes::GetNameWithoutUnderscoreC(const UObject *Obj)
{
FString Name = Obj->GetName();
if (Name.EndsWith(TEXT("_C")))
@@ -23,13 +23,13 @@ FString UMCPTypes::GetNameWithoutUnderscoreC(const UObject *Obj)
return Name;
}
void UMCPTypes::ReserveShortName(FName Name)
void UWingTypes::ReserveShortName(FName Name)
{
FString NameStr = Name.ToString();
ShortToPath.Add(NameStr.ToLower(), FString(TEXT("PRIMITIVE")));
}
FString UMCPTypes::ChooseShortName(const UObject* Obj)
FString UWingTypes::ChooseShortName(const UObject* Obj)
{
if (!Cast<UScriptStruct>(Obj) && !Cast<UClass>(Obj) && !Cast<UEnum>(Obj))
return FString();
@@ -61,7 +61,7 @@ FString UMCPTypes::ChooseShortName(const UObject* Obj)
}
}
void UMCPTypes::ChooseShortNames(UPackage* Package)
void UWingTypes::ChooseShortNames(UPackage* Package)
{
if (Package == nullptr) return;
@@ -78,7 +78,7 @@ void UMCPTypes::ChooseShortNames(UPackage* Package)
// TypeToText
// ---------------------------------------------------------------------------
FString UMCPTypes::TypeToTextInner(FName Category, FName SubCategory, UObject* SubCategoryObject)
FString UWingTypes::TypeToTextInner(FName Category, FName SubCategory, UObject* SubCategoryObject)
{
if ((Category == UEdGraphSchema_K2::PC_Boolean) ||
(Category == UEdGraphSchema_K2::PC_Int) ||
@@ -131,9 +131,9 @@ FString UMCPTypes::TypeToTextInner(FName Category, FName SubCategory, UObject* S
return FString();
}
FString UMCPTypes::TypeToText(const FEdGraphPinType& PinType)
FString UWingTypes::TypeToText(const FEdGraphPinType& PinType)
{
UMCPTypes* Types = GEditor->GetEditorSubsystem<UMCPTypes>();
UWingTypes* Types = GEditor->GetEditorSubsystem<UWingTypes>();
if (!Types) return FString();
FString Inner = Types->TypeToTextInner(PinType.PinCategory, PinType.PinSubCategory, PinType.PinSubCategoryObject.Get());
@@ -158,7 +158,7 @@ FString UMCPTypes::TypeToText(const FEdGraphPinType& PinType)
return Inner;
}
FString UMCPTypes::TypeToText(const FProperty *Property)
FString UWingTypes::TypeToText(const FProperty *Property)
{
FEdGraphPinType PinType;
if (!GetDefault<UEdGraphSchema_K2>()->ConvertPropertyToPinType(Property, PinType))
@@ -171,9 +171,9 @@ FString UMCPTypes::TypeToText(const FProperty *Property)
}
}
FString UMCPTypes::TypeToText(const UObject* Obj)
FString UWingTypes::TypeToText(const UObject* Obj)
{
UMCPTypes* Types = GEditor->GetEditorSubsystem<UMCPTypes>();
UWingTypes* Types = GEditor->GetEditorSubsystem<UWingTypes>();
if (!Types) return FString();
return Types->ChooseShortName(Obj);
}
@@ -182,7 +182,7 @@ FString UMCPTypes::TypeToText(const UObject* Obj)
// Subsystem lifecycle
// ---------------------------------------------------------------------------
void UMCPTypes::Initialize(FSubsystemCollectionBase& Collection)
void UWingTypes::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
@@ -212,10 +212,10 @@ void UMCPTypes::Initialize(FSubsystemCollectionBase& Collection)
for (UPackage* Pkg : Packages)
ChooseShortNames(Pkg);
UE_LOG(LogTemp, Display, TEXT("MCPTypes: Registered %d types"), ShortToPath.Num());
UE_LOG(LogTemp, Display, TEXT("WingTypes: Registered %d types"), ShortToPath.Num());
}
void UMCPTypes::Deinitialize()
void UWingTypes::Deinitialize()
{
Super::Deinitialize();
}
@@ -224,7 +224,7 @@ void UMCPTypes::Deinitialize()
// Tokenizer
// ---------------------------------------------------------------------------
void UMCPTypes::Tokenize(const FString& Input)
void UWingTypes::Tokenize(const FString& Input)
{
Tokens.Empty();
Cursor = 0;
@@ -262,7 +262,7 @@ void UMCPTypes::Tokenize(const FString& Input)
// Path to Object Conversion
// ---------------------------------------------------------------------------
bool UMCPTypes::ResolvePath(const FString &Name, const FString &Path, FEdGraphPinType &OutType)
bool UWingTypes::ResolvePath(const FString &Name, const FString &Path, FEdGraphPinType &OutType)
{
// Load the object.
UObject* Obj = LoadObject<UObject>(nullptr, *Path);
@@ -314,13 +314,13 @@ bool UMCPTypes::ResolvePath(const FString &Name, const FString &Path, FEdGraphPi
// Parsing Types
// ---------------------------------------------------------------------------
bool UMCPTypes::TokenIs(const TCHAR* Text) const
bool UWingTypes::TokenIs(const TCHAR* Text) const
{
if (Cursor >= Tokens.Num()) return false;
return Tokens[Cursor].Equals(Text, ESearchCase::IgnoreCase);
}
bool UMCPTypes::TokenIs(const TCHAR* Text, TCHAR Next) const
bool UWingTypes::TokenIs(const TCHAR* Text, TCHAR Next) const
{
if (Cursor >= Tokens.Num() - 1) return false;
return (Tokens[Cursor].Equals(Text, ESearchCase::IgnoreCase)) &&
@@ -328,20 +328,20 @@ bool UMCPTypes::TokenIs(const TCHAR* Text, TCHAR Next) const
(Tokens[Cursor+1][0] == Next);
}
bool UMCPTypes::TokenIs(TCHAR Next) const
bool UWingTypes::TokenIs(TCHAR Next) const
{
if (Cursor >= Tokens.Num()) return false;
return (Tokens[Cursor].Len() == 1) &&
(Tokens[Cursor][0] == Next);
}
bool UMCPTypes::TokenIsID() const
bool UWingTypes::TokenIsID() const
{
if (Cursor >= Tokens.Num()) return false;
return FChar::IsAlnum(Tokens[Cursor][0]);
}
bool UMCPTypes::ParseEOF()
bool UWingTypes::ParseEOF()
{
if (Cursor != Tokens.Num())
{
@@ -351,7 +351,7 @@ bool UMCPTypes::ParseEOF()
return true;
}
bool UMCPTypes::ParseChar(TCHAR c)
bool UWingTypes::ParseChar(TCHAR c)
{
if (!TokenIs(c))
{
@@ -362,7 +362,7 @@ bool UMCPTypes::ParseChar(TCHAR c)
return true;
}
bool UMCPTypes::ParsePlainIdentifier(FEdGraphPinType& OutType)
bool UWingTypes::ParsePlainIdentifier(FEdGraphPinType& OutType)
{
if (!TokenIsID())
{
@@ -394,7 +394,7 @@ bool UMCPTypes::ParsePlainIdentifier(FEdGraphPinType& OutType)
}
}
bool UMCPTypes::ParseWrapped(FName Wrapper, FEdGraphPinType& OutType)
bool UWingTypes::ParseWrapped(FName Wrapper, FEdGraphPinType& OutType)
{
Cursor++;
if (!ParseChar('<')) return false;
@@ -409,7 +409,7 @@ bool UMCPTypes::ParseWrapped(FName Wrapper, FEdGraphPinType& OutType)
return true;
}
bool UMCPTypes::ParseMaybeWrapped(FEdGraphPinType& OutType)
bool UWingTypes::ParseMaybeWrapped(FEdGraphPinType& OutType)
{
if (TokenIs(TEXT("Soft"), '<'))
{
@@ -426,7 +426,7 @@ bool UMCPTypes::ParseMaybeWrapped(FEdGraphPinType& OutType)
else return ParsePlainIdentifier(OutType);
}
bool UMCPTypes::ParseArrayOrSet(FEdGraphPinType& OutType)
bool UWingTypes::ParseArrayOrSet(FEdGraphPinType& OutType)
{
Cursor++;
if (!ParseChar('<')) return false;
@@ -435,7 +435,7 @@ bool UMCPTypes::ParseArrayOrSet(FEdGraphPinType& OutType)
return true;
}
bool UMCPTypes::ParseMap(FEdGraphPinType& OutType)
bool UWingTypes::ParseMap(FEdGraphPinType& OutType)
{
Cursor++;
if (!ParseChar('<')) return false;
@@ -450,7 +450,7 @@ bool UMCPTypes::ParseMap(FEdGraphPinType& OutType)
return true;
}
bool UMCPTypes::ParseType(FEdGraphPinType& OutType)
bool UWingTypes::ParseType(FEdGraphPinType& OutType)
{
if (TokenIs(TEXT("Array"), '<'))
{
@@ -475,9 +475,9 @@ bool UMCPTypes::ParseType(FEdGraphPinType& OutType)
return true;
}
FString UMCPTypes::TryTextToType(const FString& Text, FEdGraphPinType& OutPinType)
FString UWingTypes::TryTextToType(const FString& Text, FEdGraphPinType& OutPinType)
{
UMCPTypes* Types = GEditor->GetEditorSubsystem<UMCPTypes>();
UWingTypes* Types = GEditor->GetEditorSubsystem<UWingTypes>();
check(Types);
Types->Error.Empty();
Types->Tokenize(Text);
@@ -486,15 +486,15 @@ FString UMCPTypes::TryTextToType(const FString& Text, FEdGraphPinType& OutPinTyp
return FString();
}
bool UMCPTypes::TextToType(const FString& Text, FEdGraphPinType& OutPinType)
bool UWingTypes::TextToType(const FString& Text, FEdGraphPinType& OutPinType)
{
FString Error = TryTextToType(Text, OutPinType);
if (Error.IsEmpty()) return true;
UMCPServer::Print(Error);
UWingServer::Print(Error);
return false;
}
UClass* UMCPTypes::TextToOneObjectType(const FString& Text)
UClass* UWingTypes::TextToOneObjectType(const FString& Text)
{
FEdGraphPinType PinType;
if (!TextToType(Text, PinType)) return nullptr;
@@ -502,13 +502,13 @@ UClass* UMCPTypes::TextToOneObjectType(const FString& Text)
if ((!Class) || (PinType.PinCategory != UEdGraphSchema_K2::PC_Object) ||
(PinType.IsContainer()))
{
UMCPServer::Printf(TEXT("ERROR: '%s' is not a plain object class\n"), *Text);
UWingServer::Printf(TEXT("ERROR: '%s' is not a plain object class\n"), *Text);
return nullptr;
}
return Class;
}
UClass* UMCPTypes::TextToOneInterfaceType(const FString& Text)
UClass* UWingTypes::TextToOneInterfaceType(const FString& Text)
{
FEdGraphPinType PinType;
if (!TextToType(Text, PinType)) return nullptr;
@@ -516,7 +516,7 @@ UClass* UMCPTypes::TextToOneInterfaceType(const FString& Text)
if ((!Class) || (PinType.PinCategory != UEdGraphSchema_K2::PC_Interface) ||
(PinType.IsContainer()))
{
UMCPServer::Printf(TEXT("ERROR: '%s' is not an interface class\n"), *Text);
UWingServer::Printf(TEXT("ERROR: '%s' is not an interface class\n"), *Text);
return nullptr;
}
return Class;

View File

@@ -1,8 +1,8 @@
#include "MCPUtils.h"
#include "MCPJson.h"
#include "MCPTypes.h"
#include "MCPServer.h"
#include "MCPHandler.h"
#include "WingUtils.h"
#include "WingJson.h"
#include "WingTypes.h"
#include "WingServer.h"
#include "WingHandler.h"
#include "Engine/Blueprint.h"
#include "Engine/MemberReference.h"
#include "Engine/World.h"
@@ -41,7 +41,7 @@
#include "Animation/BlendSpace.h"
#include "Engine/Texture.h"
// SEH support (Windows only) — defined in BlueprintMCPServer.cpp
// SEH support (Windows only) — defined in BlueprintWingServer.cpp
#if PLATFORM_WINDOWS
extern int32 TryCompileBlueprintSEH(UBlueprint* BP, EBlueprintCompileOptions Opts);
extern int32 TrySavePackageSEH(
@@ -53,7 +53,7 @@ extern int32 TrySavePackageSEH(
// Name Formatting
// ============================================================
void MCPUtils::SanitizeNameInPlace(FString &Name)
void WingUtils::SanitizeNameInPlace(FString &Name)
{
int32 Dst = 0;
for (int32 Src = 0; Src < Name.Len(); Src++)
@@ -70,123 +70,123 @@ void MCPUtils::SanitizeNameInPlace(FString &Name)
}
FString MCPUtils::FormatName(const UWorld *World)
FString WingUtils::FormatName(const UWorld *World)
{
return World->GetPathName();
}
FString MCPUtils::FormatName(const UBlueprint *BP)
FString WingUtils::FormatName(const UBlueprint *BP)
{
return BP->GetPathName();
}
FString MCPUtils::FormatName(const UActorComponent *C)
FString WingUtils::FormatName(const UActorComponent *C)
{
return C->GetName();
}
FString MCPUtils::FormatName(const UEdGraph *Graph)
FString WingUtils::FormatName(const UEdGraph *Graph)
{
FString Name = Graph->GetName();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const UEdGraphNode* Node)
FString WingUtils::FormatName(const UEdGraphNode* Node)
{
return Node->GetName();
}
FString MCPUtils::FormatName(const UEdGraphPin *Pin)
FString WingUtils::FormatName(const UEdGraphPin *Pin)
{
FString Name = Pin->PinName.ToString();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const FMemberReference &Ref)
FString WingUtils::FormatName(const FMemberReference &Ref)
{
FString Name = Ref.GetMemberName().ToString();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const FBPVariableDescription &Var)
FString WingUtils::FormatName(const FBPVariableDescription &Var)
{
FString Name = Var.VarName.ToString();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const UStruct *Struct)
FString WingUtils::FormatName(const UStruct *Struct)
{
FString Name = Struct->GetName();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const UMaterial *Material)
FString WingUtils::FormatName(const UMaterial *Material)
{
return Material->GetPathName();
}
FString MCPUtils::FormatName(const UMaterialInstance *MaterialInstance)
FString WingUtils::FormatName(const UMaterialInstance *MaterialInstance)
{
return MaterialInstance->GetPathName();
}
FString MCPUtils::FormatName(const UMaterialFunction *MaterialFunction)
FString WingUtils::FormatName(const UMaterialFunction *MaterialFunction)
{
return MaterialFunction->GetPathName();
}
FString MCPUtils::FormatName(const UMaterialExpression *Expression)
FString WingUtils::FormatName(const UMaterialExpression *Expression)
{
FString Name = Expression->GetName();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const UStaticMesh *Mesh)
FString WingUtils::FormatName(const UStaticMesh *Mesh)
{
return Mesh->GetPathName();
}
FString MCPUtils::FormatName(const USkeletalMesh *Mesh)
FString WingUtils::FormatName(const USkeletalMesh *Mesh)
{
return Mesh->GetPathName();
}
FString MCPUtils::FormatName(const UAnimSequence *Anim)
FString WingUtils::FormatName(const UAnimSequence *Anim)
{
return Anim->GetPathName();
}
FString MCPUtils::FormatName(const UBlendSpace *BlendSpace)
FString WingUtils::FormatName(const UBlendSpace *BlendSpace)
{
return BlendSpace->GetPathName();
}
FString MCPUtils::FormatName(const UTexture *Texture)
FString WingUtils::FormatName(const UTexture *Texture)
{
return Texture->GetPathName();
}
FString MCPUtils::FormatName(const UScriptStruct *Struct)
FString WingUtils::FormatName(const UScriptStruct *Struct)
{
FString Name = Struct->GetName();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const UEnum *Enum)
FString WingUtils::FormatName(const UEnum *Enum)
{
FString Name = Enum->GetName();
SanitizeNameInPlace(Name);
return Name;
}
FString MCPUtils::FormatName(const FProperty *Prop)
FString WingUtils::FormatName(const FProperty *Prop)
{
return Prop->GetName();
}
@@ -195,10 +195,10 @@ FString MCPUtils::FormatName(const FProperty *Prop)
// Identifies
// ============================================================
// Most types are handled by the template in MCPUtils.h.
// Most types are handled by the template in WingUtils.h.
// UEdGraphNode also matches by GUID:
bool MCPUtils::Identifies(const FString &Name, const UEdGraphNode* Node)
bool WingUtils::Identifies(const FString &Name, const UEdGraphNode* Node)
{
if (Node->NodeGuid.ToString().Equals(Name, ESearchCase::IgnoreCase))
return true;
@@ -210,7 +210,7 @@ bool MCPUtils::Identifies(const FString &Name, const UEdGraphNode* Node)
// ============================================================
FString MCPUtils::FormatNodeTitle(const UEdGraphNode *Node)
FString WingUtils::FormatNodeTitle(const UEdGraphNode *Node)
{
FString Title = Node->GetNodeTitle(ENodeTitleType::FullTitle).ToString();
int32 NewlineIdx;
@@ -227,7 +227,7 @@ FString MCPUtils::FormatNodeTitle(const UEdGraphNode *Node)
// Text formatting
// ============================================================
FString MCPUtils::WrapText(const FString& Text, int32 ColLimit, const FString& Prefix)
FString WingUtils::WrapText(const FString& Text, int32 ColLimit, const FString& Prefix)
{
FString Clean = Text;
Clean.ReplaceInline(TEXT("\r\n"), TEXT("\n"));
@@ -263,7 +263,7 @@ FString MCPUtils::WrapText(const FString& Text, int32 ColLimit, const FString& P
// Enum helpers
// ============================================================
FString MCPUtils::EnumToString(UEnum* Enum, int64 Value, const FString& Prefix)
FString WingUtils::EnumToString(UEnum* Enum, int64 Value, const FString& Prefix)
{
FString Full = Enum->GetNameStringByValue(Value);
if (!Prefix.IsEmpty() && Full.StartsWith(Prefix))
@@ -271,12 +271,12 @@ FString MCPUtils::EnumToString(UEnum* Enum, int64 Value, const FString& Prefix)
return Full;
}
bool MCPUtils::StringToEnum(UEnum* Enum, const FString& Str, int64& OutValue, const FString& Prefix)
bool WingUtils::StringToEnum(UEnum* Enum, const FString& Str, int64& OutValue, const FString& Prefix)
{
OutValue = Enum->GetValueByNameString(Prefix + Str);
if (OutValue == INDEX_NONE)
{
UMCPServer::Printf(TEXT("ERROR: Invalid value '%s' for %s\n"), *Str, *Enum->GetName());
UWingServer::Printf(TEXT("ERROR: Invalid value '%s' for %s\n"), *Str, *Enum->GetName());
return false;
}
return true;
@@ -286,14 +286,14 @@ bool MCPUtils::StringToEnum(UEnum* Enum, const FString& Str, int64& OutValue, co
// Blueprint helpers
// ============================================================
TArray<UEdGraph*> MCPUtils::AllGraphs(UBlueprint* BP)
TArray<UEdGraph*> WingUtils::AllGraphs(UBlueprint* BP)
{
TArray<UEdGraph*> Graphs;
BP->GetAllGraphs(Graphs);
return Graphs;
}
TArray<UEdGraph*> MCPUtils::AllGraphsNamed(UBlueprint* BP, const FString& Name)
TArray<UEdGraph*> WingUtils::AllGraphsNamed(UBlueprint* BP, const FString& Name)
{
TArray<UEdGraph*> Result;
for (UEdGraph* Graph : AllGraphs(BP))
@@ -302,7 +302,7 @@ TArray<UEdGraph*> MCPUtils::AllGraphsNamed(UBlueprint* BP, const FString& Name)
return Result;
}
TArray<UEdGraphNode*> MCPUtils::AllNodes(UBlueprint* BP)
TArray<UEdGraphNode*> WingUtils::AllNodes(UBlueprint* BP)
{
TArray<UEdGraphNode*> Nodes;
for (UEdGraph* Graph : AllGraphs(BP))
@@ -310,7 +310,7 @@ TArray<UEdGraphNode*> MCPUtils::AllNodes(UBlueprint* BP)
return Nodes;
}
bool MCPUtils::SaveBlueprintPackage(UBlueprint* BP)
bool WingUtils::SaveBlueprintPackage(UBlueprint* BP)
{
UPackage* Package = BP->GetPackage();
UE_LOG(LogTemp, Display, TEXT("BlueprintMCP: SaveBlueprintPackage — begin for '%s'"), *BP->GetName());
@@ -440,7 +440,7 @@ bool MCPUtils::SaveBlueprintPackage(UBlueprint* BP)
// FindClassByName
// ============================================================
UClass* MCPUtils::FindClassByName(const FString& ClassName)
UClass* WingUtils::FindClassByName(const FString& ClassName)
{
// Exact match first (handles both C++ classes and Blueprint _C classes)
for (TObjectIterator<UClass> It; It; ++It)
@@ -469,7 +469,7 @@ UClass* MCPUtils::FindClassByName(const FString& ClassName)
// Material helpers
// ============================================================
void MCPUtils::EnsureMaterialGraph(UMaterial* Material)
void WingUtils::EnsureMaterialGraph(UMaterial* Material)
{
if (!Material) return;
if (!Material->MaterialGraph)
@@ -486,7 +486,7 @@ void MCPUtils::EnsureMaterialGraph(UMaterial* Material)
}
}
UMaterial* MCPUtils::ReplaceMaterialWithTransientCopy(UMaterial* Material)
UMaterial* WingUtils::ReplaceMaterialWithTransientCopy(UMaterial* Material)
{
if (!Material) return nullptr;
@@ -514,7 +514,7 @@ UMaterial* MCPUtils::ReplaceMaterialWithTransientCopy(UMaterial* Material)
return Material;
}
bool MCPUtils::SaveGenericPackage(UObject* Asset)
bool WingUtils::SaveGenericPackage(UObject* Asset)
{
if (!Asset) return false;
UPackage* Package = Asset->GetPackage();
@@ -556,7 +556,7 @@ bool MCPUtils::SaveGenericPackage(UObject* Asset)
// Anim blueprint helpers
// ============================================================
UAnimationStateMachineGraph* MCPUtils::FindStateMachineGraph(UBlueprint* BP, const FString& GraphName)
UAnimationStateMachineGraph* WingUtils::FindStateMachineGraph(UBlueprint* BP, const FString& GraphName)
{
TArray<UEdGraph*> AllGraphs;
BP->GetAllGraphs(AllGraphs);
@@ -573,7 +573,7 @@ UAnimationStateMachineGraph* MCPUtils::FindStateMachineGraph(UBlueprint* BP, con
return nullptr;
}
UAnimStateNode* MCPUtils::FindStateByName(UAnimationStateMachineGraph* SMGraph, const FString& StateName)
UAnimStateNode* WingUtils::FindStateByName(UAnimationStateMachineGraph* SMGraph, const FString& StateName)
{
for (UEdGraphNode* Node : SMGraph->Nodes)
{
@@ -585,11 +585,11 @@ UAnimStateNode* MCPUtils::FindStateByName(UAnimationStateMachineGraph* SMGraph,
}
}
}
UMCPServer::Printf(TEXT("ERROR: State '%s' not found in graph '%s'\n"), *StateName, *SMGraph->GetName());
UWingServer::Printf(TEXT("ERROR: State '%s' not found in graph '%s'\n"), *StateName, *SMGraph->GetName());
return nullptr;
}
UAnimStateTransitionNode* MCPUtils::FindTransition(UAnimationStateMachineGraph* SMGraph,
UAnimStateTransitionNode* WingUtils::FindTransition(UAnimationStateMachineGraph* SMGraph,
const FString& FromStateName, const FString& ToStateName)
{
for (UEdGraphNode* Node : SMGraph->Nodes)
@@ -613,7 +613,7 @@ UAnimStateTransitionNode* MCPUtils::FindTransition(UAnimationStateMachineGraph*
// Graph actions (node spawning)
// ============================================================
FString MCPUtils::ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action)
FString WingUtils::ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action)
{
FString Category = Action->GetCategory().ToString();
FString MenuName = Action->GetMenuDescription().ToString();
@@ -622,7 +622,7 @@ FString MCPUtils::ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action)
return Category + TEXT("|") + MenuName;
}
TArray<TSharedPtr<FEdGraphSchemaAction>> MCPUtils::SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults, bool ExactMatch)
TArray<TSharedPtr<FEdGraphSchemaAction>> WingUtils::SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults, bool ExactMatch)
{
FString QueryLower = Query.ToLower();
TArray<TSharedPtr<FEdGraphSchemaAction>> Result;
@@ -663,17 +663,17 @@ TArray<TSharedPtr<FEdGraphSchemaAction>> MCPUtils::SearchGraphActions(UEdGraph*
// ============================================================
// ============================================================
// CollectHandlerClasses — find all concrete IMCPHandler classes
// CollectHandlerClasses — find all concrete IWingHandler classes
// ============================================================
TArray<UClass*> MCPUtils::CollectHandlerClasses()
TArray<UClass*> WingUtils::CollectHandlerClasses()
{
TArray<UClass*> Result;
for (TObjectIterator<UClass> It; It; ++It)
{
UClass* Class = *It;
if (Class->HasAnyClassFlags(CLASS_Abstract)) continue;
if (!Class->ImplementsInterface(UMCPHandler::StaticClass())) continue;
if (!Class->ImplementsInterface(UWingHandler::StaticClass())) continue;
Result.Add(Class);
}
Result.Sort([](UClass& A, UClass& B) { return GetHandlerName(&A) < GetHandlerName(&B); });
@@ -684,11 +684,11 @@ TArray<UClass*> MCPUtils::CollectHandlerClasses()
// GetHandlerName — derive tool name from handler class name
// ============================================================
FString MCPUtils::GetHandlerName(UClass* HandlerClass)
FString WingUtils::GetHandlerName(UClass* HandlerClass)
{
FString Name = HandlerClass->GetName();
// Strip "MCP_" prefix
if (Name.StartsWith(TEXT("MCP_")))
// Strip "Wing_" prefix
if (Name.StartsWith(TEXT("Wing_")))
Name = Name.Mid(4);
return Name;
}
@@ -697,11 +697,11 @@ FString MCPUtils::GetHandlerName(UClass* HandlerClass)
// GetHandlerGroup — derive group name from handler class name
// ============================================================
FString MCPUtils::GetHandlerGroup(UClass* HandlerClass)
FString WingUtils::GetHandlerGroup(UClass* HandlerClass)
{
FString Name = HandlerClass->GetName();
// Strip "MCP_" prefix
if (Name.StartsWith(TEXT("MCP_")))
// Strip "Wing_" prefix
if (Name.StartsWith(TEXT("Wing_")))
Name = Name.Mid(4);
// Everything before the underscore is the group
int32 UnderscoreIdx;
@@ -718,11 +718,11 @@ FString MCPUtils::GetHandlerGroup(UClass* HandlerClass)
// FindPropertyByName
// ============================================================
FProperty* MCPUtils::FindPropertyByName(UObject* Obj, const FString& Name)
FProperty* WingUtils::FindPropertyByName(UObject* Obj, const FString& Name)
{
if (!Obj)
{
UMCPServer::Print(TEXT("ERROR: Object is null\n"));
UWingServer::Print(TEXT("ERROR: Object is null\n"));
return nullptr;
}
@@ -732,14 +732,14 @@ FProperty* MCPUtils::FindPropertyByName(UObject* Obj, const FString& Name)
if (!Identifies(Name, *PropIt)) continue;
if (Found)
{
UMCPServer::Printf(TEXT("ERROR: Ambiguous property '%s' on %s\n"), *Name, *FormatName(Obj->GetClass()));
UWingServer::Printf(TEXT("ERROR: Ambiguous property '%s' on %s\n"), *Name, *FormatName(Obj->GetClass()));
return nullptr;
}
Found = *PropIt;
}
if (!Found)
UMCPServer::Printf(TEXT("ERROR: Property '%s' not found on %s\n"), *Name, *FormatName(Obj->GetClass()));
UWingServer::Printf(TEXT("ERROR: Property '%s' not found on %s\n"), *Name, *FormatName(Obj->GetClass()));
return Found;
}
@@ -748,7 +748,7 @@ FProperty* MCPUtils::FindPropertyByName(UObject* Obj, const FString& Name)
// GetPropertyValueText
// ============================================================
FString MCPUtils::GetPropertyValueText(UObject* Container, FProperty* Prop)
FString WingUtils::GetPropertyValueText(UObject* Container, FProperty* Prop)
{
FString Result;
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
@@ -760,26 +760,26 @@ FString MCPUtils::GetPropertyValueText(UObject* Container, FProperty* Prop)
// SetPropertyValueText
// ============================================================
bool MCPUtils::SetPropertyValueText(UObject* Container, FProperty* Prop, const FString& Value)
bool WingUtils::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)
{
UMCPServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
UWingServer::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)
bool WingUtils::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)
{
UMCPServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
UWingServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
*Value, *FormatName(Prop), *Prop->GetCPPType());
return false;
}
@@ -790,7 +790,7 @@ bool MCPUtils::SetPropertyValueText(void* Container, FProperty* Prop, const FStr
// SearchProperties
// ============================================================
TArray<FProperty*> MCPUtils::SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal)
TArray<FProperty*> WingUtils::SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal)
{
TArray<FProperty*> Result;
if (!Obj) return Result;
@@ -812,43 +812,43 @@ TArray<FProperty*> MCPUtils::SearchProperties(UObject* Obj, const FString& Query
// FormatCommandHelp — verbose description of one handler command
// ============================================================
void MCPUtils::FormatCommandHelp(UClass* HandlerClass)
void WingUtils::FormatCommandHelp(UClass* HandlerClass)
{
const IMCPHandler* Handler = Cast<IMCPHandler>(HandlerClass->GetDefaultObject());
const IWingHandler* Handler = Cast<IWingHandler>(HandlerClass->GetDefaultObject());
if (!Handler) return;
FString ToolName = GetHandlerName(HandlerClass);
UMCPServer::Print(TEXT("\n"));
UMCPServer::Print(WrapText(Handler->GetDescription(), 80, TEXT("// ")));
UMCPServer::Print(TEXT("\n"));
UWingServer::Print(TEXT("\n"));
UWingServer::Print(WrapText(Handler->GetDescription(), 80, TEXT("// ")));
UWingServer::Print(TEXT("\n"));
// Command signature line
UMCPServer::Print(ToolName);
UMCPServer::Print(TEXT("("));
UWingServer::Print(ToolName);
UWingServer::Print(TEXT("("));
bool bFirst = true;
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
{
if (!bFirst) UMCPServer::Print(TEXT(","));
if (!bFirst) UWingServer::Print(TEXT(","));
bFirst = false;
if (PropIt->HasMetaData(TEXT("Optional"))) UMCPServer::Print(TEXT("?"));
UMCPServer::Print(PropIt->GetName());
if (PropIt->HasMetaData(TEXT("Optional"))) UWingServer::Print(TEXT("?"));
UWingServer::Print(PropIt->GetName());
}
UMCPServer::Print(TEXT(")\n"));
UWingServer::Print(TEXT(")\n"));
// parameter details
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
{
FProperty* Prop = *PropIt;
FString Name = Prop->GetName();
FString Type = UMCPTypes::TypeToText(Prop);
FString Type = UWingTypes::TypeToText(Prop);
bool bOptional = Prop->HasMetaData(TEXT("Optional"));
const FString& Desc = Prop->GetMetaData(TEXT("Description"));
UMCPServer::Printf(TEXT(" %s %s%s"),
UWingServer::Printf(TEXT(" %s %s%s"),
*Type, *Name, bOptional ? TEXT(" (optional)") : TEXT(""));
if (!Desc.IsEmpty())
UMCPServer::Printf(TEXT(" — %s"), *Desc);
UMCPServer::Print(TEXT("\n"));
UWingServer::Printf(TEXT(" — %s"), *Desc);
UWingServer::Print(TEXT("\n"));
}
}

View File

@@ -1,8 +1,8 @@
#include "MCPCommandlet.h"
#include "MCPServer.h"
#include "WingmanCommandlet.h"
#include "WingServer.h"
#include "Containers/Ticker.h"
UBlueprintMCPCommandlet::UBlueprintMCPCommandlet()
UWingmanCommandlet::UWingmanCommandlet()
{
IsClient = false;
IsEditor = true;
@@ -10,9 +10,9 @@ UBlueprintMCPCommandlet::UBlueprintMCPCommandlet()
LogToConsole = true;
}
int32 UBlueprintMCPCommandlet::Main(const FString& Params)
int32 UWingmanCommandlet::Main(const FString& Params)
{
// The UMCPServer editor subsystem starts the server automatically.
// The UWingServer editor subsystem starts the server automatically.
// We just need to tick it, since FTickableEditorObject doesn't tick in commandlet mode.
double LastTime = FPlatformTime::Seconds();
@@ -22,7 +22,7 @@ int32 UBlueprintMCPCommandlet::Main(const FString& Params)
double DeltaTime = CurrentTime - LastTime;
LastTime = CurrentTime;
FTSTicker::GetCoreTicker().Tick(DeltaTime);
UMCPServer::TickServer(DeltaTime);
UWingServer::TickServer(DeltaTime);
FPlatformProcess::Sleep(0.01f);
}

View File

@@ -0,0 +1,4 @@
#include "WingmanModule.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_MODULE(FWingmanModule, BlueprintMCP);

View File

@@ -3,7 +3,7 @@
#include "CoreMinimal.h"
#include "Modules/ModuleInterface.h"
class FBlueprintMCPModule : public IModuleInterface
class FWingmanModule : public IModuleInterface
{
public:
virtual void StartupModule() override {}

View File

@@ -1,7 +1,7 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPProperty.h"
#include "WingProperty.h"
#include "Engine/Blueprint.h"
#include "BPVarEditor.generated.h"
@@ -15,7 +15,7 @@ struct FBPVarEditor
GENERATED_BODY()
FBPVariableDescription* Desc = nullptr;
MCPProperty DefaultValueProp;
WingProperty DefaultValueProp;
FBPVarEditor() = default;
FBPVarEditor(UBlueprint* BP, const FString& VarName);
@@ -54,5 +54,5 @@ private:
void LoadDefault();
void SaveFlags();
bool SaveDefault();
TArray<MCPProperty> MergedProperties();
TArray<WingProperty> MergedProperties();
};

View File

@@ -6,7 +6,7 @@ class UEdGraphNode;
class UK2Node_EditablePinBase;
struct FEdGraphPinType;
struct MCPFunctionArgs
struct WingFunctionArgs
{
// Returns true if the node is an EditablePinBase subclass that
// actually supports user-defined pins (FunctionEntry, FunctionResult,

View File

@@ -8,11 +8,11 @@
class UMaterialExpression;
class MCPGraphExport
class WingGraphExport
{
public:
MCPGraphExport(UEdGraph* InGraph);
MCPGraphExport(UEdGraphNode* InNode);
WingGraphExport(UEdGraph* InGraph);
WingGraphExport(UEdGraphNode* InNode);
const FString GetOutput() { return Output.ToString(); }
const FString GetDetails() { return Details.ToString(); }

View File

@@ -1,33 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPUtils.h"
// A resolved property: the FProperty descriptor plus a pointer to
// the value's storage. operator-> forwards to the FProperty.
struct MCPProperty
{
public:
FProperty* Prop = nullptr;
void* Container = nullptr;
MCPProperty() = default;
MCPProperty(FProperty* InProp, void* Container);
FString GetText() const;
bool SetText(const FString& Value);
explicit operator bool() const { return Prop != nullptr; }
FProperty* operator->() const { return Prop; }
static void Remove(TArray<MCPProperty>& Props, const FString& Name);
static TArray<MCPProperty> GetAll(UObject* Obj, EPropertyFlags Flags);
static TArray<MCPProperty> GetAll(UStruct* StructType, void* Container, EPropertyFlags Flags);
static TArray<MCPProperty> FindAllSubstring(const TArray<MCPProperty>& Props, const FString& Substring);
static MCPProperty FindOneExactMatch(const TArray<MCPProperty>& Props, const FString& Name);
private:
bool TryParseEnum(UEnum* Enum, const FString& Text, int64 &OutValue);
bool TrySetText(const FString &Text);
static void Collect(UStruct* StructType, void* Container, TArray<MCPProperty> &Props, EPropertyFlags Flags);
};

View File

@@ -3,7 +3,7 @@
#include "CoreMinimal.h"
#include "Materials/Material.h"
class MCPMaterialParameter
class WingMaterialParameter
{
public:
static TMap<FMaterialParameterInfo, FMaterialParameterMetadata> GetMaterialParameters(UMaterialInterface* Material);

View File

@@ -1,13 +1,13 @@
#pragma once
#include "CoreMinimal.h"
#include "MCPUtils.h"
#include "WingUtils.h"
class UEdGraphPin;
class IAssetEditorInstance;
struct FWalker;
// MCPFetcher: Load an Asset and find an object within it.
// WingFetcher: Load an Asset and find an object within it.
// To find an object, you use a path. This is typical:
//
// F.Walk(TEXT("/Game/Mat/M_Test,graph,node:Param_1"))
@@ -27,36 +27,36 @@ struct FWalker;
// When you're finally at the object you want, you usually
// use the Cast method to get a pointer to the object.
//
// If any step fails, the MCPFetcher will print an error
// If any step fails, the WingFetcher will print an error
// message that can be seen by the MCP's caller. It will
// also set an error flag. Once the error flag is set, all
// further ops become no-ops. After that point, fetching
// any data will return nullptr.
//
class MCPFetcher
class WingFetcher
{
public:
// Walk a path from an asset to an object
// within that asset. If you call walk a
// second time, it will walk additional steps.
//
MCPFetcher& Walk(const FString& Path);
WingFetcher& Walk(const FString& Path);
// Walk a path using individual path
// steps instead of a path. All these steps generate
// errors if they cannot find the desired element.
//
MCPFetcher& Asset(const FString& PackagePath);
MCPFetcher& Graph(const FString& Value);
MCPFetcher& Node(const FString& Value);
MCPFetcher& Pin(const FString& Value);
MCPFetcher& Component(const FString& Value);
MCPFetcher& LevelBlueprint(const FString& Value);
WingFetcher& Asset(const FString& PackagePath);
WingFetcher& Graph(const FString& Value);
WingFetcher& Node(const FString& Value);
WingFetcher& Pin(const FString& Value);
WingFetcher& Component(const FString& Value);
WingFetcher& LevelBlueprint(const FString& Value);
// Return true if there haven't been any errors.
// Note that errors always automatically generate
// output to MCPServer::Printf.
// output to WingServer::Printf.
//
bool Ok() const { return !bError; }
@@ -108,12 +108,12 @@ public:
// Initialize empty. You need to call Asset, or walk
// a path that starts with an asset.
//
MCPFetcher() {}
WingFetcher() {}
// Initialize with an object. From there, you can walk
// to sub-objects.
//
MCPFetcher(UObject* O) : Obj(O) {}
WingFetcher(UObject* O) : Obj(O) {}
private:
@@ -130,17 +130,17 @@ private:
bool bError = false;
// Internal methods.
using WalkFunc = MCPFetcher& (MCPFetcher::*)(const FString&);
using WalkFunc = WingFetcher& (WingFetcher::*)(const FString&);
void SetObj(UObject* InObj);
void SetPin(UEdGraphPin* InPin);
MCPFetcher& SetError();
WingFetcher& SetError();
void PathFailed(const TCHAR *Kind);
MCPFetcher& TypeMismatch(const TCHAR* Walker, const TCHAR* Expected);
WingFetcher& TypeMismatch(const TCHAR* Walker, const TCHAR* Expected);
bool CheckAssetIsA(UClass* StaticClass);
WalkFunc GetWalker(const FString &Step);
};
template<> inline UEdGraphPin* MCPFetcher::Cast<UEdGraphPin>()
template<> inline UEdGraphPin* WingFetcher::Cast<UEdGraphPin>()
{
if (bError) return nullptr;
if (!ResultPin) PathFailed(TEXT("UEdGraphPin"));

Some files were not shown because too many files have changed in this diff Show More