flockbay 0.10.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +56 -0
  2. package/bin/flockbay-mcp.mjs +56 -0
  3. package/bin/flockbay.mjs +78 -0
  4. package/dist/codex/flockbayMcpStdioBridge.cjs +383 -0
  5. package/dist/codex/flockbayMcpStdioBridge.d.cts +2 -0
  6. package/dist/codex/flockbayMcpStdioBridge.d.mts +2 -0
  7. package/dist/codex/flockbayMcpStdioBridge.mjs +381 -0
  8. package/dist/flockbayScreenshotGate-DJX3Is5d.mjs +136 -0
  9. package/dist/flockbayScreenshotGate-DkxU24cR.cjs +138 -0
  10. package/dist/index--o4BPz5o.cjs +10311 -0
  11. package/dist/index-CUp3juDS.mjs +10268 -0
  12. package/dist/index.cjs +43 -0
  13. package/dist/index.d.cts +1 -0
  14. package/dist/index.d.mts +1 -0
  15. package/dist/index.mjs +40 -0
  16. package/dist/lib.cjs +33 -0
  17. package/dist/lib.d.cts +957 -0
  18. package/dist/lib.d.mts +957 -0
  19. package/dist/lib.mjs +23 -0
  20. package/dist/runCodex-D3eT-TvB.cjs +3449 -0
  21. package/dist/runCodex-o6PCbHQ7.mjs +3446 -0
  22. package/dist/runGemini-Bt0oEj_g.mjs +3183 -0
  23. package/dist/runGemini-CBxZp6I7.cjs +3185 -0
  24. package/dist/types-C-jnUdn_.cjs +4498 -0
  25. package/dist/types-DGd6ea2Z.mjs +4450 -0
  26. package/kits/kit.open_world/kit.json +59 -0
  27. package/package.json +130 -0
  28. package/scripts/claude_local_launcher.cjs +73 -0
  29. package/scripts/claude_remote_launcher.cjs +16 -0
  30. package/scripts/claude_version_utils.cjs +391 -0
  31. package/scripts/ripgrep_launcher.cjs +33 -0
  32. package/scripts/session_hook_forwarder.cjs +49 -0
  33. package/scripts/test-codex-abort-history.mjs +77 -0
  34. package/scripts/unpack-tools.cjs +222 -0
  35. package/tools/licenses/difftastic-LICENSE +21 -0
  36. package/tools/licenses/ripgrep-LICENSE +3 -0
  37. package/tools/unreal-mcp/UPSTREAM_VERSION.md +8 -0
  38. package/tools/unreal-mcp/upstream/Docs/README.md +8 -0
  39. package/tools/unreal-mcp/upstream/Docs/Tools/README.md +7 -0
  40. package/tools/unreal-mcp/upstream/Docs/Tools/actor_tools.md +184 -0
  41. package/tools/unreal-mcp/upstream/Docs/Tools/blueprint_tools.md +268 -0
  42. package/tools/unreal-mcp/upstream/Docs/Tools/editor_tools.md +104 -0
  43. package/tools/unreal-mcp/upstream/Docs/Tools/node_tools.md +274 -0
  44. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Config/FilterPlugin.ini +8 -0
  45. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPBlueprintCommands.cpp +1160 -0
  46. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPBlueprintNodeCommands.cpp +924 -0
  47. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPCommonUtils.cpp +709 -0
  48. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPEditorCommands.cpp +896 -0
  49. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPProjectCommands.cpp +72 -0
  50. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPUMGCommands.cpp +544 -0
  51. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/MCPServerRunnable.cpp +321 -0
  52. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/UnrealMCPBridge.cpp +419 -0
  53. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/UnrealMCPModule.cpp +21 -0
  54. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPBlueprintCommands.h +34 -0
  55. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPBlueprintNodeCommands.h +27 -0
  56. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPCommonUtils.h +59 -0
  57. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPEditorCommands.h +40 -0
  58. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPProjectCommands.h +20 -0
  59. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPUMGCommands.h +82 -0
  60. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/MCPServerRunnable.h +34 -0
  61. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/UnrealMCPBridge.h +64 -0
  62. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/UnrealMCPModule.h +22 -0
  63. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/UnrealMCP.Build.cs +78 -0
  64. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/UnrealMCP.uplugin +36 -0
  65. package/tools/unreal-mcp/upstream/Python/README.md +40 -0
  66. package/tools/unreal-mcp/upstream/Python/pyproject.toml +22 -0
  67. package/tools/unreal-mcp/upstream/Python/scripts/actors/test_cube.py +203 -0
  68. package/tools/unreal-mcp/upstream/Python/scripts/blueprints/test_create_and_spawn_blueprints_with_different_components.py +497 -0
  69. package/tools/unreal-mcp/upstream/Python/scripts/blueprints/test_create_and_spawn_cube_blueprint.py +194 -0
  70. package/tools/unreal-mcp/upstream/Python/scripts/node/test_component_reference.py +267 -0
  71. package/tools/unreal-mcp/upstream/Python/scripts/node/test_create_bird_blueprint_with_input_and_camera.py +618 -0
  72. package/tools/unreal-mcp/upstream/Python/scripts/node/test_input_mapping.py +366 -0
  73. package/tools/unreal-mcp/upstream/Python/scripts/node/test_physics_variables.py +390 -0
  74. package/tools/unreal-mcp/upstream/Python/tools/blueprint_tools.py +420 -0
  75. package/tools/unreal-mcp/upstream/Python/tools/editor_tools.py +369 -0
  76. package/tools/unreal-mcp/upstream/Python/tools/node_tools.py +430 -0
  77. package/tools/unreal-mcp/upstream/Python/tools/project_tools.py +64 -0
  78. package/tools/unreal-mcp/upstream/Python/tools/umg_tools.py +333 -0
  79. package/tools/unreal-mcp/upstream/Python/unreal_mcp_server.py +398 -0
  80. package/tools/unreal-mcp/upstream/Python/uv.lock +521 -0
