Remove stringbuilder parameter for handlers
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -37,7 +38,7 @@ public:
|
||||
return TEXT("Create a new Animation Blueprint asset with a specified skeleton.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -94,14 +95,14 @@ public:
|
||||
FKismetEditorUtilities::CompileBlueprint(NewAnimBP);
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(NewAnimBP);
|
||||
|
||||
Result.Appendf(TEXT("Created: %s\n"), *AssetPath);
|
||||
Result.Appendf(TEXT("ParentClass: %s\n"), *MCPUtils::FormatName(ParentClassObj));
|
||||
Result.Appendf(TEXT("Saved: %s\n"), bSaved ? TEXT("true") : TEXT("false"));
|
||||
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"));
|
||||
|
||||
TArray<UEdGraph*> Graphs = MCPUtils::AllGraphs(NewAnimBP);
|
||||
for (UEdGraph* Graph : Graphs)
|
||||
{
|
||||
Result.Appendf(TEXT("Graph: %s\n"), *MCPUtils::FormatName(Graph));
|
||||
UMCPServer::Printf(TEXT("Graph: %s\n"), *MCPUtils::FormatName(Graph));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -27,7 +28,7 @@ public:
|
||||
return TEXT("List all animation slot names used in an Animation Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UAnimBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -52,12 +53,12 @@ public:
|
||||
|
||||
for (const FString& Slot : SlotNames)
|
||||
{
|
||||
Result.Appendf(TEXT("%s\n"), *Slot);
|
||||
UMCPServer::Printf(TEXT("%s\n"), *Slot);
|
||||
}
|
||||
|
||||
if (SlotNames.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("No animation slot names found.\n"));
|
||||
UMCPServer::Print(TEXT("No animation slot names found.\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -27,7 +28,7 @@ public:
|
||||
return TEXT("List all sync group names used in an Animation Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UAnimBlueprint* AnimBP = F.Walk(Path).Cast<UAnimBlueprint>();
|
||||
@@ -52,13 +53,13 @@ public:
|
||||
|
||||
if (SyncGroupNames.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("No sync groups found.\n"));
|
||||
UMCPServer::Print(TEXT("No sync groups found.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
for (const FString& Group : SyncGroupNames)
|
||||
{
|
||||
Result.Appendf(TEXT("%s\n"), *Group);
|
||||
UMCPServer::Printf(TEXT("%s\n"), *Group);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPFetcher.h"
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
"Replaces all existing samples.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Load the blend space
|
||||
MCPAssets<UBlendSpace> Assets;
|
||||
@@ -128,10 +129,10 @@ public:
|
||||
// Save
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(BS);
|
||||
|
||||
Result.Appendf(TEXT("Set %d samples on %s\n"), SamplesSet, *MCPUtils::FormatName(BS));
|
||||
UMCPServer::Printf(TEXT("Set %d samples on %s\n"), SamplesSet, *MCPUtils::FormatName(BS));
|
||||
if (!bSaved)
|
||||
{
|
||||
Result.Append(TEXT("WARNING: package save failed\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: package save failed\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Misc/Paths.h"
|
||||
@@ -27,14 +28,14 @@ public:
|
||||
return TEXT("Copy an asset's .uasset file to a .uasset.bak backup.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
FString Filename = FPaths::ConvertRelativePathToFull(
|
||||
FPackageName::LongPackageNameToFilename(AssetPath, FPackageName::GetAssetPackageExtension()));
|
||||
|
||||
if (!IFileManager::Get().FileExists(*Filename))
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Asset file not found: %s\n"), *Filename);
|
||||
UMCPServer::Printf(TEXT("ERROR: Asset file not found: %s\n"), *Filename);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -42,10 +43,10 @@ public:
|
||||
uint32 CopyResult = IFileManager::Get().Copy(*BackupFilename, *Filename, true);
|
||||
if (CopyResult != COPY_OK)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Failed to copy %s to %s\n"), *Filename, *BackupFilename);
|
||||
UMCPServer::Printf(TEXT("ERROR: Failed to copy %s to %s\n"), *Filename, *BackupFilename);
|
||||
return;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Backed up to %s\n"), *BackupFilename);
|
||||
UMCPServer::Printf(TEXT("Backed up to %s\n"), *BackupFilename);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
"Use force=true to skip the reference check.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Verify the asset file exists on disk
|
||||
FString PackageFilename = FPackageName::LongPackageNameToFilename(
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
|
||||
if (!IFileManager::Get().FileExists(*PackageFilename))
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Asset file not found on disk: %s\n"), *PackageFilename);
|
||||
UMCPServer::Printf(TEXT("ERROR: Asset file not found on disk: %s\n"), *PackageFilename);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,22 +60,22 @@ public:
|
||||
|
||||
if (Referencers.Num() > 0 && !Force)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Asset is still referenced by %d package(s):\n"), Referencers.Num());
|
||||
UMCPServer::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);
|
||||
Result.Appendf(TEXT(" %s%s\n"), *RefStr,
|
||||
UMCPServer::Printf(TEXT(" %s%s\n"), *RefStr,
|
||||
RefPackage ? TEXT(" (loaded)") : TEXT(" (on-disk only)"));
|
||||
}
|
||||
Result.Append(TEXT("Use force=true to skip the reference check.\n"));
|
||||
UMCPServer::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)
|
||||
{
|
||||
Result.Appendf(TEXT("WARNING: Force-deleting despite %d referencer(s).\n"), Referencers.Num());
|
||||
UMCPServer::Printf(TEXT("WARNING: Force-deleting despite %d referencer(s).\n"), Referencers.Num());
|
||||
}
|
||||
|
||||
if (Force)
|
||||
@@ -110,7 +111,7 @@ public:
|
||||
|
||||
if (!bDeleted)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Failed to delete file from disk: %s\n"), *PackageFilename);
|
||||
UMCPServer::Printf(TEXT("ERROR: Failed to delete file from disk: %s\n"), *PackageFilename);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -123,6 +124,6 @@ public:
|
||||
Registry.ScanPathsSynchronous({PackageDir}, true);
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Deleted %s\n"), *AssetPath);
|
||||
UMCPServer::Printf(TEXT("Deleted %s\n"), *AssetPath);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "AssetRegistry/AssetData.h"
|
||||
@@ -26,7 +27,7 @@ public:
|
||||
return TEXT("Find all assets that reference a given asset.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
IAssetRegistry& Registry = *IAssetRegistry::Get();
|
||||
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
FAssetData AssetData = Registry.GetAssetByObjectPath(FSoftObjectPath(AssetPath));
|
||||
if (!AssetData.IsValid())
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Asset not found: %s\n"), *AssetPath);
|
||||
UMCPServer::Printf(TEXT("ERROR: Asset not found: %s\n"), *AssetPath);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
|
||||
if (Referencers.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("No referencers found.\n"));
|
||||
UMCPServer::Print(TEXT("No referencers found.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,13 +56,13 @@ public:
|
||||
Registry.GetAssetsByPackageName(Ref, RefAssets);
|
||||
if (RefAssets.Num() > 0)
|
||||
{
|
||||
Result.Appendf(TEXT("%s %s\n"),
|
||||
UMCPServer::Printf(TEXT("%s %s\n"),
|
||||
*MCPUtils::FormatName(RefAssets[0].GetClass()),
|
||||
*RefStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Appendf(TEXT("Unknown %s\n"), *RefStr);
|
||||
UMCPServer::Printf(TEXT("Unknown %s\n"), *RefStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -30,7 +31,7 @@ public:
|
||||
return TEXT("Rename or move an asset with reference fixup.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Load the asset
|
||||
MCPAssets<UObject> Assets;
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
NewAssetName = NewPath;
|
||||
if (NewPackagePath.IsEmpty())
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Cannot determine directory from AssetPath '%s'\n"), *AssetPath);
|
||||
UMCPServer::Printf(TEXT("ERROR: Cannot determine directory from AssetPath '%s'\n"), *AssetPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -61,10 +62,10 @@ public:
|
||||
|
||||
if (!AssetTools.RenameAssets(RenameData))
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Rename failed. The target path may be invalid or a conflicting asset may exist.\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Rename failed. The target path may be invalid or a conflicting asset may exist.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Renamed to %s/%s\n"), *NewPackagePath, *NewAssetName);
|
||||
UMCPServer::Printf(TEXT("Renamed to %s/%s\n"), *NewPackagePath, *NewAssetName);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Misc/PackageName.h"
|
||||
@@ -28,7 +29,7 @@ public:
|
||||
return TEXT("Restore a .uasset file from its .uasset.bak backup, reloading it in the editor.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
FString Filename = FPaths::ConvertRelativePathToFull(
|
||||
FPackageName::LongPackageNameToFilename(AssetPath, FPackageName::GetAssetPackageExtension()));
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
|
||||
if (!IFileManager::Get().FileExists(*BackupFilename))
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Backup file not found: %s\n"), *BackupFilename);
|
||||
UMCPServer::Printf(TEXT("ERROR: Backup file not found: %s\n"), *BackupFilename);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -51,7 +52,7 @@ public:
|
||||
uint32 CopyResult = IFileManager::Get().Copy(*Filename, *BackupFilename, true);
|
||||
if (CopyResult != COPY_OK)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Failed to copy backup over %s\n"), *AssetPath);
|
||||
UMCPServer::Printf(TEXT("ERROR: Failed to copy backup over %s\n"), *AssetPath);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,12 +64,12 @@ public:
|
||||
UEditorLoadingAndSavingUtils::ReloadPackages({Package}, bReloaded, ErrorMessage, EReloadPackagesInteractionMode::AssumePositive);
|
||||
if (!bReloaded)
|
||||
{
|
||||
Result.Appendf(TEXT("WARNING: Restored %s but reload failed: %s\n"),
|
||||
UMCPServer::Printf(TEXT("WARNING: Restored %s but reload failed: %s\n"),
|
||||
*AssetPath, *ErrorMessage.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Restored %s from backup\n"), *AssetPath);
|
||||
UMCPServer::Printf(TEXT("Restored %s from backup\n"), *AssetPath);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,11 +32,11 @@ public:
|
||||
return TEXT("Search for assets by name and/or type. At least one of Query or Type must be specified.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
if (Query.IsEmpty() && Type.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT("ERROR: At least one of Query or Type must be specified\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: At least one of Query or Type must be specified\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
UClass* TypeClass = MCPUtils::FindClassByName(Type);
|
||||
if (!TypeClass)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Unknown asset type '%s'\n"), *Type);
|
||||
UMCPServer::Printf(TEXT("ERROR: Unknown asset type '%s'\n"), *Type);
|
||||
return;
|
||||
}
|
||||
Assets.NoScans().Scan(TypeClass);
|
||||
@@ -63,18 +64,18 @@ public:
|
||||
const TArray<FAssetData>& AllData = Assets.AllData();
|
||||
for (const FAssetData& Data : AllData)
|
||||
{
|
||||
Result.Appendf(TEXT("%s %s\n"),
|
||||
UMCPServer::Printf(TEXT("%s %s\n"),
|
||||
*MCPUtils::FormatName(Data.GetClass()),
|
||||
*Data.PackageName.ToString());
|
||||
}
|
||||
|
||||
if (AllData.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("No assets found.\n"));
|
||||
UMCPServer::Print(TEXT("No assets found.\n"));
|
||||
}
|
||||
else if (AllData.Num() >= Limit)
|
||||
{
|
||||
Result.Appendf(TEXT("WARNING: You reached the limit of %d, to raise it, specify the Limit parameter.\n"), Limit);
|
||||
UMCPServer::Printf(TEXT("WARNING: You reached the limit of %d, to raise it, specify the Limit parameter.\n"), Limit);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
return TEXT("Create a new 2D Blend Space asset with a specified skeleton.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -46,7 +47,7 @@ public:
|
||||
UBlendSpace* NewBS = NewObject<UBlendSpace>(Maker.Package(), FName(*Maker.Name()), RF_Public | RF_Standalone);
|
||||
if (!NewBS)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Failed to create Blend Space object\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Failed to create Blend Space object\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -56,9 +57,9 @@ public:
|
||||
NewBS->MarkPackageDirty();
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(NewBS);
|
||||
|
||||
Result.Appendf(TEXT("Created %s\n"), *NewBS->GetPathName());
|
||||
Result.Appendf(TEXT("Skeleton: %s\n"), *SkeletonObj->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Created %s\n"), *NewBS->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Skeleton: %s\n"), *SkeletonObj->GetPathName());
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Package save failed\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -37,11 +38,11 @@ public:
|
||||
return TEXT("Create a new function, macro, or custom event graph in a Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
if (GraphType != TEXT("function") && GraphType != TEXT("macro") && GraphType != TEXT("customEvent"))
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Invalid GraphType '%s'. Valid values: function, macro, customEvent\n"), *GraphType);
|
||||
UMCPServer::Printf(TEXT("ERROR: Invalid GraphType '%s'. Valid values: function, macro, customEvent\n"), *GraphType);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ public:
|
||||
// Check graph name uniqueness
|
||||
if (!MCPUtils::AllGraphsNamed(BP, Graph).IsEmpty())
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: A graph named '%s' already exists in %s\n"), *Graph, *MCPUtils::FormatName(BP));
|
||||
UMCPServer::Printf(TEXT("ERROR: A graph named '%s' already exists in %s\n"), *Graph, *MCPUtils::FormatName(BP));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
{
|
||||
if (CE->CustomFunctionName == FName(*Graph))
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: A custom event named '%s' already exists in %s\n"), *Graph, *MCPUtils::FormatName(BP));
|
||||
UMCPServer::Printf(TEXT("ERROR: A custom event named '%s' already exists in %s\n"), *Graph, *MCPUtils::FormatName(BP));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -75,11 +76,11 @@ public:
|
||||
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
|
||||
if (!NewGraph)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Failed to create function graph\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Failed to create function graph\n"));
|
||||
return;
|
||||
}
|
||||
FBlueprintEditorUtils::AddFunctionGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromObject=*/static_cast<UClass*>(nullptr));
|
||||
Result.Appendf(TEXT("Created function graph: %s\n"), *MCPUtils::FormatName(NewGraph));
|
||||
UMCPServer::Printf(TEXT("Created function graph: %s\n"), *MCPUtils::FormatName(NewGraph));
|
||||
}
|
||||
else if (GraphType == TEXT("macro"))
|
||||
{
|
||||
@@ -87,11 +88,11 @@ public:
|
||||
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
|
||||
if (!NewGraph)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Failed to create macro graph\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Failed to create macro graph\n"));
|
||||
return;
|
||||
}
|
||||
FBlueprintEditorUtils::AddMacroGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromClass=*/nullptr);
|
||||
Result.Appendf(TEXT("Created macro graph: %s\n"), *MCPUtils::FormatName(NewGraph));
|
||||
UMCPServer::Printf(TEXT("Created macro graph: %s\n"), *MCPUtils::FormatName(NewGraph));
|
||||
}
|
||||
else // customEvent
|
||||
{
|
||||
@@ -100,7 +101,7 @@ public:
|
||||
EventGraph = BP->UbergraphPages[0];
|
||||
if (!EventGraph)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Blueprint has no EventGraph to add a custom event to\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Blueprint has no EventGraph to add a custom event to\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ public:
|
||||
NewEvent->CreateNewGuid();
|
||||
NewEvent->PostPlacedNewNode();
|
||||
NewEvent->AllocateDefaultPins();
|
||||
Result.Appendf(TEXT("Created custom event: %s\n"), *MCPUtils::FormatName(NewEvent));
|
||||
UMCPServer::Printf(TEXT("Created custom event: %s\n"), *MCPUtils::FormatName(NewEvent));
|
||||
}
|
||||
|
||||
MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
return TEXT("Delete a function or macro graph from a Blueprint. Cannot delete EventGraph pages.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
F.Walk(Path);
|
||||
@@ -73,12 +74,12 @@ public:
|
||||
{
|
||||
if (G && MCPUtils::Identifies(Graph, G))
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Cannot delete UbergraphPage '%s'. EventGraph pages cannot be deleted.\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: Cannot delete UbergraphPage '%s'. EventGraph pages cannot be deleted.\n"),
|
||||
*MCPUtils::FormatName(G));
|
||||
return;
|
||||
}
|
||||
}
|
||||
Result.Appendf(TEXT("ERROR: Graph '%s' not found in blueprint %s\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: Graph '%s' not found in blueprint %s\n"),
|
||||
*Graph, *MCPUtils::FormatName(BP));
|
||||
return;
|
||||
}
|
||||
@@ -88,8 +89,8 @@ public:
|
||||
FBlueprintEditorUtils::RemoveGraph(BP, TargetGraph, EGraphRemoveFlags::Default);
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Deleted %s graph %s\n"), *GraphType, *GraphName);
|
||||
UMCPServer::Printf(TEXT("Deleted %s graph %s\n"), *GraphType, *GraphName);
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Package save failed.\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Package save failed.\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
return TEXT("Rename a function or macro graph in a Blueprint. Cannot rename EventGraph pages.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
||||
@@ -40,14 +41,14 @@ public:
|
||||
UBlueprint* BP = Cast<UBlueprint>(TargetGraph->GetOuter());
|
||||
if (!BP)
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Graph '%s' is not owned by a Blueprint.\n"), *Graph);
|
||||
UMCPServer::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))
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Cannot rename UbergraphPage '%s'. EventGraph pages cannot be renamed.\n"),
|
||||
UMCPServer::Printf(TEXT("Error: Cannot rename UbergraphPage '%s'. EventGraph pages cannot be renamed.\n"),
|
||||
*MCPUtils::FormatName(TargetGraph));
|
||||
return;
|
||||
}
|
||||
@@ -57,7 +58,7 @@ public:
|
||||
bool bIsMacro = BP->MacroGraphs.Contains(TargetGraph);
|
||||
if (!bIsFunction && !bIsMacro)
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Graph '%s' is not a function or macro graph.\n"),
|
||||
UMCPServer::Printf(TEXT("Error: Graph '%s' is not a function or macro graph.\n"),
|
||||
*MCPUtils::FormatName(TargetGraph));
|
||||
return;
|
||||
}
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
{
|
||||
if (Existing != TargetGraph)
|
||||
{
|
||||
Result.Appendf(TEXT("Error: A graph named '%s' already exists in '%s'.\n"),
|
||||
UMCPServer::Printf(TEXT("Error: A graph named '%s' already exists in '%s'.\n"),
|
||||
*NewName, *MCPUtils::FormatName(BP));
|
||||
return;
|
||||
}
|
||||
@@ -76,7 +77,7 @@ public:
|
||||
FBlueprintEditorUtils::RenameGraph(TargetGraph, NewName);
|
||||
MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Renamed to %s %s\n"),
|
||||
UMCPServer::Printf(TEXT("Renamed to %s %s\n"),
|
||||
bIsFunction ? TEXT("function") : TEXT("macro"),
|
||||
*MCPUtils::FormatName(TargetGraph));
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
"Optionally attach it to an existing parent component.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -123,13 +123,13 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Added component %s (%s)"),
|
||||
UMCPServer::Printf(TEXT("Added component %s (%s)"),
|
||||
*MCPUtils::FormatName(NewNode->ComponentTemplate),
|
||||
*MCPUtils::FormatName(ComponentClassObj));
|
||||
if (ParentSCSNode)
|
||||
{
|
||||
Result.Appendf(TEXT(" under %s"), *MCPUtils::FormatName(ParentSCSNode->ComponentTemplate));
|
||||
UMCPServer::Printf(TEXT(" under %s"), *MCPUtils::FormatName(ParentSCSNode->ComponentTemplate));
|
||||
}
|
||||
Result.Appendf(TEXT("\nSaved: %s\n"), bSaved ? TEXT("true") : TEXT("false"));
|
||||
UMCPServer::Printf(TEXT("\nSaved: %s\n"), bSaved ? TEXT("true") : TEXT("false"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -49,7 +50,7 @@ public:
|
||||
return TEXT("Create a new multicast event dispatcher on a Blueprint, optionally with parameters.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UBlueprint* BP = F.Walk(Path).Cast<UBlueprint>();
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
{
|
||||
if (Var.VarName == DispatcherFName)
|
||||
{
|
||||
Result.Appendf(TEXT("Error: A variable or dispatcher named '%s' already exists.\n"), *DispatcherName);
|
||||
UMCPServer::Printf(TEXT("Error: A variable or dispatcher named '%s' already exists.\n"), *DispatcherName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +71,7 @@ public:
|
||||
// Check against existing graphs (functions, macros, etc.)
|
||||
if (!MCPUtils::AllGraphsNamed(BP, DispatcherName).IsEmpty())
|
||||
{
|
||||
Result.Appendf(TEXT("Error: A graph named '%s' already exists.\n"), *DispatcherName);
|
||||
UMCPServer::Printf(TEXT("Error: A graph named '%s' already exists.\n"), *DispatcherName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ public:
|
||||
DelegateType.PinCategory = UEdGraphSchema_K2::PC_MCDelegate;
|
||||
if (!FBlueprintEditorUtils::AddMemberVariable(BP, DispatcherFName, DelegateType))
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Failed to add delegate variable for '%s'.\n"), *DispatcherName);
|
||||
UMCPServer::Printf(TEXT("Error: Failed to add delegate variable for '%s'.\n"), *DispatcherName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ public:
|
||||
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
|
||||
if (!SigGraph)
|
||||
{
|
||||
Result.Append(TEXT("Error: Failed to create delegate signature graph.\n"));
|
||||
UMCPServer::Print(TEXT("Error: Failed to create delegate signature graph.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -116,7 +117,7 @@ public:
|
||||
if (!EntryNode)
|
||||
{
|
||||
MCPUtils::SaveBlueprintPackage(BP);
|
||||
Result.Append(TEXT("Error: Event dispatcher created but entry node not found — parameters could not be added.\n"));
|
||||
UMCPServer::Print(TEXT("Error: Event dispatcher created but entry node not found — parameters could not be added.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -137,9 +138,9 @@ public:
|
||||
|
||||
MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Created event dispatcher '%s'"), *DispatcherName);
|
||||
UMCPServer::Printf(TEXT("Created event dispatcher '%s'"), *DispatcherName);
|
||||
if (ParamCount > 0)
|
||||
Result.Appendf(TEXT(" with %d parameter(s)"), ParamCount);
|
||||
Result.Append(TEXT(".\n"));
|
||||
UMCPServer::Printf(TEXT(" with %d parameter(s)"), ParamCount);
|
||||
UMCPServer::Print(TEXT(".\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
return TEXT("Add a new parameter to a function, custom event, or event dispatcher in a Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
EntryNode->CreateUserDefinedPin(FName(*ParamName), PinType, EGPD_Output);
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Added %s parameter '%s' to %s '%s'%s\n"),
|
||||
UMCPServer::Printf(TEXT("Added %s parameter '%s' to %s '%s'%s\n"),
|
||||
*ParamType, *ParamName, *NodeType, *FunctionName,
|
||||
bSaved ? TEXT("") : TEXT(" (WARNING: save failed)"));
|
||||
}
|
||||
|
||||
@@ -33,14 +33,14 @@ public:
|
||||
"Creates stub function graphs for each interface function.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
UBlueprint* BP = Assets.Object();
|
||||
|
||||
// Resolve the interface class
|
||||
UClass* InterfaceClass = FindInterfaceClass(InterfaceName, Result);
|
||||
UClass* InterfaceClass = FindInterfaceClass(InterfaceName);
|
||||
if (!InterfaceClass) return;
|
||||
|
||||
// Check for duplicates
|
||||
@@ -64,15 +64,15 @@ public:
|
||||
}
|
||||
|
||||
// Collect stub function graph names from the newly added interface entry
|
||||
Result.Appendf(TEXT("Added interface %s\n"), *MCPUtils::FormatName(InterfaceClass));
|
||||
Result.Appendf(TEXT("Function stubs:\n"));
|
||||
UMCPServer::Printf(TEXT("Added interface %s\n"), *MCPUtils::FormatName(InterfaceClass));
|
||||
UMCPServer::Printf(TEXT("Function stubs:\n"));
|
||||
for (const FBPInterfaceDescription& IfaceDesc : BP->ImplementedInterfaces)
|
||||
{
|
||||
if (IfaceDesc.Interface != InterfaceClass) continue;
|
||||
for (const UEdGraph* Graph : IfaceDesc.Graphs)
|
||||
{
|
||||
if (Graph)
|
||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
// Resolve an interface name to a UClass. Tries loaded UInterface classes
|
||||
// first (for native interfaces), then falls back to loading a Blueprint
|
||||
// Interface asset.
|
||||
static UClass* FindInterfaceClass(const FString& Name, FStringBuilderBase& Result)
|
||||
static UClass* FindInterfaceClass(const FString& Name)
|
||||
{
|
||||
// Strategy 1: Search loaded UInterface classes by name
|
||||
for (TObjectIterator<UClass> It; It; ++It)
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
return TEXT("Add a new member variable to a Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -80,13 +80,13 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Added %s %s to %s\n"),
|
||||
UMCPServer::Printf(TEXT("Added %s %s to %s\n"),
|
||||
*VariableType, *VariableName, *MCPUtils::FormatName(BP));
|
||||
if (IsArray)
|
||||
Result.Append(TEXT("Container: Array\n"));
|
||||
UMCPServer::Print(TEXT("Container: Array\n"));
|
||||
if (!Category.IsEmpty())
|
||||
Result.Appendf(TEXT("Category: %s\n"), *Category);
|
||||
UMCPServer::Printf(TEXT("Category: %s\n"), *Category);
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("Warning: package save failed\n"));
|
||||
UMCPServer::Print(TEXT("Warning: package save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
return TEXT("Change the type of an existing parameter on a function or custom event in a Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -123,14 +123,14 @@ public:
|
||||
for (UEdGraphPin* Linked : Pin->LinkedTo)
|
||||
{
|
||||
if (!Linked || !Linked->GetOwningNode()) continue;
|
||||
Result.Appendf(TEXT("Connection at risk: %s -> %s on %s\n"),
|
||||
UMCPServer::Printf(TEXT("Connection at risk: %s -> %s on %s\n"),
|
||||
*MCPUtils::FormatName(Pin),
|
||||
*MCPUtils::FormatName(Linked),
|
||||
*MCPUtils::FormatName(Linked->GetOwningNode()));
|
||||
AtRisk++;
|
||||
}
|
||||
}
|
||||
Result.Appendf(TEXT("Dry run: %d connection(s) at risk.\n"), AtRisk);
|
||||
UMCPServer::Printf(TEXT("Dry run: %d connection(s) at risk.\n"), AtRisk);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
// Save
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Changed '%s' to %s. Save %s.\n"),
|
||||
UMCPServer::Printf(TEXT("Changed '%s' to %s. Save %s.\n"),
|
||||
*ParamName, *MCPUtils::FormatPinType(NewPinType),
|
||||
bSaved ? TEXT("succeeded") : TEXT("failed"));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPAssets.h"
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
"Supports dry-run mode to preview affected nodes before committing.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||
@@ -62,10 +63,10 @@ public:
|
||||
}
|
||||
if (!Found)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Variable '%s' not found in %s.\nAvailable variables:\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: Variable '%s' not found in %s.\nAvailable variables:\n"),
|
||||
*Variable, *MCPUtils::FormatName(BP));
|
||||
for (const FBPVariableDescription& Var : BP->NewVariables)
|
||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(Var));
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Var));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,14 +92,14 @@ public:
|
||||
for (auto* VarNode : NodeArray)
|
||||
{
|
||||
if (VarNode->GetVarName() != VarFName) continue;
|
||||
Result.Appendf(TEXT(" %s %s in %s\n"), NodeType,
|
||||
UMCPServer::Printf(TEXT(" %s %s in %s\n"), NodeType,
|
||||
*MCPUtils::FormatName(static_cast<UEdGraphNode*>(VarNode)),
|
||||
*MCPUtils::FormatName(VarNode->GetGraph()));
|
||||
for (UEdGraphPin* Pin : VarNode->Pins)
|
||||
{
|
||||
if (!Pin || Pin->LinkedTo.Num() == 0) continue;
|
||||
if (NodeType[0] == 'G' && Pin->Direction != EGPD_Output) continue; // Get nodes: only output pins
|
||||
Result.Appendf(TEXT(" %s connected to %d pin(s)\n"),
|
||||
UMCPServer::Printf(TEXT(" %s connected to %d pin(s)\n"),
|
||||
*MCPUtils::FormatName(Pin), Pin->LinkedTo.Num());
|
||||
}
|
||||
}
|
||||
@@ -114,13 +115,13 @@ public:
|
||||
|
||||
if (DryRun)
|
||||
{
|
||||
Result.Appendf(TEXT("Dry run: would change %s from %s to %s\n"),
|
||||
UMCPServer::Printf(TEXT("Dry run: would change %s from %s to %s\n"),
|
||||
*MCPUtils::FormatName(*Found),
|
||||
*MCPUtils::FormatPinType(Found->VarType),
|
||||
*MCPUtils::FormatPinType(NewPinType));
|
||||
if (bHasAffected)
|
||||
{
|
||||
Result.Append(TEXT("Affected nodes:\n"));
|
||||
UMCPServer::Print(TEXT("Affected nodes:\n"));
|
||||
AppendAffectedNodes(GetNodes, TEXT("Get"));
|
||||
AppendAffectedNodes(SetNodes, TEXT("Set"));
|
||||
}
|
||||
@@ -131,14 +132,14 @@ public:
|
||||
Found->VarType = NewPinType;
|
||||
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
Result.Appendf(TEXT("Changed %s to %s.%s\n"),
|
||||
UMCPServer::Printf(TEXT("Changed %s to %s.%s\n"),
|
||||
*MCPUtils::FormatName(*Found),
|
||||
*MCPUtils::FormatPinType(NewPinType),
|
||||
bSaved ? TEXT("") : TEXT(" WARNING: save failed."));
|
||||
|
||||
if (bHasAffected)
|
||||
{
|
||||
Result.Append(TEXT("Affected nodes:\n"));
|
||||
UMCPServer::Print(TEXT("Affected nodes:\n"));
|
||||
AppendAffectedNodes(GetNodes, TEXT("Get"));
|
||||
AppendAffectedNodes(SetNodes, TEXT("Set"));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
|
||||
// Compile a single blueprint and append results to Out.
|
||||
// Returns true if the blueprint compiled cleanly (no errors).
|
||||
static bool CompileAndReport(UBlueprint* BP, FStringBuilderBase& Out)
|
||||
static bool CompileAndReport(UBlueprint* BP)
|
||||
{
|
||||
EBlueprintCompileOptions CompileOpts =
|
||||
EBlueprintCompileOptions::SkipSave |
|
||||
@@ -61,7 +62,7 @@ public:
|
||||
if (!Node->bHasCompilerMessage) continue;
|
||||
bool bIsError = (Node->ErrorType == EMessageSeverity::Error);
|
||||
if (bIsError) ErrorCount++; else WarningCount++;
|
||||
Out.Appendf(TEXT(" %s: [%s] %s > %s: %s\n"),
|
||||
UMCPServer::Printf(TEXT(" %s: [%s] %s > %s: %s\n"),
|
||||
bIsError ? TEXT("ERROR") : TEXT("WARNING"),
|
||||
*MCPUtils::FormatName(Node->GetGraph()),
|
||||
*MCPUtils::FormatName(Node),
|
||||
@@ -74,18 +75,18 @@ public:
|
||||
|
||||
if (bIsValid && WarningCount == 0)
|
||||
{
|
||||
Out.Appendf(TEXT(" OK (status: %s)\n"), *StatusStr);
|
||||
UMCPServer::Printf(TEXT(" OK (status: %s)\n"), *StatusStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Out.Appendf(TEXT(" status: %s, errors: %d, warnings: %d\n"),
|
||||
UMCPServer::Printf(TEXT(" status: %s, errors: %d, warnings: %d\n"),
|
||||
*StatusStr, ErrorCount, WarningCount);
|
||||
}
|
||||
|
||||
return bIsValid;
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Finder;
|
||||
Finder.Scan<UBlueprint>().Scan<UWorld>();
|
||||
@@ -104,7 +105,7 @@ public:
|
||||
// countOnly: return count without compiling anything
|
||||
if (CountOnly)
|
||||
{
|
||||
Result.Appendf(TEXT("Matching blueprints: %d\n"), TotalMatching);
|
||||
UMCPServer::Printf(TEXT("Matching blueprints: %d\n"), TotalMatching);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,12 +132,12 @@ public:
|
||||
UBlueprint* BP = Loader.Object();
|
||||
|
||||
TotalChecked++;
|
||||
Result.Appendf(TEXT("%s:\n"), *MCPUtils::FormatName(BP));
|
||||
bool bValid = CompileAndReport(BP, Result);
|
||||
UMCPServer::Printf(TEXT("%s:\n"), *MCPUtils::FormatName(BP));
|
||||
bool bValid = CompileAndReport(BP);
|
||||
if (bValid) TotalPassed++; else TotalFailed++;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("\nSummary: %d checked, %d passed, %d failed (of %d matching)\n"),
|
||||
UMCPServer::Printf(TEXT("\nSummary: %d checked, %d passed, %d failed (of %d matching)\n"),
|
||||
TotalChecked, TotalPassed, TotalFailed, TotalMatching);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
return TEXT("Create a new Blueprint asset with a specified parent class and type.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -93,11 +94,11 @@ public:
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(NewBP);
|
||||
|
||||
// Report result
|
||||
Result.Appendf(TEXT("Created: %s\n"), *MCPUtils::FormatName(NewBP));
|
||||
Result.Appendf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentClassObj));
|
||||
UMCPServer::Printf(TEXT("Created: %s\n"), *MCPUtils::FormatName(NewBP));
|
||||
UMCPServer::Printf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentClassObj));
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("Warning: save failed\n"));
|
||||
UMCPServer::Print(TEXT("Warning: save failed\n"));
|
||||
for (UEdGraph* Graph : MCPUtils::AllGraphs(NewBP))
|
||||
Result.Appendf(TEXT("Graph: %s\n"), *MCPUtils::FormatName(Graph));
|
||||
UMCPServer::Printf(TEXT("Graph: %s\n"), *MCPUtils::FormatName(Graph));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -37,7 +38,7 @@ public:
|
||||
"finding divergence after copy-paste, or auditing consistency.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Load both blueprints
|
||||
MCPAssets<UBlueprint> AssetsA;
|
||||
@@ -89,13 +90,13 @@ public:
|
||||
|
||||
if (!pGA)
|
||||
{
|
||||
Result.Appendf(TEXT("Graph %s: only in B (%d nodes)\n"), *GraphName, (*pGB)->Nodes.Num());
|
||||
UMCPServer::Printf(TEXT("Graph %s: only in B (%d nodes)\n"), *GraphName, (*pGB)->Nodes.Num());
|
||||
TotalDiffs++;
|
||||
continue;
|
||||
}
|
||||
if (!pGB)
|
||||
{
|
||||
Result.Appendf(TEXT("Graph %s: only in A (%d nodes)\n"), *GraphName, (*pGA)->Nodes.Num());
|
||||
UMCPServer::Printf(TEXT("Graph %s: only in A (%d nodes)\n"), *GraphName, (*pGA)->Nodes.Num());
|
||||
TotalDiffs++;
|
||||
continue;
|
||||
}
|
||||
@@ -181,32 +182,32 @@ public:
|
||||
|
||||
if (bIdentical)
|
||||
{
|
||||
Result.Appendf(TEXT("Graph %s: identical (%d nodes)\n"), *GraphName, GA->Nodes.Num());
|
||||
UMCPServer::Printf(TEXT("Graph %s: identical (%d nodes)\n"), *GraphName, GA->Nodes.Num());
|
||||
continue;
|
||||
}
|
||||
|
||||
TotalDiffs++;
|
||||
Result.Appendf(TEXT("Graph %s: different (A=%d nodes, B=%d nodes)\n"), *GraphName, GA->Nodes.Num(), GB->Nodes.Num());
|
||||
UMCPServer::Printf(TEXT("Graph %s: different (A=%d nodes, B=%d nodes)\n"), *GraphName, GA->Nodes.Num(), GB->Nodes.Num());
|
||||
|
||||
if (!OnlyInA.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT(" Nodes only in A:\n"));
|
||||
for (const FString& Line : OnlyInA) Result.Appendf(TEXT(" %s\n"), *Line);
|
||||
UMCPServer::Print(TEXT(" Nodes only in A:\n"));
|
||||
for (const FString& Line : OnlyInA) UMCPServer::Printf(TEXT(" %s\n"), *Line);
|
||||
}
|
||||
if (!OnlyInB.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT(" Nodes only in B:\n"));
|
||||
for (const FString& Line : OnlyInB) Result.Appendf(TEXT(" %s\n"), *Line);
|
||||
UMCPServer::Print(TEXT(" Nodes only in B:\n"));
|
||||
for (const FString& Line : OnlyInB) UMCPServer::Printf(TEXT(" %s\n"), *Line);
|
||||
}
|
||||
if (!ConnsOnlyInA.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT(" Connections only in A:\n"));
|
||||
for (const FString& Line : ConnsOnlyInA) Result.Appendf(TEXT(" %s\n"), *Line);
|
||||
UMCPServer::Print(TEXT(" Connections only in A:\n"));
|
||||
for (const FString& Line : ConnsOnlyInA) UMCPServer::Printf(TEXT(" %s\n"), *Line);
|
||||
}
|
||||
if (!ConnsOnlyInB.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT(" Connections only in B:\n"));
|
||||
for (const FString& Line : ConnsOnlyInB) Result.Appendf(TEXT(" %s\n"), *Line);
|
||||
UMCPServer::Print(TEXT(" Connections only in B:\n"));
|
||||
for (const FString& Line : ConnsOnlyInB) UMCPServer::Printf(TEXT(" %s\n"), *Line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,17 +226,17 @@ public:
|
||||
|
||||
if (!VarsOnlyInA.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT("Variables only in A:\n"));
|
||||
for (const FString& Name : VarsOnlyInA) Result.Appendf(TEXT(" %s\n"), *Name);
|
||||
UMCPServer::Print(TEXT("Variables only in A:\n"));
|
||||
for (const FString& Name : VarsOnlyInA) UMCPServer::Printf(TEXT(" %s\n"), *Name);
|
||||
TotalDiffs += VarsOnlyInA.Num();
|
||||
}
|
||||
if (!VarsOnlyInB.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT("Variables only in B:\n"));
|
||||
for (const FString& Name : VarsOnlyInB) Result.Appendf(TEXT(" %s\n"), *Name);
|
||||
UMCPServer::Print(TEXT("Variables only in B:\n"));
|
||||
for (const FString& Name : VarsOnlyInB) UMCPServer::Printf(TEXT(" %s\n"), *Name);
|
||||
TotalDiffs += VarsOnlyInB.Num();
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Total differences: %d\n"), TotalDiffs);
|
||||
UMCPServer::Printf(TEXT("Total differences: %d\n"), TotalDiffs);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,46 +32,46 @@ public:
|
||||
"and graph names. Does not include graph contents (use DumpGraphs for that).");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||
if (!BP) return;
|
||||
|
||||
// Header
|
||||
Result.Appendf(TEXT("Blueprint: %s\n"), *MCPUtils::FormatName(BP));
|
||||
Result.Appendf(TEXT("Parent: %s\n"), BP->ParentClass ? *MCPUtils::FormatName(BP->ParentClass) : TEXT("None"));
|
||||
Result.Appendf(TEXT("Type: %s\n"),
|
||||
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));
|
||||
|
||||
// Animation Blueprint
|
||||
if (UAnimBlueprint* AnimBP = Cast<UAnimBlueprint>(BP))
|
||||
{
|
||||
if (AnimBP->TargetSkeleton)
|
||||
Result.Appendf(TEXT("TargetSkeleton: %s\n"), *AnimBP->TargetSkeleton->GetPathName());
|
||||
UMCPServer::Printf(TEXT("TargetSkeleton: %s\n"), *AnimBP->TargetSkeleton->GetPathName());
|
||||
}
|
||||
|
||||
// Interfaces
|
||||
for (const FBPInterfaceDescription& I : BP->ImplementedInterfaces)
|
||||
{
|
||||
if (I.Interface)
|
||||
Result.Appendf(TEXT("Interface: %s\n"), *MCPUtils::FormatName(I.Interface));
|
||||
UMCPServer::Printf(TEXT("Interface: %s\n"), *MCPUtils::FormatName(I.Interface));
|
||||
}
|
||||
|
||||
// Variables
|
||||
if (!BP->NewVariables.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT("\nVariables:\n"));
|
||||
UMCPServer::Print(TEXT("\nVariables:\n"));
|
||||
for (const FBPVariableDescription& V : BP->NewVariables)
|
||||
{
|
||||
Result.Appendf(TEXT(" %s %s"),
|
||||
UMCPServer::Printf(TEXT(" %s %s"),
|
||||
*MCPUtils::FormatPinType(V.VarType),
|
||||
*MCPUtils::FormatName(V));
|
||||
if (!V.DefaultValue.IsEmpty())
|
||||
Result.Appendf(TEXT(" = %s"), *V.DefaultValue);
|
||||
UMCPServer::Printf(TEXT(" = %s"), *V.DefaultValue);
|
||||
if (!V.Category.IsEmpty() && V.Category.ToString() != TEXT("Default"))
|
||||
Result.Appendf(TEXT(" [%s]"), *V.Category.ToString());
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT(" [%s]"), *V.Category.ToString());
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,16 +81,16 @@ public:
|
||||
const TArray<USCS_Node*>& AllNodes = SCS->GetAllNodes();
|
||||
if (!AllNodes.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT("\nComponents:\n"));
|
||||
UMCPServer::Print(TEXT("\nComponents:\n"));
|
||||
for (USCS_Node* Node : AllNodes)
|
||||
{
|
||||
if (!Node || !Node->ComponentTemplate) continue;
|
||||
Result.Appendf(TEXT(" %s (%s)"),
|
||||
UMCPServer::Printf(TEXT(" %s (%s)"),
|
||||
*MCPUtils::FormatName(Node->ComponentTemplate),
|
||||
*MCPUtils::FormatName(Node->ComponentClass));
|
||||
if (Node->ParentComponentOrVariableName != NAME_None)
|
||||
Result.Appendf(TEXT(" parent=%s"), *Node->ParentComponentOrVariableName.ToString());
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT(" parent=%s"), *Node->ParentComponentOrVariableName.ToString());
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,9 +99,9 @@ public:
|
||||
TArray<UEdGraph*> Graphs = MCPUtils::AllGraphs(BP);
|
||||
if (!Graphs.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT("\nGraphs:\n"));
|
||||
UMCPServer::Print(TEXT("\nGraphs:\n"));
|
||||
for (UEdGraph* Graph : Graphs)
|
||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
"showing hierarchy and component classes.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
F.Walk(Path);
|
||||
@@ -41,7 +42,7 @@ public:
|
||||
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
|
||||
if (!SCS)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript)\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript)\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,11 +51,11 @@ public:
|
||||
|
||||
if (AllNodes.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("No components.\n"));
|
||||
UMCPServer::Print(TEXT("No components.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
Result.Append(TEXT("WARNING: This only lists components added in this blueprint's SCS. "
|
||||
UMCPServer::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"));
|
||||
|
||||
@@ -62,34 +63,34 @@ public:
|
||||
for (USCS_Node* Root : RootNodes)
|
||||
{
|
||||
if (!Root) continue;
|
||||
EmitNode(Root, 0, Root == RootNodes[0], Result);
|
||||
EmitNode(Root, 0, Root == RootNodes[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void EmitNode(USCS_Node* Node, int32 Depth, bool bIsSceneRoot, FStringBuilderBase& Result)
|
||||
void EmitNode(USCS_Node* Node, int32 Depth, bool bIsSceneRoot)
|
||||
{
|
||||
// Indent to show hierarchy
|
||||
for (int32 i = 0; i < Depth; i++)
|
||||
Result.Append(TEXT(" "));
|
||||
UMCPServer::Print(TEXT(" "));
|
||||
|
||||
FString ClassName = Node->ComponentClass
|
||||
? MCPUtils::FormatName(Node->ComponentClass)
|
||||
: TEXT("None");
|
||||
|
||||
Result.Appendf(TEXT("%s %s"),
|
||||
UMCPServer::Printf(TEXT("%s %s"),
|
||||
*ClassName,
|
||||
*MCPUtils::FormatName(Node->ComponentTemplate));
|
||||
|
||||
if (bIsSceneRoot && Depth == 0)
|
||||
Result.Append(TEXT(" [SceneRoot]"));
|
||||
UMCPServer::Print(TEXT(" [SceneRoot]"));
|
||||
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
|
||||
for (USCS_Node* Child : Node->GetChildNodes())
|
||||
{
|
||||
if (!Child) continue;
|
||||
EmitNode(Child, Depth + 1, false, Result);
|
||||
EmitNode(Child, Depth + 1, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
return TEXT("List all event dispatchers on a Blueprint, including their parameter signatures.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UBlueprint* BP = F.Walk(Path).Cast<UBlueprint>();
|
||||
@@ -42,7 +43,7 @@ public:
|
||||
|
||||
for (const FName& DelegateName : DelegateNameSet)
|
||||
{
|
||||
Result.Appendf(TEXT("%s("), *DelegateName.ToString());
|
||||
UMCPServer::Printf(TEXT("%s("), *DelegateName.ToString());
|
||||
|
||||
UEdGraph* SigGraph = FBlueprintEditorUtils::GetDelegateSignatureGraphByName(BP, DelegateName);
|
||||
if (SigGraph)
|
||||
@@ -53,9 +54,9 @@ public:
|
||||
for (const TSharedPtr<FUserPinInfo>& PinInfo : FE->UserDefinedPins)
|
||||
{
|
||||
if (!PinInfo.IsValid()) continue;
|
||||
if (!bFirst) Result.Append(TEXT(", "));
|
||||
if (!bFirst) UMCPServer::Print(TEXT(", "));
|
||||
bFirst = false;
|
||||
Result.Appendf(TEXT("%s %s"),
|
||||
UMCPServer::Printf(TEXT("%s %s"),
|
||||
*MCPUtils::FormatPinType(PinInfo->PinType),
|
||||
*PinInfo->PinName.ToString());
|
||||
}
|
||||
@@ -63,12 +64,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Result.Append(TEXT(")\n"));
|
||||
UMCPServer::Print(TEXT(")\n"));
|
||||
}
|
||||
|
||||
if (DelegateNameSet.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("No event dispatchers found.\n"));
|
||||
UMCPServer::Print(TEXT("No event dispatchers found.\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -27,7 +28,7 @@ public:
|
||||
"including their function graphs.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
F.Walk(Path);
|
||||
@@ -41,17 +42,17 @@ public:
|
||||
if (!IfaceDesc.Interface) continue;
|
||||
bAny = true;
|
||||
|
||||
Result.Appendf(TEXT("Interface: %s\n"), *MCPUtils::FormatName(IfaceDesc.Interface));
|
||||
UMCPServer::Printf(TEXT("Interface: %s\n"), *MCPUtils::FormatName(IfaceDesc.Interface));
|
||||
for (const UEdGraph* Graph : IfaceDesc.Graphs)
|
||||
{
|
||||
if (!Graph) continue;
|
||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Graph));
|
||||
}
|
||||
}
|
||||
|
||||
if (!bAny)
|
||||
{
|
||||
Result.Append(TEXT("No interfaces implemented.\n"));
|
||||
UMCPServer::Print(TEXT("No interfaces implemented.\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
"Reports compiler warnings and errors.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Load Blueprint
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
@@ -61,24 +62,24 @@ public:
|
||||
}
|
||||
|
||||
// Summary
|
||||
Result.Appendf(TEXT("Refreshed %s: %d graphs, %d nodes"), *MCPUtils::FormatName(BP), GraphCount, NodeCount);
|
||||
UMCPServer::Printf(TEXT("Refreshed %s: %d graphs, %d nodes"), *MCPUtils::FormatName(BP), GraphCount, NodeCount);
|
||||
if (OrphanedPinsRemoved > 0)
|
||||
{
|
||||
Result.Appendf(TEXT(", %d orphaned pins removed"), OrphanedPinsRemoved);
|
||||
UMCPServer::Printf(TEXT(", %d orphaned pins removed"), OrphanedPinsRemoved);
|
||||
}
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
|
||||
// Collect compiler warnings and errors
|
||||
if (BP->Status == BS_Error)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Blueprint has compiler errors after refresh\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Blueprint has compiler errors after refresh\n"));
|
||||
}
|
||||
|
||||
for (UEdGraphNode* Node : MCPUtils::AllNodes(BP))
|
||||
{
|
||||
if (!Node->bHasCompilerMessage) continue;
|
||||
const TCHAR* Prefix = (Node->ErrorType == EMessageSeverity::Error) ? TEXT("ERROR") : TEXT("WARNING");
|
||||
Result.Appendf(TEXT("%s: [%s] %s: %s\n"),
|
||||
UMCPServer::Printf(TEXT("%s: [%s] %s: %s\n"),
|
||||
Prefix, *MCPUtils::FormatName(Node->GetGraph()),
|
||||
*MCPUtils::FormatName(Node), *Node->ErrorMsg);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
return TEXT("Remove a component from a Blueprint's SimpleConstructionScript.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||
@@ -40,7 +41,7 @@ public:
|
||||
USimpleConstructionScript* SCS = BP->SimpleConstructionScript;
|
||||
if (!SCS)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript).\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Not an Actor Blueprint (no SimpleConstructionScript).\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,12 +60,12 @@ public:
|
||||
|
||||
if (!NodeToRemove)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Component '%s' not found.\nAvailable components:\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: Component '%s' not found.\nAvailable components:\n"),
|
||||
*Component);
|
||||
for (USCS_Node* Node : AllNodes)
|
||||
{
|
||||
if (Node && Node->ComponentTemplate)
|
||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(Node->ComponentTemplate));
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Node->ComponentTemplate));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -73,7 +74,7 @@ public:
|
||||
const TArray<USCS_Node*>& RootNodes = SCS->GetRootNodes();
|
||||
if (RootNodes.Contains(NodeToRemove) && NodeToRemove->GetChildNodes().Num() > 0)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Cannot remove '%s' — it is a root component with %d child(ren). "
|
||||
UMCPServer::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),
|
||||
NodeToRemove->GetChildNodes().Num());
|
||||
@@ -87,7 +88,7 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Removed component %s.%s\n"),
|
||||
UMCPServer::Printf(TEXT("Removed component %s.%s\n"),
|
||||
*RemovedName,
|
||||
bSaved ? TEXT("") : TEXT(" WARNING: save failed."));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPAssets.h"
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
return TEXT("Remove a parameter from a function or custom event in a Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -68,11 +69,11 @@ public:
|
||||
|
||||
if (!EntryNode)
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Function or event '%s' not found.\nAvailable:\n"), *FunctionName);
|
||||
UMCPServer::Printf(TEXT("Error: Function or event '%s' not found.\nAvailable:\n"), *FunctionName);
|
||||
for (UK2Node_FunctionEntry* FE : MCPUtils::AllNodes<UK2Node_FunctionEntry>(BP))
|
||||
Result.Appendf(TEXT(" function: %s\n"), *MCPUtils::FormatName(FE->GetGraph()));
|
||||
UMCPServer::Printf(TEXT(" function: %s\n"), *MCPUtils::FormatName(FE->GetGraph()));
|
||||
for (UK2Node_CustomEvent* CE : MCPUtils::AllNodes<UK2Node_CustomEvent>(BP))
|
||||
Result.Appendf(TEXT(" event: %s\n"), *MCPUtils::FormatName(CE));
|
||||
UMCPServer::Printf(TEXT(" event: %s\n"), *MCPUtils::FormatName(CE));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,11 +91,11 @@ public:
|
||||
|
||||
if (RemovedIndex == INDEX_NONE)
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Parameter '%s' not found on %s.\nAvailable:\n"),
|
||||
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())
|
||||
Result.Appendf(TEXT(" %s\n"), *PinInfo->PinName.ToString());
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *PinInfo->PinName.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,8 +109,8 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Removed parameter '%s' from %s.\n"), *ParamName, *MCPUtils::FormatName(EntryNode));
|
||||
UMCPServer::Printf(TEXT("Removed parameter '%s' from %s.\n"), *ParamName, *MCPUtils::FormatName(EntryNode));
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("Warning: save failed.\n"));
|
||||
UMCPServer::Print(TEXT("Warning: save failed.\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
"Optionally preserve the function graphs as regular functions.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
FTopLevelAssetPath InterfacePath = FoundInterface->GetClassPathName();
|
||||
FBlueprintEditorUtils::RemoveInterface(BP, InterfacePath, PreserveFunctions);
|
||||
|
||||
Result.Appendf(TEXT("Removed interface %s\n"), *MCPUtils::FormatName(FoundInterface));
|
||||
UMCPServer::Printf(TEXT("Removed interface %s\n"), *MCPUtils::FormatName(FoundInterface));
|
||||
if (PreserveFunctions)
|
||||
Result.Append(TEXT("Function graphs preserved as regular functions.\n"));
|
||||
UMCPServer::Print(TEXT("Function graphs preserved as regular functions.\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -30,7 +31,7 @@ public:
|
||||
return TEXT("Remove a member variable from a Blueprint.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||
@@ -50,11 +51,11 @@ public:
|
||||
|
||||
if (!Found)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Variable '%s' not found in %s.\nAvailable variables:\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: Variable '%s' not found in %s.\nAvailable variables:\n"),
|
||||
*VariableName, *MCPUtils::FormatName(BP));
|
||||
for (const FBPVariableDescription& Var : BP->NewVariables)
|
||||
{
|
||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(Var));
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *MCPUtils::FormatName(Var));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
FBlueprintEditorUtils::RemoveMemberVariable(BP, VarFName);
|
||||
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
Result.Appendf(TEXT("Removed variable %s from %s.%s\n"),
|
||||
UMCPServer::Printf(TEXT("Removed variable %s from %s.%s\n"),
|
||||
*VarFName.ToString(), *MCPUtils::FormatName(BP),
|
||||
bSaved ? TEXT("") : TEXT(" WARNING: save failed."));
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
return TEXT("Change a Blueprint's parent class. Accepts C++ class names or Blueprint names.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Load Blueprint
|
||||
MCPAssets<UBlueprint> Assets;
|
||||
@@ -66,9 +66,9 @@ public:
|
||||
FKismetEditorUtilities::CompileBlueprint(BP);
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Reparented %s: %s -> %s\n"),
|
||||
UMCPServer::Printf(TEXT("Reparented %s: %s -> %s\n"),
|
||||
*MCPUtils::FormatName(BP), *OldParentName, *MCPUtils::FormatName(NewParentClassObj));
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("Warning: save failed\n"));
|
||||
UMCPServer::Print(TEXT("Warning: save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
return TEXT("List all Blueprint assets in the project, with optional filtering by name, parent class, or type.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UObject> Assets;
|
||||
Assets.NoScans().Substring(Query).Limit(500);
|
||||
@@ -73,13 +74,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("%30s %s\n"), *ParentClassName, *Asset.PackageName.ToString());
|
||||
UMCPServer::Printf(TEXT("%30s %s\n"), *ParentClassName, *Asset.PackageName.ToString());
|
||||
Count++;
|
||||
}
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
Result.Append(TEXT("No blueprint assets found.\n"));
|
||||
UMCPServer::Print(TEXT("No blueprint assets found.\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -41,7 +42,7 @@ public:
|
||||
return TEXT("Search across all Blueprint graphs for nodes matching a query string.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
int32 Limit = (MaxResults > 0) ? FMath::Clamp(MaxResults, 1, 200) : 50;
|
||||
int32 Count = 0;
|
||||
@@ -85,15 +86,15 @@ public:
|
||||
if (!bMatch) continue;
|
||||
|
||||
Count++;
|
||||
Result.Appendf(TEXT("blueprint: %s\n"), *MCPUtils::FormatName(BP));
|
||||
Result.Appendf(TEXT(" graph: %s\n"), *MCPUtils::FormatName(Node->GetGraph()));
|
||||
Result.Appendf(TEXT(" node: %s\n"), *MCPUtils::FormatName(Node));
|
||||
Result.Appendf(TEXT(" class: %s\n"), *MCPUtils::FormatName(Node->GetClass()));
|
||||
if (!FuncName.IsEmpty()) Result.Appendf(TEXT(" function: %s\n"), *FuncName);
|
||||
if (!EventName.IsEmpty()) Result.Appendf(TEXT(" event: %s\n"), *EventName);
|
||||
if (!VarName.IsEmpty()) Result.Appendf(TEXT(" variable: %s\n"), *VarName);
|
||||
if (bIsLevelBP) Result.Append(TEXT(" level-blueprint: true\n"));
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT("blueprint: %s\n"), *MCPUtils::FormatName(BP));
|
||||
UMCPServer::Printf(TEXT(" graph: %s\n"), *MCPUtils::FormatName(Node->GetGraph()));
|
||||
UMCPServer::Printf(TEXT(" node: %s\n"), *MCPUtils::FormatName(Node));
|
||||
UMCPServer::Printf(TEXT(" class: %s\n"), *MCPUtils::FormatName(Node->GetClass()));
|
||||
if (!FuncName.IsEmpty()) UMCPServer::Printf(TEXT(" function: %s\n"), *FuncName);
|
||||
if (!EventName.IsEmpty()) UMCPServer::Printf(TEXT(" event: %s\n"), *EventName);
|
||||
if (!VarName.IsEmpty()) UMCPServer::Printf(TEXT(" variable: %s\n"), *VarName);
|
||||
if (bIsLevelBP) UMCPServer::Print(TEXT(" level-blueprint: true\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,7 +121,7 @@ public:
|
||||
SearchBlueprint(LevelBP, true);
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Results: %d\n"), Count);
|
||||
if (Count >= Limit) Result.Appendf(TEXT("(limit %d reached, use MaxResults to increase)\n"), Limit);
|
||||
UMCPServer::Printf(TEXT("Results: %d\n"), Count);
|
||||
if (Count >= Limit) UMCPServer::Printf(TEXT("(limit %d reached, use MaxResults to increase)\n"), Limit);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "UObject/UObjectIterator.h"
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
"Returns class names, parent class, package, and flags.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
Limit = FMath::Clamp(Limit, 1, 500);
|
||||
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
}
|
||||
if (!ParentClassObj)
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Parent class '%s' not found\n"), *ParentClass);
|
||||
UMCPServer::Printf(TEXT("Error: Parent class '%s' not found\n"), *ParentClass);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -78,16 +79,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Found %d classes"), TotalMatched);
|
||||
UMCPServer::Printf(TEXT("Found %d classes"), TotalMatched);
|
||||
if (TotalMatched > Limit)
|
||||
{
|
||||
Result.Appendf(TEXT(" (showing %d)"), Limit);
|
||||
UMCPServer::Printf(TEXT(" (showing %d)"), Limit);
|
||||
}
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
|
||||
for (UClass* Class : Matches)
|
||||
{
|
||||
Result.Appendf(TEXT(" %s"), *MCPUtils::FormatName(Class));
|
||||
UMCPServer::Printf(TEXT(" %s"), *MCPUtils::FormatName(Class));
|
||||
|
||||
// Flags
|
||||
TStringBuilder<64> Flags;
|
||||
@@ -97,15 +98,15 @@ public:
|
||||
if (Class->ClassGeneratedBy) Flags.Append(TEXT(" Blueprint"));
|
||||
if (Flags.Len() > 0)
|
||||
{
|
||||
Result.Appendf(TEXT(" [%s]"), Flags.ToString() + 1); // skip leading space
|
||||
UMCPServer::Printf(TEXT(" [%s]"), Flags.ToString() + 1); // skip leading space
|
||||
}
|
||||
|
||||
if (Class->GetSuperClass())
|
||||
{
|
||||
Result.Appendf(TEXT(" : %s"), *MCPUtils::FormatName(Class->GetSuperClass()));
|
||||
UMCPServer::Printf(TEXT(" : %s"), *MCPUtils::FormatName(Class->GetSuperClass()));
|
||||
}
|
||||
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Class_ShowProperties.generated.h"
|
||||
@@ -27,16 +28,16 @@ public:
|
||||
return TEXT("List properties on a UClass, including type, owning class, and property flags.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
UClass* FoundClass = MCPUtils::FindClassByName(ClassName);
|
||||
if (!FoundClass)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Class '%s' not found\n"), *ClassName);
|
||||
UMCPServer::Printf(TEXT("ERROR: Class '%s' not found\n"), *ClassName);
|
||||
return;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Properties of %s:\n"), *MCPUtils::FormatName(FoundClass));
|
||||
UMCPServer::Printf(TEXT("Properties of %s:\n"), *MCPUtils::FormatName(FoundClass));
|
||||
|
||||
int32 Count = 0;
|
||||
for (TFieldIterator<FProperty> PropIt(FoundClass); PropIt; ++PropIt)
|
||||
@@ -61,18 +62,18 @@ public:
|
||||
if (Prop->HasAnyPropertyFlags(CPF_RepNotify)) Flags.Append(TEXT(" RepNotify"));
|
||||
|
||||
UClass* OwnerClass = Prop->GetOwnerClass();
|
||||
Result.Appendf(TEXT(" %s %s"), *MCPUtils::FormatPropertyType(Prop), *PropName);
|
||||
UMCPServer::Printf(TEXT(" %s %s"), *MCPUtils::FormatPropertyType(Prop), *PropName);
|
||||
if (OwnerClass && OwnerClass != FoundClass)
|
||||
Result.Appendf(TEXT(" [%s]"), *MCPUtils::FormatName(OwnerClass));
|
||||
UMCPServer::Printf(TEXT(" [%s]"), *MCPUtils::FormatName(OwnerClass));
|
||||
if (Flags.Len() > 0)
|
||||
Result.Appendf(TEXT(" (%s)"), Flags.ToString() + 1); // skip leading space
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT(" (%s)"), Flags.ToString() + 1); // skip leading space
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
Count++;
|
||||
}
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
Result.Append(TEXT("No properties found.\n"));
|
||||
UMCPServer::Print(TEXT("No properties found.\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "Editor.h"
|
||||
#include "Subsystems/AssetEditorSubsystem.h"
|
||||
@@ -22,19 +23,19 @@ public:
|
||||
return TEXT("List all currently open asset editors, showing which has focus and whether they have unsaved changes.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
|
||||
if (!Sub)
|
||||
{
|
||||
Result.Append(TEXT("Error: AssetEditorSubsystem not available\n"));
|
||||
UMCPServer::Print(TEXT("Error: AssetEditorSubsystem not available\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
TArray<UObject*> EditedAssets = Sub->GetAllEditedAssets();
|
||||
if (EditedAssets.IsEmpty())
|
||||
{
|
||||
Result.Append(TEXT("No asset editors are open.\n"));
|
||||
UMCPServer::Print(TEXT("No asset editors are open.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -42,7 +43,7 @@ public:
|
||||
{
|
||||
bool bDirty = Asset->GetOutermost()->IsDirty();
|
||||
|
||||
Result.Appendf(TEXT(" %s%s\n"),
|
||||
UMCPServer::Printf(TEXT(" %s%s\n"),
|
||||
bDirty ? TEXT("[unsaved] ") : TEXT(""),
|
||||
*Asset->GetPathName());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "Editor.h"
|
||||
@@ -26,7 +27,7 @@ public:
|
||||
return TEXT("Open an asset in its editor and bring it to focus.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UObject* Obj = F.Walk(Path).Cast<UObject>();
|
||||
@@ -35,13 +36,13 @@ public:
|
||||
UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
|
||||
if (!Sub)
|
||||
{
|
||||
Result.Append(TEXT("Error: AssetEditorSubsystem not available\n"));
|
||||
UMCPServer::Print(TEXT("Error: AssetEditorSubsystem not available\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Sub->OpenEditorForAsset(Obj))
|
||||
Result.Appendf(TEXT("Opened editor for %s\n"), *Obj->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Opened editor for %s\n"), *Obj->GetPathName());
|
||||
else
|
||||
Result.Appendf(TEXT("Error: Could not open editor for %s\n"), *Obj->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Error: Could not open editor for %s\n"), *Obj->GetPathName());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -32,7 +33,7 @@ public:
|
||||
return TEXT("Create a new UserDefinedEnum asset with the specified values.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -64,8 +65,8 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(NewEnum);
|
||||
|
||||
Result.Appendf(TEXT("Created %s with %d values\n"), *NewEnum->GetPathName(), EnumValues.Num());
|
||||
UMCPServer::Printf(TEXT("Created %s with %d values\n"), *NewEnum->GetPathName(), EnumValues.Num());
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Package save failed\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -49,7 +50,7 @@ public:
|
||||
"Use GraphNodeSearchTypes first to find the exact action name.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
||||
@@ -68,13 +69,13 @@ public:
|
||||
TArray<TSharedPtr<FEdGraphSchemaAction>> Matches = MCPUtils::SearchGraphActions(TargetGraph, Entry.ActionName, 0, /*ExactMatch=*/true);
|
||||
if (Matches.Num() == 0)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: No action found matching '%s'. Use GraphNodeSearchTypes to find available actions.\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: No action found matching '%s'. Use GraphNodeSearchTypes to find available actions.\n"),
|
||||
*Entry.ActionName);
|
||||
continue;
|
||||
}
|
||||
if (Matches.Num() > 1)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Ambiguous: %d actions match '%s'.\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: Ambiguous: %d actions match '%s'.\n"),
|
||||
Matches.Num(), *Entry.ActionName);
|
||||
continue;
|
||||
}
|
||||
@@ -84,18 +85,18 @@ public:
|
||||
UEdGraphNode* NewNode = Matches[0]->PerformAction(TargetGraph, nullptr, Location, /*bSelectNewNode=*/false);
|
||||
if (!NewNode)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: PerformAction returned null for '%s'.\n"), *Entry.ActionName);
|
||||
UMCPServer::Printf(TEXT("ERROR: PerformAction returned null for '%s'.\n"), *Entry.ActionName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!NewNode->NodeGuid.IsValid())
|
||||
NewNode->CreateNewGuid();
|
||||
|
||||
Result.Appendf(TEXT("Spawned: %s (%s)\n"),
|
||||
UMCPServer::Printf(TEXT("Spawned: %s (%s)\n"),
|
||||
*MCPUtils::FormatName(NewNode), *MCPUtils::FormatName(NewNode->GetClass()));
|
||||
SuccessCount++;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Spawned %d/%d nodes.\n"), SuccessCount, TotalCount);
|
||||
UMCPServer::Printf(TEXT("Spawned %d/%d nodes.\n"), SuccessCount, TotalCount);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
"Cannot delete undeletable nodes (entry points, root nodes, etc).");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>();
|
||||
@@ -63,6 +63,6 @@ public:
|
||||
Graph->RemoveNode(FoundNode);
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Deleted node '%s' from graph '%s'.\n"), *NodeTitle, *GraphName);
|
||||
UMCPServer::Printf(TEXT("Deleted node '%s' from graph '%s'.\n"), *NodeTitle, *GraphName);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -39,7 +40,7 @@ public:
|
||||
"Connections are not preserved on the duplicates.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
|
||||
if (Nodes.Array.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Nodes array is empty\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Nodes array is empty\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
}
|
||||
if (!Found)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Node '%s' not found in graph\n"), *Name);
|
||||
UMCPServer::Printf(TEXT("ERROR: Node '%s' not found in graph\n"), *Name);
|
||||
continue;
|
||||
}
|
||||
SourceNodes.Add(Found);
|
||||
@@ -81,7 +82,7 @@ public:
|
||||
UEdGraphNode* NewNode = DuplicateObject<UEdGraphNode>(SourceNode, TargetGraph);
|
||||
if (!NewNode)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Failed to duplicate %s\n"), *MCPUtils::FormatName(SourceNode));
|
||||
UMCPServer::Printf(TEXT("ERROR: Failed to duplicate %s\n"), *MCPUtils::FormatName(SourceNode));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -96,7 +97,7 @@ public:
|
||||
}
|
||||
|
||||
TargetGraph->AddNode(NewNode, false, false);
|
||||
Result.Appendf(TEXT("Duplicated: %s -> %s\n"), *MCPUtils::FormatName(SourceNode), *MCPUtils::FormatName(NewNode));
|
||||
UMCPServer::Printf(TEXT("Duplicated: %s -> %s\n"), *MCPUtils::FormatName(SourceNode), *MCPUtils::FormatName(NewNode));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -26,14 +27,14 @@ public:
|
||||
return TEXT("Get the comment text and bubble visibility of a node.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>();
|
||||
if (!FoundNode) return;
|
||||
|
||||
Result.Appendf(TEXT("Node: %s\n"), *MCPUtils::FormatName(FoundNode));
|
||||
Result.Appendf(TEXT("Comment: %s\n"), *FoundNode->NodeComment);
|
||||
Result.Appendf(TEXT("BubbleVisible: %s\n"), FoundNode->bCommentBubbleVisible ? TEXT("true") : TEXT("false"));
|
||||
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"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
"Returns full action names for use with GraphNodeCreate.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
int32 ClampedMax = FMath::Clamp(MaxResults, 1, 500);
|
||||
|
||||
@@ -47,16 +48,16 @@ public:
|
||||
|
||||
for (const TSharedPtr<FEdGraphSchemaAction>& Action : Actions)
|
||||
{
|
||||
Result.Appendf(TEXT("%s\n"), *MCPUtils::ActionFullName(Action));
|
||||
UMCPServer::Printf(TEXT("%s\n"), *MCPUtils::ActionFullName(Action));
|
||||
}
|
||||
|
||||
if (Actions.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("No matching node types found.\n"));
|
||||
UMCPServer::Print(TEXT("No matching node types found.\n"));
|
||||
}
|
||||
else if (Actions.Num() >= ClampedMax)
|
||||
{
|
||||
Result.Appendf(TEXT("WARNING: Reached limit of %d results. Refine your query or increase MaxResults.\n"), ClampedMax);
|
||||
UMCPServer::Printf(TEXT("WARNING: Reached limit of %d results. Refine your query or increase MaxResults.\n"), ClampedMax);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
return TEXT("Set a node's comment text. Makes the comment bubble visible if non-empty.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>();
|
||||
@@ -44,6 +45,6 @@ public:
|
||||
FoundNode->bCommentBubblePinned = true;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Comment set on %s\n"), *MCPUtils::FormatName(FoundNode));
|
||||
UMCPServer::Printf(TEXT("Comment set on %s\n"), *MCPUtils::FormatName(FoundNode));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,8 +53,7 @@ public:
|
||||
// K2 graphs: set pin default values.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void HandleK2Entry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj, const UEdGraphSchema_K2* K2Schema,
|
||||
FStringBuilderBase& Result)
|
||||
void HandleK2Entry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj, const UEdGraphSchema_K2* K2Schema)
|
||||
{
|
||||
MCPFetcher F(GraphObj);
|
||||
UEdGraphPin* Pin = F.Node(Entry.Node).Pin(Entry.Name).Cast<UEdGraphPin>();
|
||||
@@ -64,7 +63,7 @@ public:
|
||||
|
||||
if (Pin->Direction != EGPD_Input)
|
||||
{
|
||||
Result.Appendf(TEXT("error: %s is an output pin\n"), *MCPUtils::FormatName(Pin));
|
||||
UMCPServer::Printf(TEXT("error: %s is an output pin\n"), *MCPUtils::FormatName(Pin));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ public:
|
||||
FString Error = K2Schema->IsPinDefaultValid(Pin, UseDefaultValue, UseDefaultObject, UseDefaultText);
|
||||
if (!Error.IsEmpty())
|
||||
{
|
||||
Result.Appendf(TEXT("error: %s: %s\n"), *MCPUtils::FormatName(Pin), *Error);
|
||||
UMCPServer::Printf(TEXT("error: %s: %s\n"), *MCPUtils::FormatName(Pin), *Error);
|
||||
return;
|
||||
}
|
||||
UMCPServer::AddTouchedObject(Node);
|
||||
@@ -88,8 +87,7 @@ public:
|
||||
// Material graphs: set material expression properties.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void HandleMaterialEntry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj,
|
||||
FStringBuilderBase& Result)
|
||||
void HandleMaterialEntry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj)
|
||||
{
|
||||
MCPFetcher F(GraphObj);
|
||||
UEdGraphNode* Node = F.Node(Entry.Node).Cast<UEdGraphNode>();
|
||||
@@ -106,7 +104,7 @@ public:
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Fetch the graph once.
|
||||
MCPFetcher GraphFetcher;
|
||||
@@ -119,7 +117,7 @@ public:
|
||||
|
||||
if (!K2Schema && !MGSchema)
|
||||
{
|
||||
Result.Appendf(TEXT("error: unsupported graph schema %s\n"), *Schema->GetClass()->GetName());
|
||||
UMCPServer::Printf(TEXT("error: unsupported graph schema %s\n"), *Schema->GetClass()->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -130,11 +128,11 @@ public:
|
||||
continue;
|
||||
|
||||
if (K2Schema)
|
||||
HandleK2Entry(Entry, GraphObj, K2Schema, Result);
|
||||
HandleK2Entry(Entry, GraphObj, K2Schema);
|
||||
else if (MGSchema)
|
||||
HandleMaterialEntry(Entry, GraphObj, Result);
|
||||
HandleMaterialEntry(Entry, GraphObj);
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Done.\n"));
|
||||
UMCPServer::Printf(TEXT("Done.\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -46,7 +47,7 @@ public:
|
||||
return TEXT("Reposition one or more nodes in a Blueprint graph.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||
@@ -65,10 +66,10 @@ public:
|
||||
|
||||
Node->NodePosX = Entry.X;
|
||||
Node->NodePosY = Entry.Y;
|
||||
Result.Appendf(TEXT("Moved %s to (%d, %d)\n"), *MCPUtils::FormatName(Node), Entry.X, Entry.Y);
|
||||
UMCPServer::Printf(TEXT("Moved %s to (%d, %d)\n"), *MCPUtils::FormatName(Node), Entry.X, Entry.Y);
|
||||
SuccessCount++;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Moved %d/%d nodes.\n"), SuccessCount, Nodes.Array.Num());
|
||||
UMCPServer::Printf(TEXT("Moved %d/%d nodes.\n"), SuccessCount, Nodes.Array.Num());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
return TEXT("Connect pins between nodes in a graph (Blueprint or Material).");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraph* G = F.Walk(Graph).ToGraph().Cast<UEdGraph>();
|
||||
@@ -72,7 +73,7 @@ public:
|
||||
const FPinConnectionResponse Response = Schema->CanCreateConnection(SourcePin, TargetPin);
|
||||
if (Response.Response == CONNECT_RESPONSE_DISALLOW)
|
||||
{
|
||||
Result.Appendf(TEXT("error: Cannot connect %s.%s to %s.%s: %s\n"),
|
||||
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),
|
||||
*Response.Message.ToString());
|
||||
@@ -83,6 +84,6 @@ public:
|
||||
SuccessCount++;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Connected %d/%d pins.\n"), SuccessCount, TotalCount);
|
||||
UMCPServer::Printf(TEXT("Connected %d/%d pins.\n"), SuccessCount, TotalCount);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
"Can disconnect a specific link or all links on a pin.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UEdGraph* G = F.Walk(Graph).ToGraph().Cast<UEdGraph>();
|
||||
@@ -73,7 +74,7 @@ public:
|
||||
|
||||
if (!Pin->LinkedTo.Contains(Target))
|
||||
{
|
||||
Result.Appendf(TEXT("Error: %s.%s is not connected to %s.%s\n"),
|
||||
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));
|
||||
continue;
|
||||
@@ -91,14 +92,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Disconnected %d link(s) from %s.%s\n"),
|
||||
UMCPServer::Printf(TEXT("Disconnected %d link(s) from %s.%s\n"),
|
||||
DisconnectedCount,
|
||||
*MCPUtils::FormatName(Pin->GetOwningNode()), *MCPUtils::FormatName(Pin));
|
||||
SuccessCount++;
|
||||
TotalDisconnected += DisconnectedCount;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Done: %d/%d succeeded, %d links broken.\n"),
|
||||
UMCPServer::Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"),
|
||||
SuccessCount, Disconnections.Array.Num(), TotalDisconnected);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
"If given a blueprint or material, dumps all graphs. If given a specific graph, dumps only that one.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
F.Walk(Path);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
return TEXT("Create a new UMaterialFunction asset with an optional description.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -46,8 +47,8 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(MF);
|
||||
|
||||
Result.Appendf(TEXT("Created %s\n"), *MF->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Created %s\n"), *MF->GetPathName());
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Package save failed\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
return TEXT("Remove a parameter override from a Material Instance, reverting it to the parent material's value.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UMaterialInstanceConstant* MI = F.Asset(Path).Cast<UMaterialInstanceConstant>();
|
||||
@@ -66,13 +67,13 @@ public:
|
||||
|
||||
if (Removed == 0)
|
||||
{
|
||||
Result.Appendf(TEXT("No override found for parameter '%s' (association=%s layer=%d) on %s"),
|
||||
UMCPServer::Printf(TEXT("No override found for parameter '%s' (association=%s layer=%d) on %s"),
|
||||
*Parameter, *ParameterAssociation, ParameterLayer, *MCPUtils::FormatName(MI));
|
||||
return;
|
||||
}
|
||||
|
||||
MCPUtils::SaveGenericPackage(MI);
|
||||
Result.Appendf(TEXT("Cleared override for '%s' on %s\n"),
|
||||
UMCPServer::Printf(TEXT("Cleared override for '%s' on %s\n"),
|
||||
*Parameter, *MCPUtils::FormatName(MI));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
return TEXT("Create a new Material Instance Constant asset with a specified parent material.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
|
||||
if (!ParentMaterialObj)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Parent material '%s' not found\n"), *ParentMaterial);
|
||||
UMCPServer::Printf(TEXT("ERROR: Parent material '%s' not found\n"), *ParentMaterial);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,14 +78,14 @@ public:
|
||||
// Save.
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(MI);
|
||||
|
||||
Result.Appendf(TEXT("Created %s\n"), *MI->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Created %s\n"), *MI->GetPathName());
|
||||
if (UMaterialInstance* ParentMI = Cast<UMaterialInstance>(ParentMaterialObj))
|
||||
Result.Appendf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMI));
|
||||
UMCPServer::Printf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMI));
|
||||
else if (UMaterial* ParentMat = Cast<UMaterial>(ParentMaterialObj))
|
||||
Result.Appendf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMat));
|
||||
UMCPServer::Printf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMat));
|
||||
else
|
||||
Result.Appendf(TEXT("Parent: %s\n"), *ParentMaterialObj->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Parent: %s\n"), *ParentMaterialObj->GetPathName());
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Package save failed\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -27,7 +28,7 @@ public:
|
||||
return TEXT("List all parameters on a Material Instance, showing current values and which are overridden.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UMaterialInstanceConstant* MI = F.Asset(Path).Cast<UMaterialInstanceConstant>();
|
||||
@@ -40,8 +41,8 @@ public:
|
||||
for (auto& [Info, Meta] : AllParams)
|
||||
{
|
||||
if (!Meta.bOverride) continue;
|
||||
if (!bHasOverrides) { Result.Append(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
|
||||
MCPUtils::FormatMaterialParameter(Result, Info, Meta);
|
||||
if (!bHasOverrides) { UMCPServer::Print(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
|
||||
MCPUtils::FormatMaterialParameter(Info, Meta);
|
||||
}
|
||||
|
||||
// Inherited (non-overridden) parameters.
|
||||
@@ -49,8 +50,8 @@ public:
|
||||
for (auto& [Info, Meta] : AllParams)
|
||||
{
|
||||
if (Meta.bOverride) continue;
|
||||
if (!bHasInherited) { Result.Append(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
|
||||
MCPUtils::FormatMaterialParameter(Result, Info, Meta);
|
||||
if (!bHasInherited) { UMCPServer::Print(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
|
||||
MCPUtils::FormatMaterialParameter(Info, Meta);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -40,7 +41,7 @@ public:
|
||||
return TEXT("Set a parameter override on a Material Instance.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UMaterialInstanceConstant* MI = F.Asset(Path).Cast<UMaterialInstanceConstant>();
|
||||
@@ -59,13 +60,13 @@ public:
|
||||
FMaterialParameterMetadata* Found = AllParams.Find(ParamID);
|
||||
if (!Found)
|
||||
{
|
||||
Result.Appendf(TEXT("No parameter named '%s' with association=%s layer=%d"),
|
||||
UMCPServer::Printf(TEXT("No parameter named '%s' with association=%s layer=%d"),
|
||||
*Parameter, *ParameterAssociation, ParameterLayer);
|
||||
return;
|
||||
}
|
||||
if (Found->PrimitiveDataIndex != INDEX_NONE)
|
||||
{
|
||||
Result.Appendf(TEXT("Parameter '%s' uses custom primitive data and cannot be set on a material instance"), *Parameter);
|
||||
UMCPServer::Printf(TEXT("Parameter '%s' uses custom primitive data and cannot be set on a material instance"), *Parameter);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -78,7 +79,7 @@ public:
|
||||
float ScalarValue;
|
||||
if (!FDefaultValueHelper::ParseFloat(Value, ScalarValue))
|
||||
{
|
||||
Result.Appendf(TEXT("Failed to parse '%s' as a float"), *Value);
|
||||
UMCPServer::Printf(TEXT("Failed to parse '%s' as a float"), *Value);
|
||||
return;
|
||||
}
|
||||
MI->SetScalarParameterValueEditorOnly(ParamID, ScalarValue);
|
||||
@@ -89,19 +90,19 @@ public:
|
||||
FLinearColor Color;
|
||||
if (!Color.InitFromString(Value))
|
||||
{
|
||||
Result.Appendf(TEXT("Failed to parse '%s' as a color/vector (expected format: '(R=1,G=0,B=0,A=1)')"), *Value);
|
||||
UMCPServer::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:
|
||||
Result.Appendf(TEXT("Parameters of type %d (see EMaterialParameterType) are not implemented"), (int)Type);
|
||||
UMCPServer::Printf(TEXT("Parameters of type %d (see EMaterialParameterType) are not implemented"), (int)Type);
|
||||
return;
|
||||
}
|
||||
MCPUtils::SaveGenericPackage(MI);
|
||||
|
||||
Result.Appendf(TEXT("Set '%s' = %s on %s\n"),
|
||||
UMCPServer::Printf(TEXT("Set '%s' = %s on %s\n"),
|
||||
*Parameter, *Value, *MCPUtils::FormatName(MI));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -26,7 +27,7 @@ public:
|
||||
return TEXT("Force recompile a material and check for compilation errors.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Load material
|
||||
MCPFetcher F;
|
||||
@@ -47,14 +48,14 @@ public:
|
||||
|
||||
if (Errors.IsEmpty())
|
||||
{
|
||||
Result.Appendf(TEXT("%s compiled successfully.\n"), *MCPUtils::FormatName(MaterialObj));
|
||||
UMCPServer::Printf(TEXT("%s compiled successfully.\n"), *MCPUtils::FormatName(MaterialObj));
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Appendf(TEXT("%s compiled with %d error(s):\n"), *MCPUtils::FormatName(MaterialObj), Errors.Num());
|
||||
UMCPServer::Printf(TEXT("%s compiled with %d error(s):\n"), *MCPUtils::FormatName(MaterialObj), Errors.Num());
|
||||
for (const FString& Err : Errors)
|
||||
{
|
||||
Result.Appendf(TEXT(" %s\n"), *Err);
|
||||
UMCPServer::Printf(TEXT(" %s\n"), *Err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -38,7 +39,7 @@ public:
|
||||
return TEXT("Create a new UMaterial asset with optional domain, blend mode, and two-sided settings.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -73,11 +74,11 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(MaterialObj);
|
||||
|
||||
Result.Appendf(TEXT("Created %s\n"), *MaterialObj->GetPathName());
|
||||
Result.Appendf(TEXT("Domain: %s\n"), *MCPUtils::EnumToString(MaterialObj->MaterialDomain, TEXT("MD_")));
|
||||
Result.Appendf(TEXT("BlendMode: %s\n"), *MCPUtils::EnumToString(MaterialObj->BlendMode, TEXT("BLEND_")));
|
||||
Result.Appendf(TEXT("TwoSided: %s\n"), MaterialObj->TwoSided ? TEXT("true") : TEXT("false"));
|
||||
UMCPServer::Printf(TEXT("Created %s\n"), *MaterialObj->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Domain: %s\n"), *MCPUtils::EnumToString(MaterialObj->MaterialDomain, TEXT("MD_")));
|
||||
UMCPServer::Printf(TEXT("BlendMode: %s\n"), *MCPUtils::EnumToString(MaterialObj->BlendMode, TEXT("BLEND_")));
|
||||
UMCPServer::Printf(TEXT("TwoSided: %s\n"), MaterialObj->TwoSided ? TEXT("true") : TEXT("false"));
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Package save failed\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
return TEXT("List all parameters on a Material, showing their default values.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UMaterial* Mat = F.Asset(Path).Cast<UMaterial>();
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
for (auto& [Info, Meta] : AllParams)
|
||||
{
|
||||
MCPUtils::FormatMaterialParameter(Result, Info, Meta);
|
||||
MCPUtils::FormatMaterialParameter(Info, Meta);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPProperty.h"
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
"showing current values and which properties are editable.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Resolve the path to an object and get its editable template.
|
||||
MCPFetcher F;
|
||||
@@ -70,9 +71,9 @@ public:
|
||||
for (const FString& Category : Categories)
|
||||
{
|
||||
if (Category.IsEmpty())
|
||||
Result.Append(TEXT("\nUncategorized:\n"));
|
||||
UMCPServer::Print(TEXT("\nUncategorized:\n"));
|
||||
else
|
||||
Result.Appendf(TEXT("\n%s:\n"), *Category);
|
||||
UMCPServer::Printf(TEXT("\n%s:\n"), *Category);
|
||||
|
||||
for (MCPProperty& P : ByCategory[Category])
|
||||
{
|
||||
@@ -83,7 +84,7 @@ public:
|
||||
ValueStr = ValueStr.Left(80) + TEXT("...");
|
||||
|
||||
bool bEditable = !P->HasAnyPropertyFlags(CPF_EditConst);
|
||||
Result.Appendf(TEXT(" %s %s %s = %s\n"),
|
||||
UMCPServer::Printf(TEXT(" %s %s %s = %s\n"),
|
||||
bEditable ? TEXT("editable") : TEXT("readonly"),
|
||||
*MCPUtils::FormatPropertyType(P.Prop),
|
||||
*PropName,
|
||||
@@ -92,6 +93,6 @@ public:
|
||||
}
|
||||
|
||||
if (Props.IsEmpty())
|
||||
Result.Append(TEXT(" (no blueprint-visible properties found)\n"));
|
||||
UMCPServer::Print(TEXT(" (no blueprint-visible properties found)\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPProperty.h"
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
return TEXT("Get the value of a single property on an object resolved via MCPFetcher path.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPFetcher F;
|
||||
UObject* Template = F.Walk(Path).Template().Cast<UObject>();
|
||||
@@ -38,7 +39,7 @@ public:
|
||||
MCPProperty P = MCPProperty::GetOneExactMatch(Template, CPF_Edit, Property);
|
||||
if (!P) return;
|
||||
|
||||
Result.Append(P.GetText());
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(P.GetText());
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPProperty.h"
|
||||
@@ -30,7 +31,7 @@ public:
|
||||
"Properties is a JSON object like {\"TwoSided\": \"true\", \"BlendMode\": \"BLEND_Translucent\"}.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Resolve the path to an object and get its editable template.
|
||||
MCPFetcher F;
|
||||
@@ -39,7 +40,7 @@ public:
|
||||
|
||||
if (!Properties.Json || Properties.Json->Values.Num() == 0)
|
||||
{
|
||||
Result.Append(TEXT("Error: No properties specified\n"));
|
||||
UMCPServer::Print(TEXT("Error: No properties specified\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
FString ValueStr;
|
||||
if (!Pair.Value->TryGetString(ValueStr))
|
||||
{
|
||||
Result.Appendf(TEXT("Error: Value for '%s' must be a string\n"), *Pair.Key);
|
||||
UMCPServer::Printf(TEXT("Error: Value for '%s' must be a string\n"), *Pair.Key);
|
||||
return;
|
||||
}
|
||||
Resolved.Emplace(P, ValueStr);
|
||||
@@ -71,8 +72,8 @@ public:
|
||||
// Save.
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(Template);
|
||||
|
||||
Result.Appendf(TEXT("Set %d/%d properties.\n"), SuccessCount, Properties.Json->Values.Num());
|
||||
UMCPServer::Printf(TEXT("Set %d/%d properties.\n"), SuccessCount, Properties.Json->Values.Num());
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("Warning: Save failed\n"));
|
||||
UMCPServer::Print(TEXT("Warning: Save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "ShowCommands.generated.h"
|
||||
|
||||
@@ -23,7 +24,7 @@ public:
|
||||
return TEXT("List all available commands with their descriptions.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
void EmitCommandList()
|
||||
{
|
||||
FString QueryLower = Query.ToLower();
|
||||
FString PrevGroup;
|
||||
@@ -39,40 +40,47 @@ public:
|
||||
if (Group != PrevGroup)
|
||||
{
|
||||
if (!PrevGroup.IsEmpty())
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
PrevGroup = Group;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
MCPUtils::FormatCommandHelp(Class, Result);
|
||||
MCPUtils::FormatCommandHelp(Class);
|
||||
continue;
|
||||
}
|
||||
Result.Append(ToolName);
|
||||
Result.Append(TEXT("("));
|
||||
UMCPServer::Print(ToolName);
|
||||
UMCPServer::Print(TEXT("("));
|
||||
bool bFirst = true;
|
||||
for (TFieldIterator<FProperty> PropIt(Class, EFieldIterationFlags::None); PropIt; ++PropIt)
|
||||
{
|
||||
if (!bFirst) Result.Append(TEXT(","));
|
||||
if (!bFirst) UMCPServer::Print(TEXT(","));
|
||||
bFirst = false;
|
||||
if (PropIt->HasMetaData(TEXT("Optional"))) Result.Append(TEXT("?"));
|
||||
Result.Append(MCPUtils::FormatPropertyType(*PropIt));
|
||||
Result.Append(TEXT(" "));
|
||||
Result.Append(MCPUtils::PropertyNameToJsonKey(PropIt->GetName()));
|
||||
if (PropIt->HasMetaData(TEXT("Optional"))) UMCPServer::Print(TEXT("?"));
|
||||
UMCPServer::Print(MCPUtils::FormatPropertyType(*PropIt));
|
||||
UMCPServer::Print(TEXT(" "));
|
||||
UMCPServer::Print(MCPUtils::PropertyNameToJsonKey(PropIt->GetName()));
|
||||
}
|
||||
Result.Append(TEXT(")\n"));
|
||||
UMCPServer::Print(TEXT(")\n"));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Handle() override
|
||||
{
|
||||
UMCPServer::Printf(TEXT("\n"));
|
||||
|
||||
EmitCommandList();
|
||||
|
||||
// Append Path documentation.
|
||||
Result.Append(TEXT("\n"));
|
||||
Result.Append(TEXT("Some commands take a Path parameter. A Path starts with an asset\n"));
|
||||
Result.Append(TEXT("package path (e.g. /Game/Widgets/WB_Hotkeys), followed by zero or\n"));
|
||||
Result.Append(TEXT("more comma-separated steps that navigate into the asset:\n"));
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("Some commands take a Path parameter. A Path starts with an asset\n"));
|
||||
UMCPServer::Print(TEXT("package path (e.g. /Game/Widgets/WB_Hotkeys), followed by zero or\n"));
|
||||
UMCPServer::Print(TEXT("more comma-separated steps that navigate into the asset:\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
for (const MCPFetcher::FWalker& W : MCPFetcher::GetWalkerTable())
|
||||
{
|
||||
Result.Appendf(TEXT(" %s — %s\n"), W.Key, W.Description);
|
||||
UMCPServer::Printf(TEXT(" %s — %s\n"), W.Key, W.Description);
|
||||
}
|
||||
Result.Append(TEXT("\nExample: /Game/Widgets/WB_Hotkeys,graph:EventGraph,node:Self_Reference_03,pin:Result\n"));
|
||||
UMCPServer::Print(TEXT("\nExample: /Game/Widgets/WB_Hotkeys,graph:EventGraph,node:Self_Reference_03,pin:Result\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPFetcher.h"
|
||||
@@ -49,7 +50,7 @@ public:
|
||||
"Optionally assign an animation asset to the state.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Resolve the anim blueprint
|
||||
MCPFetcher F;
|
||||
@@ -60,14 +61,14 @@ public:
|
||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||
if (!SMGraph)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for duplicate state name
|
||||
if (MCPUtils::FindStateByName(SMGraph, StateName))
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: State '%s' already exists in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
|
||||
UMCPServer::Printf(TEXT("ERROR: State '%s' already exists in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,7 +111,7 @@ public:
|
||||
FKismetEditorUtilities::CompileBlueprint(AnimBP);
|
||||
MCPUtils::SaveBlueprintPackage(AnimBP);
|
||||
|
||||
Result.Appendf(TEXT("Created state '%s' in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
|
||||
Result.Appendf(TEXT(" node: %s\n"), *MCPUtils::FormatName(NewState));
|
||||
UMCPServer::Printf(TEXT("Created state '%s' in %s\n"), *StateName, *MCPUtils::FormatName(SMGraph));
|
||||
UMCPServer::Printf(TEXT(" node: %s\n"), *MCPUtils::FormatName(NewState));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -48,7 +49,7 @@ public:
|
||||
return TEXT("Add a transition between two states in an animation state machine graph.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UAnimBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -57,7 +58,7 @@ public:
|
||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||
if (!SMGraph)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ public:
|
||||
FKismetEditorUtilities::CompileBlueprint(AnimBP);
|
||||
MCPUtils::SaveBlueprintPackage(AnimBP);
|
||||
|
||||
Result.Appendf(TEXT("Created transition %s -> %s: %s\n"),
|
||||
UMCPServer::Printf(TEXT("Created transition %s -> %s: %s\n"),
|
||||
*FromState, *ToState, *MCPUtils::FormatName(TransNode));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
return TEXT("Remove a state and its connected transitions from an animation state machine graph.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Fetch the state machine graph via MCPFetcher
|
||||
MCPFetcher F;
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
UBlueprint* BP = Cast<UBlueprint>(SMGraph->GetOuter()->GetOuter());
|
||||
if (!BP)
|
||||
{
|
||||
Result.Append(TEXT("ERROR: Could not find owning blueprint.\n"));
|
||||
UMCPServer::Print(TEXT("ERROR: Could not find owning blueprint.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ public:
|
||||
FKismetEditorUtilities::CompileBlueprint(BP);
|
||||
MCPUtils::SaveBlueprintPackage(BP);
|
||||
|
||||
Result.Appendf(TEXT("Removed state %s and %d transition(s).\n"),
|
||||
UMCPServer::Printf(TEXT("Removed state %s and %d transition(s).\n"),
|
||||
*MCPUtils::FormatName(StateNode), RemovedTransitions);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPFetcher.h"
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
return TEXT("Set or replace the animation sequence played by a state in an animation state machine.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Resolve the anim blueprint
|
||||
MCPFetcher F;
|
||||
@@ -54,7 +55,7 @@ public:
|
||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||
if (!SMGraph)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in %s\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
|
||||
if (!InnerGraph)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName);
|
||||
UMCPServer::Printf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,8 +103,8 @@ public:
|
||||
MCPUtils::SaveBlueprintPackage(AnimBP);
|
||||
|
||||
if (bCreatedNew)
|
||||
Result.Appendf(TEXT("Created sequence player in state '%s', assigned %s\n"), *StateName, *MCPUtils::FormatName(AnimSeq));
|
||||
UMCPServer::Printf(TEXT("Created sequence player in state '%s', assigned %s\n"), *StateName, *MCPUtils::FormatName(AnimSeq));
|
||||
else
|
||||
Result.Appendf(TEXT("Updated sequence player in state '%s' to %s\n"), *StateName, *MCPUtils::FormatName(AnimSeq));
|
||||
UMCPServer::Printf(TEXT("Updated sequence player in state '%s' to %s\n"), *StateName, *MCPUtils::FormatName(AnimSeq));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPFetcher.h"
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
"and optionally wire blueprint variables to the X and Y axis inputs.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Load the anim blueprint
|
||||
MCPAssets<UAnimBlueprint> Assets;
|
||||
@@ -62,13 +63,13 @@ public:
|
||||
|
||||
// Find the state machine graph and state
|
||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||
if (!SMGraph) { Result.Appendf(TEXT("ERROR: State machine graph '%s' not found\n"), *Graph); return; }
|
||||
if (!SMGraph) { UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found\n"), *Graph); return; }
|
||||
|
||||
UAnimStateNode* StateNode = MCPUtils::FindStateByName(SMGraph, StateName);
|
||||
if (!StateNode) return;
|
||||
|
||||
UEdGraph* InnerGraph = StateNode->GetBoundGraph();
|
||||
if (!InnerGraph) { Result.Appendf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName); return; }
|
||||
if (!InnerGraph) { UMCPServer::Printf(TEXT("ERROR: State '%s' has no bound graph\n"), *StateName); return; }
|
||||
|
||||
// Load the blend space asset
|
||||
MCPAssets<UBlendSpace> BlendSpaceAssets;
|
||||
@@ -100,17 +101,17 @@ public:
|
||||
ConnectToOutputPose(BSNode, InnerGraph);
|
||||
|
||||
// Wire X and Y variables if provided
|
||||
WireVariable(AnimBP, InnerGraph, BSNode, XVariable, TEXT("X"), Result);
|
||||
WireVariable(AnimBP, InnerGraph, BSNode, YVariable, TEXT("Y"), Result);
|
||||
WireVariable(AnimBP, InnerGraph, BSNode, XVariable, TEXT("X"));
|
||||
WireVariable(AnimBP, InnerGraph, BSNode, YVariable, TEXT("Y"));
|
||||
|
||||
// Compile and save
|
||||
FKismetEditorUtilities::CompileBlueprint(AnimBP);
|
||||
bool bSaved = MCPUtils::SaveBlueprintPackage(AnimBP);
|
||||
|
||||
Result.Appendf(TEXT("BlendSpacePlayer %s placed in state %s\n"),
|
||||
UMCPServer::Printf(TEXT("BlendSpacePlayer %s placed in state %s\n"),
|
||||
*MCPUtils::FormatName(BSNode), *StateName);
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Failed to save package\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Failed to save package\n"));
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -160,7 +161,7 @@ private:
|
||||
|
||||
void WireVariable(UAnimBlueprint* AnimBP, UEdGraph* InnerGraph,
|
||||
UAnimGraphNode_BlendSpacePlayer* BSNode, const FString& VarName,
|
||||
const TCHAR* PinName, FStringBuilderBase& Result)
|
||||
const TCHAR* PinName)
|
||||
{
|
||||
if (VarName.IsEmpty()) return;
|
||||
|
||||
@@ -185,7 +186,7 @@ private:
|
||||
}
|
||||
if (!bVarFound)
|
||||
{
|
||||
Result.Appendf(TEXT("WARNING: Variable '%s' not found, skipping %s wire\n"), *VarName, PinName);
|
||||
UMCPServer::Printf(TEXT("WARNING: Variable '%s' not found, skipping %s wire\n"), *VarName, PinName);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
return TEXT("Update properties on an existing transition between two states in an animation state machine.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPAssets<UAnimBlueprint> Assets;
|
||||
if (!Assets.Exact(Blueprint).ENone().ETwo().Load()) return;
|
||||
@@ -62,14 +63,14 @@ public:
|
||||
UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph);
|
||||
if (!SMGraph)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *MCPUtils::FormatName(AnimBP));
|
||||
return;
|
||||
}
|
||||
|
||||
UAnimStateTransitionNode* TransNode = MCPUtils::FindTransition(SMGraph, FromState, ToState);
|
||||
if (!TransNode)
|
||||
{
|
||||
Result.Appendf(TEXT("ERROR: Transition from '%s' to '%s' not found in graph '%s'\n"),
|
||||
UMCPServer::Printf(TEXT("ERROR: Transition from '%s' to '%s' not found in graph '%s'\n"),
|
||||
*FromState, *ToState, *Graph);
|
||||
return;
|
||||
}
|
||||
@@ -85,7 +86,7 @@ public:
|
||||
FKismetEditorUtilities::CompileBlueprint(AnimBP);
|
||||
MCPUtils::SaveBlueprintPackage(AnimBP);
|
||||
|
||||
Result.Appendf(TEXT("Updated transition %s -> %s: %s\n"),
|
||||
UMCPServer::Printf(TEXT("Updated transition %s -> %s: %s\n"),
|
||||
*FromState, *ToState, *MCPUtils::FormatName(TransNode));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPServer.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPUtils.h"
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
return TEXT("Create a new UserDefinedStruct asset with optional initial properties.");
|
||||
}
|
||||
|
||||
virtual void Handle(FStringBuilderBase& Result) override
|
||||
virtual void Handle() override
|
||||
{
|
||||
MCPPackageMaker Maker(AssetPath);
|
||||
if (!Maker.Ok()) return;
|
||||
@@ -88,10 +89,10 @@ public:
|
||||
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(NewStruct);
|
||||
|
||||
Result.Appendf(TEXT("Created %s\n"), *NewStruct->GetPathName());
|
||||
UMCPServer::Printf(TEXT("Created %s\n"), *NewStruct->GetPathName());
|
||||
if (PropsAdded > 0)
|
||||
Result.Appendf(TEXT("Properties added: %d\n"), PropsAdded);
|
||||
UMCPServer::Printf(TEXT("Properties added: %d\n"), PropsAdded);
|
||||
if (!bSaved)
|
||||
Result.Append(TEXT("WARNING: Package save failed\n"));
|
||||
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -260,57 +260,17 @@ TStatId UMCPServer::GetStatId() const
|
||||
|
||||
FString UMCPServer::HandleRequest(const FString& Line)
|
||||
{
|
||||
// Turn the request string into a JSON tree.
|
||||
TSharedPtr<FJsonObject> Request;
|
||||
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Line);
|
||||
FJsonSerializer::Deserialize(Reader, Request);
|
||||
if (!Request.IsValid())
|
||||
{
|
||||
return TEXT("Request is not valid JSON");
|
||||
}
|
||||
|
||||
// Extract the command from the request.
|
||||
FString Command;
|
||||
if (!Request->TryGetStringField(TEXT("command"), Command))
|
||||
{
|
||||
return TEXT("Request does not contain 'command' parameter");
|
||||
}
|
||||
Request->RemoveField(TEXT("command"));
|
||||
|
||||
// Find the handler UClass for the specified command.
|
||||
UClass** HandlerClass = MCPHandlerRegistry.Find(Command);
|
||||
if (!HandlerClass)
|
||||
{
|
||||
return FString::Printf(TEXT("Unknown command: %s"), *Command);
|
||||
}
|
||||
|
||||
// Make an object of the handler class.
|
||||
TStrongObjectPtr<UObject> HandlerObj(NewObject<UObject>(GetTransientPackage(), *HandlerClass));
|
||||
IMCPHandler* Handler = Cast<IMCPHandler>(HandlerObj.Get());
|
||||
|
||||
// Populate the handler object with the request parameters.
|
||||
HandlerOutput.Reset();
|
||||
if (!MCPUtils::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
||||
{
|
||||
HandlerOutput.Append(TEXT("\nUsage:\n"));
|
||||
MCPUtils::FormatCommandHelp(*HandlerClass, HandlerOutput);
|
||||
FString Result = HandlerOutput.ToString();
|
||||
HandlerOutput.Reset();
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Invoke the handler with log capture.
|
||||
LogCapture.CapturedErrors.Empty();
|
||||
LogCapture.bEnabled = true;
|
||||
HandlerOutput.Reset();
|
||||
Handler->Handle(HandlerOutput);
|
||||
|
||||
TryCallHandler(Line);
|
||||
|
||||
Notifier.SendNotifications();
|
||||
LogCapture.bEnabled = false;
|
||||
for (const FString& Msg : LogCapture.CapturedErrors)
|
||||
{
|
||||
HandlerOutput.Append(TEXT("LOG: "));
|
||||
HandlerOutput.Append(Msg);
|
||||
HandlerOutput.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT("UE_LOG: %s\n"), *Msg);
|
||||
}
|
||||
LogCapture.CapturedErrors.Empty();
|
||||
FString Result = HandlerOutput.ToString();
|
||||
@@ -322,6 +282,51 @@ FString UMCPServer::HandleRequest(const FString& Line)
|
||||
return Result;
|
||||
}
|
||||
|
||||
void UMCPServer::TryCallHandler(const FString &Line)
|
||||
{
|
||||
// Turn the request string into a JSON tree.
|
||||
TSharedPtr<FJsonObject> Request;
|
||||
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Line);
|
||||
FJsonSerializer::Deserialize(Reader, Request);
|
||||
if (!Request.IsValid())
|
||||
{
|
||||
UMCPServer::Printf(TEXT("Request is not valid JSON"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract the command from the request.
|
||||
FString Command;
|
||||
if (!Request->TryGetStringField(TEXT("command"), Command))
|
||||
{
|
||||
UMCPServer::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);
|
||||
if (!HandlerClass)
|
||||
{
|
||||
UMCPServer::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());
|
||||
|
||||
// Populate the handler object with the request parameters.
|
||||
if (!MCPUtils::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
||||
{
|
||||
UMCPServer::Printf(TEXT("\nUsage:\n\n"));
|
||||
MCPUtils::FormatCommandHelp(*HandlerClass);
|
||||
return;
|
||||
}
|
||||
|
||||
// Invoke the handler.
|
||||
Handler->Handle();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Connection Maintenance
|
||||
// ============================================================
|
||||
|
||||
@@ -813,7 +813,7 @@ bool MCPUtils::ParseMaterialParameterAssociation(const FString& Str, EMaterialPa
|
||||
return true;
|
||||
}
|
||||
|
||||
void MCPUtils::FormatMaterialParameter(FStringBuilderBase& Result, const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
|
||||
void MCPUtils::FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
|
||||
{
|
||||
// Association prefix for layer/blend parameters.
|
||||
FString Prefix;
|
||||
@@ -825,35 +825,35 @@ void MCPUtils::FormatMaterialParameter(FStringBuilderBase& Result, const FMateri
|
||||
switch (Meta.Value.Type)
|
||||
{
|
||||
case EMaterialParameterType::Scalar:
|
||||
Result.Appendf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
|
||||
UMCPServer::Printf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
|
||||
break;
|
||||
case EMaterialParameterType::Vector:
|
||||
{
|
||||
FLinearColor C = Meta.Value.AsLinearColor();
|
||||
Result.Appendf(TEXT(" %sVector \"%s\" = (R=%.3f, G=%.3f, B=%.3f, A=%.3f)\n"),
|
||||
UMCPServer::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();
|
||||
Result.Appendf(TEXT(" %sDoubleVector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
|
||||
UMCPServer::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());
|
||||
Result.Appendf(TEXT(" %sTexture \"%s\" = %s\n"),
|
||||
UMCPServer::Printf(TEXT(" %sTexture \"%s\" = %s\n"),
|
||||
*Prefix, *Info.Name.ToString(), Tex ? *MCPUtils::FormatName(Tex) : TEXT("None"));
|
||||
break;
|
||||
}
|
||||
case EMaterialParameterType::StaticSwitch:
|
||||
Result.Appendf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
|
||||
UMCPServer::Printf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
|
||||
*Prefix, *Info.Name.ToString(), Meta.Value.AsStaticSwitch() ? TEXT("true") : TEXT("false"));
|
||||
break;
|
||||
default:
|
||||
Result.Appendf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
|
||||
UMCPServer::Printf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1398,29 +1398,29 @@ TArray<FProperty*> MCPUtils::SearchProperties(UObject* Obj, const FString& Query
|
||||
// FormatCommandHelp — verbose description of one handler command
|
||||
// ============================================================
|
||||
|
||||
void MCPUtils::FormatCommandHelp(UClass* HandlerClass, FStringBuilderBase& Result)
|
||||
void MCPUtils::FormatCommandHelp(UClass* HandlerClass)
|
||||
{
|
||||
const IMCPHandler* Handler = Cast<IMCPHandler>(HandlerClass->GetDefaultObject());
|
||||
if (!Handler) return;
|
||||
|
||||
FString ToolName = GetHandlerName(HandlerClass);
|
||||
|
||||
Result.Append(TEXT("\n"));
|
||||
Result.Append(WrapText(Handler->GetDescription(), 80, TEXT("// ")));
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
UMCPServer::Print(WrapText(Handler->GetDescription(), 80, TEXT("// ")));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
|
||||
// Command signature line
|
||||
Result.Append(ToolName);
|
||||
Result.Append(TEXT("("));
|
||||
UMCPServer::Print(ToolName);
|
||||
UMCPServer::Print(TEXT("("));
|
||||
bool bFirst = true;
|
||||
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
|
||||
{
|
||||
if (!bFirst) Result.Append(TEXT(","));
|
||||
if (!bFirst) UMCPServer::Print(TEXT(","));
|
||||
bFirst = false;
|
||||
if (PropIt->HasMetaData(TEXT("Optional"))) Result.Append(TEXT("?"));
|
||||
Result.Append(PropertyNameToJsonKey(PropIt->GetName()));
|
||||
if (PropIt->HasMetaData(TEXT("Optional"))) UMCPServer::Print(TEXT("?"));
|
||||
UMCPServer::Print(PropertyNameToJsonKey(PropIt->GetName()));
|
||||
}
|
||||
Result.Append(TEXT(")\n"));
|
||||
UMCPServer::Print(TEXT(")\n"));
|
||||
|
||||
// parameter details
|
||||
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
|
||||
@@ -1431,10 +1431,10 @@ void MCPUtils::FormatCommandHelp(UClass* HandlerClass, FStringBuilderBase& Resul
|
||||
bool bOptional = Prop->HasMetaData(TEXT("Optional"));
|
||||
const FString& Desc = Prop->GetMetaData(TEXT("Description"));
|
||||
|
||||
Result.Appendf(TEXT(" %s %s%s"),
|
||||
UMCPServer::Printf(TEXT(" %s %s%s"),
|
||||
*Type, *Name, bOptional ? TEXT(" (optional)") : TEXT(""));
|
||||
if (!Desc.IsEmpty())
|
||||
Result.Appendf(TEXT(" — %s"), *Desc);
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT(" — %s"), *Desc);
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,5 +51,5 @@ public:
|
||||
virtual FString GetDescription() const = 0;
|
||||
|
||||
// Called after parameter fields have been populated from JSON.
|
||||
virtual void Handle(FStringBuilderBase& Result) {}
|
||||
virtual void Handle() {}
|
||||
};
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
|
||||
/** Print text to the handler output buffer. */
|
||||
static void Print(const TCHAR* Text) { GMCPServer->HandlerOutput.Append(Text); }
|
||||
static void Print(const FString& Text) { GMCPServer->HandlerOutput.Append(Text); }
|
||||
|
||||
/** Print formatted text to the handler output buffer. */
|
||||
template <typename FmtType, typename... ArgTypes>
|
||||
@@ -79,6 +80,7 @@ private:
|
||||
|
||||
// Handle a complete JSON line and return the response JSON
|
||||
FString HandleRequest(const FString& Line);
|
||||
void TryCallHandler(const FString &Line);
|
||||
|
||||
// ----- TCP server -----
|
||||
FSocket* ListenSocket = nullptr;
|
||||
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
// ----- Material Parameters -----
|
||||
static TMap<FMaterialParameterInfo, FMaterialParameterMetadata> GetMaterialParameters(UMaterialInterface* Material);
|
||||
static bool ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation);
|
||||
static void FormatMaterialParameter(FStringBuilderBase& Result, const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta);
|
||||
static void FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta);
|
||||
|
||||
// ----- Editable template -----
|
||||
static TArray<FProperty*> SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal);
|
||||
@@ -183,7 +183,7 @@ public:
|
||||
static TArray<UClass*> CollectHandlerClasses();
|
||||
static FString GetHandlerName(UClass* HandlerClass);
|
||||
static FString GetHandlerGroup(UClass* HandlerClass);
|
||||
static void FormatCommandHelp(UClass* HandlerClass, FStringBuilderBase& Result);
|
||||
static void FormatCommandHelp(UClass* HandlerClass);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user