unreal-engine-mcp-server 0.5.4 → 0.5.5

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 (468) hide show
  1. package/dist/automation/bridge.d.ts.map +1 -0
  2. package/dist/automation/bridge.js.map +1 -0
  3. package/dist/automation/connection-manager.d.ts.map +1 -0
  4. package/dist/automation/connection-manager.js.map +1 -0
  5. package/dist/automation/handshake.d.ts.map +1 -0
  6. package/dist/automation/handshake.js.map +1 -0
  7. package/dist/automation/index.d.ts.map +1 -0
  8. package/dist/automation/index.js.map +1 -0
  9. package/dist/automation/message-handler.d.ts.map +1 -0
  10. package/dist/automation/message-handler.js.map +1 -0
  11. package/dist/automation/request-tracker.d.ts.map +1 -0
  12. package/dist/automation/request-tracker.js.map +1 -0
  13. package/dist/automation/types.d.ts.map +1 -0
  14. package/dist/automation/types.js.map +1 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +4 -3
  17. package/dist/cli.js.map +1 -0
  18. package/dist/config/class-aliases.d.ts.map +1 -0
  19. package/dist/config/class-aliases.js.map +1 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/constants.d.ts.map +1 -0
  23. package/dist/constants.js.map +1 -0
  24. package/dist/graphql/loaders.d.ts.map +1 -0
  25. package/dist/graphql/loaders.js.map +1 -0
  26. package/dist/graphql/resolvers.d.ts.map +1 -0
  27. package/dist/graphql/resolvers.js +29 -29
  28. package/dist/graphql/resolvers.js.map +1 -0
  29. package/dist/graphql/schema.d.ts.map +1 -0
  30. package/dist/graphql/schema.js.map +1 -0
  31. package/dist/graphql/server.d.ts.map +1 -0
  32. package/dist/graphql/server.js.map +1 -0
  33. package/dist/graphql/types.d.ts.map +1 -0
  34. package/dist/graphql/types.js.map +1 -0
  35. package/dist/handlers/resource-handlers.d.ts.map +1 -0
  36. package/dist/handlers/resource-handlers.js.map +1 -0
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +64 -7
  40. package/dist/index.js.map +1 -0
  41. package/dist/resources/actors.d.ts.map +1 -0
  42. package/dist/resources/actors.js.map +1 -0
  43. package/dist/resources/assets.d.ts.map +1 -0
  44. package/dist/resources/assets.js +6 -4
  45. package/dist/resources/assets.js.map +1 -0
  46. package/dist/resources/levels.d.ts.map +1 -0
  47. package/dist/resources/levels.js.map +1 -0
  48. package/dist/server/resource-registry.d.ts.map +1 -0
  49. package/dist/server/resource-registry.js.map +1 -0
  50. package/dist/server/tool-registry.d.ts.map +1 -0
  51. package/dist/server/tool-registry.js.map +1 -0
  52. package/dist/server-setup.d.ts.map +1 -0
  53. package/dist/server-setup.js.map +1 -0
  54. package/dist/services/health-monitor.d.ts.map +1 -0
  55. package/dist/services/health-monitor.js.map +1 -0
  56. package/dist/services/metrics-server.d.ts.map +1 -0
  57. package/dist/services/metrics-server.js.map +1 -0
  58. package/dist/tools/actors.d.ts.map +1 -0
  59. package/dist/tools/actors.js +3 -1
  60. package/dist/tools/actors.js.map +1 -0
  61. package/dist/tools/animation.d.ts.map +1 -0
  62. package/dist/tools/animation.js +2 -2
  63. package/dist/tools/animation.js.map +1 -0
  64. package/dist/tools/assets.d.ts.map +1 -0
  65. package/dist/tools/assets.js.map +1 -0
  66. package/dist/tools/audio.d.ts.map +1 -0
  67. package/dist/tools/audio.js.map +1 -0
  68. package/dist/tools/base-tool.d.ts.map +1 -0
  69. package/dist/tools/base-tool.js.map +1 -0
  70. package/dist/tools/behavior-tree.d.ts.map +1 -0
  71. package/dist/tools/behavior-tree.js.map +1 -0
  72. package/dist/tools/blueprint.d.ts.map +1 -0
  73. package/dist/tools/blueprint.js +4 -2
  74. package/dist/tools/blueprint.js.map +1 -0
  75. package/dist/tools/consolidated-tool-definitions.d.ts.map +1 -0
  76. package/dist/tools/consolidated-tool-definitions.js.map +1 -0
  77. package/dist/tools/consolidated-tool-handlers.d.ts.map +1 -0
  78. package/dist/tools/consolidated-tool-handlers.js.map +1 -0
  79. package/dist/tools/debug.d.ts.map +1 -0
  80. package/dist/tools/debug.js +3 -1
  81. package/dist/tools/debug.js.map +1 -0
  82. package/dist/tools/dynamic-handler-registry.d.ts.map +1 -0
  83. package/dist/tools/dynamic-handler-registry.js +3 -1
  84. package/dist/tools/dynamic-handler-registry.js.map +1 -0
  85. package/dist/tools/editor.d.ts.map +1 -0
  86. package/dist/tools/editor.js +1 -1
  87. package/dist/tools/editor.js.map +1 -0
  88. package/dist/tools/engine.d.ts.map +1 -0
  89. package/dist/tools/engine.js.map +1 -0
  90. package/dist/tools/environment.d.ts.map +1 -0
  91. package/dist/tools/environment.js +2 -2
  92. package/dist/tools/environment.js.map +1 -0
  93. package/dist/tools/foliage.d.ts.map +1 -0
  94. package/dist/tools/foliage.js.map +1 -0
  95. package/dist/tools/handlers/actor-handlers.d.ts +1 -1
  96. package/dist/tools/handlers/actor-handlers.d.ts.map +1 -0
  97. package/dist/tools/handlers/actor-handlers.js +6 -5
  98. package/dist/tools/handlers/actor-handlers.js.map +1 -0
  99. package/dist/tools/handlers/animation-handlers.d.ts.map +1 -0
  100. package/dist/tools/handlers/animation-handlers.js.map +1 -0
  101. package/dist/tools/handlers/argument-helper.d.ts.map +1 -0
  102. package/dist/tools/handlers/argument-helper.js.map +1 -0
  103. package/dist/tools/handlers/asset-handlers.d.ts.map +1 -0
  104. package/dist/tools/handlers/asset-handlers.js +5 -1
  105. package/dist/tools/handlers/asset-handlers.js.map +1 -0
  106. package/dist/tools/handlers/audio-handlers.d.ts.map +1 -0
  107. package/dist/tools/handlers/audio-handlers.js.map +1 -0
  108. package/dist/tools/handlers/blueprint-handlers.d.ts.map +1 -0
  109. package/dist/tools/handlers/blueprint-handlers.js +2 -1
  110. package/dist/tools/handlers/blueprint-handlers.js.map +1 -0
  111. package/dist/tools/handlers/common-handlers.d.ts.map +1 -0
  112. package/dist/tools/handlers/common-handlers.js.map +1 -0
  113. package/dist/tools/handlers/editor-handlers.d.ts.map +1 -0
  114. package/dist/tools/handlers/editor-handlers.js +12 -2
  115. package/dist/tools/handlers/editor-handlers.js.map +1 -0
  116. package/dist/tools/handlers/effect-handlers.d.ts.map +1 -0
  117. package/dist/tools/handlers/effect-handlers.js.map +1 -0
  118. package/dist/tools/handlers/environment-handlers.d.ts.map +1 -0
  119. package/dist/tools/handlers/environment-handlers.js.map +1 -0
  120. package/dist/tools/handlers/graph-handlers.d.ts.map +1 -0
  121. package/dist/tools/handlers/graph-handlers.js +61 -1
  122. package/dist/tools/handlers/graph-handlers.js.map +1 -0
  123. package/dist/tools/handlers/input-handlers.d.ts.map +1 -0
  124. package/dist/tools/handlers/input-handlers.js.map +1 -0
  125. package/dist/tools/handlers/inspect-handlers.d.ts.map +1 -0
  126. package/dist/tools/handlers/inspect-handlers.js.map +1 -0
  127. package/dist/tools/handlers/level-handlers.d.ts.map +1 -0
  128. package/dist/tools/handlers/level-handlers.js.map +1 -0
  129. package/dist/tools/handlers/lighting-handlers.d.ts.map +1 -0
  130. package/dist/tools/handlers/lighting-handlers.js +23 -1
  131. package/dist/tools/handlers/lighting-handlers.js.map +1 -0
  132. package/dist/tools/handlers/performance-handlers.d.ts.map +1 -0
  133. package/dist/tools/handlers/performance-handlers.js +15 -2
  134. package/dist/tools/handlers/performance-handlers.js.map +1 -0
  135. package/dist/tools/handlers/pipeline-handlers.d.ts.map +1 -0
  136. package/dist/tools/handlers/pipeline-handlers.js.map +1 -0
  137. package/dist/tools/handlers/sequence-handlers.d.ts.map +1 -0
  138. package/dist/tools/handlers/sequence-handlers.js.map +1 -0
  139. package/dist/tools/handlers/system-handlers.d.ts.map +1 -0
  140. package/dist/tools/handlers/system-handlers.js +16 -1
  141. package/dist/tools/handlers/system-handlers.js.map +1 -0
  142. package/dist/tools/input.d.ts.map +1 -0
  143. package/dist/tools/input.js +3 -1
  144. package/dist/tools/input.js.map +1 -0
  145. package/dist/tools/introspection.d.ts.map +1 -0
  146. package/dist/tools/introspection.js.map +1 -0
  147. package/dist/tools/landscape.d.ts.map +1 -0
  148. package/dist/tools/landscape.js +3 -1
  149. package/dist/tools/landscape.js.map +1 -0
  150. package/dist/tools/level.d.ts.map +1 -0
  151. package/dist/tools/level.js.map +1 -0
  152. package/dist/tools/lighting.d.ts.map +1 -0
  153. package/dist/tools/lighting.js +3 -1
  154. package/dist/tools/lighting.js.map +1 -0
  155. package/dist/tools/logs.d.ts.map +1 -0
  156. package/dist/tools/logs.js.map +1 -0
  157. package/dist/tools/materials.d.ts.map +1 -0
  158. package/dist/tools/materials.js +3 -1
  159. package/dist/tools/materials.js.map +1 -0
  160. package/dist/tools/niagara.d.ts.map +1 -0
  161. package/dist/tools/niagara.js +7 -5
  162. package/dist/tools/niagara.js.map +1 -0
  163. package/dist/tools/performance.d.ts.map +1 -0
  164. package/dist/tools/performance.js.map +1 -0
  165. package/dist/tools/physics.d.ts.map +1 -0
  166. package/dist/tools/physics.js +9 -7
  167. package/dist/tools/physics.js.map +1 -0
  168. package/dist/tools/property-dictionary.d.ts.map +1 -0
  169. package/dist/tools/property-dictionary.js.map +1 -0
  170. package/dist/tools/sequence.d.ts.map +1 -0
  171. package/dist/tools/sequence.js +3 -1
  172. package/dist/tools/sequence.js.map +1 -0
  173. package/dist/tools/tool-definition-utils.d.ts.map +1 -0
  174. package/dist/tools/tool-definition-utils.js.map +1 -0
  175. package/dist/tools/ui.d.ts.map +1 -0
  176. package/dist/tools/ui.js +3 -1
  177. package/dist/tools/ui.js.map +1 -0
  178. package/dist/types/automation-responses.d.ts.map +1 -0
  179. package/dist/types/automation-responses.js.map +1 -0
  180. package/dist/types/env.d.ts.map +1 -0
  181. package/dist/types/env.js.map +1 -0
  182. package/dist/types/handler-types.d.ts.map +1 -0
  183. package/dist/types/handler-types.js.map +1 -0
  184. package/dist/types/tool-interfaces.d.ts.map +1 -0
  185. package/dist/types/tool-interfaces.js.map +1 -0
  186. package/dist/types/tool-types.d.ts.map +1 -0
  187. package/dist/types/tool-types.js.map +1 -0
  188. package/dist/unreal-bridge.d.ts +1 -0
  189. package/dist/unreal-bridge.d.ts.map +1 -0
  190. package/dist/unreal-bridge.js +8 -0
  191. package/dist/unreal-bridge.js.map +1 -0
  192. package/dist/utils/command-validator.d.ts.map +1 -0
  193. package/dist/utils/command-validator.js.map +1 -0
  194. package/dist/utils/elicitation.d.ts.map +1 -0
  195. package/dist/utils/elicitation.js.map +1 -0
  196. package/dist/utils/error-handler.d.ts.map +1 -0
  197. package/dist/utils/error-handler.js.map +1 -0
  198. package/dist/utils/ini-reader.d.ts.map +1 -0
  199. package/dist/utils/ini-reader.js.map +1 -0
  200. package/dist/utils/logger.d.ts.map +1 -0
  201. package/dist/utils/logger.js.map +1 -0
  202. package/dist/utils/normalize.d.ts.map +1 -0
  203. package/dist/utils/normalize.js.map +1 -0
  204. package/dist/utils/path-security.d.ts.map +1 -0
  205. package/dist/utils/path-security.js.map +1 -0
  206. package/dist/utils/response-factory.d.ts.map +1 -0
  207. package/dist/utils/response-factory.js +3 -1
  208. package/dist/utils/response-factory.js.map +1 -0
  209. package/dist/utils/response-validator.d.ts.map +1 -0
  210. package/dist/utils/response-validator.js.map +1 -0
  211. package/dist/utils/result-helpers.d.ts.map +1 -0
  212. package/dist/utils/result-helpers.js.map +1 -0
  213. package/dist/utils/safe-json.d.ts.map +1 -0
  214. package/dist/utils/safe-json.js.map +1 -0
  215. package/dist/utils/unreal-command-queue.d.ts.map +1 -0
  216. package/dist/utils/unreal-command-queue.js.map +1 -0
  217. package/dist/utils/validation.d.ts.map +1 -0
  218. package/dist/utils/validation.js.map +1 -0
  219. package/dist/wasm/index.d.ts.map +1 -0
  220. package/dist/wasm/index.js.map +1 -0
  221. package/package.json +12 -34
  222. package/server.json +2 -2
  223. package/.dockerignore +0 -57
  224. package/.env.example +0 -26
  225. package/.env.production +0 -61
  226. package/.eslintrc.json +0 -0
  227. package/.eslintrc.override.json +0 -8
  228. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -94
  229. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  230. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -56
  231. package/.github/copilot-instructions.md +0 -478
  232. package/.github/dependabot.yml +0 -19
  233. package/.github/labeler.yml +0 -24
  234. package/.github/labels.yml +0 -70
  235. package/.github/pull_request_template.md +0 -42
  236. package/.github/release-drafter-config.yml +0 -51
  237. package/.github/workflows/auto-merge.yml +0 -38
  238. package/.github/workflows/ci.yml +0 -38
  239. package/.github/workflows/dependency-review.yml +0 -17
  240. package/.github/workflows/gemini-issue-triage.yml +0 -172
  241. package/.github/workflows/greetings.yml +0 -27
  242. package/.github/workflows/labeler.yml +0 -17
  243. package/.github/workflows/links.yml +0 -80
  244. package/.github/workflows/pr-size-labeler.yml +0 -137
  245. package/.github/workflows/publish-mcp.yml +0 -79
  246. package/.github/workflows/release-drafter.yml +0 -24
  247. package/.github/workflows/release.yml +0 -112
  248. package/.github/workflows/semantic-pull-request.yml +0 -35
  249. package/.github/workflows/smoke-test.yml +0 -36
  250. package/.github/workflows/stale.yml +0 -28
  251. package/CONTRIBUTING.md +0 -140
  252. package/Dockerfile +0 -37
  253. package/GEMINI.md +0 -115
  254. package/Public/Plugin_setup_guide.mp4 +0 -0
  255. package/Public/icon.png +0 -0
  256. package/claude_desktop_config_example.json +0 -15
  257. package/dist/types/responses.d.ts +0 -249
  258. package/dist/types/responses.js +0 -2
  259. package/docs/GraphQL-API.md +0 -888
  260. package/docs/Migration-Guide-v0.5.0.md +0 -684
  261. package/docs/Roadmap.md +0 -53
  262. package/docs/WebAssembly-Integration.md +0 -628
  263. package/docs/editor-plugin-extension.md +0 -370
  264. package/docs/handler-mapping.md +0 -249
  265. package/docs/native-automation-progress.md +0 -128
  266. package/docs/testing-guide.md +0 -423
  267. package/eslint.config.mjs +0 -68
  268. package/mcp-config-example.json +0 -14
  269. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +0 -8
  270. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +0 -64
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +0 -189
  272. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +0 -22
  273. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +0 -30
  274. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +0 -1983
  275. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +0 -72
  276. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +0 -46
  277. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +0 -846
  278. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +0 -2393
  279. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +0 -300
  280. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +0 -2807
  281. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +0 -1087
  282. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +0 -488
  283. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +0 -643
  284. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +0 -31
  285. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +0 -1094
  286. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +0 -5750
  287. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +0 -152
  288. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +0 -2614
  289. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +0 -42
  290. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +0 -1237
  291. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +0 -1725
  292. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +0 -2265
  293. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +0 -954
  294. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +0 -209
  295. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +0 -41
  296. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +0 -1164
  297. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +0 -762
  298. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +0 -663
  299. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +0 -136
  300. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +0 -494
  301. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +0 -278
  302. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +0 -625
  303. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +0 -401
  304. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +0 -67
  305. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +0 -472
  306. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +0 -2634
  307. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +0 -189
  308. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +0 -917
  309. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +0 -39
  310. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +0 -2706
  311. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +0 -519
  312. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +0 -38
  313. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +0 -668
  314. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +0 -346
  315. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +0 -1345
  316. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +0 -149
  317. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -782
  318. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +0 -115
  319. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +0 -796
  320. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +0 -117
  321. package/scripts/check-unreal-connection.mjs +0 -19
  322. package/scripts/clean-tmp.js +0 -23
  323. package/scripts/patch-wasm.js +0 -26
  324. package/scripts/run-all-tests.mjs +0 -136
  325. package/scripts/smoke-test.ts +0 -94
  326. package/scripts/sync-mcp-plugin.js +0 -143
  327. package/scripts/test-no-plugin-alternates.mjs +0 -113
  328. package/scripts/validate-server.js +0 -46
  329. package/scripts/verify-automation-bridge.js +0 -200
  330. package/src/automation/bridge.ts +0 -630
  331. package/src/automation/connection-manager.ts +0 -148
  332. package/src/automation/handshake.ts +0 -99
  333. package/src/automation/index.ts +0 -2
  334. package/src/automation/message-handler.ts +0 -192
  335. package/src/automation/request-tracker.ts +0 -155
  336. package/src/automation/types.ts +0 -108
  337. package/src/cli.ts +0 -34
  338. package/src/config/class-aliases.ts +0 -65
  339. package/src/config.ts +0 -73
  340. package/src/constants.ts +0 -29
  341. package/src/graphql/loaders.ts +0 -244
  342. package/src/graphql/resolvers.ts +0 -1008
  343. package/src/graphql/schema.ts +0 -452
  344. package/src/graphql/server.ts +0 -156
  345. package/src/graphql/types.ts +0 -10
  346. package/src/handlers/resource-handlers.ts +0 -186
  347. package/src/index.ts +0 -243
  348. package/src/resources/actors.ts +0 -127
  349. package/src/resources/assets.ts +0 -286
  350. package/src/resources/levels.ts +0 -68
  351. package/src/server/resource-registry.ts +0 -47
  352. package/src/server/tool-registry.ts +0 -354
  353. package/src/server-setup.ts +0 -114
  354. package/src/services/health-monitor.ts +0 -132
  355. package/src/services/metrics-server.ts +0 -176
  356. package/src/tools/actors.ts +0 -564
  357. package/src/tools/animation.ts +0 -941
  358. package/src/tools/assets.ts +0 -394
  359. package/src/tools/audio.ts +0 -499
  360. package/src/tools/base-tool.ts +0 -52
  361. package/src/tools/behavior-tree.ts +0 -45
  362. package/src/tools/blueprint.ts +0 -940
  363. package/src/tools/consolidated-tool-definitions.ts +0 -1256
  364. package/src/tools/consolidated-tool-handlers.ts +0 -302
  365. package/src/tools/debug.ts +0 -622
  366. package/src/tools/dynamic-handler-registry.ts +0 -33
  367. package/src/tools/editor.ts +0 -435
  368. package/src/tools/engine.ts +0 -43
  369. package/src/tools/environment.ts +0 -281
  370. package/src/tools/foliage.ts +0 -596
  371. package/src/tools/handlers/actor-handlers.ts +0 -244
  372. package/src/tools/handlers/animation-handlers.ts +0 -237
  373. package/src/tools/handlers/argument-helper.ts +0 -142
  374. package/src/tools/handlers/asset-handlers.ts +0 -550
  375. package/src/tools/handlers/audio-handlers.ts +0 -194
  376. package/src/tools/handlers/blueprint-handlers.ts +0 -380
  377. package/src/tools/handlers/common-handlers.ts +0 -108
  378. package/src/tools/handlers/editor-handlers.ts +0 -124
  379. package/src/tools/handlers/effect-handlers.ts +0 -224
  380. package/src/tools/handlers/environment-handlers.ts +0 -183
  381. package/src/tools/handlers/graph-handlers.ts +0 -117
  382. package/src/tools/handlers/input-handlers.ts +0 -28
  383. package/src/tools/handlers/inspect-handlers.ts +0 -450
  384. package/src/tools/handlers/level-handlers.ts +0 -253
  385. package/src/tools/handlers/lighting-handlers.ts +0 -151
  386. package/src/tools/handlers/performance-handlers.ts +0 -132
  387. package/src/tools/handlers/pipeline-handlers.ts +0 -194
  388. package/src/tools/handlers/sequence-handlers.ts +0 -438
  389. package/src/tools/handlers/system-handlers.ts +0 -564
  390. package/src/tools/input.ts +0 -160
  391. package/src/tools/introspection.ts +0 -689
  392. package/src/tools/landscape.ts +0 -649
  393. package/src/tools/level.ts +0 -989
  394. package/src/tools/lighting.ts +0 -1052
  395. package/src/tools/logs.ts +0 -219
  396. package/src/tools/materials.ts +0 -295
  397. package/src/tools/niagara.ts +0 -485
  398. package/src/tools/performance.ts +0 -661
  399. package/src/tools/physics.ts +0 -679
  400. package/src/tools/property-dictionary.ts +0 -98
  401. package/src/tools/sequence.ts +0 -385
  402. package/src/tools/tool-definition-utils.ts +0 -35
  403. package/src/tools/ui.ts +0 -452
  404. package/src/types/automation-responses.ts +0 -119
  405. package/src/types/env.ts +0 -17
  406. package/src/types/handler-types.ts +0 -442
  407. package/src/types/responses.ts +0 -355
  408. package/src/types/tool-interfaces.ts +0 -250
  409. package/src/types/tool-types.ts +0 -575
  410. package/src/unreal-bridge.ts +0 -693
  411. package/src/utils/command-validator.ts +0 -139
  412. package/src/utils/elicitation.ts +0 -132
  413. package/src/utils/error-handler.ts +0 -287
  414. package/src/utils/ini-reader.ts +0 -86
  415. package/src/utils/logger.ts +0 -35
  416. package/src/utils/normalize.test.ts +0 -162
  417. package/src/utils/normalize.ts +0 -146
  418. package/src/utils/path-security.ts +0 -43
  419. package/src/utils/response-factory.ts +0 -44
  420. package/src/utils/response-validator.ts +0 -395
  421. package/src/utils/result-helpers.ts +0 -195
  422. package/src/utils/safe-json.test.ts +0 -90
  423. package/src/utils/safe-json.ts +0 -70
  424. package/src/utils/unreal-command-queue.ts +0 -166
  425. package/src/utils/validation.test.ts +0 -184
  426. package/src/utils/validation.ts +0 -312
  427. package/src/wasm/index.ts +0 -838
  428. package/test-server.mjs +0 -100
  429. package/tests/test-animation.mjs +0 -369
  430. package/tests/test-asset-advanced.mjs +0 -82
  431. package/tests/test-asset-graph.mjs +0 -311
  432. package/tests/test-audio.mjs +0 -417
  433. package/tests/test-automation-timeouts.mjs +0 -98
  434. package/tests/test-behavior-tree.mjs +0 -444
  435. package/tests/test-blueprint-graph.mjs +0 -410
  436. package/tests/test-blueprint.mjs +0 -577
  437. package/tests/test-client-mode.mjs +0 -86
  438. package/tests/test-console-command.mjs +0 -56
  439. package/tests/test-control-actor.mjs +0 -425
  440. package/tests/test-control-editor.mjs +0 -112
  441. package/tests/test-graphql.mjs +0 -372
  442. package/tests/test-input.mjs +0 -349
  443. package/tests/test-inspect.mjs +0 -302
  444. package/tests/test-landscape.mjs +0 -316
  445. package/tests/test-lighting.mjs +0 -428
  446. package/tests/test-manage-asset.mjs +0 -438
  447. package/tests/test-manage-level.mjs +0 -89
  448. package/tests/test-materials.mjs +0 -356
  449. package/tests/test-niagara.mjs +0 -185
  450. package/tests/test-no-inline-python.mjs +0 -122
  451. package/tests/test-performance.mjs +0 -539
  452. package/tests/test-plugin-handshake.mjs +0 -82
  453. package/tests/test-runner.mjs +0 -993
  454. package/tests/test-sequence.mjs +0 -104
  455. package/tests/test-system.mjs +0 -96
  456. package/tests/test-wasm.mjs +0 -283
  457. package/tests/test-world-partition.mjs +0 -215
  458. package/tsconfig.json +0 -56
  459. package/vitest.config.ts +0 -35
  460. package/wasm/Cargo.lock +0 -363
  461. package/wasm/Cargo.toml +0 -42
  462. package/wasm/LICENSE +0 -21
  463. package/wasm/README.md +0 -253
  464. package/wasm/src/dependency_resolver.rs +0 -377
  465. package/wasm/src/lib.rs +0 -153
  466. package/wasm/src/property_parser.rs +0 -271
  467. package/wasm/src/transform_math.rs +0 -396
  468. package/wasm/tests/integration.rs +0 -109