@@ -0,0 +1,72 @@
1
+ #include "Commands/UnrealMCPProjectCommands.h"
2
+ #include "Commands/UnrealMCPCommonUtils.h"
3
+ #include "GameFramework/InputSettings.h"
4
+
5
+ FUnrealMCPProjectCommands::FUnrealMCPProjectCommands()
6
+ {
7
+ }
8
+
9
+ TSharedPtr<FJsonObject> FUnrealMCPProjectCommands::HandleCommand(const FString& CommandType, const TSharedPtr<FJsonObject>& Params)
10
+ {
11
+ if (CommandType == TEXT("create_input_mapping"))
12
+ {
13
+ return HandleCreateInputMapping(Params);
14
+ }
15
+
16
+ return FUnrealMCPCommonUtils::CreateErrorResponse(FString::Printf(TEXT("Unknown project command: %s"), *CommandType));
17
+ }
18
+
19
+ TSharedPtr<FJsonObject> FUnrealMCPProjectCommands::HandleCreateInputMapping(const TSharedPtr<FJsonObject>& Params)
20
+ {
21
+ // Get required parameters
22
+ FString ActionName;
23
+ if (!Params->TryGetStringField(TEXT("action_name"), ActionName))
24
+ {
25
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Missing 'action_name' parameter"));
26
+ }
27
+
28
+ FString Key;
29
+ if (!Params->TryGetStringField(TEXT("key"), Key))
30
+ {
31
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Missing 'key' parameter"));
32
+ }
33
+
34
+ // Get the input settings
35
+ UInputSettings* InputSettings = GetMutableDefault<UInputSettings>();
36
+ if (!InputSettings)
37
+ {
38
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Failed to get input settings"));
39
+ }
40
+
41
+ // Create the input action mapping
42
+ FInputActionKeyMapping ActionMapping;
43
+ ActionMapping.ActionName = FName(*ActionName);
44
+ ActionMapping.Key = FKey(*Key);
45
+
46
+ // Add modifiers if provided
47
+ if (Params->HasField(TEXT("shift")))
48
+ {
49
+ ActionMapping.bShift = Params->GetBoolField(TEXT("shift"));
50
+ }
51
+ if (Params->HasField(TEXT("ctrl")))
52
+ {
53
+ ActionMapping.bCtrl = Params->GetBoolField(TEXT("ctrl"));
54
+ }
55
+ if (Params->HasField(TEXT("alt")))
56
+ {
57
+ ActionMapping.bAlt = Params->GetBoolField(TEXT("alt"));
58
+ }
59
+ if (Params->HasField(TEXT("cmd")))
60
+ {
61
+ ActionMapping.bCmd = Params->GetBoolField(TEXT("cmd"));
62
+ }
63
+
64
+ // Add the mapping
65
+ InputSettings->AddActionMapping(ActionMapping);
66
+ InputSettings->SaveConfig();
67
+
68
+ TSharedPtr<FJsonObject> ResultObj = MakeShared<FJsonObject>();
69
+ ResultObj->SetStringField(TEXT("action_name"), ActionName);
70
+ ResultObj->SetStringField(TEXT("key"), Key);
71
+ return ResultObj;
72
+ }
@@ -0,0 +1,544 @@
1
+ #include "Commands/UnrealMCPUMGCommands.h"
2
+ #include "Commands/UnrealMCPCommonUtils.h"
3
+ #include "Editor.h"
4
+ #include "EditorAssetLibrary.h"
5
+ #include "AssetRegistry/AssetRegistryModule.h"
6
+ #include "Blueprint/UserWidget.h"
7
+ #include "Components/TextBlock.h"
8
+ #include "WidgetBlueprint.h"
9
+ // We'll create widgets using regular Factory classes
10
+ #include "Factories/Factory.h"
11
+ // Remove problematic includes that don't exist in UE 5.5
12
+ // #include "UMGEditorSubsystem.h"
13
+ // #include "WidgetBlueprintFactory.h"
14
+ #include "WidgetBlueprintEditor.h"
15
+ #include "Blueprint/WidgetTree.h"
16
+ #include "Components/CanvasPanel.h"
17
+ #include "Components/CanvasPanelSlot.h"
18
+ #include "JsonObjectConverter.h"
19
+ #include "Kismet2/BlueprintEditorUtils.h"
20
+ #include "Components/Button.h"
21
+ #include "K2Node_FunctionEntry.h"
22
+ #include "K2Node_CallFunction.h"
23
+ #include "K2Node_VariableGet.h"
24
+ #include "K2Node_VariableSet.h"
25
+ #include "Kismet/GameplayStatics.h"
26
+ #include "Kismet2/KismetEditorUtilities.h"
27
+ #include "K2Node_Event.h"
28
+
29
+ FUnrealMCPUMGCommands::FUnrealMCPUMGCommands()
30
+ {
31
+ }
32
+
33
+ TSharedPtr<FJsonObject> FUnrealMCPUMGCommands::HandleCommand(const FString& CommandName, const TSharedPtr<FJsonObject>& Params)
34
+ {
35
+ if (CommandName == TEXT("create_umg_widget_blueprint"))
36
+ {
37
+ return HandleCreateUMGWidgetBlueprint(Params);
38
+ }
39
+ else if (CommandName == TEXT("add_text_block_to_widget"))
40
+ {
41
+ return HandleAddTextBlockToWidget(Params);
42
+ }
43
+ else if (CommandName == TEXT("add_widget_to_viewport"))
44
+ {
45
+ return HandleAddWidgetToViewport(Params);
46
+ }
47
+ else if (CommandName == TEXT("add_button_to_widget"))
48
+ {
49
+ return HandleAddButtonToWidget(Params);
50
+ }
51
+ else if (CommandName == TEXT("bind_widget_event"))
52
+ {
53
+ return HandleBindWidgetEvent(Params);
54
+ }
55
+ else if (CommandName == TEXT("set_text_block_binding"))
56
+ {
57
+ return HandleSetTextBlockBinding(Params);
58
+ }
59
+
60
+ return FUnrealMCPCommonUtils::CreateErrorResponse(FString::Printf(TEXT("Unknown UMG command: %s"), *CommandName));
61
+ }
62
+
63
+ TSharedPtr<FJsonObject> FUnrealMCPUMGCommands::HandleCreateUMGWidgetBlueprint(const TSharedPtr<FJsonObject>& Params)
64
+ {
65
+ // Get required parameters
66
+ FString BlueprintName;
67
+ if (!Params->TryGetStringField(TEXT("name"), BlueprintName))
68
+ {
69
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Missing 'name' parameter"));
70
+ }
71
+
72
+ // Create the full asset path
73
+ FString PackagePath = TEXT("/Game/Widgets/");
74
+ FString AssetName = BlueprintName;
75
+ FString FullPath = PackagePath + AssetName;
76
+
77
+ // Check if asset already exists
78
+ if (UEditorAssetLibrary::DoesAssetExist(FullPath))
79
+ {
80
+ return FUnrealMCPCommonUtils::CreateErrorResponse(FString::Printf(TEXT("Widget Blueprint '%s' already exists"), *BlueprintName));
81
+ }
82
+
83
+ // Create package
84
+ UPackage* Package = CreatePackage(*FullPath);
85
+ if (!Package)
86
+ {
87
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Failed to create package"));
88
+ }
89
+
90
+ // Create Widget Blueprint using KismetEditorUtilities
91
+ UBlueprint* NewBlueprint = FKismetEditorUtilities::CreateBlueprint(
92
+ UUserWidget::StaticClass(), // Parent class
93
+ Package, // Outer package
94
+ FName(*AssetName), // Blueprint name
95
+ BPTYPE_Normal, // Blueprint type
96
+ UBlueprint::StaticClass(), // Blueprint class
97
+ UBlueprintGeneratedClass::StaticClass(), // Generated class
98
+ FName("CreateUMGWidget") // Creation method name
99
+ );
100
+
101
+ // Make sure the Blueprint was created successfully
102
+ UWidgetBlueprint* WidgetBlueprint = Cast<UWidgetBlueprint>(NewBlueprint);
103
+ if (!WidgetBlueprint)
104
+ {
105
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Failed to create Widget Blueprint"));
106
+ }
107
+
108
+ // Add a default Canvas Panel if one doesn't exist
109
+ if (!WidgetBlueprint->WidgetTree->RootWidget)
110
+ {
111
+ UCanvasPanel* RootCanvas = WidgetBlueprint->WidgetTree->ConstructWidget<UCanvasPanel>(UCanvasPanel::StaticClass());
112
+ WidgetBlueprint->WidgetTree->RootWidget = RootCanvas;
113
+ }
114
+
115
+ // Mark the package dirty and notify asset registry
116
+ Package->MarkPackageDirty();
117
+ FAssetRegistryModule::AssetCreated(WidgetBlueprint);
118
+
119
+ // Compile the blueprint
120
+ FKismetEditorUtilities::CompileBlueprint(WidgetBlueprint);
121
+
122
+ // Create success response
123
+ TSharedPtr<FJsonObject> ResultObj = MakeShared<FJsonObject>();
124
+ ResultObj->SetStringField(TEXT("name"), BlueprintName);
125
+ ResultObj->SetStringField(TEXT("path"), FullPath);
126
+ return ResultObj;
127
+ }
128
+
129
+ TSharedPtr<FJsonObject> FUnrealMCPUMGCommands::HandleAddTextBlockToWidget(const TSharedPtr<FJsonObject>& Params)
130
+ {
131
+ // Get required parameters
132
+ FString BlueprintName;
133
+ if (!Params->TryGetStringField(TEXT("blueprint_name"), BlueprintName))
134
+ {
135
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Missing 'blueprint_name' parameter"));
136
+ }
137
+
138
+ FString WidgetName;
139
+ if (!Params->TryGetStringField(TEXT("widget_name"), WidgetName))
140
+ {
141
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Missing 'widget_name' parameter"));
142
+ }
143
+
144
+ // Find the Widget Blueprint
145
+ FString FullPath = TEXT("/Game/Widgets/") + BlueprintName;
146
+ UWidgetBlueprint* WidgetBlueprint = Cast<UWidgetBlueprint>(UEditorAssetLibrary::LoadAsset(FullPath));
147
+ if (!WidgetBlueprint)
148
+ {
149
+ return FUnrealMCPCommonUtils::CreateErrorResponse(FString::Printf(TEXT("Widget Blueprint '%s' not found"), *BlueprintName));
150
+ }
151
+
152
+ // Get optional parameters
153
+ FString InitialText = TEXT("New Text Block");
154
+ Params->TryGetStringField(TEXT("text"), InitialText);
155
+
156
+ FVector2D Position(0.0f, 0.0f);
157
+ if (Params->HasField(TEXT("position")))
158
+ {
159
+ const TArray<TSharedPtr<FJsonValue>>* PosArray;
160
+ if (Params->TryGetArrayField(TEXT("position"), PosArray) && PosArray->Num() >= 2)
161
+ {
162
+ Position.X = (*PosArray)[0]->AsNumber();
163
+ Position.Y = (*PosArray)[1]->AsNumber();
164
+ }
165
+ }
166
+
167
+ // Create Text Block widget
168
+ UTextBlock* TextBlock = WidgetBlueprint->WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), *WidgetName);
169
+ if (!TextBlock)
170
+ {
171
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Failed to create Text Block widget"));
172
+ }
173
+
174
+ // Set initial text
175
+ TextBlock->SetText(FText::FromString(InitialText));
176
+
177
+ // Add to canvas panel
178
+ UCanvasPanel* RootCanvas = Cast<UCanvasPanel>(WidgetBlueprint->WidgetTree->RootWidget);
179
+ if (!RootCanvas)
180
+ {
181
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Root Canvas Panel not found"));
182
+ }
183
+
184
+ UCanvasPanelSlot* PanelSlot = RootCanvas->AddChildToCanvas(TextBlock);
185
+ PanelSlot->SetPosition(Position);
186
+
187
+ // Mark the package dirty and compile
188
+ WidgetBlueprint->MarkPackageDirty();
189
+ FKismetEditorUtilities::CompileBlueprint(WidgetBlueprint);
190
+
191
+ // Create success response
192
+ TSharedPtr<FJsonObject> ResultObj = MakeShared<FJsonObject>();
193
+ ResultObj->SetStringField(TEXT("widget_name"), WidgetName);
194
+ ResultObj->SetStringField(TEXT("text"), InitialText);
195
+ return ResultObj;
196
+ }
197
+
198
+ TSharedPtr<FJsonObject> FUnrealMCPUMGCommands::HandleAddWidgetToViewport(const TSharedPtr<FJsonObject>& Params)
199
+ {
200
+ // Get required parameters
201
+ FString BlueprintName;
202
+ if (!Params->TryGetStringField(TEXT("blueprint_name"), BlueprintName))
203
+ {
204
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Missing 'blueprint_name' parameter"));
205
+ }
206
+
207
+ // Find the Widget Blueprint
208
+ FString FullPath = TEXT("/Game/Widgets/") + BlueprintName;
209
+ UWidgetBlueprint* WidgetBlueprint = Cast<UWidgetBlueprint>(UEditorAssetLibrary::LoadAsset(FullPath));
210
+ if (!WidgetBlueprint)
211
+ {
212
+ return FUnrealMCPCommonUtils::CreateErrorResponse(FString::Printf(TEXT("Widget Blueprint '%s' not found"), *BlueprintName));
213
+ }
214
+
215
+ // Get optional Z-order parameter
216
+ int32 ZOrder = 0;
217
+ Params->TryGetNumberField(TEXT("z_order"), ZOrder);
218
+
219
+ // Create widget instance
220
+ UClass* WidgetClass = WidgetBlueprint->GeneratedClass;
221
+ if (!WidgetClass)
222
+ {
223
+ return FUnrealMCPCommonUtils::CreateErrorResponse(TEXT("Failed to get widget class"));
224
+ }
225
+
226
+ // Note: This creates the widget but doesn't add it to viewport
227
+ // The actual addition to viewport should be done through Blueprint nodes
228
+ // as it requires a game context
229
+
230
+ // Create success response with instructions
231
+ TSharedPtr<FJsonObject> ResultObj = MakeShared<FJsonObject>();
232
+ ResultObj->SetStringField(TEXT("blueprint_name"), BlueprintName);
233
+ ResultObj->SetStringField(TEXT("class_path"), WidgetClass->GetPathName());
234
+ ResultObj->SetNumberField(TEXT("z_order"), ZOrder);
235
+ ResultObj->SetStringField(TEXT("note"), TEXT("Widget class ready. Use CreateWidget and AddToViewport nodes in Blueprint to display in game."));
236
+ return ResultObj;
237
+ }
238
+
239
+ TSharedPtr<FJsonObject> FUnrealMCPUMGCommands::HandleAddButtonToWidget(const TSharedPtr<FJsonObject>& Params)
240
+ {
241
+ TSharedPtr<FJsonObject> Response = MakeShared<FJsonObject>();
242
+
243
+ // Get required parameters
244
+ FString BlueprintName;
245
+ if (!Params->TryGetStringField(TEXT("blueprint_name"), BlueprintName))
246
+ {
247
+ Response->SetStringField(TEXT("error"), TEXT("Missing blueprint_name parameter"));
248
+ return Response;
249
+ }
250
+
251
+ FString WidgetName;
252
+ if (!Params->TryGetStringField(TEXT("widget_name"), WidgetName))
253
+ {
254
+ Response->SetStringField(TEXT("error"), TEXT("Missing widget_name parameter"));
255
+ return Response;
256
+ }
257
+
258
+ FString ButtonText;
259
+ if (!Params->TryGetStringField(TEXT("text"), ButtonText))
260
+ {
261
+ Response->SetStringField(TEXT("error"), TEXT("Missing text parameter"));
262
+ return Response;
263
+ }
264
+
265
+ // Load the Widget Blueprint
266
+ const FString BlueprintPath = FString::Printf(TEXT("/Game/Widgets/%s.%s"), *BlueprintName, *BlueprintName);
267
+ UWidgetBlueprint* WidgetBlueprint = Cast<UWidgetBlueprint>(UEditorAssetLibrary::LoadAsset(BlueprintPath));
268
+ if (!WidgetBlueprint)
269
+ {
270
+ Response->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to load Widget Blueprint: %s"), *BlueprintPath));
271
+ return Response;
272
+ }
273
+
274
+ // Create Button widget
275
+ UButton* Button = NewObject<UButton>(WidgetBlueprint->GeneratedClass->GetDefaultObject(), UButton::StaticClass(), *WidgetName);
276
+ if (!Button)
277
+ {
278
+ Response->SetStringField(TEXT("error"), TEXT("Failed to create Button widget"));
279
+ return Response;
280
+ }
281
+
282
+ // Set button text
283
+ UTextBlock* ButtonTextBlock = NewObject<UTextBlock>(Button, UTextBlock::StaticClass(), *(WidgetName + TEXT("_Text")));
284
+ if (ButtonTextBlock)
285
+ {
286
+ ButtonTextBlock->SetText(FText::FromString(ButtonText));
287
+ Button->AddChild(ButtonTextBlock);
288
+ }
289
+
290
+ // Get canvas panel and add button
291
+ UCanvasPanel* RootCanvas = Cast<UCanvasPanel>(WidgetBlueprint->WidgetTree->RootWidget);
292
+ if (!RootCanvas)
293
+ {
294
+ Response->SetStringField(TEXT("error"), TEXT("Root widget is not a Canvas Panel"));
295
+ return Response;
296
+ }
297
+
298
+ // Add to canvas and set position
299
+ UCanvasPanelSlot* ButtonSlot = RootCanvas->AddChildToCanvas(Button);
300
+ if (ButtonSlot)
301
+ {
302
+ const TArray<TSharedPtr<FJsonValue>>* Position;
303
+ if (Params->TryGetArrayField(TEXT("position"), Position) && Position->Num() >= 2)
304
+ {
305
+ FVector2D Pos(
306
+ (*Position)[0]->AsNumber(),
307
+ (*Position)[1]->AsNumber()
308
+ );
309
+ ButtonSlot->SetPosition(Pos);
310
+ }
311
+ }
312
+
313
+ // Save the Widget Blueprint
314
+ FKismetEditorUtilities::CompileBlueprint(WidgetBlueprint);
315
+ UEditorAssetLibrary::SaveAsset(BlueprintPath, false);
316
+
317
+ Response->SetBoolField(TEXT("success"), true);
318
+ Response->SetStringField(TEXT("widget_name"), WidgetName);
319
+ return Response;
320
+ }
321
+
322
+ TSharedPtr<FJsonObject> FUnrealMCPUMGCommands::HandleBindWidgetEvent(const TSharedPtr<FJsonObject>& Params)
323
+ {
324
+ TSharedPtr<FJsonObject> Response = MakeShared<FJsonObject>();
325
+
326
+ // Get required parameters
327
+ FString BlueprintName;
328
+ if (!Params->TryGetStringField(TEXT("blueprint_name"), BlueprintName))
329
+ {
330
+ Response->SetStringField(TEXT("error"), TEXT("Missing blueprint_name parameter"));
331
+ return Response;
332
+ }
333
+
334
+ FString WidgetName;
335
+ if (!Params->TryGetStringField(TEXT("widget_name"), WidgetName))
336
+ {
337
+ Response->SetStringField(TEXT("error"), TEXT("Missing widget_name parameter"));
338
+ return Response;
339
+ }
340
+
341
+ FString EventName;
342
+ if (!Params->TryGetStringField(TEXT("event_name"), EventName))
343
+ {
344
+ Response->SetStringField(TEXT("error"), TEXT("Missing event_name parameter"));
345
+ return Response;
346
+ }
347
+
348
+ // Load the Widget Blueprint
349
+ const FString BlueprintPath = FString::Printf(TEXT("/Game/Widgets/%s.%s"), *BlueprintName, *BlueprintName);
350
+ UWidgetBlueprint* WidgetBlueprint = Cast<UWidgetBlueprint>(UEditorAssetLibrary::LoadAsset(BlueprintPath));
351
+ if (!WidgetBlueprint)
352
+ {
353
+ Response->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to load Widget Blueprint: %s"), *BlueprintPath));
354
+ return Response;
355
+ }
356
+
357
+ // Create the event graph if it doesn't exist
358
+ UEdGraph* EventGraph = FBlueprintEditorUtils::FindEventGraph(WidgetBlueprint);
359
+ if (!EventGraph)
360
+ {
361
+ Response->SetStringField(TEXT("error"), TEXT("Failed to find or create event graph"));
362
+ return Response;
363
+ }
364
+
365
+ // Find the widget in the blueprint
366
+ UWidget* Widget = WidgetBlueprint->WidgetTree->FindWidget(*WidgetName);
367
+ if (!Widget)
368
+ {
369
+ Response->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to find widget: %s"), *WidgetName));
370
+ return Response;
371
+ }
372
+
373
+ // Create the event node (e.g., OnClicked for buttons)
374
+ UK2Node_Event* EventNode = nullptr;
375
+
376
+ // Find existing nodes first
377
+ TArray<UK2Node_Event*> AllEventNodes;
378
+ FBlueprintEditorUtils::GetAllNodesOfClass<UK2Node_Event>(WidgetBlueprint, AllEventNodes);
379
+
380
+ for (UK2Node_Event* Node : AllEventNodes)
381
+ {
382
+ if (Node->CustomFunctionName == FName(*EventName) && Node->EventReference.GetMemberParentClass() == Widget->GetClass())
383
+ {
384
+ EventNode = Node;
385
+ break;
386
+ }
387
+ }
388
+
389
+ // If no existing node, create a new one
390
+ if (!EventNode)
391
+ {
392
+ // Calculate position - place it below existing nodes
393
+ float MaxHeight = 0.0f;
394
+ for (UEdGraphNode* Node : EventGraph->Nodes)
395
+ {
396
+ MaxHeight = FMath::Max(MaxHeight, Node->NodePosY);
397
+ }
398
+
399
+ const FVector2D NodePos(200, MaxHeight + 200);
400
+
401
+ // Call CreateNewBoundEventForClass, which returns void, so we can't capture the return value directly
402
+ // We'll need to find the node after creating it
403
+ FKismetEditorUtilities::CreateNewBoundEventForClass(
404
+ Widget->GetClass(),
405
+ FName(*EventName),
406
+ WidgetBlueprint,
407
+ nullptr // We don't need a specific property binding
408
+ );
409
+
410
+ // Now find the newly created node
411
+ TArray<UK2Node_Event*> UpdatedEventNodes;
412
+ FBlueprintEditorUtils::GetAllNodesOfClass<UK2Node_Event>(WidgetBlueprint, UpdatedEventNodes);
413
+
414
+ for (UK2Node_Event* Node : UpdatedEventNodes)
415
+ {
416
+ if (Node->CustomFunctionName == FName(*EventName) && Node->EventReference.GetMemberParentClass() == Widget->GetClass())
417
+ {
418
+ EventNode = Node;
419
+
420
+ // Set position of the node
421
+ EventNode->NodePosX = NodePos.X;
422
+ EventNode->NodePosY = NodePos.Y;
423
+
424
+ break;
425
+ }
426
+ }
427
+ }
428
+
429
+ if (!EventNode)
430
+ {
431
+ Response->SetStringField(TEXT("error"), TEXT("Failed to create event node"));
432
+ return Response;
433
+ }
434
+
435
+ // Save the Widget Blueprint
436
+ FKismetEditorUtilities::CompileBlueprint(WidgetBlueprint);
437
+ UEditorAssetLibrary::SaveAsset(BlueprintPath, false);
438
+
439
+ Response->SetBoolField(TEXT("success"), true);
440
+ Response->SetStringField(TEXT("event_name"), EventName);
441
+ return Response;
442
+ }
443
+
444
+ TSharedPtr<FJsonObject> FUnrealMCPUMGCommands::HandleSetTextBlockBinding(const TSharedPtr<FJsonObject>& Params)
445
+ {
446
+ TSharedPtr<FJsonObject> Response = MakeShared<FJsonObject>();
447
+
448
+ // Get required parameters
449
+ FString BlueprintName;
450
+ if (!Params->TryGetStringField(TEXT("blueprint_name"), BlueprintName))
451
+ {
452
+ Response->SetStringField(TEXT("error"), TEXT("Missing blueprint_name parameter"));
453
+ return Response;
454
+ }
455
+
456
+ FString WidgetName;
457
+ if (!Params->TryGetStringField(TEXT("widget_name"), WidgetName))
458
+ {
459
+ Response->SetStringField(TEXT("error"), TEXT("Missing widget_name parameter"));
460
+ return Response;
461
+ }
462
+
463
+ FString BindingName;
464
+ if (!Params->TryGetStringField(TEXT("binding_name"), BindingName))
465
+ {
466
+ Response->SetStringField(TEXT("error"), TEXT("Missing binding_name parameter"));
467
+ return Response;
468
+ }
469
+
470
+ // Load the Widget Blueprint
471
+ const FString BlueprintPath = FString::Printf(TEXT("/Game/Widgets/%s.%s"), *BlueprintName, *BlueprintName);
472
+ UWidgetBlueprint* WidgetBlueprint = Cast<UWidgetBlueprint>(UEditorAssetLibrary::LoadAsset(BlueprintPath));
473
+ if (!WidgetBlueprint)
474
+ {
475
+ Response->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to load Widget Blueprint: %s"), *BlueprintPath));
476
+ return Response;
477
+ }
478
+
479
+ // Create a variable for binding if it doesn't exist
480
+ FBlueprintEditorUtils::AddMemberVariable(
481
+ WidgetBlueprint,
482
+ FName(*BindingName),
483
+ FEdGraphPinType(UEdGraphSchema_K2::PC_Text, NAME_None, nullptr, EPinContainerType::None, false, FEdGraphTerminalType())
484
+ );
485
+
486
+ // Find the TextBlock widget
487
+ UTextBlock* TextBlock = Cast<UTextBlock>(WidgetBlueprint->WidgetTree->FindWidget(FName(*WidgetName)));
488
+ if (!TextBlock)
489
+ {
490
+ Response->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to find TextBlock widget: %s"), *WidgetName));
491
+ return Response;
492
+ }
493
+
494
+ // Create binding function
495
+ const FString FunctionName = FString::Printf(TEXT("Get%s"), *BindingName);
496
+ UEdGraph* FuncGraph = FBlueprintEditorUtils::CreateNewGraph(
497
+ WidgetBlueprint,
498
+ FName(*FunctionName),
499
+ UEdGraph::StaticClass(),
500
+ UEdGraphSchema_K2::StaticClass()
501
+ );
502
+
503
+ if (FuncGraph)
504
+ {
505
+ // Add the function to the blueprint with proper template parameter
506
+ // Template requires null for last parameter when not using a signature-source
507
+ FBlueprintEditorUtils::AddFunctionGraph<UClass>(WidgetBlueprint, FuncGraph, false, nullptr);
508
+
509
+ // Create entry node
510
+ UK2Node_FunctionEntry* EntryNode = nullptr;
511
+
512
+ // Create entry node - use the API that exists in UE 5.5
513
+ EntryNode = NewObject<UK2Node_FunctionEntry>(FuncGraph);
514
+ FuncGraph->AddNode(EntryNode, false, false);
515
+ EntryNode->NodePosX = 0;
516
+ EntryNode->NodePosY = 0;
517
+ EntryNode->FunctionReference.SetExternalMember(FName(*FunctionName), WidgetBlueprint->GeneratedClass);
518
+ EntryNode->AllocateDefaultPins();
519
+
520
+ // Create get variable node
521
+ UK2Node_VariableGet* GetVarNode = NewObject<UK2Node_VariableGet>(FuncGraph);
522
+ GetVarNode->VariableReference.SetSelfMember(FName(*BindingName));
523
+ FuncGraph->AddNode(GetVarNode, false, false);
524
+ GetVarNode->NodePosX = 200;
525
+ GetVarNode->NodePosY = 0;
526
+ GetVarNode->AllocateDefaultPins();
527
+
528
+ // Connect nodes
529
+ UEdGraphPin* EntryThenPin = EntryNode->FindPin(UEdGraphSchema_K2::PN_Then);
530
+ UEdGraphPin* GetVarOutPin = GetVarNode->FindPin(UEdGraphSchema_K2::PN_ReturnValue);
531
+ if (EntryThenPin && GetVarOutPin)
532
+ {
533
+ EntryThenPin->MakeLinkTo(GetVarOutPin);
534
+ }
535
+ }
536
+
537
+ // Save the Widget Blueprint
538
+ FKismetEditorUtilities::CompileBlueprint(WidgetBlueprint);
539
+ UEditorAssetLibrary::SaveAsset(BlueprintPath, false);
540
+
541
+ Response->SetBoolField(TEXT("success"), true);
542
+ Response->SetStringField(TEXT("binding_name"), BindingName);
543
+ return Response;
544
+ }