191 lines
5.7 KiB
C++
191 lines
5.7 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "MCPHandler.h"
|
|
#include "MCPFetcher.h"
|
|
#include "MCPUtils.h"
|
|
#include "Engine/Blueprint.h"
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
|
#include "Blueprint_SetVariableMetadata.generated.h"
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
|
|
UCLASS()
|
|
class UMCP_Blueprint_SetVariableMetadata : public UObject, public IMCPHandler
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
FString Blueprint;
|
|
|
|
UPROPERTY(meta=(Description="Name of the variable to modify"))
|
|
FString Variable;
|
|
|
|
UPROPERTY(meta=(Optional, Description="Category to assign the variable to"))
|
|
FString Category;
|
|
|
|
UPROPERTY(meta=(Optional, Description="Tooltip text for the variable"))
|
|
FString Tooltip;
|
|
|
|
UPROPERTY(meta=(Optional, Description="Replication mode: none, replicated, or repNotify"))
|
|
FString Replication;
|
|
|
|
UPROPERTY(meta=(Optional, Description="If true, expose this variable on spawn"))
|
|
bool ExposeOnSpawn = false;
|
|
|
|
UPROPERTY(meta=(Optional, Description="If true, mark the variable as private"))
|
|
bool IsPrivate = false;
|
|
|
|
UPROPERTY(meta=(Optional, Description="Editability mode: editAnywhere, editDefaultsOnly, editInstanceOnly, or none"))
|
|
FString Editability;
|
|
|
|
virtual FString GetDescription() const override
|
|
{
|
|
return TEXT("Set variable metadata properties such as category, tooltip, "
|
|
"replication, editability, and visibility flags.");
|
|
}
|
|
|
|
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
|
{
|
|
MCPFetcher F(Result);
|
|
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
if (!BP) return;
|
|
|
|
// Find the variable using Identifies for consistent name matching
|
|
FBPVariableDescription* VarDesc = nullptr;
|
|
for (FBPVariableDescription& Var : BP->NewVariables)
|
|
{
|
|
if (MCPUtils::FormatName(Var) == Variable ||
|
|
Var.VarName.ToString().Equals(Variable, ESearchCase::IgnoreCase))
|
|
{
|
|
VarDesc = &Var;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!VarDesc)
|
|
{
|
|
Result.Appendf(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));
|
|
}
|
|
return;
|
|
}
|
|
|
|
FName VarFName = VarDesc->VarName;
|
|
int32 ChangeCount = 0;
|
|
F.PreEdit();
|
|
|
|
// Category
|
|
if (Json->HasField(TEXT("category")))
|
|
{
|
|
VarDesc->Category = FText::FromString(Category);
|
|
FBlueprintEditorUtils::SetBlueprintVariableCategory(BP, VarFName, nullptr, FText::FromString(Category));
|
|
Result.Appendf(TEXT("Set category to '%s'.\n"), *Category);
|
|
ChangeCount++;
|
|
}
|
|
|
|
// Tooltip
|
|
if (Json->HasField(TEXT("tooltip")))
|
|
{
|
|
FBlueprintEditorUtils::SetBlueprintVariableMetaData(BP, VarFName, nullptr, TEXT("tooltip"), Tooltip);
|
|
Result.Appendf(TEXT("Set tooltip to '%s'.\n"), *Tooltip);
|
|
ChangeCount++;
|
|
}
|
|
|
|
// Replication
|
|
if (Json->HasField(TEXT("replication")))
|
|
{
|
|
if (Replication == TEXT("none"))
|
|
{
|
|
VarDesc->PropertyFlags &= ~CPF_Net;
|
|
VarDesc->PropertyFlags &= ~CPF_RepNotify;
|
|
VarDesc->RepNotifyFunc = NAME_None;
|
|
}
|
|
else if (Replication == TEXT("replicated"))
|
|
{
|
|
VarDesc->PropertyFlags |= CPF_Net;
|
|
VarDesc->PropertyFlags &= ~CPF_RepNotify;
|
|
VarDesc->RepNotifyFunc = NAME_None;
|
|
}
|
|
else if (Replication == TEXT("repNotify"))
|
|
{
|
|
VarDesc->PropertyFlags |= CPF_Net | CPF_RepNotify;
|
|
VarDesc->RepNotifyFunc = FName(*FString::Printf(TEXT("OnRep_%s"), *Variable));
|
|
}
|
|
else
|
|
{
|
|
Result.Appendf(TEXT("ERROR: Invalid replication value '%s'. Valid: none, replicated, repNotify\n"), *Replication);
|
|
return;
|
|
}
|
|
Result.Appendf(TEXT("Set replication to '%s'.\n"), *Replication);
|
|
ChangeCount++;
|
|
}
|
|
|
|
// ExposeOnSpawn
|
|
if (Json->HasField(TEXT("exposeOnSpawn")))
|
|
{
|
|
if (ExposeOnSpawn)
|
|
VarDesc->PropertyFlags |= CPF_ExposeOnSpawn;
|
|
else
|
|
VarDesc->PropertyFlags &= ~CPF_ExposeOnSpawn;
|
|
Result.Appendf(TEXT("Set exposeOnSpawn to %s.\n"), ExposeOnSpawn ? TEXT("true") : TEXT("false"));
|
|
ChangeCount++;
|
|
}
|
|
|
|
// isPrivate
|
|
if (Json->HasField(TEXT("isPrivate")))
|
|
{
|
|
FBlueprintEditorUtils::SetBlueprintVariableMetaData(BP, VarFName, nullptr,
|
|
TEXT("BlueprintPrivate"), IsPrivate ? TEXT("true") : TEXT("false"));
|
|
Result.Appendf(TEXT("Set isPrivate to %s.\n"), IsPrivate ? TEXT("true") : TEXT("false"));
|
|
ChangeCount++;
|
|
}
|
|
|
|
// Editability
|
|
if (Json->HasField(TEXT("editability")))
|
|
{
|
|
VarDesc->PropertyFlags &= ~(CPF_Edit | CPF_DisableEditOnInstance | CPF_DisableEditOnTemplate);
|
|
|
|
if (Editability == TEXT("editAnywhere"))
|
|
{
|
|
VarDesc->PropertyFlags |= CPF_Edit;
|
|
}
|
|
else if (Editability == TEXT("editDefaultsOnly"))
|
|
{
|
|
VarDesc->PropertyFlags |= CPF_Edit | CPF_DisableEditOnInstance;
|
|
}
|
|
else if (Editability == TEXT("editInstanceOnly"))
|
|
{
|
|
VarDesc->PropertyFlags |= CPF_Edit | CPF_DisableEditOnTemplate;
|
|
}
|
|
else if (Editability != TEXT("none"))
|
|
{
|
|
Result.Appendf(TEXT("ERROR: Invalid editability value '%s'. Valid: editAnywhere, editDefaultsOnly, editInstanceOnly, none\n"), *Editability);
|
|
return;
|
|
}
|
|
Result.Appendf(TEXT("Set editability to '%s'.\n"), *Editability);
|
|
ChangeCount++;
|
|
}
|
|
|
|
if (ChangeCount == 0)
|
|
{
|
|
Result.Append(TEXT("ERROR: No metadata fields specified. Provide at least one of: category, tooltip, replication, exposeOnSpawn, isPrivate, editability\n"));
|
|
return;
|
|
}
|
|
|
|
F.PostEdit();
|
|
bool bSaved = MCPUtils::SaveBlueprintPackage(BP);
|
|
|
|
Result.Appendf(TEXT("Updated %d field(s) on %s in %s.%s\n"),
|
|
ChangeCount, *VarFName.ToString(), *MCPUtils::FormatName(BP),
|
|
bSaved ? TEXT("") : TEXT(" WARNING: save failed."));
|
|
}
|
|
};
|