ue-mcp 1.2.1 → 1.2.2
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.
- package/dist/context-cli.js +16 -16
- package/dist/engine-observer.js +68 -68
- package/dist/flow/guard.d.ts +26 -37
- package/dist/flow/guard.js +40 -25
- package/dist/flow/guard.js.map +1 -1
- package/dist/flow/guarded-bridge.d.ts +0 -10
- package/dist/flow/guarded-bridge.js +18 -23
- package/dist/flow/guarded-bridge.js.map +1 -1
- package/dist/flow/schema.d.ts +276 -16
- package/dist/flow/task-guards.d.ts +1 -1
- package/dist/flow/task-guards.js +44 -68
- package/dist/flow/task-guards.js.map +1 -1
- package/dist/instructions.js +130 -130
- package/dist/plugin-cli.js +299 -299
- package/dist/tool-counts.json +2 -2
- package/package.json +2 -2
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/EngineStatusHooks.cpp +76 -76
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/EngineStatusHooks.h +27 -27
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerRegistry.cpp +128 -128
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerRegistry.h +63 -63
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_ControlRig.cpp +230 -230
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Struct.cpp +323 -323
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Internal.h +20 -20
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/ChooserHandlers_Nested.cpp +537 -537
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DemoHandlers.h +77 -77
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_Build.cpp +353 -353
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.h +18 -18
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers_InputRuntime.cpp +246 -246
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.cpp +597 -597
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.h +51 -51
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.cpp +878 -878
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers_Sculpt.cpp +449 -449
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers_Function.cpp +275 -275
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers_Graph.cpp +551 -551
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NetworkingHandlers.cpp +531 -531
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NetworkingHandlers.h +28 -28
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PhysicsHandlers.cpp +677 -677
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.cpp +822 -822
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.h +22 -22
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.cpp +218 -218
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.h +17 -17
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/VolumeHelpers_Internal.cpp +46 -46
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/VolumeHelpers_Internal.h +23 -23
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/MCPExternalRegistry.cpp +83 -83
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/UE_MCP_BridgeModule.h +14 -14
- package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Private/UE_MCP_BridgeStatusModule.cpp +37 -37
- package/dist/manifest-signature.d.ts +0 -1
- package/dist/manifest-signature.js +0 -53
- package/dist/manifest-signature.js.map +0 -1
- package/dist/pie/schema.d.ts +0 -791
- package/dist/pie/schema.js +0 -151
- package/dist/pie/schema.js.map +0 -1
- package/dist/watch-cli.js.map +0 -1
- /package/plugin/ue_mcp_bridge/{ue_mcp_bridge.uplugin → UE_MCP_Bridge.uplugin} +0 -0
|
@@ -1,353 +1,353 @@
|
|
|
1
|
-
// Split from EditorHandlers.cpp to keep that file under 3k lines.
|
|
2
|
-
// All functions below are still members of FEditorHandlers - this file is a
|
|
3
|
-
// translation-unit partition, not a new class. Handler registration
|
|
4
|
-
// stays in EditorHandlers.cpp::RegisterHandlers.
|
|
5
|
-
|
|
6
|
-
#include "EditorHandlers.h"
|
|
7
|
-
#include "HandlerRegistry.h"
|
|
8
|
-
#include "HandlerUtils.h"
|
|
9
|
-
#include "Editor.h"
|
|
10
|
-
#include "Editor/EditorEngine.h"
|
|
11
|
-
#include "FileHelpers.h"
|
|
12
|
-
#include "Engine/World.h"
|
|
13
|
-
#include "Engine/Engine.h"
|
|
14
|
-
#include "GameFramework/Actor.h"
|
|
15
|
-
#include "Misc/Paths.h"
|
|
16
|
-
#include "Misc/FileHelper.h"
|
|
17
|
-
#include "Misc/CommandLine.h"
|
|
18
|
-
#include "HAL/PlatformProcess.h"
|
|
19
|
-
#include "HAL/PlatformFileManager.h"
|
|
20
|
-
#include "HAL/PlatformFile.h"
|
|
21
|
-
#include "Modules/ModuleManager.h"
|
|
22
|
-
#if PLATFORM_WINDOWS
|
|
23
|
-
#include "ILiveCodingModule.h"
|
|
24
|
-
#endif
|
|
25
|
-
#include "Kismet/KismetSystemLibrary.h"
|
|
26
|
-
#include "EditorValidatorSubsystem.h"
|
|
27
|
-
#include "Dom/JsonObject.h"
|
|
28
|
-
#include "Dom/JsonValue.h"
|
|
29
|
-
|
|
30
|
-
TSharedPtr<FJsonValue> FEditorHandlers::BuildLighting(const TSharedPtr<FJsonObject>& Params)
|
|
31
|
-
{
|
|
32
|
-
REQUIRE_EDITOR_WORLD(World);
|
|
33
|
-
|
|
34
|
-
FString Quality = OptionalString(Params, TEXT("quality"), TEXT("Preview"));
|
|
35
|
-
|
|
36
|
-
// Map quality string to console command
|
|
37
|
-
FString Command;
|
|
38
|
-
if (Quality == TEXT("Preview"))
|
|
39
|
-
{
|
|
40
|
-
Command = TEXT("BUILD LIGHTING QUALITY=Preview");
|
|
41
|
-
}
|
|
42
|
-
else if (Quality == TEXT("Medium"))
|
|
43
|
-
{
|
|
44
|
-
Command = TEXT("BUILD LIGHTING QUALITY=Medium");
|
|
45
|
-
}
|
|
46
|
-
else if (Quality == TEXT("High"))
|
|
47
|
-
{
|
|
48
|
-
Command = TEXT("BUILD LIGHTING QUALITY=High");
|
|
49
|
-
}
|
|
50
|
-
else if (Quality == TEXT("Production"))
|
|
51
|
-
{
|
|
52
|
-
Command = TEXT("BUILD LIGHTING QUALITY=Production");
|
|
53
|
-
}
|
|
54
|
-
else
|
|
55
|
-
{
|
|
56
|
-
Command = TEXT("BUILD LIGHTING QUALITY=Preview");
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(World, Command, nullptr);
|
|
60
|
-
|
|
61
|
-
auto Result = MCPSuccess();
|
|
62
|
-
Result->SetStringField(TEXT("quality"), Quality);
|
|
63
|
-
Result->SetStringField(TEXT("command"), Command);
|
|
64
|
-
Result->SetStringField(TEXT("message"), FString::Printf(TEXT("Lighting build triggered (%s)"), *Quality));
|
|
65
|
-
return MCPResult(Result);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
TSharedPtr<FJsonValue> FEditorHandlers::BuildAll(const TSharedPtr<FJsonObject>& Params)
|
|
70
|
-
{
|
|
71
|
-
REQUIRE_EDITOR_WORLD(World);
|
|
72
|
-
|
|
73
|
-
// Execute full build: geometry, lighting, and paths
|
|
74
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("MAP REBUILD"), nullptr);
|
|
75
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("BUILD LIGHTING"), nullptr);
|
|
76
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("RebuildNavigation"), nullptr);
|
|
77
|
-
|
|
78
|
-
auto Result = MCPSuccess();
|
|
79
|
-
Result->SetStringField(TEXT("message"), TEXT("Build All triggered (geometry + lighting + navigation)"));
|
|
80
|
-
return MCPResult(Result);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
TSharedPtr<FJsonValue> FEditorHandlers::ValidateAssets(const TSharedPtr<FJsonObject>& Params)
|
|
85
|
-
{
|
|
86
|
-
FString Directory = OptionalString(Params, TEXT("directory"), TEXT("/Game/"));
|
|
87
|
-
|
|
88
|
-
// Try to use the EditorValidatorSubsystem if available
|
|
89
|
-
UEditorValidatorSubsystem* ValidatorSubsystem = GEditor ? GEditor->GetEditorSubsystem<UEditorValidatorSubsystem>() : nullptr;
|
|
90
|
-
|
|
91
|
-
if (ValidatorSubsystem)
|
|
92
|
-
{
|
|
93
|
-
// Use the DataValidation console command for broad validation
|
|
94
|
-
if (GEditor && GEditor->GetEditorWorldContext().World())
|
|
95
|
-
{
|
|
96
|
-
FString Command = FString::Printf(TEXT("DataValidation.ValidateAssets %s"), *Directory);
|
|
97
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(
|
|
98
|
-
GEditor->GetEditorWorldContext().World(),
|
|
99
|
-
Command,
|
|
100
|
-
nullptr
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
auto Result = MCPSuccess();
|
|
105
|
-
Result->SetStringField(TEXT("directory"), Directory);
|
|
106
|
-
Result->SetStringField(TEXT("message"), TEXT("Asset validation triggered via EditorValidatorSubsystem"));
|
|
107
|
-
return MCPResult(Result);
|
|
108
|
-
}
|
|
109
|
-
else
|
|
110
|
-
{
|
|
111
|
-
// Fallback: trigger via console command
|
|
112
|
-
if (GEditor && GEditor->GetEditorWorldContext().World())
|
|
113
|
-
{
|
|
114
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(
|
|
115
|
-
GEditor->GetEditorWorldContext().World(),
|
|
116
|
-
TEXT("DataValidation.ValidateAssets"),
|
|
117
|
-
nullptr
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
auto Result = MCPSuccess();
|
|
122
|
-
Result->SetStringField(TEXT("directory"), Directory);
|
|
123
|
-
Result->SetStringField(TEXT("message"), TEXT("Asset validation triggered via console command"));
|
|
124
|
-
return MCPResult(Result);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
TSharedPtr<FJsonValue> FEditorHandlers::CookContent(const TSharedPtr<FJsonObject>& Params)
|
|
130
|
-
{
|
|
131
|
-
REQUIRE_EDITOR_WORLD(World);
|
|
132
|
-
|
|
133
|
-
FString Platform = OptionalString(Params, TEXT("platform"), TEXT("Windows"));
|
|
134
|
-
|
|
135
|
-
FString Command = FString::Printf(TEXT("CookOnTheFly -TargetPlatform=%s"), *Platform);
|
|
136
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(World, Command, nullptr);
|
|
137
|
-
|
|
138
|
-
auto Result = MCPSuccess();
|
|
139
|
-
Result->SetStringField(TEXT("platform"), Platform);
|
|
140
|
-
Result->SetStringField(TEXT("command"), Command);
|
|
141
|
-
Result->SetStringField(TEXT("message"), FString::Printf(TEXT("Cook triggered for %s"), *Platform));
|
|
142
|
-
return MCPResult(Result);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
TSharedPtr<FJsonValue> FEditorHandlers::HotReload(const TSharedPtr<FJsonObject>& Params)
|
|
147
|
-
{
|
|
148
|
-
#if PLATFORM_WINDOWS
|
|
149
|
-
ILiveCodingModule* LiveCoding = FModuleManager::GetModulePtr<ILiveCodingModule>(LIVE_CODING_MODULE_NAME);
|
|
150
|
-
if (LiveCoding && LiveCoding->IsEnabledForSession())
|
|
151
|
-
{
|
|
152
|
-
if (LiveCoding->IsCompiling())
|
|
153
|
-
{
|
|
154
|
-
auto Result = MCPSuccess();
|
|
155
|
-
Result->SetStringField(TEXT("message"), TEXT("Live Coding compile already in progress"));
|
|
156
|
-
return MCPResult(Result);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
LiveCoding->EnableByDefault(true);
|
|
160
|
-
LiveCoding->Compile();
|
|
161
|
-
auto Result = MCPSuccess();
|
|
162
|
-
Result->SetStringField(TEXT("message"), TEXT("Live Coding compile triggered"));
|
|
163
|
-
return MCPResult(Result);
|
|
164
|
-
}
|
|
165
|
-
else
|
|
166
|
-
#endif
|
|
167
|
-
{
|
|
168
|
-
// Live Coding not available (or not on Windows) - fall back to console command
|
|
169
|
-
UWorld* World = GetEditorWorld();
|
|
170
|
-
if (World)
|
|
171
|
-
{
|
|
172
|
-
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("LiveCoding.Compile"), nullptr);
|
|
173
|
-
auto Result = MCPSuccess();
|
|
174
|
-
Result->SetStringField(TEXT("message"), TEXT("Hot reload triggered via console command (Live Coding module not active in session)"));
|
|
175
|
-
return MCPResult(Result);
|
|
176
|
-
}
|
|
177
|
-
else
|
|
178
|
-
{
|
|
179
|
-
return MCPError(TEXT("Neither Live Coding module nor editor world available for hot reload"));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
TSharedPtr<FJsonValue> FEditorHandlers::BuildGeometry(const TSharedPtr<FJsonObject>& Params)
|
|
186
|
-
{
|
|
187
|
-
REQUIRE_EDITOR_WORLD(World);
|
|
188
|
-
|
|
189
|
-
GEditor->Exec(World, TEXT("MAP REBUILD"));
|
|
190
|
-
|
|
191
|
-
auto Result = MCPSuccess();
|
|
192
|
-
Result->SetStringField(TEXT("message"), TEXT("Geometry rebuild triggered"));
|
|
193
|
-
return MCPResult(Result);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
TSharedPtr<FJsonValue> FEditorHandlers::BuildHlod(const TSharedPtr<FJsonObject>& Params)
|
|
198
|
-
{
|
|
199
|
-
REQUIRE_EDITOR_WORLD(World);
|
|
200
|
-
|
|
201
|
-
GEditor->Exec(World, TEXT("BuildHLOD"));
|
|
202
|
-
|
|
203
|
-
auto Result = MCPSuccess();
|
|
204
|
-
Result->SetStringField(TEXT("message"), TEXT("HLOD build triggered"));
|
|
205
|
-
return MCPResult(Result);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
// #14: Build project via UnrealBuildTool
|
|
210
|
-
TSharedPtr<FJsonValue> FEditorHandlers::BuildProject(const TSharedPtr<FJsonObject>& Params)
|
|
211
|
-
{
|
|
212
|
-
if (!GEditor)
|
|
213
|
-
{
|
|
214
|
-
return MCPError(TEXT("Editor not available"));
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
FString Configuration = OptionalString(Params, TEXT("configuration"), TEXT("Development"));
|
|
218
|
-
FString Platform = OptionalString(Params, TEXT("platform"), TEXT("Win64"));
|
|
219
|
-
bool bClean = OptionalBool(Params, TEXT("clean"), false);
|
|
220
|
-
|
|
221
|
-
// Build the project by invoking the engine's build tool
|
|
222
|
-
// Use the project path from the running editor
|
|
223
|
-
FString ProjectPath = FPaths::GetProjectFilePath();
|
|
224
|
-
if (ProjectPath.IsEmpty())
|
|
225
|
-
{
|
|
226
|
-
return MCPError(TEXT("No project file path available"));
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Find UnrealBuildTool
|
|
230
|
-
FString EngineDir = FPaths::EngineDir();
|
|
231
|
-
FString UBTPath;
|
|
232
|
-
|
|
233
|
-
#if PLATFORM_WINDOWS
|
|
234
|
-
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool.exe"));
|
|
235
|
-
if (!FPaths::FileExists(UBTPath))
|
|
236
|
-
{
|
|
237
|
-
// Try legacy path
|
|
238
|
-
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool.exe"));
|
|
239
|
-
}
|
|
240
|
-
#else
|
|
241
|
-
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool"));
|
|
242
|
-
#endif
|
|
243
|
-
|
|
244
|
-
if (!FPaths::FileExists(UBTPath))
|
|
245
|
-
{
|
|
246
|
-
return MCPError(FString::Printf(TEXT("UnrealBuildTool not found at '%s'"), *UBTPath));
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Build the command line
|
|
250
|
-
FString ProjectName = FPaths::GetBaseFilename(ProjectPath);
|
|
251
|
-
FString Args = FString::Printf(
|
|
252
|
-
TEXT("%sEditor %s %s -Project=\"%s\" -WaitMutex -FromMsBuild"),
|
|
253
|
-
*ProjectName, *Platform, *Configuration, *ProjectPath);
|
|
254
|
-
|
|
255
|
-
if (bClean)
|
|
256
|
-
{
|
|
257
|
-
Args += TEXT(" -Clean");
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Launch the process asynchronously
|
|
261
|
-
FProcHandle ProcHandle = FPlatformProcess::CreateProc(
|
|
262
|
-
*UBTPath, *Args, true, false, false, nullptr, 0, nullptr, nullptr);
|
|
263
|
-
|
|
264
|
-
if (!ProcHandle.IsValid())
|
|
265
|
-
{
|
|
266
|
-
return MCPError(TEXT("Failed to launch UnrealBuildTool"));
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
auto Result = MCPSuccess();
|
|
270
|
-
Result->SetStringField(TEXT("ubtPath"), UBTPath);
|
|
271
|
-
Result->SetStringField(TEXT("args"), Args);
|
|
272
|
-
Result->SetStringField(TEXT("configuration"), Configuration);
|
|
273
|
-
Result->SetStringField(TEXT("platform"), Platform);
|
|
274
|
-
Result->SetStringField(TEXT("note"), TEXT("Build launched asynchronously. Check output log for progress."));
|
|
275
|
-
return MCPResult(Result);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// #49: Generate VS project files
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
// #49: Generate VS project files
|
|
282
|
-
TSharedPtr<FJsonValue> FEditorHandlers::GenerateProjectFiles(const TSharedPtr<FJsonObject>& Params)
|
|
283
|
-
{
|
|
284
|
-
FString ProjectPath = FPaths::GetProjectFilePath();
|
|
285
|
-
if (ProjectPath.IsEmpty())
|
|
286
|
-
{
|
|
287
|
-
return MCPError(TEXT("No project file path available"));
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Find the GenerateProjectFiles script
|
|
291
|
-
FString EngineDir = FPaths::EngineDir();
|
|
292
|
-
FString ScriptPath;
|
|
293
|
-
#if PLATFORM_WINDOWS
|
|
294
|
-
ScriptPath = FPaths::Combine(EngineDir, TEXT("Build"), TEXT("BatchFiles"), TEXT("GenerateProjectFiles.bat"));
|
|
295
|
-
#elif PLATFORM_MAC
|
|
296
|
-
ScriptPath = FPaths::Combine(EngineDir, TEXT("Build"), TEXT("BatchFiles"), TEXT("Mac"), TEXT("GenerateProjectFiles.sh"));
|
|
297
|
-
#else
|
|
298
|
-
ScriptPath = FPaths::Combine(EngineDir, TEXT("Build"), TEXT("BatchFiles"), TEXT("Linux"), TEXT("GenerateProjectFiles.sh"));
|
|
299
|
-
#endif
|
|
300
|
-
|
|
301
|
-
if (!FPaths::FileExists(ScriptPath))
|
|
302
|
-
{
|
|
303
|
-
// Alternative: use UnrealBuildTool directly with -projectfiles flag
|
|
304
|
-
FString UBTPath;
|
|
305
|
-
#if PLATFORM_WINDOWS
|
|
306
|
-
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool.exe"));
|
|
307
|
-
if (!FPaths::FileExists(UBTPath))
|
|
308
|
-
{
|
|
309
|
-
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool.exe"));
|
|
310
|
-
}
|
|
311
|
-
#else
|
|
312
|
-
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool"));
|
|
313
|
-
#endif
|
|
314
|
-
if (!FPaths::FileExists(UBTPath))
|
|
315
|
-
{
|
|
316
|
-
return MCPError(TEXT("Neither GenerateProjectFiles script nor UnrealBuildTool found"));
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
FString Args = FString::Printf(TEXT("-projectfiles -project=\"%s\" -game -rocket -progress"), *ProjectPath);
|
|
320
|
-
FProcHandle ProcHandle = FPlatformProcess::CreateProc(
|
|
321
|
-
*UBTPath, *Args, true, false, false, nullptr, 0, nullptr, nullptr);
|
|
322
|
-
|
|
323
|
-
if (!ProcHandle.IsValid())
|
|
324
|
-
{
|
|
325
|
-
return MCPError(TEXT("Failed to launch UnrealBuildTool for project file generation"));
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
auto Result = MCPSuccess();
|
|
329
|
-
Result->SetStringField(TEXT("tool"), UBTPath);
|
|
330
|
-
Result->SetStringField(TEXT("args"), Args);
|
|
331
|
-
Result->SetStringField(TEXT("projectPath"), ProjectPath);
|
|
332
|
-
Result->SetStringField(TEXT("note"), TEXT("Project file generation launched. Check output log for progress."));
|
|
333
|
-
return MCPResult(Result);
|
|
334
|
-
}
|
|
335
|
-
else
|
|
336
|
-
{
|
|
337
|
-
FString Args = FString::Printf(TEXT("-project=\"%s\" -game"), *ProjectPath);
|
|
338
|
-
FProcHandle ProcHandle = FPlatformProcess::CreateProc(
|
|
339
|
-
*ScriptPath, *Args, true, false, false, nullptr, 0, nullptr, nullptr);
|
|
340
|
-
|
|
341
|
-
if (!ProcHandle.IsValid())
|
|
342
|
-
{
|
|
343
|
-
return MCPError(TEXT("Failed to launch GenerateProjectFiles"));
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
auto Result = MCPSuccess();
|
|
347
|
-
Result->SetStringField(TEXT("tool"), ScriptPath);
|
|
348
|
-
Result->SetStringField(TEXT("args"), Args);
|
|
349
|
-
Result->SetStringField(TEXT("projectPath"), ProjectPath);
|
|
350
|
-
Result->SetStringField(TEXT("note"), TEXT("Project file generation launched. Check output log for progress."));
|
|
351
|
-
return MCPResult(Result);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
1
|
+
// Split from EditorHandlers.cpp to keep that file under 3k lines.
|
|
2
|
+
// All functions below are still members of FEditorHandlers - this file is a
|
|
3
|
+
// translation-unit partition, not a new class. Handler registration
|
|
4
|
+
// stays in EditorHandlers.cpp::RegisterHandlers.
|
|
5
|
+
|
|
6
|
+
#include "EditorHandlers.h"
|
|
7
|
+
#include "HandlerRegistry.h"
|
|
8
|
+
#include "HandlerUtils.h"
|
|
9
|
+
#include "Editor.h"
|
|
10
|
+
#include "Editor/EditorEngine.h"
|
|
11
|
+
#include "FileHelpers.h"
|
|
12
|
+
#include "Engine/World.h"
|
|
13
|
+
#include "Engine/Engine.h"
|
|
14
|
+
#include "GameFramework/Actor.h"
|
|
15
|
+
#include "Misc/Paths.h"
|
|
16
|
+
#include "Misc/FileHelper.h"
|
|
17
|
+
#include "Misc/CommandLine.h"
|
|
18
|
+
#include "HAL/PlatformProcess.h"
|
|
19
|
+
#include "HAL/PlatformFileManager.h"
|
|
20
|
+
#include "HAL/PlatformFile.h"
|
|
21
|
+
#include "Modules/ModuleManager.h"
|
|
22
|
+
#if PLATFORM_WINDOWS
|
|
23
|
+
#include "ILiveCodingModule.h"
|
|
24
|
+
#endif
|
|
25
|
+
#include "Kismet/KismetSystemLibrary.h"
|
|
26
|
+
#include "EditorValidatorSubsystem.h"
|
|
27
|
+
#include "Dom/JsonObject.h"
|
|
28
|
+
#include "Dom/JsonValue.h"
|
|
29
|
+
|
|
30
|
+
TSharedPtr<FJsonValue> FEditorHandlers::BuildLighting(const TSharedPtr<FJsonObject>& Params)
|
|
31
|
+
{
|
|
32
|
+
REQUIRE_EDITOR_WORLD(World);
|
|
33
|
+
|
|
34
|
+
FString Quality = OptionalString(Params, TEXT("quality"), TEXT("Preview"));
|
|
35
|
+
|
|
36
|
+
// Map quality string to console command
|
|
37
|
+
FString Command;
|
|
38
|
+
if (Quality == TEXT("Preview"))
|
|
39
|
+
{
|
|
40
|
+
Command = TEXT("BUILD LIGHTING QUALITY=Preview");
|
|
41
|
+
}
|
|
42
|
+
else if (Quality == TEXT("Medium"))
|
|
43
|
+
{
|
|
44
|
+
Command = TEXT("BUILD LIGHTING QUALITY=Medium");
|
|
45
|
+
}
|
|
46
|
+
else if (Quality == TEXT("High"))
|
|
47
|
+
{
|
|
48
|
+
Command = TEXT("BUILD LIGHTING QUALITY=High");
|
|
49
|
+
}
|
|
50
|
+
else if (Quality == TEXT("Production"))
|
|
51
|
+
{
|
|
52
|
+
Command = TEXT("BUILD LIGHTING QUALITY=Production");
|
|
53
|
+
}
|
|
54
|
+
else
|
|
55
|
+
{
|
|
56
|
+
Command = TEXT("BUILD LIGHTING QUALITY=Preview");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(World, Command, nullptr);
|
|
60
|
+
|
|
61
|
+
auto Result = MCPSuccess();
|
|
62
|
+
Result->SetStringField(TEXT("quality"), Quality);
|
|
63
|
+
Result->SetStringField(TEXT("command"), Command);
|
|
64
|
+
Result->SetStringField(TEXT("message"), FString::Printf(TEXT("Lighting build triggered (%s)"), *Quality));
|
|
65
|
+
return MCPResult(Result);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
TSharedPtr<FJsonValue> FEditorHandlers::BuildAll(const TSharedPtr<FJsonObject>& Params)
|
|
70
|
+
{
|
|
71
|
+
REQUIRE_EDITOR_WORLD(World);
|
|
72
|
+
|
|
73
|
+
// Execute full build: geometry, lighting, and paths
|
|
74
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("MAP REBUILD"), nullptr);
|
|
75
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("BUILD LIGHTING"), nullptr);
|
|
76
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("RebuildNavigation"), nullptr);
|
|
77
|
+
|
|
78
|
+
auto Result = MCPSuccess();
|
|
79
|
+
Result->SetStringField(TEXT("message"), TEXT("Build All triggered (geometry + lighting + navigation)"));
|
|
80
|
+
return MCPResult(Result);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
TSharedPtr<FJsonValue> FEditorHandlers::ValidateAssets(const TSharedPtr<FJsonObject>& Params)
|
|
85
|
+
{
|
|
86
|
+
FString Directory = OptionalString(Params, TEXT("directory"), TEXT("/Game/"));
|
|
87
|
+
|
|
88
|
+
// Try to use the EditorValidatorSubsystem if available
|
|
89
|
+
UEditorValidatorSubsystem* ValidatorSubsystem = GEditor ? GEditor->GetEditorSubsystem<UEditorValidatorSubsystem>() : nullptr;
|
|
90
|
+
|
|
91
|
+
if (ValidatorSubsystem)
|
|
92
|
+
{
|
|
93
|
+
// Use the DataValidation console command for broad validation
|
|
94
|
+
if (GEditor && GEditor->GetEditorWorldContext().World())
|
|
95
|
+
{
|
|
96
|
+
FString Command = FString::Printf(TEXT("DataValidation.ValidateAssets %s"), *Directory);
|
|
97
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(
|
|
98
|
+
GEditor->GetEditorWorldContext().World(),
|
|
99
|
+
Command,
|
|
100
|
+
nullptr
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
auto Result = MCPSuccess();
|
|
105
|
+
Result->SetStringField(TEXT("directory"), Directory);
|
|
106
|
+
Result->SetStringField(TEXT("message"), TEXT("Asset validation triggered via EditorValidatorSubsystem"));
|
|
107
|
+
return MCPResult(Result);
|
|
108
|
+
}
|
|
109
|
+
else
|
|
110
|
+
{
|
|
111
|
+
// Fallback: trigger via console command
|
|
112
|
+
if (GEditor && GEditor->GetEditorWorldContext().World())
|
|
113
|
+
{
|
|
114
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(
|
|
115
|
+
GEditor->GetEditorWorldContext().World(),
|
|
116
|
+
TEXT("DataValidation.ValidateAssets"),
|
|
117
|
+
nullptr
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
auto Result = MCPSuccess();
|
|
122
|
+
Result->SetStringField(TEXT("directory"), Directory);
|
|
123
|
+
Result->SetStringField(TEXT("message"), TEXT("Asset validation triggered via console command"));
|
|
124
|
+
return MCPResult(Result);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
TSharedPtr<FJsonValue> FEditorHandlers::CookContent(const TSharedPtr<FJsonObject>& Params)
|
|
130
|
+
{
|
|
131
|
+
REQUIRE_EDITOR_WORLD(World);
|
|
132
|
+
|
|
133
|
+
FString Platform = OptionalString(Params, TEXT("platform"), TEXT("Windows"));
|
|
134
|
+
|
|
135
|
+
FString Command = FString::Printf(TEXT("CookOnTheFly -TargetPlatform=%s"), *Platform);
|
|
136
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(World, Command, nullptr);
|
|
137
|
+
|
|
138
|
+
auto Result = MCPSuccess();
|
|
139
|
+
Result->SetStringField(TEXT("platform"), Platform);
|
|
140
|
+
Result->SetStringField(TEXT("command"), Command);
|
|
141
|
+
Result->SetStringField(TEXT("message"), FString::Printf(TEXT("Cook triggered for %s"), *Platform));
|
|
142
|
+
return MCPResult(Result);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
TSharedPtr<FJsonValue> FEditorHandlers::HotReload(const TSharedPtr<FJsonObject>& Params)
|
|
147
|
+
{
|
|
148
|
+
#if PLATFORM_WINDOWS
|
|
149
|
+
ILiveCodingModule* LiveCoding = FModuleManager::GetModulePtr<ILiveCodingModule>(LIVE_CODING_MODULE_NAME);
|
|
150
|
+
if (LiveCoding && LiveCoding->IsEnabledForSession())
|
|
151
|
+
{
|
|
152
|
+
if (LiveCoding->IsCompiling())
|
|
153
|
+
{
|
|
154
|
+
auto Result = MCPSuccess();
|
|
155
|
+
Result->SetStringField(TEXT("message"), TEXT("Live Coding compile already in progress"));
|
|
156
|
+
return MCPResult(Result);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
LiveCoding->EnableByDefault(true);
|
|
160
|
+
LiveCoding->Compile();
|
|
161
|
+
auto Result = MCPSuccess();
|
|
162
|
+
Result->SetStringField(TEXT("message"), TEXT("Live Coding compile triggered"));
|
|
163
|
+
return MCPResult(Result);
|
|
164
|
+
}
|
|
165
|
+
else
|
|
166
|
+
#endif
|
|
167
|
+
{
|
|
168
|
+
// Live Coding not available (or not on Windows) - fall back to console command
|
|
169
|
+
UWorld* World = GetEditorWorld();
|
|
170
|
+
if (World)
|
|
171
|
+
{
|
|
172
|
+
UKismetSystemLibrary::ExecuteConsoleCommand(World, TEXT("LiveCoding.Compile"), nullptr);
|
|
173
|
+
auto Result = MCPSuccess();
|
|
174
|
+
Result->SetStringField(TEXT("message"), TEXT("Hot reload triggered via console command (Live Coding module not active in session)"));
|
|
175
|
+
return MCPResult(Result);
|
|
176
|
+
}
|
|
177
|
+
else
|
|
178
|
+
{
|
|
179
|
+
return MCPError(TEXT("Neither Live Coding module nor editor world available for hot reload"));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
TSharedPtr<FJsonValue> FEditorHandlers::BuildGeometry(const TSharedPtr<FJsonObject>& Params)
|
|
186
|
+
{
|
|
187
|
+
REQUIRE_EDITOR_WORLD(World);
|
|
188
|
+
|
|
189
|
+
GEditor->Exec(World, TEXT("MAP REBUILD"));
|
|
190
|
+
|
|
191
|
+
auto Result = MCPSuccess();
|
|
192
|
+
Result->SetStringField(TEXT("message"), TEXT("Geometry rebuild triggered"));
|
|
193
|
+
return MCPResult(Result);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
TSharedPtr<FJsonValue> FEditorHandlers::BuildHlod(const TSharedPtr<FJsonObject>& Params)
|
|
198
|
+
{
|
|
199
|
+
REQUIRE_EDITOR_WORLD(World);
|
|
200
|
+
|
|
201
|
+
GEditor->Exec(World, TEXT("BuildHLOD"));
|
|
202
|
+
|
|
203
|
+
auto Result = MCPSuccess();
|
|
204
|
+
Result->SetStringField(TEXT("message"), TEXT("HLOD build triggered"));
|
|
205
|
+
return MCPResult(Result);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
// #14: Build project via UnrealBuildTool
|
|
210
|
+
TSharedPtr<FJsonValue> FEditorHandlers::BuildProject(const TSharedPtr<FJsonObject>& Params)
|
|
211
|
+
{
|
|
212
|
+
if (!GEditor)
|
|
213
|
+
{
|
|
214
|
+
return MCPError(TEXT("Editor not available"));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
FString Configuration = OptionalString(Params, TEXT("configuration"), TEXT("Development"));
|
|
218
|
+
FString Platform = OptionalString(Params, TEXT("platform"), TEXT("Win64"));
|
|
219
|
+
bool bClean = OptionalBool(Params, TEXT("clean"), false);
|
|
220
|
+
|
|
221
|
+
// Build the project by invoking the engine's build tool
|
|
222
|
+
// Use the project path from the running editor
|
|
223
|
+
FString ProjectPath = FPaths::GetProjectFilePath();
|
|
224
|
+
if (ProjectPath.IsEmpty())
|
|
225
|
+
{
|
|
226
|
+
return MCPError(TEXT("No project file path available"));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Find UnrealBuildTool
|
|
230
|
+
FString EngineDir = FPaths::EngineDir();
|
|
231
|
+
FString UBTPath;
|
|
232
|
+
|
|
233
|
+
#if PLATFORM_WINDOWS
|
|
234
|
+
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool.exe"));
|
|
235
|
+
if (!FPaths::FileExists(UBTPath))
|
|
236
|
+
{
|
|
237
|
+
// Try legacy path
|
|
238
|
+
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool.exe"));
|
|
239
|
+
}
|
|
240
|
+
#else
|
|
241
|
+
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool"));
|
|
242
|
+
#endif
|
|
243
|
+
|
|
244
|
+
if (!FPaths::FileExists(UBTPath))
|
|
245
|
+
{
|
|
246
|
+
return MCPError(FString::Printf(TEXT("UnrealBuildTool not found at '%s'"), *UBTPath));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Build the command line
|
|
250
|
+
FString ProjectName = FPaths::GetBaseFilename(ProjectPath);
|
|
251
|
+
FString Args = FString::Printf(
|
|
252
|
+
TEXT("%sEditor %s %s -Project=\"%s\" -WaitMutex -FromMsBuild"),
|
|
253
|
+
*ProjectName, *Platform, *Configuration, *ProjectPath);
|
|
254
|
+
|
|
255
|
+
if (bClean)
|
|
256
|
+
{
|
|
257
|
+
Args += TEXT(" -Clean");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Launch the process asynchronously
|
|
261
|
+
FProcHandle ProcHandle = FPlatformProcess::CreateProc(
|
|
262
|
+
*UBTPath, *Args, true, false, false, nullptr, 0, nullptr, nullptr);
|
|
263
|
+
|
|
264
|
+
if (!ProcHandle.IsValid())
|
|
265
|
+
{
|
|
266
|
+
return MCPError(TEXT("Failed to launch UnrealBuildTool"));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
auto Result = MCPSuccess();
|
|
270
|
+
Result->SetStringField(TEXT("ubtPath"), UBTPath);
|
|
271
|
+
Result->SetStringField(TEXT("args"), Args);
|
|
272
|
+
Result->SetStringField(TEXT("configuration"), Configuration);
|
|
273
|
+
Result->SetStringField(TEXT("platform"), Platform);
|
|
274
|
+
Result->SetStringField(TEXT("note"), TEXT("Build launched asynchronously. Check output log for progress."));
|
|
275
|
+
return MCPResult(Result);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// #49: Generate VS project files
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
// #49: Generate VS project files
|
|
282
|
+
TSharedPtr<FJsonValue> FEditorHandlers::GenerateProjectFiles(const TSharedPtr<FJsonObject>& Params)
|
|
283
|
+
{
|
|
284
|
+
FString ProjectPath = FPaths::GetProjectFilePath();
|
|
285
|
+
if (ProjectPath.IsEmpty())
|
|
286
|
+
{
|
|
287
|
+
return MCPError(TEXT("No project file path available"));
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Find the GenerateProjectFiles script
|
|
291
|
+
FString EngineDir = FPaths::EngineDir();
|
|
292
|
+
FString ScriptPath;
|
|
293
|
+
#if PLATFORM_WINDOWS
|
|
294
|
+
ScriptPath = FPaths::Combine(EngineDir, TEXT("Build"), TEXT("BatchFiles"), TEXT("GenerateProjectFiles.bat"));
|
|
295
|
+
#elif PLATFORM_MAC
|
|
296
|
+
ScriptPath = FPaths::Combine(EngineDir, TEXT("Build"), TEXT("BatchFiles"), TEXT("Mac"), TEXT("GenerateProjectFiles.sh"));
|
|
297
|
+
#else
|
|
298
|
+
ScriptPath = FPaths::Combine(EngineDir, TEXT("Build"), TEXT("BatchFiles"), TEXT("Linux"), TEXT("GenerateProjectFiles.sh"));
|
|
299
|
+
#endif
|
|
300
|
+
|
|
301
|
+
if (!FPaths::FileExists(ScriptPath))
|
|
302
|
+
{
|
|
303
|
+
// Alternative: use UnrealBuildTool directly with -projectfiles flag
|
|
304
|
+
FString UBTPath;
|
|
305
|
+
#if PLATFORM_WINDOWS
|
|
306
|
+
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool.exe"));
|
|
307
|
+
if (!FPaths::FileExists(UBTPath))
|
|
308
|
+
{
|
|
309
|
+
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool.exe"));
|
|
310
|
+
}
|
|
311
|
+
#else
|
|
312
|
+
UBTPath = FPaths::Combine(EngineDir, TEXT("Binaries"), TEXT("DotNET"), TEXT("UnrealBuildTool"), TEXT("UnrealBuildTool"));
|
|
313
|
+
#endif
|
|
314
|
+
if (!FPaths::FileExists(UBTPath))
|
|
315
|
+
{
|
|
316
|
+
return MCPError(TEXT("Neither GenerateProjectFiles script nor UnrealBuildTool found"));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
FString Args = FString::Printf(TEXT("-projectfiles -project=\"%s\" -game -rocket -progress"), *ProjectPath);
|
|
320
|
+
FProcHandle ProcHandle = FPlatformProcess::CreateProc(
|
|
321
|
+
*UBTPath, *Args, true, false, false, nullptr, 0, nullptr, nullptr);
|
|
322
|
+
|
|
323
|
+
if (!ProcHandle.IsValid())
|
|
324
|
+
{
|
|
325
|
+
return MCPError(TEXT("Failed to launch UnrealBuildTool for project file generation"));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
auto Result = MCPSuccess();
|
|
329
|
+
Result->SetStringField(TEXT("tool"), UBTPath);
|
|
330
|
+
Result->SetStringField(TEXT("args"), Args);
|
|
331
|
+
Result->SetStringField(TEXT("projectPath"), ProjectPath);
|
|
332
|
+
Result->SetStringField(TEXT("note"), TEXT("Project file generation launched. Check output log for progress."));
|
|
333
|
+
return MCPResult(Result);
|
|
334
|
+
}
|
|
335
|
+
else
|
|
336
|
+
{
|
|
337
|
+
FString Args = FString::Printf(TEXT("-project=\"%s\" -game"), *ProjectPath);
|
|
338
|
+
FProcHandle ProcHandle = FPlatformProcess::CreateProc(
|
|
339
|
+
*ScriptPath, *Args, true, false, false, nullptr, 0, nullptr, nullptr);
|
|
340
|
+
|
|
341
|
+
if (!ProcHandle.IsValid())
|
|
342
|
+
{
|
|
343
|
+
return MCPError(TEXT("Failed to launch GenerateProjectFiles"));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
auto Result = MCPSuccess();
|
|
347
|
+
Result->SetStringField(TEXT("tool"), ScriptPath);
|
|
348
|
+
Result->SetStringField(TEXT("args"), Args);
|
|
349
|
+
Result->SetStringField(TEXT("projectPath"), ProjectPath);
|
|
350
|
+
Result->SetStringField(TEXT("note"), TEXT("Project file generation launched. Check output log for progress."));
|
|
351
|
+
return MCPResult(Result);
|
|
352
|
+
}
|
|
353
|
+
}
|