@@ -1,762 +0,0 @@
1
- #include "McpAutomationBridgeGlobals.h"
2
- #include "McpAutomationBridgeHelpers.h"
3
- #include "McpAutomationBridgeSubsystem.h"
4
-
5
- #if WITH_EDITOR
6
- #include "Editor.h"
7
- #include "EditorLevelUtils.h"
8
- #include "Engine/LevelStreaming.h"
9
- #include "Engine/LevelStreamingAlwaysLoaded.h"
10
- #include "Engine/LevelStreamingDynamic.h"
11
- #include "Engine/World.h"
12
- #include "FileHelpers.h"
13
- #include "LevelEditor.h"
14
- #include "RenderingThread.h"
15
-
16
- // Check for LevelEditorSubsystem
17
- #if defined(__has_include)
18
- #if __has_include("Subsystems/LevelEditorSubsystem.h")
19
- #include "Subsystems/LevelEditorSubsystem.h"
20
- #define MCP_HAS_LEVELEDITOR_SUBSYSTEM 1
21
- #elif __has_include("LevelEditorSubsystem.h")
22
- #include "LevelEditorSubsystem.h"
23
- #define MCP_HAS_LEVELEDITOR_SUBSYSTEM 1
24
- #else
25
- #define MCP_HAS_LEVELEDITOR_SUBSYSTEM 0
26
- #endif
27
- #else
28
- #define MCP_HAS_LEVELEDITOR_SUBSYSTEM 0
29
- #endif
30
- #endif
31
-
32
- bool UMcpAutomationBridgeSubsystem::HandleLevelAction(
33
- const FString &RequestId, const FString &Action,
34
- const TSharedPtr<FJsonObject> &Payload,
35
- TSharedPtr<FMcpBridgeWebSocket> RequestingSocket) {
36
- const FString Lower = Action.ToLower();
37
- const bool bIsLevelAction =
38
- (Lower == TEXT("manage_level") || Lower == TEXT("save_current_level") ||
39
- Lower == TEXT("create_new_level") || Lower == TEXT("stream_level") ||
40
- Lower == TEXT("spawn_light") || Lower == TEXT("build_lighting") ||
41
- Lower == TEXT("spawn_light") || Lower == TEXT("build_lighting") ||
42
- Lower == TEXT("bake_lightmap") || Lower == TEXT("list_levels") ||
43
- Lower == TEXT("export_level") || Lower == TEXT("import_level") ||
44
- Lower == TEXT("add_sublevel"));
45
- if (!bIsLevelAction)
46
- return false;
47
-
48
- FString EffectiveAction = Lower;
49
-
50
- // Unpack manage_level
51
- if (Lower == TEXT("manage_level")) {
52
- if (!Payload.IsValid()) {
53
- SendAutomationError(RequestingSocket, RequestId,
54
- TEXT("manage_level payload missing"),
55
- TEXT("INVALID_PAYLOAD"));
56
- return true;
57
- }
58
- FString SubAction;
59
- Payload->TryGetStringField(TEXT("action"), SubAction);
60
- const FString LowerSub = SubAction.ToLower();
61
-
62
- if (LowerSub == TEXT("load") || LowerSub == TEXT("load_level")) {
63
- // Map to Open command
64
- FString LevelPath;
65
- Payload->TryGetStringField(TEXT("levelPath"), LevelPath);
66
-
67
- // Determine invalid characters for checks
68
- if (LevelPath.IsEmpty()) {
69
- SendAutomationError(RequestingSocket, RequestId,
70
- TEXT("levelPath required"),
71
- TEXT("INVALID_ARGUMENT"));
72
- }
73
-
74
- // Auto-resolve short names
75
- if (!LevelPath.StartsWith(TEXT("/")) && !FPaths::FileExists(LevelPath)) {
76
- FString TryPath = FString::Printf(TEXT("/Game/Maps/%s"), *LevelPath);
77
- if (FPackageName::DoesPackageExist(TryPath)) {
78
- LevelPath = TryPath;
79
- }
80
- }
81
-
82
- #if WITH_EDITOR
83
- if (!GEditor) {
84
- SendAutomationResponse(RequestingSocket, RequestId, false,
85
- TEXT("Editor not available"), nullptr,
86
- TEXT("EDITOR_NOT_AVAILABLE"));
87
- return true;
88
- }
89
-
90
- // Try to resolve package path to filename
91
- FString Filename;
92
- bool bGotFilename = false;
93
- if (FPackageName::IsPackageFilename(LevelPath)) {
94
- Filename = LevelPath;
95
- bGotFilename = true;
96
- } else {
97
- // Assume package path
98
- if (FPackageName::TryConvertLongPackageNameToFilename(
99
- LevelPath, Filename, FPackageName::GetMapPackageExtension())) {
100
- bGotFilename = true;
101
- }
102
- }
103
-
104
- // If conversion failed, it might be a short name? But LoadMap usually
105
- // needs full path. Let's try to load what we have if conversion returned
106
- // something, else fallback to input.
107
- const FString FileToLoad = bGotFilename ? Filename : LevelPath;
108
-
109
- // Force any pending work to complete
110
- FlushRenderingCommands();
111
-
112
- // LoadMap prompts for save if dirty. To avoid blocking automation, we
113
- // should carefuly consider. But for now, we assume user wants standard
114
- // behavior or has saved. There isn't a simple "Force Load" via FileUtils
115
- // without clearing dirty flags manually. We will proceed with LoadMap.
116
- const bool bLoaded = FEditorFileUtils::LoadMap(FileToLoad);
117
-
118
- if (bLoaded) {
119
- TSharedPtr<FJsonObject> Resp = MakeShared<FJsonObject>();
120
- Resp->SetStringField(TEXT("levelPath"), LevelPath);
121
- SendAutomationResponse(RequestingSocket, RequestId, true,
122
- TEXT("Level loaded"), Resp, FString());
123
- return true;
124
- } else {
125
- // Fallback to ExecuteConsoleCommand "Open" if LoadMap failed (e.g.
126
- // maybe it was a raw asset path or something) But actually if LoadMap
127
- // fails, Open likely fails too.
128
- SendAutomationResponse(
129
- RequestingSocket, RequestId, false,
130
- FString::Printf(TEXT("Failed to load map: %s"), *LevelPath),
131
- nullptr, TEXT("LOAD_FAILED"));
132
- return true;
133
- }
134
- #else
135
- return false;
136
- #endif
137
- } else if (LowerSub == TEXT("save")) {
138
- EffectiveAction = TEXT("save_current_level");
139
- } else if (LowerSub == TEXT("save_as") ||
140
- LowerSub == TEXT("save_level_as")) {
141
- EffectiveAction = TEXT("save_level_as");
142
- } else if (LowerSub == TEXT("create_level")) {
143
- EffectiveAction = TEXT("create_new_level");
144
- } else if (LowerSub == TEXT("stream")) {
145
- EffectiveAction = TEXT("stream_level");
146
- } else if (LowerSub == TEXT("create_light")) {
147
- EffectiveAction = TEXT("spawn_light");
148
- } else if (LowerSub == TEXT("list") || LowerSub == TEXT("list_levels")) {
149
- EffectiveAction = TEXT("list_levels");
150
- } else if (LowerSub == TEXT("export_level")) {
151
- EffectiveAction = TEXT("export_level");
152
- } else if (LowerSub == TEXT("import_level")) {
153
- } else if (LowerSub == TEXT("import_level")) {
154
- EffectiveAction = TEXT("import_level");
155
- } else if (LowerSub == TEXT("add_sublevel")) {
156
- EffectiveAction = TEXT("add_sublevel");
157
- } else {
158
- SendAutomationError(
159
- RequestingSocket, RequestId,
160
- FString::Printf(TEXT("Unknown manage_level action: %s"), *SubAction),
161
- TEXT("UNKNOWN_ACTION"));
162
- return true;
163
- }
164
- }
165
-
166
- #if WITH_EDITOR
167
- if (EffectiveAction == TEXT("save_current_level")) {
168
- if (!GEditor) {
169
- SendAutomationResponse(RequestingSocket, RequestId, false,
170
- TEXT("Editor not available"), nullptr,
171
- TEXT("EDITOR_NOT_AVAILABLE"));
172
- return true;
173
- }
174
-
175
- UWorld *World = GEditor->GetEditorWorldContext().World();
176
- if (!World) {
177
- SendAutomationResponse(RequestingSocket, RequestId, false,
178
- TEXT("No world loaded"), nullptr,
179
- TEXT("NO_WORLD"));
180
- return true;
181
- }
182
-
183
- bool bSaved = FEditorFileUtils::SaveCurrentLevel();
184
- if (bSaved) {
185
- TSharedPtr<FJsonObject> Resp = MakeShared<FJsonObject>();
186
- Resp->SetStringField(TEXT("levelPath"), World->GetOutermost()->GetName());
187
- SendAutomationResponse(RequestingSocket, RequestId, true,
188
- TEXT("Level saved"), Resp, FString());
189
- } else {
190
- // Provide detailed error information
191
- TSharedPtr<FJsonObject> ErrorDetail = MakeShared<FJsonObject>();
192
- FString PackageName = World->GetOutermost()->GetName();
193
- ErrorDetail->SetStringField(TEXT("attemptedPath"), PackageName);
194
-
195
- FString Filename;
196
- FString ErrorReason = TEXT("Unknown save failure");
197
-
198
- if (PackageName.Contains(TEXT("Untitled")) ||
199
- PackageName.StartsWith(TEXT("/Temp/"))) {
200
- ErrorReason = TEXT(
201
- "Level is unsaved/temporary. Use save_level_as with a path first.");
202
- ErrorDetail->SetStringField(
203
- TEXT("hint"),
204
- TEXT(
205
- "Use manage_level with action='save_as' and provide savePath"));
206
- } else if (FPackageName::TryConvertLongPackageNameToFilename(
207
- PackageName, Filename,
208
- FPackageName::GetMapPackageExtension())) {
209
- if (IFileManager::Get().IsReadOnly(*Filename)) {
210
- ErrorReason = TEXT("File is read-only or locked by another process");
211
- ErrorDetail->SetStringField(TEXT("filename"), Filename);
212
- } else if (!IFileManager::Get().DirectoryExists(
213
- *FPaths::GetPath(Filename))) {
214
- ErrorReason = TEXT("Target directory does not exist");
215
- ErrorDetail->SetStringField(TEXT("directory"),
216
- FPaths::GetPath(Filename));
217
- } else {
218
- ErrorReason =
219
- TEXT("Save operation failed - check Output Log for details");
220
- ErrorDetail->SetStringField(TEXT("filename"), Filename);
221
- }
222
- }
223
-
224
- ErrorDetail->SetStringField(TEXT("reason"), ErrorReason);
225
- SendAutomationResponse(
226
- RequestingSocket, RequestId, false,
227
- FString::Printf(TEXT("Failed to save level: %s"), *ErrorReason),
228
- ErrorDetail, TEXT("SAVE_FAILED"));
229
- }
230
- return true;
231
- }
232
- if (EffectiveAction == TEXT("save_level_as")) {
233
- // Force cleanup to prevent potential deadlocks with HLODs/WorldPartition
234
- // during save
235
- if (GEditor) {
236
- FlushRenderingCommands();
237
- GEditor->ForceGarbageCollection(true);
238
- FlushRenderingCommands();
239
- }
240
-
241
- FString SavePath;
242
- if (Payload.IsValid())
243
- Payload->TryGetStringField(TEXT("savePath"), SavePath);
244
- if (SavePath.IsEmpty()) {
245
- SendAutomationResponse(RequestingSocket, RequestId, false,
246
- TEXT("savePath required for save_level_as"),
247
- nullptr, TEXT("INVALID_ARGUMENT"));
248
- return true;
249
- }
250
-
251
- #if defined(MCP_HAS_LEVELEDITOR_SUBSYSTEM)
252
- if (ULevelEditorSubsystem *LevelEditorSS =
253
- GEditor->GetEditorSubsystem<ULevelEditorSubsystem>()) {
254
- bool bSaved = false;
255
- #if __has_include("FileHelpers.h")
256
- if (UWorld *World = GEditor->GetEditorWorldContext().World()) {
257
- bSaved = FEditorFileUtils::SaveMap(World, SavePath);
258
- }
259
- #endif
260
- if (bSaved) {
261
- TSharedPtr<FJsonObject> Resp = MakeShared<FJsonObject>();
262
- Resp->SetStringField(TEXT("levelPath"), SavePath);
263
- SendAutomationResponse(
264
- RequestingSocket, RequestId, true,
265
- FString::Printf(TEXT("Level saved as %s"), *SavePath), Resp,
266
- FString());
267
- } else {
268
- SendAutomationResponse(RequestingSocket, RequestId, false,
269
- TEXT("Failed to save level as"), nullptr,
270
- TEXT("SAVE_FAILED"));
271
- }
272
- return true;
273
- }
274
- #endif
275
- SendAutomationResponse(RequestingSocket, RequestId, false,
276
- TEXT("LevelEditorSubsystem not available"), nullptr,
277
- TEXT("SUBSYSTEM_MISSING"));
278
- return true;
279
- }
280
- if (EffectiveAction == TEXT("build_lighting") ||
281
- EffectiveAction == TEXT("bake_lightmap")) {
282
- TSharedPtr<FJsonObject> P = MakeShared<FJsonObject>();
283
- P->SetStringField(TEXT("functionName"), TEXT("BUILD_LIGHTING"));
284
- if (Payload.IsValid()) {
285
- FString Q;
286
- if (Payload->TryGetStringField(TEXT("quality"), Q) && !Q.IsEmpty())
287
- P->SetStringField(TEXT("quality"), Q);
288
- }
289
- return HandleExecuteEditorFunction(
290
- RequestId, TEXT("execute_editor_function"), P, RequestingSocket);
291
- }
292
- if (EffectiveAction == TEXT("create_new_level")) {
293
- FString LevelName;
294
- if (Payload.IsValid())
295
- Payload->TryGetStringField(TEXT("levelName"), LevelName);
296
-
297
- FString LevelPath;
298
- if (Payload.IsValid())
299
- Payload->TryGetStringField(TEXT("levelPath"), LevelPath);
300
-
301
- // Construct valid package path
302
- FString SavePath = LevelPath;
303
- if (SavePath.IsEmpty() && !LevelName.IsEmpty()) {
304
- if (LevelName.StartsWith(TEXT("/")))
305
- SavePath = LevelName;
306
- else
307
- SavePath = FString::Printf(TEXT("/Game/Maps/%s"), *LevelName);
308
- }
309
-
310
- if (SavePath.IsEmpty()) {
311
- SendAutomationResponse(
312
- RequestingSocket, RequestId, false,
313
- TEXT("levelName or levelPath required for create_level"), nullptr,
314
- TEXT("INVALID_ARGUMENT"));
315
- return true;
316
- }
317
-
318
- // Check if map already exists
319
- if (FPackageName::DoesPackageExist(SavePath)) {
320
- // If exists, just open it
321
- const FString Cmd = FString::Printf(TEXT("Open %s"), *SavePath);
322
- TSharedPtr<FJsonObject> P = MakeShared<FJsonObject>();
323
- P->SetStringField(TEXT("command"), Cmd);
324
- return HandleExecuteEditorFunction(
325
- RequestId, TEXT("execute_console_command"), P, RequestingSocket);
326
- }
327
-
328
- // Create new map
329
- #if defined(MCP_HAS_LEVELEDITOR_SUBSYSTEM) && __has_include("FileHelpers.h")
330
- if (GEditor->IsPlaySessionInProgress()) {
331
- GEditor->RequestEndPlayMap();
332
- SendAutomationResponse(
333
- RequestingSocket, RequestId, false,
334
- TEXT("Cannot create level while Play In Editor is active."), nullptr,
335
- TEXT("PIE_ACTIVE"));
336
- return true;
337
- }
338
-
339
- // Force cleanup of previous world/resources to prevent RenderCore/Driver
340
- // crashes (monza/D3D12) especially when tests run back-to-back triggering
341
- // thumbnail generation or world partition shutdown.
342
- if (GEditor) {
343
- FlushRenderingCommands();
344
- GEditor->ForceGarbageCollection(true);
345
- FlushRenderingCommands();
346
- }
347
-
348
- if (UWorld *NewWorld =
349
- GEditor->NewMap(true)) // true = force new map (creates untitled)
350
- {
351
- GEditor->GetEditorWorldContext().SetCurrentWorld(NewWorld);
352
-
353
- // Save it to valid path
354
- // ISSUE #1 FIX: Ensure directory exists
355
- FString Filename;
356
- if (FPackageName::TryConvertLongPackageNameToFilename(
357
- SavePath, Filename, FPackageName::GetMapPackageExtension())) {
358
- IFileManager::Get().MakeDirectory(*FPaths::GetPath(Filename), true);
359
- }
360
-
361
- if (FEditorFileUtils::SaveMap(NewWorld, SavePath)) {
362
- TSharedPtr<FJsonObject> Resp = MakeShared<FJsonObject>();
363
- Resp->SetStringField(TEXT("levelPath"), SavePath);
364
- Resp->SetStringField(TEXT("packagePath"), SavePath);
365
- Resp->SetStringField(TEXT("objectPath"),
366
- SavePath + TEXT(".") +
367
- FPaths::GetBaseFilename(SavePath));
368
- SendAutomationResponse(
369
- RequestingSocket, RequestId, true,
370
- FString::Printf(TEXT("Level created: %s"), *SavePath), Resp,
371
- FString());
372
- } else {
373
- SendAutomationResponse(RequestingSocket, RequestId, false,
374
- TEXT("Failed to save new level"), nullptr,
375
- TEXT("SAVE_FAILED"));
376
- }
377
- } else {
378
- SendAutomationResponse(RequestingSocket, RequestId, false,
379
- TEXT("Failed to create new map"), nullptr,
380
- TEXT("CREATION_FAILED"));
381
- }
382
- return true;
383
- #else
384
- // Fallback for missing headers (shouldn't happen given build.cs)
385
- const FString Cmd = FString::Printf(TEXT("Open %s"), *SavePath);
386
- TSharedPtr<FJsonObject> P = MakeShared<FJsonObject>();
387
- P->SetStringField(TEXT("command"), Cmd);
388
- return HandleExecuteEditorFunction(
389
- RequestId, TEXT("execute_console_command"), P, RequestingSocket);
390
- #endif
391
- }
392
- if (EffectiveAction == TEXT("stream_level")) {
393
- FString LevelName;
394
- bool bLoad = true;
395
- bool bVis = true;
396
- if (Payload.IsValid()) {
397
- Payload->TryGetStringField(TEXT("levelName"), LevelName);
398
- Payload->TryGetBoolField(TEXT("shouldBeLoaded"), bLoad);
399
- Payload->TryGetBoolField(TEXT("shouldBeVisible"), bVis);
400
- if (LevelName.IsEmpty())
401
- Payload->TryGetStringField(TEXT("levelPath"), LevelName);
402
- }
403
- if (LevelName.TrimStartAndEnd().IsEmpty()) {
404
- SendAutomationResponse(
405
- RequestingSocket, RequestId, false,
406
- TEXT("stream_level requires levelName or levelPath"), nullptr,
407
- TEXT("INVALID_ARGUMENT"));
408
- return true;
409
- }
410
- const FString Cmd =
411
- FString::Printf(TEXT("StreamLevel %s %s %s"), *LevelName,
412
- bLoad ? TEXT("Load") : TEXT("Unload"),
413
- bVis ? TEXT("Show") : TEXT("Hide"));
414
- TSharedPtr<FJsonObject> P = MakeShared<FJsonObject>();
415
- P->SetStringField(TEXT("command"), Cmd);
416
- return HandleExecuteEditorFunction(
417
- RequestId, TEXT("execute_console_command"), P, RequestingSocket);
418
- }
419
- if (EffectiveAction == TEXT("spawn_light")) {
420
- FString LightType = TEXT("Point");
421
- if (Payload.IsValid())
422
- Payload->TryGetStringField(TEXT("lightType"), LightType);
423
- const FString LT = LightType.ToLower();
424
- FString ClassName;
425
- if (LT == TEXT("directional"))
426
- ClassName = TEXT("DirectionalLight");
427
- else if (LT == TEXT("spot"))
428
- ClassName = TEXT("SpotLight");
429
- else if (LT == TEXT("rect"))
430
- ClassName = TEXT("RectLight");
431
- else
432
- ClassName = TEXT("PointLight");
433
- TSharedPtr<FJsonObject> Params = MakeShared<FJsonObject>();
434
- if (Payload.IsValid()) {
435
- const TSharedPtr<FJsonObject> *L = nullptr;
436
- if (Payload->TryGetObjectField(TEXT("location"), L) && L &&
437
- (*L).IsValid())
438
- Params->SetObjectField(TEXT("location"), *L);
439
- const TSharedPtr<FJsonObject> *R = nullptr;
440
- if (Payload->TryGetObjectField(TEXT("rotation"), R) && R &&
441
- (*R).IsValid())
442
- Params->SetObjectField(TEXT("rotation"), *R);
443
- }
444
- TSharedPtr<FJsonObject> P = MakeShared<FJsonObject>();
445
- P->SetStringField(TEXT("functionName"), TEXT("SPAWN_ACTOR_AT_LOCATION"));
446
- P->SetStringField(TEXT("class_path"), ClassName);
447
- P->SetObjectField(TEXT("params"), Params.ToSharedRef());
448
- return HandleExecuteEditorFunction(
449
- RequestId, TEXT("execute_editor_function"), P, RequestingSocket);
450
- }
451
- if (EffectiveAction == TEXT("list_levels")) {
452
- TSharedPtr<FJsonObject> Resp = MakeShared<FJsonObject>();
453
- TArray<TSharedPtr<FJsonValue>> LevelsArray;
454
-
455
- UWorld *World =
456
- GEditor ? GEditor->GetEditorWorldContext().World() : nullptr;
457
-
458
- // Add current persistent level
459
- if (World) {
460
- TSharedPtr<FJsonObject> CurrentLevel = MakeShared<FJsonObject>();
461
- CurrentLevel->SetStringField(TEXT("name"), World->GetMapName());
462
- CurrentLevel->SetStringField(TEXT("path"),
463
- World->GetOutermost()->GetName());
464
- CurrentLevel->SetBoolField(TEXT("isPersistent"), true);
465
- CurrentLevel->SetBoolField(TEXT("isLoaded"), true);
466
- CurrentLevel->SetBoolField(TEXT("isVisible"), true);
467
- LevelsArray.Add(MakeShared<FJsonValueObject>(CurrentLevel));
468
-
469
- // Add streaming levels
470
- for (const ULevelStreaming *StreamingLevel :
471
- World->GetStreamingLevels()) {
472
- if (!StreamingLevel)
473
- continue;
474
-
475
- TSharedPtr<FJsonObject> LevelEntry = MakeShared<FJsonObject>();
476
- LevelEntry->SetStringField(TEXT("name"),
477
- StreamingLevel->GetWorldAssetPackageName());
478
- LevelEntry->SetStringField(
479
- TEXT("path"),
480
- StreamingLevel->GetWorldAssetPackageFName().ToString());
481
- LevelEntry->SetBoolField(TEXT("isPersistent"), false);
482
- LevelEntry->SetBoolField(TEXT("isLoaded"),
483
- StreamingLevel->IsLevelLoaded());
484
- LevelEntry->SetBoolField(TEXT("isVisible"),
485
- StreamingLevel->IsLevelVisible());
486
- LevelEntry->SetStringField(
487
- TEXT("streamingState"),
488
- StreamingLevel->IsStreamingStatePending() ? TEXT("Pending")
489
- : StreamingLevel->IsLevelLoaded() ? TEXT("Loaded")
490
- : TEXT("Unloaded"));
491
- LevelsArray.Add(MakeShared<FJsonValueObject>(LevelEntry));
492
- }
493
- }
494
-
495
- // Also query Asset Registry for all map assets
496
- IAssetRegistry &AssetRegistry =
497
- FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry")
498
- .Get();
499
- TArray<FAssetData> MapAssets;
500
- AssetRegistry.GetAssetsByClass(
501
- FTopLevelAssetPath(TEXT("/Script/Engine"), TEXT("World")), MapAssets,
502
- false);
503
-
504
- TArray<TSharedPtr<FJsonValue>> AllMapsArray;
505
- for (const FAssetData &MapAsset : MapAssets) {
506
- TSharedPtr<FJsonObject> MapEntry = MakeShared<FJsonObject>();
507
- MapEntry->SetStringField(TEXT("name"), MapAsset.AssetName.ToString());
508
- MapEntry->SetStringField(TEXT("path"), MapAsset.PackageName.ToString());
509
- MapEntry->SetStringField(TEXT("objectPath"),
510
- MapAsset.GetObjectPathString());
511
- AllMapsArray.Add(MakeShared<FJsonValueObject>(MapEntry));
512
- }
513
-
514
- Resp->SetArrayField(TEXT("currentWorldLevels"), LevelsArray);
515
- Resp->SetNumberField(TEXT("currentWorldLevelCount"), LevelsArray.Num());
516
- Resp->SetArrayField(TEXT("allMaps"), AllMapsArray);
517
- Resp->SetNumberField(TEXT("allMapsCount"), AllMapsArray.Num());
518
-
519
- if (World) {
520
- Resp->SetStringField(TEXT("currentMap"), World->GetMapName());
521
- Resp->SetStringField(TEXT("currentMapPath"),
522
- World->GetOutermost()->GetName());
523
- }
524
-
525
- SendAutomationResponse(RequestingSocket, RequestId, true,
526
- TEXT("Levels listed"), Resp, FString());
527
- return true;
528
- }
529
- if (EffectiveAction == TEXT("export_level")) {
530
- FString LevelPath;
531
- if (Payload.IsValid())
532
- Payload->TryGetStringField(TEXT("levelPath"), LevelPath);
533
- FString ExportPath;
534
- if (Payload.IsValid())
535
- Payload->TryGetStringField(TEXT("exportPath"), ExportPath);
536
- if (ExportPath.IsEmpty())
537
- if (Payload.IsValid())
538
- Payload->TryGetStringField(TEXT("destinationPath"), ExportPath);
539
-
540
- if (ExportPath.IsEmpty()) {
541
- SendAutomationResponse(RequestingSocket, RequestId, false,
542
- TEXT("exportPath required"), nullptr,
543
- TEXT("INVALID_ARGUMENT"));
544
- return true;
545
- }
546
-
547
- if (!GEditor) {
548
- SendAutomationResponse(RequestingSocket, RequestId, false,
549
- TEXT("Editor not available"), nullptr,
550
- TEXT("EDITOR_NOT_AVAILABLE"));
551
- return true;
552
- }
553
-
554
- UWorld *WorldToExport = nullptr;
555
- if (!LevelPath.IsEmpty()) {
556
- // If levelPath provided, we should probably load it first? Or export from
557
- // asset. Exporting unloaded level asset usually involves loading it. For
558
- // now, if levelPath is current, use current. If not, error (or attempt
559
- // load).
560
- UWorld *Current = GEditor->GetEditorWorldContext().World();
561
- if (Current && (Current->GetOutermost()->GetName() == LevelPath ||
562
- Current->GetPathName() == LevelPath)) {
563
- WorldToExport = Current;
564
- } else {
565
- // Should we load?
566
- // SendAutomationError(RequestingSocket, RequestId, TEXT("Level must be
567
- // loaded to export"), TEXT("LEVEL_NOT_LOADED")); return true; For
568
- // robustness, let's assume export current if path matches or empty.
569
- }
570
- }
571
- if (!WorldToExport)
572
- WorldToExport = GEditor->GetEditorWorldContext().World();
573
-
574
- if (!WorldToExport) {
575
- SendAutomationResponse(RequestingSocket, RequestId, false,
576
- TEXT("No world loaded"), nullptr,
577
- TEXT("NO_WORLD"));
578
- return true;
579
- }
580
-
581
- // Ensure directory
582
- IFileManager::Get().MakeDirectory(*FPaths::GetPath(ExportPath), true);
583
-
584
- // FEditorFileUtils::ExportMap(WorldToExport, ExportPath); // Legacy/Removed
585
- // Use SaveMap for .umap or FEditorFileUtils::SaveLevel
586
- FEditorFileUtils::SaveMap(WorldToExport, ExportPath);
587
-
588
- SendAutomationResponse(RequestingSocket, RequestId, true,
589
- TEXT("Level exported"), nullptr);
590
- return true;
591
- }
592
- if (EffectiveAction == TEXT("import_level")) {
593
- FString DestinationPath;
594
- if (Payload.IsValid())
595
- Payload->TryGetStringField(TEXT("destinationPath"), DestinationPath);
596
- FString SourcePath;
597
- if (Payload.IsValid())
598
- Payload->TryGetStringField(TEXT("sourcePath"), SourcePath);
599
- if (SourcePath.IsEmpty())
600
- if (Payload.IsValid())
601
- Payload->TryGetStringField(TEXT("packagePath"), SourcePath); // Mapping
602
-
603
- if (SourcePath.IsEmpty()) {
604
- SendAutomationResponse(RequestingSocket, RequestId, false,
605
- TEXT("sourcePath/packagePath required"), nullptr,
606
- TEXT("INVALID_ARGUMENT"));
607
- return true;
608
- }
609
-
610
- // If SourcePath is a package (starts with /Game), handle as Duplicate/Copy
611
- if (SourcePath.StartsWith(TEXT("/"))) {
612
- if (DestinationPath.IsEmpty()) {
613
- SendAutomationResponse(RequestingSocket, RequestId, false,
614
- TEXT("destinationPath required for asset copy"),
615
- nullptr, TEXT("INVALID_ARGUMENT"));
616
- return true;
617
- }
618
- if (UEditorAssetLibrary::DuplicateAsset(SourcePath, DestinationPath)) {
619
- SendAutomationResponse(RequestingSocket, RequestId, true,
620
- TEXT("Level imported (duplicated)"), nullptr);
621
- } else {
622
- SendAutomationResponse(RequestingSocket, RequestId, false,
623
- TEXT("Failed to duplicate level asset"), nullptr,
624
- TEXT("IMPORT_FAILED"));
625
- }
626
- return true;
627
- }
628
-
629
- // If SourcePath is file, try Import
630
- if (!GEditor) {
631
- SendAutomationResponse(RequestingSocket, RequestId, false,
632
- TEXT("Editor not available"), nullptr,
633
- TEXT("EDITOR_NOT_AVAILABLE"));
634
- return true;
635
- }
636
-
637
- FString DestPath = DestinationPath.IsEmpty()
638
- ? TEXT("/Game/Maps")
639
- : FPaths::GetPath(DestinationPath);
640
- FString DestName = FPaths::GetBaseFilename(
641
- DestinationPath.IsEmpty() ? SourcePath : DestinationPath);
642
-
643
- TArray<FString> Files;
644
- Files.Add(SourcePath);
645
- // FEditorFileUtils::Import(DestPath, DestName); // Ambiguous/Removed
646
- // Use GEditor->ImportMap or handle via AssetTools
647
- // Simple fallback:
648
- if (GEditor) {
649
- // ImportMap is usually for T3D. If SourcePath is .umap, we should
650
- // Copy/Load. Assuming T3D import or similar:
651
- // GEditor->ImportMap(*DestPath, *DestName, *SourcePath);
652
- // ImportMap is deprecated/removed. For .umap files, manual import or Copy
653
- // is preferred.
654
- SendAutomationResponse(RequestingSocket, RequestId, false,
655
- TEXT("Direct map file import not supported. Use "
656
- "import_level with a package path to copy."),
657
- nullptr, TEXT("NOT_IMPLEMENTED"));
658
- return true;
659
- }
660
- // Automation of Import is tricky without a factory wrapper.
661
- // Use AssetTools Import.
662
-
663
- SendAutomationResponse(
664
- RequestingSocket, RequestId, false,
665
- TEXT("File-based level import not fully automatic yet"), nullptr,
666
- TEXT("NOT_IMPLEMENTED"));
667
- return true;
668
- }
669
- if (EffectiveAction == TEXT("add_sublevel")) {
670
- FString SubLevelPath;
671
- if (Payload.IsValid())
672
- Payload->TryGetStringField(TEXT("subLevelPath"), SubLevelPath);
673
- if (SubLevelPath.IsEmpty() && Payload.IsValid())
674
- Payload->TryGetStringField(TEXT("levelPath"), SubLevelPath);
675
-
676
- if (SubLevelPath.IsEmpty()) {
677
- SendAutomationError(RequestingSocket, RequestId,
678
- TEXT("subLevelPath required"),
679
- TEXT("INVALID_ARGUMENT"));
680
- return true;
681
- }
682
-
683
- // Robustness: Cleanup before adding
684
- if (GEditor) {
685
- GEditor->ForceGarbageCollection(true);
686
- }
687
-
688
- // Verify file existence (more robust than DoesPackageExist for new files)
689
- FString Filename;
690
- bool bFileFound = false;
691
- if (FPackageName::TryConvertLongPackageNameToFilename(
692
- SubLevelPath, Filename, FPackageName::GetMapPackageExtension())) {
693
- if (IFileManager::Get().FileExists(*Filename)) {
694
- bFileFound = true;
695
- }
696
- }
697
-
698
- // Fallback: Check without conversion if it's already a file path?
699
- if (!bFileFound && IFileManager::Get().FileExists(*SubLevelPath)) {
700
- bFileFound = true;
701
- }
702
-
703
- if (!bFileFound) {
704
- // Try checking DoesPackageExist as last resort
705
- if (!FPackageName::DoesPackageExist(SubLevelPath)) {
706
- SendAutomationResponse(
707
- RequestingSocket, RequestId, false,
708
- FString::Printf(TEXT("Level file not found: %s"), *SubLevelPath),
709
- nullptr, TEXT("PACKAGE_NOT_FOUND"));
710
- return true;
711
- }
712
- }
713
-
714
- FString StreamingMethod = TEXT("Blueprint");
715
- if (Payload.IsValid())
716
- Payload->TryGetStringField(TEXT("streamingMethod"), StreamingMethod);
717
-
718
- if (!GEditor) {
719
- SendAutomationResponse(RequestingSocket, RequestId, false,
720
- TEXT("Editor unavailable"), nullptr,
721
- TEXT("NO_EDITOR"));
722
- return true;
723
- }
724
-
725
- UWorld *World = GEditor->GetEditorWorldContext().World();
726
- if (!World) {
727
- SendAutomationResponse(RequestingSocket, RequestId, false,
728
- TEXT("No world loaded"), nullptr,
729
- TEXT("NO_WORLD"));
730
- return true;
731
- }
732
-
733
- // Determine streaming class
734
- UClass *StreamingClass = ULevelStreamingDynamic::StaticClass();
735
- if (StreamingMethod.Equals(TEXT("AlwaysLoaded"), ESearchCase::IgnoreCase)) {
736
- StreamingClass = ULevelStreamingAlwaysLoaded::StaticClass();
737
- }
738
-
739
- ULevelStreaming *NewLevel = UEditorLevelUtils::AddLevelToWorld(
740
- World, *SubLevelPath, StreamingClass);
741
- if (NewLevel) {
742
- SendAutomationResponse(RequestingSocket, RequestId, true,
743
- TEXT("Sublevel added successfully"), nullptr);
744
- } else {
745
- // Did we fail because it's already there?
746
- SendAutomationResponse(
747
- RequestingSocket, RequestId, false,
748
- FString::Printf(TEXT("Failed to add sublevel %s (Check logs)"),
749
- *SubLevelPath),
750
- nullptr, TEXT("ADD_FAILED"));
751
- }
752
- return true;
753
- }
754
-
755
- return false;
756
- #else
757
- SendAutomationResponse(RequestingSocket, RequestId, false,
758
- TEXT("Level actions require editor build."), nullptr,
759
- TEXT("NOT_IMPLEMENTED"));
760
- return true;
761
- #endif
762
- }