Working on editing materials
This commit is contained in:
BIN
Content/Testing/M_Test.uasset
LFS
BIN
Content/Testing/M_Test.uasset
LFS
Binary file not shown.
@@ -11,14 +11,46 @@
|
||||
#include "K2Node_CallFunction.h"
|
||||
#include "K2Node_FunctionEntry.h"
|
||||
|
||||
static FString WrapText(const FString& Text, int32 ColLimit, const FString& Prefix)
|
||||
{
|
||||
FString Clean = Text;
|
||||
Clean.ReplaceInline(TEXT("\r\n"), TEXT("\n"));
|
||||
TArray<FString> Words;
|
||||
Clean.ParseIntoArrayWS(Words);
|
||||
|
||||
TStringBuilder<1024> Result;
|
||||
int32 Col = 0;
|
||||
for (const FString& Word : Words)
|
||||
{
|
||||
if (Col > 0 && Col + 1 + Word.Len() > ColLimit)
|
||||
{
|
||||
Result.Append(TEXT("\n"));
|
||||
Col = 0;
|
||||
}
|
||||
if (Col == 0)
|
||||
{
|
||||
Result.Append(Prefix);
|
||||
Col = Prefix.Len();
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Append(TEXT(" "));
|
||||
Col += 1;
|
||||
}
|
||||
Result.Append(Word);
|
||||
Col += Word.Len();
|
||||
}
|
||||
return Result.ToString();
|
||||
}
|
||||
|
||||
FlxBlueprintExporter::FlxBlueprintExporter(UEdGraph* InGraph)
|
||||
: Graph(InGraph)
|
||||
{
|
||||
SortNodes();
|
||||
AssignNodeNames();
|
||||
EmitLocalVariables();
|
||||
EmitNodeList();
|
||||
EmitDetails();
|
||||
EmitGraph();
|
||||
EmitComments();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -194,20 +226,11 @@ void FlxBlueprintExporter::SortNodes()
|
||||
}
|
||||
}
|
||||
|
||||
void FlxBlueprintExporter::AssignNodeNames()
|
||||
{
|
||||
// Node names are now computed on the fly by FormatNodeName.
|
||||
}
|
||||
|
||||
void FlxBlueprintExporter::EmitNode(UEdGraphNode* Node)
|
||||
{
|
||||
if (Node->IsA<UEdGraphNode_Comment>())
|
||||
{
|
||||
Output.Appendf(TEXT("\n// %s\n"), *Node->NodeComment);
|
||||
return;
|
||||
}
|
||||
if (Node->IsA<UEdGraphNode_Comment>()) return;
|
||||
|
||||
Output.Appendf(TEXT("\nnode %s\n"), *MCPUtils::FormatName(Node));
|
||||
Output.Appendf(TEXT("\nnode %s: %s\n"), *MCPUtils::FormatName(Node), *MCPUtils::FormatNodeTitle(Node));
|
||||
|
||||
// Emit input data pins.
|
||||
for (UEdGraphPin* Pin : FilterPins(Node, EGPD_Input))
|
||||
@@ -280,14 +303,50 @@ void FlxBlueprintExporter::EmitGraph()
|
||||
}
|
||||
}
|
||||
|
||||
void FlxBlueprintExporter::EmitNodeList()
|
||||
void FlxBlueprintExporter::EmitDetails()
|
||||
{
|
||||
for (UEdGraphNode* Node : SortedNodes)
|
||||
{
|
||||
if (Node->IsA<UK2Node_Knot>()) continue;
|
||||
if (Node->IsA<UEdGraphNode_Comment>()) continue;
|
||||
if (Node->IsA<UK2Node_VariableGet>()) continue;
|
||||
Details.Appendf(TEXT("%s = %s\n"),
|
||||
*MCPUtils::FormatName(Node), *Node->NodeGuid.ToString());
|
||||
Details.Appendf(TEXT("details %s\n"), *MCPUtils::FormatName(Node));
|
||||
Details.Appendf(TEXT(" pos %d, %d\n"), Node->NodePosX, Node->NodePosY);
|
||||
}
|
||||
}
|
||||
|
||||
void FlxBlueprintExporter::EmitComments()
|
||||
{
|
||||
for (UEdGraphNode* CommentNode : SortedNodes)
|
||||
{
|
||||
if (!CommentNode->IsA<UEdGraphNode_Comment>()) continue;
|
||||
|
||||
int32 CX = CommentNode->NodePosX;
|
||||
int32 CY = CommentNode->NodePosY;
|
||||
int32 CW = CommentNode->NodeWidth;
|
||||
int32 CH = CommentNode->NodeHeight;
|
||||
|
||||
// Emit header.
|
||||
Output.Append(TEXT("\ncomment:\n"));
|
||||
|
||||
// Emit wrapped, indented body.
|
||||
Output.Append(WrapText(CommentNode->NodeComment, 70, TEXT(" - ")));
|
||||
Output.Append(TEXT("\n"));
|
||||
|
||||
// Find contained nodes.
|
||||
TArray<FString> ContainedNames;
|
||||
for (UEdGraphNode* Node : SortedNodes)
|
||||
{
|
||||
if (Node->IsA<UEdGraphNode_Comment>()) continue;
|
||||
int32 NX = Node->NodePosX;
|
||||
int32 NY = Node->NodePosY;
|
||||
if (NX >= CX && NY >= CY && NX <= CX + CW && NY <= CY + CH)
|
||||
ContainedNames.Add(MCPUtils::FormatName(Node));
|
||||
}
|
||||
|
||||
if (ContainedNames.Num() > 0)
|
||||
{
|
||||
Output.Appendf(TEXT(" applies to: %s\n"), *FString::Join(ContainedNames, TEXT(", ")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +1,45 @@
|
||||
# Your Goals
|
||||
|
||||
We want to do several things. I'll give you
|
||||
the concise list of goals, then I'll circle back
|
||||
and give you the coding standard we're trying
|
||||
to achieve.
|
||||
|
||||
- Convert these handlers to use plain-text output
|
||||
wherever it is practical.
|
||||
|
||||
- MCPAssetFinder and MCPFetcher are powerful tools
|
||||
to retrieve assets and objects. We want to migrate
|
||||
the code to use these over hand-rolled solutions.
|
||||
|
||||
- Get rid of ad-hoc code to calculate object names,
|
||||
which inevitably results in inconsistent naming.
|
||||
|
||||
- To make some of these handlers process batches,
|
||||
rather than single objects, where it makes sense
|
||||
to do so.
|
||||
|
||||
- To reduce the amount of code that's just passing
|
||||
error messages around.
|
||||
|
||||
- To get rid of UE_LOG calls.
|
||||
|
||||
# Our Coding Standards
|
||||
|
||||
This is what we're trying to achieve with these goals.
|
||||
|
||||
* When searching for uassets, the tool MCPAssetFinder is
|
||||
often the most precise, concise, and efficient tool.
|
||||
Please study this API before starting. Using this
|
||||
tool gives more reliable and more concise code than
|
||||
hand-rolling code to obtain assets.
|
||||
* Command-handlers are classes that implement the MCPHandler
|
||||
interface. The command's json parameters automatically get
|
||||
injected into the handler's properties using reflection
|
||||
code. Check out a few handlers to see how this works.
|
||||
|
||||
* Class MCPFetcher can precisely and easily retrieve objects
|
||||
of all different kinds using clear, specific identifiers.
|
||||
It is the best tool when you need the caller to specify a
|
||||
blueprint, or a graph, or a pin - you name it. It relieves
|
||||
you of the burden of digging around in unreal's data
|
||||
structures. It also enforces a naming consistency
|
||||
across handlers. Please study this API.
|
||||
of all different kinds using a 'path'. Study the API
|
||||
of this class, we use it everywhere. It is the best tool
|
||||
when you need the caller to specify a blueprint, or a
|
||||
graph, or a pin - you name it.
|
||||
|
||||
* To get the name of an object, there are tons of methods
|
||||
you could call: pin->GetName(), pin->NodeGuid.ToString(),
|
||||
node->GetTitle()... there are *so many* ways to get a
|
||||
readable label. All of those ways are *NOT ALLOWED*. The
|
||||
only valid way to get a name for an object is using
|
||||
MCPUtils::FormatName(obj). This is to enforce consistent
|
||||
naming. FormatName has been designed to produce very
|
||||
clear, very readable, and highly unique identifiers.
|
||||
More importantly, if one tool outputs a name, a different
|
||||
tool will accept that name, because both tools use the
|
||||
same naming scheme.
|
||||
* When you want to scan for a list of assets, MCPAssets
|
||||
is the best tool. This wraps Unreal's asset database
|
||||
in a convenient interface. Please study this API.
|
||||
|
||||
* The only valid way to get a name for an object is using
|
||||
MCPUtils::FormatName(obj). We don't allow the use of
|
||||
pin->GetName, or node->GetTitle, or any other name-fetching
|
||||
routine. Using only MCPUtils::FormatName guarantees
|
||||
consistency: that means, names output by one tool can
|
||||
be parsed by a different tool.
|
||||
|
||||
* To check whether a string matches an object's name,
|
||||
there's only one valid way to do that as well: using
|
||||
bool MCPUtils::Identifies(Name, Obj). Don't compare
|
||||
the name yourself: you might get the case-sensitivity
|
||||
wrong, you might forget to ignore trailing whitespace,
|
||||
there are too many things that could go wrong. We've
|
||||
provided MCPUtils::Identifies, which does it right
|
||||
every time, for every kind of object.
|
||||
bool MCPUtils::Identifies(Name, Obj).
|
||||
|
||||
* Concise output is better. The output of these handlers
|
||||
will primarily be consumed by LLMs with finite context
|
||||
windows. Plain-text handlers beat json handlers for
|
||||
minimizing tokens: read the API for MCPHandler.h to learn
|
||||
how to create a plain text handler. Avoid sending
|
||||
information the caller didn't ask for. Don't echo the
|
||||
command parameters: the caller knows what parameters he
|
||||
sent. Don't make things unnecessarily verbose:
|
||||
"type=int varname=x" can be shortened to "int x."
|
||||
windows. Avoid sending information the caller didn't ask
|
||||
for. Don't echo the command parameters: the caller knows
|
||||
what parameters he sent. Don't make things unnecessarily
|
||||
verbose: "type=int varname=x" can be shortened to "int x."
|
||||
Generate output in a form that *you* would want to
|
||||
consume.
|
||||
|
||||
* It's really important to send good error messages back to
|
||||
the caller. Every handler has a second parameter, the
|
||||
"output device", which is used to send data back to the
|
||||
caller. The "output device" can either be a stringbuilder,
|
||||
or a json tree. Our two core tools, MCPFetcher and
|
||||
MCPAssetFinder, have powerful error handling built in: if
|
||||
you give them a reference to the output device, they
|
||||
will send error messages directly back to the caller
|
||||
without your intervention. This is bulletproof.
|
||||
Study class MCPErrorCallback to see how this works: any
|
||||
function that takes MCPErrorCallback can put errors
|
||||
directly into an "output device".
|
||||
|
||||
* If the output device of your handler is a shared ptr
|
||||
to a json tree, you might see code that passes &*Json to
|
||||
an MCPErrorCallback. That's legacy: it used to be necessary
|
||||
to convert the shared pointer into a regular pointer.
|
||||
Now the MCPErrorCallback can accept the shared pointer
|
||||
directly.
|
||||
* You can pass the output StringBuilder directly into
|
||||
MCPFetcher and MCPAssets. If you do, these will automatically
|
||||
generate good error messages. If either of these classes
|
||||
returns 'false', you don't need to generate an error
|
||||
message: it's already been done. Any other routine that
|
||||
accepts MCPErrorCallback can do the same.
|
||||
|
||||
* It's good for handlers to do operations in batches,
|
||||
where possible. SpawnNodes is better than SpawnNode.
|
||||
@@ -108,10 +54,9 @@ This is what we're trying to achieve with these goals.
|
||||
Better to report problems via the response. Please remove
|
||||
UE_LOG calls in handlers.
|
||||
|
||||
* In addition to refactoring some handlers, we'd like you
|
||||
to make some notes in a markdown file. The markdown
|
||||
file should have the name UMCPHandler_XXX.Notes.md.
|
||||
Tell us what you think is good about the handler, what
|
||||
needs more work, and areas where you weren't entirely
|
||||
confident about what to do, so you acted conservatively.
|
||||
If there's more to do, we'd like to know.
|
||||
* When you're going to edit something, it's important to
|
||||
mark things dirty. There's a very powerful tool for that:
|
||||
MCPUtils::PreEdit and MCPUtils::PostEdit, which can also
|
||||
be accessed through MCPFetcher::PreEdit and PostEdit.
|
||||
These routines are very careful about marking everything
|
||||
dirty, so you don't have to worry about it.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddMaterialExpression : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -36,7 +36,7 @@ struct FConnectMaterialPinsEntry
|
||||
};
|
||||
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ConnectMaterialExpressionPins : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DeleteMaterialExpression : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -30,7 +30,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DescribeMaterialInEnglish : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -19,7 +19,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DisconnectMaterialExpressionPin : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -21,7 +21,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DumpMaterial : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -29,7 +29,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DumpMaterialFunction : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -17,7 +17,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SearchWithinMaterials : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -17,7 +17,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetMaterialExpressionPosition : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -26,7 +26,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetMaterialExpressionProperty : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -19,7 +19,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddAnimStateToMachine : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddAnimStateTransition : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddBlueprintComponent : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddBlueprintInterface : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddBlueprintVariable : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -29,7 +29,7 @@ struct FDispatcherParamEntry
|
||||
FString Type;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddEventDispatcher : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddFunctionParameter : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_AddStructField : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_BackupAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ChangeBlueprintVariableType : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ChangeFunctionParameterType : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ChangeStructNodeType : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
// Pre-flight check: can two pins be connected?
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CheckPinConnectionCompatibility : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CompileBlueprint : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CompileMaterial : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -26,7 +26,7 @@ struct FConnectPinsEntry
|
||||
};
|
||||
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ConnectPins : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateAnimBlueprintAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateBlendSpaceAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateBlueprintAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateBlueprintGraph : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateEnumAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateMaterialAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateMaterialFunctionAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateMaterialInstanceAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -29,7 +29,7 @@ struct FStructPropertyEntry
|
||||
FString Type;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_CreateStructAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DeleteAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DeleteBlueprintGraph : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DeleteNodeFromGraph : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DiffTwoBlueprints : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -26,7 +26,7 @@ struct FDisconnectPinEntry
|
||||
};
|
||||
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DisconnectPins : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DumpBlueprint : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DumpGraphs : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DumpMaterialInstanceParameters : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DumpProperties : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -26,6 +26,9 @@ public:
|
||||
UPROPERTY(meta=(Optional, Description="Truncate values to 80 characters (default true)"))
|
||||
bool Truncate = true;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Only show properties declared on the object's own class, not inherited ones"))
|
||||
bool Local = false;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("List all blueprint-visible properties on an object resolved via MCPFetcher path, "
|
||||
@@ -34,16 +37,12 @@ public:
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
// Resolve the path to an object.
|
||||
// Resolve the path to an object and get its editable template.
|
||||
MCPFetcher F(Result);
|
||||
UObject* Obj = F.Walk(Path).Cast<UObject>();
|
||||
if (!Obj) return;
|
||||
|
||||
// Get the editable template (e.g. Blueprint → CDO).
|
||||
UObject* Template = MCPUtils::GetEditableTemplate(Obj, Result);
|
||||
UObject* Template = F.Walk(Path).Template().Cast<UObject>();
|
||||
if (!Template) return;
|
||||
|
||||
TArray<FProperty*> Props = MCPUtils::BlueprintVisibleProperties(Template, Query);
|
||||
TArray<FProperty*> Props = MCPUtils::SearchProperties(Template, Query, CPF_Edit, Local);
|
||||
|
||||
UStruct* CurrentOwner = nullptr;
|
||||
for (FProperty* Prop : Props)
|
||||
@@ -63,7 +62,7 @@ public:
|
||||
if (Truncate && (ValueStr.Len() > 80))
|
||||
ValueStr = ValueStr.Left(80) + TEXT("...");
|
||||
|
||||
bool bEditable = Prop->HasAnyPropertyFlags(CPF_Edit);
|
||||
bool bEditable = !Prop->HasAnyPropertyFlags(CPF_EditConst);
|
||||
Result.Appendf(TEXT(" %s %s %s = %s\n"),
|
||||
bEditable ? TEXT("editable") : TEXT("readonly"),
|
||||
*MCPUtils::FormatPropertyType(Prop),
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DuplicateNodesInGraph : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_FindAssetReferences : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_FindMaterialReferences : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_GetNodeComment : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// HandleGetPinInfo — detailed information about a specific pin
|
||||
// ============================================================
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_GetPinDetails : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListAnimSlotNames : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListAnimSyncGroups : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListBlueprintAssets : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListBlueprintComponents : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListBlueprintInterfaces : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListClassProperties : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListEventDispatchers : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ListOpenAssetEditors : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_OpenAssetEditor : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RefreshAllNodesInGraph : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RemoveAnimStateFromMachine : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RemoveBlueprintComponent : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RemoveBlueprintInterface : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RemoveBlueprintVariable : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RemoveFunctionParameter : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RemoveStructField : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RenameAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RenameBlueprintGraph : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ReparentBlueprint : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ReparentMaterialInstance : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_ReplaceFunctionCallsInBlueprint : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_RestoreAsset : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SearchAssets : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SearchSpawnableNodeTypes : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
// HandleSearchByType — find all usages of a type across blueprints
|
||||
// ============================================================
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SearchTypeUsageInBlueprints : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// HandleListClasses — discover available UClasses
|
||||
// ============================================================
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SearchUnrealClasses : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SearchWithinBlueprints : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetAnimStateAnimation : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetAnimStateBlendSpace : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetAnimTransitionRule : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -29,7 +29,7 @@ struct FBlendSpaceSampleEntry
|
||||
float Y = 0.0f;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetBlendSpaceSamplePoints : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetBlueprintVariableMetadata : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetClassDefaultValue : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetMaterialInstanceParameter : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetMaterialProperty : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetNodeComment : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -30,7 +30,7 @@ struct FMoveNodeEntry
|
||||
};
|
||||
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetNodePositions : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -26,7 +26,7 @@ struct FSetPinDefaultEntry
|
||||
};
|
||||
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetPinDefaultValues : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -45,7 +45,6 @@ public:
|
||||
int32 SuccessCount = 0;
|
||||
int32 TotalCount = Pins.Array.Num();
|
||||
TSet<UEdGraphNode*> ModifiedNodes;
|
||||
TSet<UBlueprint*> ModifiedBlueprints;
|
||||
|
||||
for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
|
||||
{
|
||||
@@ -67,19 +66,13 @@ public:
|
||||
|
||||
const UEdGraphSchema* Schema = Node->GetGraph()->GetSchema();
|
||||
if (Schema)
|
||||
{
|
||||
FString ValidationError = Schema->IsPinDefaultValid(Pin, Entry.Value, nullptr, FText::GetEmpty());
|
||||
if (!ValidationError.IsEmpty())
|
||||
{
|
||||
Result.Appendf(TEXT("error: Invalid value for %s: %s\n"), *MCPUtils::FormatName(Pin), *ValidationError);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Schema->TrySetDefaultValue(*Pin, Entry.Value);
|
||||
else
|
||||
Pin->DefaultValue = Entry.Value;
|
||||
|
||||
SuccessCount++;
|
||||
ModifiedNodes.Add(Node);
|
||||
ModifiedBlueprints.Add(FBlueprintEditorUtils::FindBlueprintForNodeChecked(Node));
|
||||
F.PostEdit();
|
||||
}
|
||||
|
||||
for (UEdGraphNode* Node : ModifiedNodes)
|
||||
@@ -87,11 +80,6 @@ public:
|
||||
Node->ReconstructNode();
|
||||
}
|
||||
|
||||
for (UBlueprint* BP : ModifiedBlueprints)
|
||||
{
|
||||
FBlueprintEditorUtils::MarkBlueprintAsModified(BP);
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("Set %d/%d pin defaults.\n"), SuccessCount, TotalCount);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SetProperties : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -31,13 +31,9 @@ public:
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
// Resolve the path to an object.
|
||||
// Resolve the path to an object and get its editable template.
|
||||
MCPFetcher F(Result);
|
||||
UObject* Obj = F.Walk(Path).Cast<UObject>();
|
||||
if (!Obj) return;
|
||||
|
||||
// Get the editable template (e.g. Blueprint → CDO).
|
||||
UObject* Template = MCPUtils::GetEditableTemplate(Obj, Result);
|
||||
UObject* Template = F.Walk(Path).Template().Cast<UObject>();
|
||||
if (!Template) return;
|
||||
|
||||
if (!Properties.Json || Properties.Json->Values.Num() == 0)
|
||||
@@ -67,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
// Apply all changes in a single Pre/PostEditChange bracket.
|
||||
Template->PreEditChange(nullptr);
|
||||
F.PreEdit();
|
||||
|
||||
int32 SuccessCount = 0;
|
||||
for (const auto& Pair : Properties.Json->Values)
|
||||
@@ -86,11 +82,10 @@ public:
|
||||
SuccessCount++;
|
||||
}
|
||||
|
||||
Template->PostEditChange();
|
||||
F.PostEdit();
|
||||
|
||||
// Save.
|
||||
Template->MarkPackageDirty();
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(Obj);
|
||||
bool bSaved = MCPUtils::SaveGenericPackage(Template);
|
||||
|
||||
Result.Appendf(TEXT("Set %d/%d properties.\n"), SuccessCount, Properties.Json->Values.Num());
|
||||
if (!bSaved)
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPFetcher.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "UMCPHandler_ShowCommands.generated.h"
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Documentation"))
|
||||
class UMCPHandler_ShowCommands : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@@ -22,22 +23,16 @@ public:
|
||||
return TEXT("List all available commands with their descriptions.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
void EmitGroup(const FString& GroupName, const TArray<UClass*>& Classes, FStringBuilderBase& Result)
|
||||
{
|
||||
FString QueryLower = Query.ToLower();
|
||||
|
||||
for (UClass* Class : MCPUtils::CollectHandlerClasses())
|
||||
Result.Appendf(TEXT("\n=== %s ===\n\n"), *GroupName);
|
||||
for (UClass* Class : Classes)
|
||||
{
|
||||
FString ToolName = MCPUtils::GetToolName(Class);
|
||||
if (!ToolName.ToLower().Contains(QueryLower))
|
||||
continue;
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
MCPUtils::FormatCommandHelp(Class, Result);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Append(MCPUtils::GetToolName(Class));
|
||||
Result.Append(TEXT("("));
|
||||
bool bFirst = true;
|
||||
@@ -46,10 +41,53 @@ public:
|
||||
if (!bFirst) Result.Append(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()));
|
||||
}
|
||||
Result.Append(TEXT(")\n"));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
FString QueryLower = Query.ToLower();
|
||||
|
||||
// Group handlers by their Group metadata.
|
||||
TMap<FString, TArray<UClass*>> Groups;
|
||||
for (UClass* Class : MCPUtils::CollectHandlerClasses())
|
||||
{
|
||||
FString ToolName = MCPUtils::GetToolName(Class);
|
||||
if (!ToolName.ToLower().Contains(QueryLower))
|
||||
continue;
|
||||
FString Group = Class->GetMetaData(TEXT("Group"));
|
||||
if (Group.IsEmpty()) Group = TEXT("Unclassified");
|
||||
Groups.FindOrAdd(Group).Add(Class);
|
||||
}
|
||||
|
||||
// Emit high-priority groups first, in order.
|
||||
static const TCHAR* HighPriority[] = { TEXT("Documentation") };
|
||||
for (const TCHAR* HP : HighPriority)
|
||||
{
|
||||
TArray<UClass*> Classes;
|
||||
if (Groups.RemoveAndCopyValue(HP, Classes))
|
||||
EmitGroup(HP, Classes, Result);
|
||||
}
|
||||
|
||||
// Emit remaining groups.
|
||||
for (const auto& Pair : Groups)
|
||||
EmitGroup(Pair.Key, Pair.Value, Result);
|
||||
|
||||
// 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"));
|
||||
for (const MCPFetcher::FWalker& W : MCPFetcher::GetWalkerTable())
|
||||
{
|
||||
Result.Appendf(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"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ struct FSpawnNodeEntry
|
||||
};
|
||||
|
||||
|
||||
UCLASS()
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_SpawnNodes : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include "EdGraph/EdGraph.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
#include "EdGraph/EdGraphPin.h"
|
||||
#include "UObject/PropertyAccessUtil.h"
|
||||
#include "Engine/SimpleConstructionScript.h"
|
||||
#include "Engine/SCS_Node.h"
|
||||
#include "Engine/World.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "MaterialGraph/MaterialGraph.h"
|
||||
#include "MaterialGraph/MaterialGraphNode.h"
|
||||
#include "Engine/LevelScriptBlueprint.h"
|
||||
|
||||
MCPFetcher& MCPFetcher::SetError(const FString& Msg)
|
||||
@@ -31,6 +31,19 @@ MCPFetcher& MCPFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expected)
|
||||
return *this;
|
||||
}
|
||||
|
||||
const TArray<MCPFetcher::FWalker>& MCPFetcher::GetWalkerTable()
|
||||
{
|
||||
static const TArray<FWalker> Table = {
|
||||
{ TEXT("graph"), TEXT("Find a named UEdGraph (blank name for material graphs)"), &MCPFetcher::Graph },
|
||||
{ TEXT("node"), TEXT("Find a named UEdGraphNode within a graph or blueprint"), &MCPFetcher::Node },
|
||||
{ TEXT("pin"), TEXT("Find a named UEdGraphPin on a node"), &MCPFetcher::Pin },
|
||||
{ TEXT("component"), TEXT("Find a named component in a Blueprint's SCS"), &MCPFetcher::Component },
|
||||
{ TEXT("levelblueprint"), TEXT("Get the level blueprint from a UWorld"), &MCPFetcher::LevelBlueprint },
|
||||
// { TEXT("matexp"), TEXT("Get the UMaterialExpression from a UMaterialGraphNode"), &MCPFetcher::MatExp },
|
||||
};
|
||||
return Table;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::Walk(const FString& Path)
|
||||
{
|
||||
if (bError) return *this;
|
||||
@@ -53,6 +66,8 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
|
||||
Start = 1;
|
||||
}
|
||||
|
||||
const TArray<FWalker>& Walkers = GetWalkerTable();
|
||||
|
||||
// Walk each subsequent segment
|
||||
for (int32 i = Start; i < Segments.Num(); i++)
|
||||
{
|
||||
@@ -60,13 +75,16 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
|
||||
if (!Segments[i].Split(TEXT(":"), &Key, &Value))
|
||||
Key = Segments[i];
|
||||
|
||||
if (StrEq(Key, TEXT("graph"))) Graph(Value);
|
||||
else if (StrEq(Key, TEXT("node"))) Node(Value);
|
||||
else if (StrEq(Key, TEXT("pin"))) Pin(Value);
|
||||
else if (StrEq(Key, TEXT("component"))) Component(Value);
|
||||
else if (StrEq(Key, TEXT("property"))) Property(Value);
|
||||
else if (StrEq(Key, TEXT("levelblueprint"))) LevelBlueprint();
|
||||
else
|
||||
bool bFound = false;
|
||||
for (const FWalker& W : Walkers)
|
||||
{
|
||||
if (!StrEq(Key, W.Key)) continue;
|
||||
(this->*W.Func)(Value);
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
SetError(FString::Printf(TEXT("Unknown walker '%s'"), *Key));
|
||||
return *this;
|
||||
@@ -215,30 +233,7 @@ MCPFetcher& MCPFetcher::Component(const FString& Value)
|
||||
return SetError(FString::Printf(TEXT("Component '%s' not found in %s"), *Value, *BP->GetName()));
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::Property(const FString& Value)
|
||||
{
|
||||
if (bError) return *this;
|
||||
|
||||
if (!Obj)
|
||||
return TypeMismatch(TEXT("property"), TEXT("UObject"));
|
||||
|
||||
FProperty* Prop = Obj->GetClass()->FindPropertyByName(FName(*Value));
|
||||
if (!Prop)
|
||||
return SetError(FString::Printf(TEXT("Property '%s' not found on %s"), *Value, *Obj->GetClass()->GetName()));
|
||||
|
||||
FObjectProperty* ObjProp = CastField<FObjectProperty>(Prop);
|
||||
if (!ObjProp)
|
||||
return SetError(FString::Printf(TEXT("Property '%s' is not an object property (type: %s)"), *Value, *Prop->GetCPPType()));
|
||||
|
||||
UObject* PropValue = ObjProp->GetObjectPropertyValue(Prop->ContainerPtrToValuePtr<void>(Obj));
|
||||
if (!PropValue)
|
||||
return SetError(FString::Printf(TEXT("Property '%s' is null on %s"), *Value, *Obj->GetName()));
|
||||
|
||||
SetObj(PropValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::LevelBlueprint()
|
||||
MCPFetcher& MCPFetcher::LevelBlueprint(const FString& Value)
|
||||
{
|
||||
if (bError) return *this;
|
||||
|
||||
@@ -256,3 +251,36 @@ MCPFetcher& MCPFetcher::LevelBlueprint()
|
||||
SetObj(LevelBP);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::Template()
|
||||
{
|
||||
if (bError) return *this;
|
||||
if (!Obj)
|
||||
return SetError(TEXT("Template: object is null"));
|
||||
|
||||
if (UBlueprint* BP = ::Cast<UBlueprint>(Obj))
|
||||
{
|
||||
if (!BP->GeneratedClass)
|
||||
return SetError(FString::Printf(TEXT("Blueprint '%s' has no GeneratedClass"), *Obj->GetName()));
|
||||
SetObj(BP->GeneratedClass->GetDefaultObject());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Everything else is its own template — no navigation needed.
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::MatExp(const FString& Value)
|
||||
{
|
||||
if (bError) return *this;
|
||||
|
||||
UMaterialGraphNode* MatNode = ::Cast<UMaterialGraphNode>(Obj);
|
||||
if (!MatNode)
|
||||
return TypeMismatch(TEXT("matexp"), TEXT("UMaterialGraphNode"));
|
||||
|
||||
if (!MatNode->MaterialExpression)
|
||||
return SetError(FString::Printf(TEXT("Node '%s' has no MaterialExpression"), *MCPUtils::FormatName(MatNode)));
|
||||
|
||||
SetObj(MatNode->MaterialExpression);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "Handlers/UMCPHandler_AddBlueprintVariable.h"
|
||||
#include "Handlers/UMCPHandler_AddEventDispatcher.h"
|
||||
#include "Handlers/UMCPHandler_AddFunctionParameter.h"
|
||||
#include "Handlers/UMCPHandler_AddMaterialExpression.h"
|
||||
#include "Handlers/UMCPHandler_AddStructField.h"
|
||||
#include "Handlers/UMCPHandler_BackupAsset.h"
|
||||
#include "Handlers/UMCPHandler_ChangeBlueprintVariableType.h"
|
||||
@@ -15,7 +14,6 @@
|
||||
#include "Handlers/UMCPHandler_CompileBlueprint.h"
|
||||
#include "Handlers/UMCPHandler_CompileMaterial.h"
|
||||
#include "Handlers/UMCPHandler_ConnectPins.h"
|
||||
#include "Handlers/UMCPHandler_ConnectMaterialExpressionPins.h"
|
||||
#include "Handlers/UMCPHandler_CreateAnimBlueprintAsset.h"
|
||||
#include "Handlers/UMCPHandler_CreateBlendSpaceAsset.h"
|
||||
#include "Handlers/UMCPHandler_CreateBlueprintAsset.h"
|
||||
@@ -27,17 +25,12 @@
|
||||
#include "Handlers/UMCPHandler_CreateStructAsset.h"
|
||||
#include "Handlers/UMCPHandler_DeleteAsset.h"
|
||||
#include "Handlers/UMCPHandler_DeleteBlueprintGraph.h"
|
||||
#include "Handlers/UMCPHandler_DeleteMaterialExpression.h"
|
||||
#include "Handlers/UMCPHandler_DeleteNodeFromGraph.h"
|
||||
#include "Handlers/UMCPHandler_DescribeMaterialInEnglish.h"
|
||||
#include "Handlers/UMCPHandler_DiffTwoBlueprints.h"
|
||||
#include "Handlers/UMCPHandler_DisconnectPins.h"
|
||||
#include "Handlers/UMCPHandler_DisconnectMaterialExpressionPin.h"
|
||||
#include "Handlers/UMCPHandler_DumpBlueprint.h"
|
||||
#include "Handlers/UMCPHandler_DumpProperties.h"
|
||||
#include "Handlers/UMCPHandler_DumpGraphs.h"
|
||||
#include "Handlers/UMCPHandler_DumpMaterial.h"
|
||||
#include "Handlers/UMCPHandler_DumpMaterialFunction.h"
|
||||
#include "Handlers/UMCPHandler_DumpMaterialInstanceParameters.h"
|
||||
#include "Handlers/UMCPHandler_DuplicateNodesInGraph.h"
|
||||
#include "Handlers/UMCPHandler_FindAssetReferences.h"
|
||||
@@ -71,15 +64,12 @@
|
||||
#include "Handlers/UMCPHandler_SearchTypeUsageInBlueprints.h"
|
||||
#include "Handlers/UMCPHandler_SearchUnrealClasses.h"
|
||||
#include "Handlers/UMCPHandler_SearchWithinBlueprints.h"
|
||||
#include "Handlers/UMCPHandler_SearchWithinMaterials.h"
|
||||
#include "Handlers/UMCPHandler_SetAnimStateAnimation.h"
|
||||
#include "Handlers/UMCPHandler_SetAnimStateBlendSpace.h"
|
||||
#include "Handlers/UMCPHandler_SetAnimTransitionRule.h"
|
||||
#include "Handlers/UMCPHandler_SetBlendSpaceSamplePoints.h"
|
||||
#include "Handlers/UMCPHandler_SetBlueprintVariableMetadata.h"
|
||||
#include "Handlers/UMCPHandler_SetClassDefaultValue.h"
|
||||
#include "Handlers/UMCPHandler_SetMaterialExpressionPosition.h"
|
||||
#include "Handlers/UMCPHandler_SetMaterialExpressionProperty.h"
|
||||
#include "Handlers/UMCPHandler_SetMaterialInstanceParameter.h"
|
||||
#include "Handlers/UMCPHandler_SetMaterialProperty.h"
|
||||
#include "Handlers/UMCPHandler_SetNodeComment.h"
|
||||
|
||||
@@ -125,11 +125,6 @@ void MCPUtils::SanitizeNameInPlace(FString &Name)
|
||||
if (Name.IsEmpty()) Name = TEXT("_");
|
||||
}
|
||||
|
||||
void MCPUtils::AppendNumericSuffix(FString &Name, int32 N)
|
||||
{
|
||||
if (N > 0)
|
||||
Name += FString::Printf(TEXT("_%d"), N - 1);
|
||||
}
|
||||
|
||||
FString MCPUtils::FormatName(const UWorld *World)
|
||||
{
|
||||
@@ -155,14 +150,7 @@ FString MCPUtils::FormatName(const UEdGraph *Graph)
|
||||
|
||||
FString MCPUtils::FormatName(const UEdGraphNode* Node)
|
||||
{
|
||||
// Sanitized first line of the node title.
|
||||
FString Title = Node->GetNodeTitle(ENodeTitleType::FullTitle).ToString();
|
||||
int32 NewlineIdx;
|
||||
if (Title.FindChar(TEXT('\n'), NewlineIdx))
|
||||
Title.LeftInline(NewlineIdx);
|
||||
SanitizeNameInPlace(Title);
|
||||
AppendNumericSuffix(Title, Node->GetFName().GetNumber());
|
||||
return Title;
|
||||
return Node->GetName();
|
||||
}
|
||||
|
||||
FString MCPUtils::FormatName(const UEdGraphPin *Pin)
|
||||
@@ -259,99 +247,12 @@ FString MCPUtils::FormatName(const FProperty *Prop)
|
||||
return Prop->GetName();
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const FBPVariableDescription &Var)
|
||||
{
|
||||
return FormatName(Var).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UStruct *Struct)
|
||||
{
|
||||
return FormatName(Struct).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UMaterial *Material)
|
||||
{
|
||||
return FormatName(Material).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UMaterialInstance *MaterialInstance)
|
||||
{
|
||||
return FormatName(MaterialInstance).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UMaterialFunction *MaterialFunction)
|
||||
{
|
||||
return FormatName(MaterialFunction).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UMaterialExpression *Expression)
|
||||
{
|
||||
return FormatName(Expression).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UStaticMesh *Mesh)
|
||||
{
|
||||
return FormatName(Mesh).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const USkeletalMesh *Mesh)
|
||||
{
|
||||
return FormatName(Mesh).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UAnimSequence *Anim)
|
||||
{
|
||||
return FormatName(Anim).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UBlendSpace *BlendSpace)
|
||||
{
|
||||
return FormatName(BlendSpace).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UTexture *Texture)
|
||||
{
|
||||
return FormatName(Texture).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UScriptStruct *Struct)
|
||||
{
|
||||
return FormatName(Struct).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UEnum *Enum)
|
||||
{
|
||||
return FormatName(Enum).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const FProperty *Prop)
|
||||
{
|
||||
return FormatName(Prop).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Identifies
|
||||
// ============================================================
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UWorld *World)
|
||||
{
|
||||
return FormatName(World).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UBlueprint *BP)
|
||||
{
|
||||
return FormatName(BP).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UActorComponent *C)
|
||||
{
|
||||
return FormatName(C).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UEdGraph *Graph)
|
||||
{
|
||||
return FormatName(Graph).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
// Most types are handled by the template in MCPUtils.h.
|
||||
// UEdGraphNode also matches by GUID:
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UEdGraphNode* Node)
|
||||
{
|
||||
@@ -360,15 +261,9 @@ bool MCPUtils::Identifies(const FString &Name, const UEdGraphNode* Node)
|
||||
return FormatName(Node).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const UEdGraphPin *Pin)
|
||||
{
|
||||
return FormatName(Pin).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
bool MCPUtils::Identifies(const FString &Name, const FMemberReference &Ref)
|
||||
{
|
||||
return FormatName(Ref).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
// ============================================================
|
||||
// Formatting other things
|
||||
// ============================================================
|
||||
|
||||
FString MCPUtils::FormatPinType(const FEdGraphPinType& PinType)
|
||||
{
|
||||
@@ -386,6 +281,14 @@ FString MCPUtils::FormatPinType(UEdGraphPin* Pin)
|
||||
return FormatPinType(Pin->PinType);
|
||||
}
|
||||
|
||||
FString MCPUtils::FormatNodeTitle(const UEdGraphNode *Node)
|
||||
{
|
||||
FString Title = Node->GetNodeTitle(ENodeTitleType::FullTitle).ToString();
|
||||
int32 NewlineIdx;
|
||||
if (Title.FindChar(TEXT('\n'), NewlineIdx))
|
||||
Title.LeftInline(NewlineIdx);
|
||||
return Title;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// JSON helpers
|
||||
@@ -1210,6 +1113,29 @@ UMaterial* MCPUtils::ReplaceMaterialWithTransientCopy(UMaterial* Material)
|
||||
return Material;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// PreEdit / PostEdit
|
||||
// ============================================================
|
||||
|
||||
void MCPUtils::PreEdit(const TArray<UObject*>& Objects)
|
||||
{
|
||||
for (UObject* Obj : Objects)
|
||||
Obj->PreEditChange(nullptr);
|
||||
}
|
||||
|
||||
void MCPUtils::PostEdit(const TArray<UObject*>& Objects)
|
||||
{
|
||||
for (int32 i = Objects.Num() - 1; i >= 0; --i)
|
||||
{
|
||||
UObject* Obj = Objects[i];
|
||||
Obj->PostEditChange();
|
||||
Obj->MarkPackageDirty();
|
||||
|
||||
if (UBlueprint* BP = Cast<UBlueprint>(Obj))
|
||||
FBlueprintEditorUtils::MarkBlueprintAsModified(BP);
|
||||
}
|
||||
}
|
||||
|
||||
bool MCPUtils::SaveMaterialPackage(UMaterial* Material)
|
||||
{
|
||||
if (!Material) return false;
|
||||
@@ -1761,10 +1687,10 @@ FString MCPUtils::FormatPropertyType(FProperty* Prop)
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// GetEditableTemplate
|
||||
// GetTemplate
|
||||
// ============================================================
|
||||
|
||||
UObject* MCPUtils::GetEditableTemplate(UObject* Obj, MCPErrorCallback Error)
|
||||
UObject* MCPUtils::GetTemplate(UObject* Obj, MCPErrorCallback Error)
|
||||
{
|
||||
if (!Obj)
|
||||
{
|
||||
@@ -1783,17 +1709,7 @@ UObject* MCPUtils::GetEditableTemplate(UObject* Obj, MCPErrorCallback Error)
|
||||
return BP->GeneratedClass->GetDefaultObject();
|
||||
}
|
||||
|
||||
// These asset types are safe to edit directly.
|
||||
if (Cast<UMaterial>(Obj)) return Obj;
|
||||
if (Cast<UMaterialInstance>(Obj)) return Obj;
|
||||
if (Cast<UStaticMesh>(Obj)) return Obj;
|
||||
if (Cast<USkeletalMesh>(Obj)) return Obj;
|
||||
if (Cast<UTexture>(Obj)) return Obj;
|
||||
if (Cast<UActorComponent>(Obj)) return Obj;
|
||||
|
||||
// Unknown type — refuse for safety.
|
||||
Error.SetError(FString::Printf(TEXT("Object type '%s' is not supported for generic property editing"), *Obj->GetClass()->GetName()));
|
||||
return nullptr;
|
||||
return Obj;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
@@ -1856,18 +1772,20 @@ bool MCPUtils::SetPropertyValueText(UObject* Container, FProperty* Prop, const F
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// BlueprintVisibleProperties
|
||||
// SearchProperties
|
||||
// ============================================================
|
||||
|
||||
TArray<FProperty*> MCPUtils::BlueprintVisibleProperties(UObject* Obj, const FString& Query)
|
||||
TArray<FProperty*> MCPUtils::SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal)
|
||||
{
|
||||
TArray<FProperty*> Result;
|
||||
if (!Obj) return Result;
|
||||
for (TFieldIterator<FProperty> PropIt(Obj->GetClass()); PropIt; ++PropIt)
|
||||
UClass* ObjClass = Obj->GetClass();
|
||||
for (TFieldIterator<FProperty> PropIt(ObjClass); PropIt; ++PropIt)
|
||||
{
|
||||
FProperty* Prop = *PropIt;
|
||||
if (!Prop) continue;
|
||||
if (!Prop->HasAnyPropertyFlags(CPF_BlueprintVisible)) continue;
|
||||
if (Flags != 0 && !Prop->HasAnyPropertyFlags(Flags)) continue;
|
||||
if (bLocal && Prop->GetOwnerStruct() != ObjClass) continue;
|
||||
if (!Query.IsEmpty() && !FormatName(Prop).Contains(Query, ESearchCase::IgnoreCase))
|
||||
continue;
|
||||
Result.Add(Prop);
|
||||
|
||||
@@ -59,11 +59,11 @@ private:
|
||||
FString FormatPinSource(UEdGraphPin* Pin);
|
||||
void Traverse(UEdGraphNode* Node);
|
||||
void SortNodes();
|
||||
void AssignNodeNames();
|
||||
void EmitNode(UEdGraphNode* Node);
|
||||
void EmitLocalVariables();
|
||||
void EmitGraph();
|
||||
void EmitNodeList();
|
||||
void EmitDetails();
|
||||
void EmitComments();
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -11,17 +11,11 @@ class UEdGraphPin;
|
||||
// followed by zero or more comma-separated walker segments of the form
|
||||
// "key:value". Each segment navigates from the current object to a child.
|
||||
//
|
||||
// Supported walkers:
|
||||
// graph:Name - find a named UEdGraph within a UBlueprint
|
||||
// node:Name - find a named UEdGraphNode within a UEdGraph
|
||||
// pin:Name - find a named UEdGraphPin on a UEdGraphNode
|
||||
// component:Name - find a named component in a Blueprint's SCS
|
||||
// property:Name - follow an object-valued UProperty to its value
|
||||
// levelblueprint - get the level blueprint from a UWorld
|
||||
// The list of supported walkers is defined by GetWalkerTable().
|
||||
//
|
||||
// Example paths:
|
||||
// /Game/Widgets/WB_Hotkeys,graph:ReadLuaConfiguration,node:Self_Reference_03,pin:Result
|
||||
// /Game/Tangibles/TAN_Character,component:CharacterMesh0,property:SkeletalMeshAsset
|
||||
// /Game/Tangibles/TAN_Character,component:CharacterMesh0
|
||||
//
|
||||
// Builder-style usage:
|
||||
// MCPFetcher F(cb);
|
||||
@@ -46,13 +40,31 @@ public:
|
||||
MCPFetcher& Node(const FString& Value);
|
||||
MCPFetcher& Pin(const FString& Value);
|
||||
MCPFetcher& Component(const FString& Value);
|
||||
MCPFetcher& Property(const FString& Value);
|
||||
MCPFetcher& LevelBlueprint();
|
||||
MCPFetcher& LevelBlueprint(const FString& Value);
|
||||
MCPFetcher& MatExp(const FString& Value);
|
||||
|
||||
// C++-only walk step: resolve to the editable template
|
||||
// (e.g. Blueprint → CDO, everything else → as-is).
|
||||
MCPFetcher& Template();
|
||||
|
||||
// Parse string and walk multiple steps.
|
||||
MCPFetcher& Walk(const FString& Path);
|
||||
|
||||
// Walker table entry.
|
||||
struct FWalker
|
||||
{
|
||||
const TCHAR* Key; // e.g. "graph", "node", "matexp"
|
||||
const TCHAR* Description; // brief help text
|
||||
MCPFetcher& (MCPFetcher::*Func)(const FString& Value);
|
||||
};
|
||||
|
||||
// Returns the static table of all supported walkers.
|
||||
static const TArray<FWalker>& GetWalkerTable();
|
||||
|
||||
bool Ok() const { return !bError; }
|
||||
const TArray<UObject*>& Visited() const { return Chain; }
|
||||
void PreEdit() { MCPUtils::PreEdit(Chain); }
|
||||
void PostEdit() { MCPUtils::PostEdit(Chain); }
|
||||
template<class T> T *Cast()
|
||||
{
|
||||
if (bError) return nullptr;
|
||||
@@ -63,8 +75,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TArray<UObject*> Chain;
|
||||
static bool StrEq(const FString& A, const TCHAR* B) { return A.Equals(B, ESearchCase::IgnoreCase); }
|
||||
void SetObj(UObject* InObj) { Obj = InObj; ResultPin = nullptr; }
|
||||
void SetObj(UObject* InObj) { if (InObj) Chain.AddUnique(InObj); Obj = InObj; ResultPin = nullptr; }
|
||||
void SetPin(UEdGraphPin* InPin) { ResultPin = InPin; Obj = nullptr; }
|
||||
MCPFetcher& SetError(const FString& Msg);
|
||||
MCPFetcher& TypeMismatch(const TCHAR* Walker, const TCHAR* Expected);
|
||||
|
||||
@@ -148,32 +148,20 @@ public:
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
static bool Identifies(const FString &Name, const UWorld *World);
|
||||
static bool Identifies(const FString &Name, const UBlueprint *BP);
|
||||
static bool Identifies(const FString &Name, const UActorComponent *C);
|
||||
static bool Identifies(const FString &Name, const UEdGraph *Graph);
|
||||
template<typename T>
|
||||
static bool Identifies(const FString &Name, T&& Obj)
|
||||
{
|
||||
return FormatName(std::forward<T>(Obj)).Equals(Name, ESearchCase::IgnoreCase);
|
||||
}
|
||||
|
||||
// UEdGraphNode also matches by GUID.
|
||||
static bool Identifies(const FString &Name, const UEdGraphNode* Node);
|
||||
static bool Identifies(const FString &Name, const UEdGraphPin *Pin);
|
||||
static bool Identifies(const FString &Name, const FMemberReference &Ref);
|
||||
static bool Identifies(const FString &Name, const FBPVariableDescription &Var);
|
||||
static bool Identifies(const FString &Name, const UStruct *Struct);
|
||||
static bool Identifies(const FString &Name, const UMaterial *Material);
|
||||
static bool Identifies(const FString &Name, const UMaterialInstance *MaterialInstance);
|
||||
static bool Identifies(const FString &Name, const UMaterialFunction *MaterialFunction);
|
||||
static bool Identifies(const FString &Name, const UMaterialExpression *Expression);
|
||||
static bool Identifies(const FString &Name, const UStaticMesh *Mesh);
|
||||
static bool Identifies(const FString &Name, const USkeletalMesh *Mesh);
|
||||
static bool Identifies(const FString &Name, const UAnimSequence *Anim);
|
||||
static bool Identifies(const FString &Name, const UBlendSpace *BlendSpace);
|
||||
static bool Identifies(const FString &Name, const UTexture *Texture);
|
||||
static bool Identifies(const FString &Name, const UScriptStruct *Struct);
|
||||
static bool Identifies(const FString &Name, const UEnum *Enum);
|
||||
static bool Identifies(const FString &Name, const FProperty *Prop);
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
static FString FormatPinType(const FEdGraphPinType& PinType);
|
||||
static FString FormatPinType(UEdGraphPin* Pin);
|
||||
static FString FormatNodeTitle(const UEdGraphNode *Node);
|
||||
|
||||
// ----- Asset path helpers -----
|
||||
// Splits "/Game/Foo/Bar" into PackagePath="/Game/Foo" and AssetName="Bar".
|
||||
@@ -282,12 +270,19 @@ public:
|
||||
static FString ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action);
|
||||
static TArray<TSharedPtr<FEdGraphSchemaAction>> SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults = 0, bool ExactMatch = false);
|
||||
|
||||
// ----- Pre/Post edit -----
|
||||
// Call before and after modifying objects. Walks the list looking for
|
||||
// known parent types (UMaterial, UBlueprint, etc.) and issues the
|
||||
// appropriate notifications.
|
||||
static void PreEdit(const TArray<UObject*>& Objects);
|
||||
static void PostEdit(const TArray<UObject*>& Objects);
|
||||
|
||||
// ----- Editable template -----
|
||||
// Given an object, returns the appropriate template object for generic
|
||||
// property editing, or nullptr if the type isn't whitelisted.
|
||||
// UBlueprint → CDO; UMaterial, UActorComponent, etc. → as-is.
|
||||
static UObject* GetEditableTemplate(UObject* Obj, MCPErrorCallback Error);
|
||||
static TArray<FProperty*> BlueprintVisibleProperties(UObject* Obj, const FString& Query = FString());
|
||||
static UObject* GetTemplate(UObject* Obj, MCPErrorCallback Error);
|
||||
static TArray<FProperty*> SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal);
|
||||
|
||||
static FProperty* FindPropertyByName(UObject* Obj, const FString& Name, MCPErrorCallback Error = nullptr);
|
||||
static FString GetPropertyValueText(UObject* Container, FProperty* Prop);
|
||||
|
||||
@@ -1720,7 +1720,6 @@ p_thread(Info *info) { /* ... thread */
|
||||
|
||||
/* Write general information. */
|
||||
WRITE_VALUE(thread->status, uint8_t);
|
||||
WRITE_VALUE(thread->nextid, uint64_t);
|
||||
WRITE_VALUE(eris_savestackidx(thread,
|
||||
eris_restorestack(thread, thread->errfunc)), size_t);
|
||||
/* These are only used while a thread is being executed or can be deduced:
|
||||
@@ -1887,7 +1886,6 @@ u_thread(Info *info) { /* ... */
|
||||
|
||||
/* Read general information. */
|
||||
thread->status = READ_VALUE(uint8_t);
|
||||
thread->nextid = READ_VALUE(uint64_t);
|
||||
thread->errfunc = eris_savestack(thread,
|
||||
eris_restorestackidx(thread, READ_VALUE(size_t)));
|
||||
if (thread->errfunc) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user