unreal-engine-mcp-server 0.4.6 → 0.5.0
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/.env.example +26 -0
- package/.env.production +38 -7
- package/.eslintrc.json +0 -54
- package/.eslintrc.override.json +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +94 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +56 -0
- package/.github/copilot-instructions.md +478 -45
- package/.github/dependabot.yml +19 -0
- package/.github/labeler.yml +24 -0
- package/.github/labels.yml +70 -0
- package/.github/pull_request_template.md +42 -0
- package/.github/release-drafter.yml +148 -0
- package/.github/workflows/auto-merge.yml +38 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/dependency-review.yml +17 -0
- package/.github/workflows/gemini-issue-triage.yml +172 -0
- package/.github/workflows/greetings.yml +23 -0
- package/.github/workflows/labeler.yml +16 -0
- package/.github/workflows/links.yml +80 -0
- package/.github/workflows/pr-size-labeler.yml +137 -0
- package/.github/workflows/publish-mcp.yml +12 -7
- package/.github/workflows/release-drafter.yml +23 -0
- package/.github/workflows/release.yml +112 -0
- package/.github/workflows/semantic-pull-request.yml +35 -0
- package/.github/workflows/smoke-test.yml +36 -0
- package/.github/workflows/stale.yml +28 -0
- package/CHANGELOG.md +269 -22
- package/CONTRIBUTING.md +140 -0
- package/README.md +166 -72
- package/claude_desktop_config_example.json +7 -6
- package/dist/automation/bridge.d.ts +50 -0
- package/dist/automation/bridge.js +452 -0
- package/dist/automation/connection-manager.d.ts +23 -0
- package/dist/automation/connection-manager.js +107 -0
- package/dist/automation/handshake.d.ts +11 -0
- package/dist/automation/handshake.js +89 -0
- package/dist/automation/index.d.ts +3 -0
- package/dist/automation/index.js +3 -0
- package/dist/automation/message-handler.d.ts +12 -0
- package/dist/automation/message-handler.js +149 -0
- package/dist/automation/request-tracker.d.ts +25 -0
- package/dist/automation/request-tracker.js +98 -0
- package/dist/automation/types.d.ts +130 -0
- package/dist/automation/types.js +2 -0
- package/dist/cli.js +32 -5
- package/dist/config.d.ts +27 -0
- package/dist/config.js +60 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +12 -0
- package/dist/graphql/resolvers.d.ts +268 -0
- package/dist/graphql/resolvers.js +743 -0
- package/dist/graphql/schema.d.ts +5 -0
- package/dist/graphql/schema.js +437 -0
- package/dist/graphql/server.d.ts +26 -0
- package/dist/graphql/server.js +115 -0
- package/dist/graphql/types.d.ts +7 -0
- package/dist/graphql/types.js +2 -0
- package/dist/handlers/resource-handlers.d.ts +20 -0
- package/dist/handlers/resource-handlers.js +180 -0
- package/dist/index.d.ts +31 -18
- package/dist/index.js +119 -604
- package/dist/prompts/index.js +4 -4
- package/dist/resources/actors.d.ts +17 -12
- package/dist/resources/actors.js +56 -76
- package/dist/resources/assets.d.ts +6 -14
- package/dist/resources/assets.js +115 -147
- package/dist/resources/levels.d.ts +13 -13
- package/dist/resources/levels.js +25 -34
- package/dist/server/resource-registry.d.ts +20 -0
- package/dist/server/resource-registry.js +37 -0
- package/dist/server/tool-registry.d.ts +23 -0
- package/dist/server/tool-registry.js +322 -0
- package/dist/server-setup.d.ts +21 -0
- package/dist/server-setup.js +111 -0
- package/dist/services/health-monitor.d.ts +34 -0
- package/dist/services/health-monitor.js +105 -0
- package/dist/services/metrics-server.d.ts +11 -0
- package/dist/services/metrics-server.js +105 -0
- package/dist/tools/actors.d.ts +147 -9
- package/dist/tools/actors.js +350 -311
- package/dist/tools/animation.d.ts +135 -4
- package/dist/tools/animation.js +510 -411
- package/dist/tools/assets.d.ts +117 -19
- package/dist/tools/assets.js +259 -284
- package/dist/tools/audio.d.ts +102 -42
- package/dist/tools/audio.js +272 -685
- package/dist/tools/base-tool.d.ts +17 -0
- package/dist/tools/base-tool.js +46 -0
- package/dist/tools/behavior-tree.d.ts +94 -0
- package/dist/tools/behavior-tree.js +39 -0
- package/dist/tools/blueprint/helpers.d.ts +29 -0
- package/dist/tools/blueprint/helpers.js +182 -0
- package/dist/tools/blueprint.d.ts +228 -118
- package/dist/tools/blueprint.js +685 -832
- package/dist/tools/consolidated-tool-definitions.d.ts +5475 -1627
- package/dist/tools/consolidated-tool-definitions.js +829 -482
- package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
- package/dist/tools/consolidated-tool-handlers.js +211 -1009
- package/dist/tools/debug.d.ts +143 -85
- package/dist/tools/debug.js +234 -180
- package/dist/tools/dynamic-handler-registry.d.ts +11 -0
- package/dist/tools/dynamic-handler-registry.js +101 -0
- package/dist/tools/editor.d.ts +139 -18
- package/dist/tools/editor.js +239 -244
- package/dist/tools/engine.d.ts +10 -4
- package/dist/tools/engine.js +13 -5
- package/dist/tools/environment.d.ts +36 -0
- package/dist/tools/environment.js +267 -0
- package/dist/tools/foliage.d.ts +105 -14
- package/dist/tools/foliage.js +219 -331
- package/dist/tools/handlers/actor-handlers.d.ts +3 -0
- package/dist/tools/handlers/actor-handlers.js +232 -0
- package/dist/tools/handlers/animation-handlers.d.ts +3 -0
- package/dist/tools/handlers/animation-handlers.js +185 -0
- package/dist/tools/handlers/argument-helper.d.ts +16 -0
- package/dist/tools/handlers/argument-helper.js +80 -0
- package/dist/tools/handlers/asset-handlers.d.ts +3 -0
- package/dist/tools/handlers/asset-handlers.js +496 -0
- package/dist/tools/handlers/audio-handlers.d.ts +3 -0
- package/dist/tools/handlers/audio-handlers.js +166 -0
- package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
- package/dist/tools/handlers/blueprint-handlers.js +358 -0
- package/dist/tools/handlers/common-handlers.d.ts +14 -0
- package/dist/tools/handlers/common-handlers.js +56 -0
- package/dist/tools/handlers/editor-handlers.d.ts +3 -0
- package/dist/tools/handlers/editor-handlers.js +119 -0
- package/dist/tools/handlers/effect-handlers.d.ts +3 -0
- package/dist/tools/handlers/effect-handlers.js +171 -0
- package/dist/tools/handlers/environment-handlers.d.ts +3 -0
- package/dist/tools/handlers/environment-handlers.js +170 -0
- package/dist/tools/handlers/graph-handlers.d.ts +3 -0
- package/dist/tools/handlers/graph-handlers.js +90 -0
- package/dist/tools/handlers/input-handlers.d.ts +3 -0
- package/dist/tools/handlers/input-handlers.js +21 -0
- package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
- package/dist/tools/handlers/inspect-handlers.js +383 -0
- package/dist/tools/handlers/level-handlers.d.ts +3 -0
- package/dist/tools/handlers/level-handlers.js +237 -0
- package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
- package/dist/tools/handlers/lighting-handlers.js +144 -0
- package/dist/tools/handlers/performance-handlers.d.ts +3 -0
- package/dist/tools/handlers/performance-handlers.js +130 -0
- package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
- package/dist/tools/handlers/pipeline-handlers.js +110 -0
- package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
- package/dist/tools/handlers/sequence-handlers.js +376 -0
- package/dist/tools/handlers/system-handlers.d.ts +4 -0
- package/dist/tools/handlers/system-handlers.js +506 -0
- package/dist/tools/input.d.ts +19 -0
- package/dist/tools/input.js +89 -0
- package/dist/tools/introspection.d.ts +103 -40
- package/dist/tools/introspection.js +425 -568
- package/dist/tools/landscape.d.ts +97 -36
- package/dist/tools/landscape.js +280 -409
- package/dist/tools/level.d.ts +130 -10
- package/dist/tools/level.js +639 -675
- package/dist/tools/lighting.d.ts +77 -38
- package/dist/tools/lighting.js +441 -943
- package/dist/tools/logs.d.ts +45 -0
- package/dist/tools/logs.js +210 -0
- package/dist/tools/materials.d.ts +91 -24
- package/dist/tools/materials.js +190 -118
- package/dist/tools/niagara.d.ts +149 -39
- package/dist/tools/niagara.js +232 -182
- package/dist/tools/performance.d.ts +27 -12
- package/dist/tools/performance.js +204 -122
- package/dist/tools/physics.d.ts +32 -77
- package/dist/tools/physics.js +171 -582
- package/dist/tools/property-dictionary.d.ts +13 -0
- package/dist/tools/property-dictionary.js +82 -0
- package/dist/tools/sequence.d.ts +73 -48
- package/dist/tools/sequence.js +196 -748
- package/dist/tools/tool-definition-utils.d.ts +59 -0
- package/dist/tools/tool-definition-utils.js +35 -0
- package/dist/tools/ui.d.ts +66 -34
- package/dist/tools/ui.js +134 -214
- package/dist/types/env.d.ts +0 -3
- package/dist/types/env.js +0 -7
- package/dist/types/tool-interfaces.d.ts +898 -0
- package/dist/types/tool-interfaces.js +2 -0
- package/dist/types/tool-types.d.ts +195 -11
- package/dist/types/tool-types.js +0 -4
- package/dist/unreal-bridge.d.ts +24 -131
- package/dist/unreal-bridge.js +364 -1506
- package/dist/utils/command-validator.d.ts +9 -0
- package/dist/utils/command-validator.js +67 -0
- package/dist/utils/elicitation.d.ts +1 -1
- package/dist/utils/elicitation.js +12 -15
- package/dist/utils/error-handler.d.ts +2 -51
- package/dist/utils/error-handler.js +11 -87
- package/dist/utils/ini-reader.d.ts +3 -0
- package/dist/utils/ini-reader.js +69 -0
- package/dist/utils/logger.js +9 -6
- package/dist/utils/normalize.d.ts +3 -0
- package/dist/utils/normalize.js +56 -0
- package/dist/utils/response-factory.d.ts +7 -0
- package/dist/utils/response-factory.js +33 -0
- package/dist/utils/response-validator.d.ts +3 -24
- package/dist/utils/response-validator.js +130 -81
- package/dist/utils/result-helpers.d.ts +4 -5
- package/dist/utils/result-helpers.js +15 -16
- package/dist/utils/safe-json.js +5 -11
- package/dist/utils/unreal-command-queue.d.ts +24 -0
- package/dist/utils/unreal-command-queue.js +120 -0
- package/dist/utils/validation.d.ts +0 -40
- package/dist/utils/validation.js +1 -78
- package/dist/wasm/index.d.ts +70 -0
- package/dist/wasm/index.js +535 -0
- package/docs/GraphQL-API.md +888 -0
- package/docs/Migration-Guide-v0.5.0.md +692 -0
- package/docs/Roadmap.md +53 -0
- package/docs/WebAssembly-Integration.md +628 -0
- package/docs/editor-plugin-extension.md +370 -0
- package/docs/handler-mapping.md +242 -0
- package/docs/native-automation-progress.md +128 -0
- package/docs/testing-guide.md +423 -0
- package/mcp-config-example.json +6 -6
- package/package.json +60 -27
- package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
- package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
- package/scripts/check-unreal-connection.mjs +19 -0
- package/scripts/clean-tmp.js +23 -0
- package/scripts/patch-wasm.js +26 -0
- package/scripts/run-all-tests.mjs +131 -0
- package/scripts/smoke-test.ts +94 -0
- package/scripts/sync-mcp-plugin.js +143 -0
- package/scripts/test-no-plugin-alternates.mjs +113 -0
- package/scripts/validate-server.js +46 -0
- package/scripts/verify-automation-bridge.js +200 -0
- package/server.json +57 -21
- package/src/automation/bridge.ts +558 -0
- package/src/automation/connection-manager.ts +130 -0
- package/src/automation/handshake.ts +99 -0
- package/src/automation/index.ts +2 -0
- package/src/automation/message-handler.ts +167 -0
- package/src/automation/request-tracker.ts +123 -0
- package/src/automation/types.ts +107 -0
- package/src/cli.ts +33 -6
- package/src/config.ts +73 -0
- package/src/constants.ts +12 -0
- package/src/graphql/resolvers.ts +1010 -0
- package/src/graphql/schema.ts +452 -0
- package/src/graphql/server.ts +154 -0
- package/src/graphql/types.ts +7 -0
- package/src/handlers/resource-handlers.ts +186 -0
- package/src/index.ts +152 -649
- package/src/prompts/index.ts +4 -4
- package/src/resources/actors.ts +58 -76
- package/src/resources/assets.ts +147 -134
- package/src/resources/levels.ts +28 -33
- package/src/server/resource-registry.ts +47 -0
- package/src/server/tool-registry.ts +354 -0
- package/src/server-setup.ts +148 -0
- package/src/services/health-monitor.ts +132 -0
- package/src/services/metrics-server.ts +142 -0
- package/src/tools/actors.ts +417 -322
- package/src/tools/animation.ts +671 -461
- package/src/tools/assets.ts +353 -289
- package/src/tools/audio.ts +323 -766
- package/src/tools/base-tool.ts +52 -0
- package/src/tools/behavior-tree.ts +45 -0
- package/src/tools/blueprint/helpers.ts +189 -0
- package/src/tools/blueprint.ts +787 -965
- package/src/tools/consolidated-tool-definitions.ts +993 -500
- package/src/tools/consolidated-tool-handlers.ts +272 -1122
- package/src/tools/debug.ts +292 -187
- package/src/tools/dynamic-handler-registry.ts +151 -0
- package/src/tools/editor.ts +309 -246
- package/src/tools/engine.ts +14 -3
- package/src/tools/environment.ts +287 -0
- package/src/tools/foliage.ts +314 -379
- package/src/tools/handlers/actor-handlers.ts +271 -0
- package/src/tools/handlers/animation-handlers.ts +237 -0
- package/src/tools/handlers/argument-helper.ts +142 -0
- package/src/tools/handlers/asset-handlers.ts +532 -0
- package/src/tools/handlers/audio-handlers.ts +194 -0
- package/src/tools/handlers/blueprint-handlers.ts +380 -0
- package/src/tools/handlers/common-handlers.ts +87 -0
- package/src/tools/handlers/editor-handlers.ts +123 -0
- package/src/tools/handlers/effect-handlers.ts +220 -0
- package/src/tools/handlers/environment-handlers.ts +183 -0
- package/src/tools/handlers/graph-handlers.ts +116 -0
- package/src/tools/handlers/input-handlers.ts +28 -0
- package/src/tools/handlers/inspect-handlers.ts +450 -0
- package/src/tools/handlers/level-handlers.ts +252 -0
- package/src/tools/handlers/lighting-handlers.ts +147 -0
- package/src/tools/handlers/performance-handlers.ts +132 -0
- package/src/tools/handlers/pipeline-handlers.ts +127 -0
- package/src/tools/handlers/sequence-handlers.ts +415 -0
- package/src/tools/handlers/system-handlers.ts +564 -0
- package/src/tools/input.ts +101 -0
- package/src/tools/introspection.ts +493 -584
- package/src/tools/landscape.ts +394 -489
- package/src/tools/level.ts +752 -694
- package/src/tools/lighting.ts +583 -984
- package/src/tools/logs.ts +219 -0
- package/src/tools/materials.ts +231 -121
- package/src/tools/niagara.ts +293 -168
- package/src/tools/performance.ts +320 -168
- package/src/tools/physics.ts +268 -613
- package/src/tools/property-dictionary.ts +98 -0
- package/src/tools/sequence.ts +255 -815
- package/src/tools/tool-definition-utils.ts +35 -0
- package/src/tools/ui.ts +207 -283
- package/src/types/env.ts +0 -10
- package/src/types/tool-interfaces.ts +250 -0
- package/src/types/tool-types.ts +250 -13
- package/src/unreal-bridge.ts +460 -1550
- package/src/utils/command-validator.ts +75 -0
- package/src/utils/elicitation.ts +10 -7
- package/src/utils/error-handler.ts +14 -90
- package/src/utils/ini-reader.ts +86 -0
- package/src/utils/logger.ts +8 -3
- package/src/utils/normalize.ts +60 -0
- package/src/utils/response-factory.ts +39 -0
- package/src/utils/response-validator.ts +176 -56
- package/src/utils/result-helpers.ts +21 -19
- package/src/utils/safe-json.ts +14 -11
- package/src/utils/unreal-command-queue.ts +152 -0
- package/src/utils/validation.ts +4 -1
- package/src/wasm/index.ts +838 -0
- package/test-server.mjs +100 -0
- package/tests/run-unreal-tool-tests.mjs +242 -14
- package/tests/test-animation.mjs +44 -0
- package/tests/test-asset-advanced.mjs +82 -0
- package/tests/test-asset-errors.mjs +35 -0
- package/tests/test-audio.mjs +219 -0
- package/tests/test-automation-timeouts.mjs +98 -0
- package/tests/test-behavior-tree.mjs +261 -0
- package/tests/test-blueprint-events.mjs +35 -0
- package/tests/test-blueprint-graph.mjs +79 -0
- package/tests/test-blueprint.mjs +577 -0
- package/tests/test-client-mode.mjs +86 -0
- package/tests/test-console-command.mjs +56 -0
- package/tests/test-control-actor.mjs +425 -0
- package/tests/test-control-editor.mjs +80 -0
- package/tests/test-extra-tools.mjs +38 -0
- package/tests/test-graphql.mjs +322 -0
- package/tests/test-inspect.mjs +72 -0
- package/tests/test-landscape.mjs +60 -0
- package/tests/test-manage-asset.mjs +438 -0
- package/tests/test-manage-level.mjs +70 -0
- package/tests/test-materials.mjs +356 -0
- package/tests/test-niagara.mjs +185 -0
- package/tests/test-no-inline-python.mjs +122 -0
- package/tests/test-plugin-handshake.mjs +82 -0
- package/tests/test-render.mjs +33 -0
- package/tests/test-runner.mjs +933 -0
- package/tests/test-search-assets.mjs +66 -0
- package/tests/test-sequence.mjs +68 -0
- package/tests/test-system.mjs +57 -0
- package/tests/test-wasm.mjs +193 -0
- package/tests/test-world-partition.mjs +215 -0
- package/tsconfig.json +3 -3
- package/wasm/Cargo.lock +363 -0
- package/wasm/Cargo.toml +42 -0
- package/wasm/LICENSE +21 -0
- package/wasm/README.md +253 -0
- package/wasm/src/dependency_resolver.rs +377 -0
- package/wasm/src/lib.rs +153 -0
- package/wasm/src/property_parser.rs +271 -0
- package/wasm/src/transform_math.rs +396 -0
- package/wasm/tests/integration.rs +109 -0
- package/.github/workflows/smithery-build.yml +0 -29
- package/dist/tools/build_environment_advanced.d.ts +0 -65
- package/dist/tools/build_environment_advanced.js +0 -633
- package/dist/tools/rc.d.ts +0 -110
- package/dist/tools/rc.js +0 -437
- package/dist/tools/visual.d.ts +0 -40
- package/dist/tools/visual.js +0 -282
- package/dist/utils/http.d.ts +0 -6
- package/dist/utils/http.js +0 -151
- package/dist/utils/python-output.d.ts +0 -18
- package/dist/utils/python-output.js +0 -290
- package/dist/utils/python.d.ts +0 -2
- package/dist/utils/python.js +0 -4
- package/dist/utils/stdio-redirect.d.ts +0 -2
- package/dist/utils/stdio-redirect.js +0 -20
- package/docs/unreal-tool-test-cases.md +0 -572
- package/smithery.yaml +0 -29
- package/src/tools/build_environment_advanced.ts +0 -732
- package/src/tools/rc.ts +0 -515
- package/src/tools/visual.ts +0 -281
- package/src/utils/http.ts +0 -187
- package/src/utils/python-output.ts +0 -351
- package/src/utils/python.ts +0 -3
- package/src/utils/stdio-redirect.ts +0 -18
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
#include "Async/Async.h"
|
|
2
|
+
#include "HAL/PlatformTime.h"
|
|
3
|
+
#include "McpAutomationBridgeGlobals.h"
|
|
4
|
+
#include "McpAutomationBridgeHelpers.h"
|
|
5
|
+
#include "McpAutomationBridgeSubsystem.h"
|
|
6
|
+
#include "McpConnectionManager.h"
|
|
7
|
+
#include "Misc/ScopeExit.h"
|
|
8
|
+
#include "Misc/ScopeLock.h"
|
|
9
|
+
|
|
10
|
+
void UMcpAutomationBridgeSubsystem::ProcessAutomationRequest(
|
|
11
|
+
const FString &RequestId, const FString &Action,
|
|
12
|
+
const TSharedPtr<FJsonObject> &Payload,
|
|
13
|
+
TSharedPtr<FMcpBridgeWebSocket> RequestingSocket) {
|
|
14
|
+
// This large implementation was extracted from the original subsystem
|
|
15
|
+
// translation unit to keep the core file smaller and focused. It
|
|
16
|
+
// contains the main dispatcher that delegates to specialized handler
|
|
17
|
+
// functions (property/blueprint/sequence/asset handlers) and retains
|
|
18
|
+
// the queuing/scope-exit safety logic expected by callers.
|
|
19
|
+
|
|
20
|
+
// Ensure automation processing happens on the game thread
|
|
21
|
+
// This trace is intentionally verbose — routine requests can be high
|
|
22
|
+
// frequency and will otherwise flood the logs. Developers can enable
|
|
23
|
+
// Verbose logging to see these messages when required.
|
|
24
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
25
|
+
TEXT(">>> ProcessAutomationRequest ENTRY: RequestId=%s action='%s' "
|
|
26
|
+
"(thread=%s)"),
|
|
27
|
+
*RequestId, *Action,
|
|
28
|
+
IsInGameThread() ? TEXT("GameThread") : TEXT("SocketThread"));
|
|
29
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
30
|
+
TEXT("ProcessAutomationRequest invoked (thread=%s) RequestId=%s "
|
|
31
|
+
"action=%s activeSockets=%d pendingQueue=%d"),
|
|
32
|
+
IsInGameThread() ? TEXT("GameThread") : TEXT("SocketThread"),
|
|
33
|
+
*RequestId, *Action,
|
|
34
|
+
ConnectionManager.IsValid() ? ConnectionManager->GetActiveSocketCount()
|
|
35
|
+
: 0,
|
|
36
|
+
PendingAutomationRequests.Num());
|
|
37
|
+
if (!IsInGameThread()) {
|
|
38
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
39
|
+
TEXT("Scheduling ProcessAutomationRequest on GameThread: "
|
|
40
|
+
"RequestId=%s action=%s"),
|
|
41
|
+
*RequestId, *Action);
|
|
42
|
+
AsyncTask(ENamedThreads::GameThread,
|
|
43
|
+
[WeakThis = TWeakObjectPtr<UMcpAutomationBridgeSubsystem>(this),
|
|
44
|
+
RequestId, Action, Payload, RequestingSocket]() {
|
|
45
|
+
if (UMcpAutomationBridgeSubsystem *Pinned = WeakThis.Get()) {
|
|
46
|
+
Pinned->ProcessAutomationRequest(RequestId, Action, Payload,
|
|
47
|
+
RequestingSocket);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Guard against unsafe engine states (Saving, GC, Async Loading)
|
|
54
|
+
// Calling StaticFindObject (via ResolveClassByName) during these states can
|
|
55
|
+
// cause crashes.
|
|
56
|
+
if (GIsSavingPackage || IsGarbageCollecting() || IsAsyncLoading()) {
|
|
57
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
58
|
+
TEXT("Deferring ProcessAutomationRequest due to active "
|
|
59
|
+
"Serialization/GC/Loading: RequestId=%s Action=%s"),
|
|
60
|
+
*RequestId, *Action);
|
|
61
|
+
|
|
62
|
+
FPendingAutomationRequest P;
|
|
63
|
+
P.RequestId = RequestId;
|
|
64
|
+
P.Action = Action;
|
|
65
|
+
P.Payload = Payload;
|
|
66
|
+
P.RequestingSocket = RequestingSocket;
|
|
67
|
+
{
|
|
68
|
+
FScopeLock Lock(&PendingAutomationRequestsMutex);
|
|
69
|
+
PendingAutomationRequests.Add(MoveTemp(P));
|
|
70
|
+
bPendingRequestsScheduled = true;
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
76
|
+
TEXT("Starting ProcessAutomationRequest on GameThread: RequestId=%s "
|
|
77
|
+
"action=%s bProcessingAutomationRequest=%s"),
|
|
78
|
+
*RequestId, *Action,
|
|
79
|
+
bProcessingAutomationRequest ? TEXT("true") : TEXT("false"));
|
|
80
|
+
|
|
81
|
+
const FString LowerAction = Action.ToLower();
|
|
82
|
+
|
|
83
|
+
if (ConnectionManager.IsValid()) {
|
|
84
|
+
ConnectionManager->StartRequestTelemetry(RequestId, Action);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Reentrancy guard / enqueue
|
|
88
|
+
if (bProcessingAutomationRequest) {
|
|
89
|
+
FPendingAutomationRequest P;
|
|
90
|
+
P.RequestId = RequestId;
|
|
91
|
+
P.Action = Action;
|
|
92
|
+
P.Payload = Payload;
|
|
93
|
+
P.RequestingSocket = RequestingSocket;
|
|
94
|
+
{
|
|
95
|
+
FScopeLock Lock(&PendingAutomationRequestsMutex);
|
|
96
|
+
PendingAutomationRequests.Add(MoveTemp(P));
|
|
97
|
+
bPendingRequestsScheduled = true;
|
|
98
|
+
}
|
|
99
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
100
|
+
TEXT("Enqueued automation request %s for action %s (processing in "
|
|
101
|
+
"progress)."),
|
|
102
|
+
*RequestId, *Action);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
bProcessingAutomationRequest = true;
|
|
107
|
+
bool bDispatchHandled = false;
|
|
108
|
+
FString ConsumedHandlerLabel = TEXT("unknown-handler");
|
|
109
|
+
const double DispatchStartSeconds = FPlatformTime::Seconds();
|
|
110
|
+
|
|
111
|
+
auto HandleAndLog = [&](const TCHAR *HandlerLabel, auto &&Callable) -> bool {
|
|
112
|
+
const bool bResult = Callable();
|
|
113
|
+
if (bResult) {
|
|
114
|
+
bDispatchHandled = true;
|
|
115
|
+
ConsumedHandlerLabel = HandlerLabel;
|
|
116
|
+
}
|
|
117
|
+
return bResult;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
{
|
|
121
|
+
ON_SCOPE_EXIT {
|
|
122
|
+
bProcessingAutomationRequest = false;
|
|
123
|
+
const double DispatchEndSeconds = FPlatformTime::Seconds();
|
|
124
|
+
const double DurationMs =
|
|
125
|
+
(DispatchEndSeconds - DispatchStartSeconds) * 1000.0;
|
|
126
|
+
if (bDispatchHandled) {
|
|
127
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
128
|
+
TEXT("ProcessAutomationRequest: Completed handler='%s' "
|
|
129
|
+
"RequestId=%s action='%s' (%.3f ms)"),
|
|
130
|
+
*ConsumedHandlerLabel, *RequestId, *Action, DurationMs);
|
|
131
|
+
} else {
|
|
132
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Warning,
|
|
133
|
+
TEXT("ProcessAutomationRequest: No handler consumed "
|
|
134
|
+
"RequestId=%s action='%s' (%.3f ms)"),
|
|
135
|
+
*RequestId, *Action, DurationMs);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (bPendingRequestsScheduled) {
|
|
139
|
+
bPendingRequestsScheduled = false;
|
|
140
|
+
ProcessPendingAutomationRequests();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
// Map this requestId to the requesting socket so responses can be
|
|
146
|
+
// delivered reliably
|
|
147
|
+
if (!RequestId.IsEmpty() && RequestingSocket.IsValid() &&
|
|
148
|
+
ConnectionManager.IsValid()) {
|
|
149
|
+
ConnectionManager->RegisterRequestSocket(RequestId, RequestingSocket);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---------------------------------------------------------
|
|
153
|
+
// Check Handler Registry (O(1) dispatch)
|
|
154
|
+
// ---------------------------------------------------------
|
|
155
|
+
if (const FAutomationHandler *Handler = AutomationHandlers.Find(Action)) {
|
|
156
|
+
if (HandleAndLog(*Action, [&]() {
|
|
157
|
+
return (*Handler)(RequestId, Action, Payload, RequestingSocket);
|
|
158
|
+
})) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
164
|
+
TEXT("ProcessAutomationRequest: Starting handler dispatch for "
|
|
165
|
+
"action='%s'"),
|
|
166
|
+
*Action);
|
|
167
|
+
|
|
168
|
+
// Prioritize blueprint actions early only for blueprint-like actions to
|
|
169
|
+
// avoid noisy prefix logs
|
|
170
|
+
{
|
|
171
|
+
FString LowerNormalized = LowerAction;
|
|
172
|
+
LowerNormalized.ReplaceInline(TEXT("-"), TEXT("_"));
|
|
173
|
+
LowerNormalized.ReplaceInline(TEXT(" "), TEXT("_"));
|
|
174
|
+
const bool bLooksBlueprint =
|
|
175
|
+
(LowerNormalized.StartsWith(TEXT("blueprint_")) ||
|
|
176
|
+
LowerNormalized.StartsWith(TEXT("manage_blueprint")) ||
|
|
177
|
+
LowerNormalized.Contains(TEXT("_scs")) ||
|
|
178
|
+
LowerNormalized.Contains(TEXT("scs_")) ||
|
|
179
|
+
LowerNormalized.Contains(TEXT("scs")));
|
|
180
|
+
if (bLooksBlueprint) {
|
|
181
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
182
|
+
TEXT("ProcessAutomationRequest: Checking "
|
|
183
|
+
"HandleBlueprintAction (early)"));
|
|
184
|
+
if (HandleAndLog(TEXT("HandleBlueprintAction (early)"), [&]() {
|
|
185
|
+
return HandleBlueprintAction(RequestId, Action, Payload,
|
|
186
|
+
RequestingSocket);
|
|
187
|
+
})) {
|
|
188
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
189
|
+
TEXT("HandleBlueprintAction (early) consumed request"));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Allow small handlers to short-circuit fast (property/function)
|
|
196
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
197
|
+
TEXT("ProcessAutomationRequest: About to call "
|
|
198
|
+
"HandleExecuteEditorFunction"));
|
|
199
|
+
if (HandleAndLog(TEXT("HandleExecuteEditorFunction"), [&]() {
|
|
200
|
+
return HandleExecuteEditorFunction(RequestId, Action, Payload,
|
|
201
|
+
RequestingSocket);
|
|
202
|
+
})) {
|
|
203
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
204
|
+
TEXT("HandleExecuteEditorFunction consumed request"));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
208
|
+
TEXT("ProcessAutomationRequest: HandleExecuteEditorFunction "
|
|
209
|
+
"returned false"));
|
|
210
|
+
|
|
211
|
+
// Level utilities (top-level aliases)
|
|
212
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
213
|
+
TEXT("ProcessAutomationRequest: Checking HandleLevelAction"));
|
|
214
|
+
if (HandleAndLog(TEXT("HandleLevelAction"), [&]() {
|
|
215
|
+
return HandleLevelAction(RequestId, Action, Payload,
|
|
216
|
+
RequestingSocket);
|
|
217
|
+
})) {
|
|
218
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
219
|
+
TEXT("HandleLevelAction consumed request"));
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Try asset actions early (materials, import, list, rename, etc.)
|
|
224
|
+
UE_LOG(
|
|
225
|
+
LogMcpAutomationBridgeSubsystem, Verbose,
|
|
226
|
+
TEXT("ProcessAutomationRequest: Checking HandleAssetAction (early)"));
|
|
227
|
+
if (HandleAndLog(TEXT("HandleAssetAction (early)"), [&]() {
|
|
228
|
+
return HandleAssetAction(RequestId, Action, Payload,
|
|
229
|
+
RequestingSocket);
|
|
230
|
+
})) {
|
|
231
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
232
|
+
TEXT("HandleAssetAction (early) consumed request"));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (HandleAndLog(TEXT("HandleSetObjectProperty"), [&]() {
|
|
236
|
+
return HandleSetObjectProperty(RequestId, Action, Payload,
|
|
237
|
+
RequestingSocket);
|
|
238
|
+
}))
|
|
239
|
+
return;
|
|
240
|
+
if (HandleAndLog(TEXT("HandleGetObjectProperty"), [&]() {
|
|
241
|
+
return HandleGetObjectProperty(RequestId, Action, Payload,
|
|
242
|
+
RequestingSocket);
|
|
243
|
+
}))
|
|
244
|
+
return;
|
|
245
|
+
// Array manipulation operations
|
|
246
|
+
if (HandleAndLog(TEXT("HandleArrayAppend"), [&]() {
|
|
247
|
+
return HandleArrayAppend(RequestId, Action, Payload,
|
|
248
|
+
RequestingSocket);
|
|
249
|
+
}))
|
|
250
|
+
return;
|
|
251
|
+
if (HandleAndLog(TEXT("HandleArrayRemove"), [&]() {
|
|
252
|
+
return HandleArrayRemove(RequestId, Action, Payload,
|
|
253
|
+
RequestingSocket);
|
|
254
|
+
}))
|
|
255
|
+
return;
|
|
256
|
+
if (HandleAndLog(TEXT("HandleArrayInsert"), [&]() {
|
|
257
|
+
return HandleArrayInsert(RequestId, Action, Payload,
|
|
258
|
+
RequestingSocket);
|
|
259
|
+
}))
|
|
260
|
+
return;
|
|
261
|
+
if (HandleAndLog(TEXT("HandleArrayGetElement"), [&]() {
|
|
262
|
+
return HandleArrayGetElement(RequestId, Action, Payload,
|
|
263
|
+
RequestingSocket);
|
|
264
|
+
}))
|
|
265
|
+
return;
|
|
266
|
+
if (HandleAndLog(TEXT("HandleArraySetElement"), [&]() {
|
|
267
|
+
return HandleArraySetElement(RequestId, Action, Payload,
|
|
268
|
+
RequestingSocket);
|
|
269
|
+
}))
|
|
270
|
+
return;
|
|
271
|
+
if (HandleAndLog(TEXT("HandleArrayClear"), [&]() {
|
|
272
|
+
return HandleArrayClear(RequestId, Action, Payload,
|
|
273
|
+
RequestingSocket);
|
|
274
|
+
}))
|
|
275
|
+
return;
|
|
276
|
+
// Map manipulation operations
|
|
277
|
+
if (HandleAndLog(TEXT("HandleMapSetValue"), [&]() {
|
|
278
|
+
return HandleMapSetValue(RequestId, Action, Payload,
|
|
279
|
+
RequestingSocket);
|
|
280
|
+
}))
|
|
281
|
+
return;
|
|
282
|
+
if (HandleAndLog(TEXT("HandleMapGetValue"), [&]() {
|
|
283
|
+
return HandleMapGetValue(RequestId, Action, Payload,
|
|
284
|
+
RequestingSocket);
|
|
285
|
+
}))
|
|
286
|
+
return;
|
|
287
|
+
if (HandleAndLog(TEXT("HandleMapRemoveKey"), [&]() {
|
|
288
|
+
return HandleMapRemoveKey(RequestId, Action, Payload,
|
|
289
|
+
RequestingSocket);
|
|
290
|
+
}))
|
|
291
|
+
return;
|
|
292
|
+
if (HandleAndLog(TEXT("HandleMapHasKey"), [&]() {
|
|
293
|
+
return HandleMapHasKey(RequestId, Action, Payload,
|
|
294
|
+
RequestingSocket);
|
|
295
|
+
}))
|
|
296
|
+
return;
|
|
297
|
+
if (HandleAndLog(TEXT("HandleMapGetKeys"), [&]() {
|
|
298
|
+
return HandleMapGetKeys(RequestId, Action, Payload,
|
|
299
|
+
RequestingSocket);
|
|
300
|
+
}))
|
|
301
|
+
return;
|
|
302
|
+
if (HandleAndLog(TEXT("HandleMapClear"), [&]() {
|
|
303
|
+
return HandleMapClear(RequestId, Action, Payload, RequestingSocket);
|
|
304
|
+
}))
|
|
305
|
+
return;
|
|
306
|
+
// Set manipulation operations
|
|
307
|
+
if (HandleAndLog(TEXT("HandleSetAdd"), [&]() {
|
|
308
|
+
return HandleSetAdd(RequestId, Action, Payload, RequestingSocket);
|
|
309
|
+
}))
|
|
310
|
+
return;
|
|
311
|
+
if (HandleAndLog(TEXT("HandleSetRemove"), [&]() {
|
|
312
|
+
return HandleSetRemove(RequestId, Action, Payload,
|
|
313
|
+
RequestingSocket);
|
|
314
|
+
}))
|
|
315
|
+
return;
|
|
316
|
+
if (HandleAndLog(TEXT("HandleSetContains"), [&]() {
|
|
317
|
+
return HandleSetContains(RequestId, Action, Payload,
|
|
318
|
+
RequestingSocket);
|
|
319
|
+
}))
|
|
320
|
+
return;
|
|
321
|
+
if (HandleAndLog(TEXT("HandleSetClear"), [&]() {
|
|
322
|
+
return HandleSetClear(RequestId, Action, Payload, RequestingSocket);
|
|
323
|
+
}))
|
|
324
|
+
return;
|
|
325
|
+
// Asset dependency graph traversal
|
|
326
|
+
if (HandleAndLog(TEXT("HandleGetAssetReferences"), [&]() {
|
|
327
|
+
return HandleGetAssetReferences(RequestId, Action, Payload,
|
|
328
|
+
RequestingSocket);
|
|
329
|
+
}))
|
|
330
|
+
return;
|
|
331
|
+
if (HandleAndLog(TEXT("HandleGetAssetDependencies"), [&]() {
|
|
332
|
+
return HandleGetAssetDependencies(RequestId, Action, Payload,
|
|
333
|
+
RequestingSocket);
|
|
334
|
+
}))
|
|
335
|
+
return;
|
|
336
|
+
// Asset workflow handlers
|
|
337
|
+
if (HandleAndLog(TEXT("HandleFixupRedirectors"), [&]() {
|
|
338
|
+
return HandleFixupRedirectors(RequestId, Action, Payload,
|
|
339
|
+
RequestingSocket);
|
|
340
|
+
}))
|
|
341
|
+
return;
|
|
342
|
+
if (HandleAndLog(TEXT("HandleSourceControlCheckout"), [&]() {
|
|
343
|
+
return HandleSourceControlCheckout(RequestId, Action, Payload,
|
|
344
|
+
RequestingSocket);
|
|
345
|
+
}))
|
|
346
|
+
return;
|
|
347
|
+
if (HandleAndLog(TEXT("HandleSourceControlSubmit"), [&]() {
|
|
348
|
+
return HandleSourceControlSubmit(RequestId, Action, Payload,
|
|
349
|
+
RequestingSocket);
|
|
350
|
+
}))
|
|
351
|
+
return;
|
|
352
|
+
if (HandleAndLog(TEXT("HandleBulkRenameAssets"), [&]() {
|
|
353
|
+
return HandleBulkRenameAssets(RequestId, Action, Payload,
|
|
354
|
+
RequestingSocket);
|
|
355
|
+
}))
|
|
356
|
+
return;
|
|
357
|
+
if (HandleAndLog(TEXT("HandleBulkDeleteAssets"), [&]() {
|
|
358
|
+
return HandleBulkDeleteAssets(RequestId, Action, Payload,
|
|
359
|
+
RequestingSocket);
|
|
360
|
+
}))
|
|
361
|
+
return;
|
|
362
|
+
if (HandleAndLog(TEXT("HandleGenerateThumbnail"), [&]() {
|
|
363
|
+
return HandleGenerateThumbnail(RequestId, Action, Payload,
|
|
364
|
+
RequestingSocket);
|
|
365
|
+
}))
|
|
366
|
+
return;
|
|
367
|
+
// Landscape operations
|
|
368
|
+
if (HandleAndLog(TEXT("HandleCreateLandscape"), [&]() {
|
|
369
|
+
return HandleCreateLandscape(RequestId, Action, Payload,
|
|
370
|
+
RequestingSocket);
|
|
371
|
+
}))
|
|
372
|
+
return;
|
|
373
|
+
if (HandleAndLog(TEXT("HandleCreateProceduralTerrain"), [&]() {
|
|
374
|
+
return HandleCreateProceduralTerrain(RequestId, Action, Payload,
|
|
375
|
+
RequestingSocket);
|
|
376
|
+
}))
|
|
377
|
+
return;
|
|
378
|
+
if (HandleAndLog(TEXT("HandleCreateLandscapeGrassType"), [&]() {
|
|
379
|
+
return HandleCreateLandscapeGrassType(RequestId, Action, Payload,
|
|
380
|
+
RequestingSocket);
|
|
381
|
+
}))
|
|
382
|
+
return;
|
|
383
|
+
if (HandleAndLog(TEXT("HandleSculptLandscape"), [&]() {
|
|
384
|
+
return HandleSculptLandscape(RequestId, Action, Payload,
|
|
385
|
+
RequestingSocket);
|
|
386
|
+
}))
|
|
387
|
+
return;
|
|
388
|
+
if (HandleAndLog(TEXT("HandleSetLandscapeMaterial"), [&]() {
|
|
389
|
+
return HandleSetLandscapeMaterial(RequestId, Action, Payload,
|
|
390
|
+
RequestingSocket);
|
|
391
|
+
}))
|
|
392
|
+
return;
|
|
393
|
+
if (HandleAndLog(TEXT("HandleEditLandscape"), [&]() {
|
|
394
|
+
return HandleEditLandscape(RequestId, Action, Payload,
|
|
395
|
+
RequestingSocket);
|
|
396
|
+
}))
|
|
397
|
+
return;
|
|
398
|
+
// Foliage operations
|
|
399
|
+
if (HandleAndLog(TEXT("HandleAddFoliageType"), [&]() {
|
|
400
|
+
return HandleAddFoliageType(RequestId, Action, Payload,
|
|
401
|
+
RequestingSocket);
|
|
402
|
+
}))
|
|
403
|
+
return;
|
|
404
|
+
if (HandleAndLog(TEXT("HandleCreateProceduralFoliage"), [&]() {
|
|
405
|
+
return HandleCreateProceduralFoliage(RequestId, Action, Payload,
|
|
406
|
+
RequestingSocket);
|
|
407
|
+
}))
|
|
408
|
+
return;
|
|
409
|
+
if (HandleAndLog(TEXT("HandlePaintFoliage"), [&]() {
|
|
410
|
+
return HandlePaintFoliage(RequestId, Action, Payload,
|
|
411
|
+
RequestingSocket);
|
|
412
|
+
}))
|
|
413
|
+
return;
|
|
414
|
+
if (HandleAndLog(TEXT("HandleAddFoliageInstances"), [&]() {
|
|
415
|
+
return HandleAddFoliageInstances(RequestId, Action, Payload,
|
|
416
|
+
RequestingSocket);
|
|
417
|
+
}))
|
|
418
|
+
return;
|
|
419
|
+
if (HandleAndLog(TEXT("HandleRemoveFoliage"), [&]() {
|
|
420
|
+
return HandleRemoveFoliage(RequestId, Action, Payload,
|
|
421
|
+
RequestingSocket);
|
|
422
|
+
}))
|
|
423
|
+
return;
|
|
424
|
+
if (HandleAndLog(TEXT("HandleGetFoliageInstances"), [&]() {
|
|
425
|
+
return HandleGetFoliageInstances(RequestId, Action, Payload,
|
|
426
|
+
RequestingSocket);
|
|
427
|
+
}))
|
|
428
|
+
return;
|
|
429
|
+
// Niagara operations
|
|
430
|
+
if (HandleAndLog(TEXT("HandleCreateNiagaraSystem"), [&]() {
|
|
431
|
+
return HandleCreateNiagaraSystem(RequestId, Action, Payload,
|
|
432
|
+
RequestingSocket);
|
|
433
|
+
}))
|
|
434
|
+
return;
|
|
435
|
+
if (HandleAndLog(TEXT("HandleCreateNiagaraRibbon"), [&]() {
|
|
436
|
+
return HandleCreateNiagaraRibbon(RequestId, Action, Payload,
|
|
437
|
+
RequestingSocket);
|
|
438
|
+
}))
|
|
439
|
+
return;
|
|
440
|
+
if (HandleAndLog(TEXT("HandleCreateNiagaraEmitter"), [&]() {
|
|
441
|
+
return HandleCreateNiagaraEmitter(RequestId, Action, Payload,
|
|
442
|
+
RequestingSocket);
|
|
443
|
+
}))
|
|
444
|
+
return;
|
|
445
|
+
if (HandleAndLog(TEXT("HandleSpawnNiagaraActor"), [&]() {
|
|
446
|
+
return HandleSpawnNiagaraActor(RequestId, Action, Payload,
|
|
447
|
+
RequestingSocket);
|
|
448
|
+
}))
|
|
449
|
+
return;
|
|
450
|
+
if (HandleAndLog(TEXT("HandleModifyNiagaraParameter"), [&]() {
|
|
451
|
+
return HandleModifyNiagaraParameter(RequestId, Action, Payload,
|
|
452
|
+
RequestingSocket);
|
|
453
|
+
}))
|
|
454
|
+
return;
|
|
455
|
+
// Animation blueprint operations
|
|
456
|
+
if (HandleAndLog(TEXT("HandleCreateAnimBlueprint"), [&]() {
|
|
457
|
+
return HandleCreateAnimBlueprint(RequestId, Action, Payload,
|
|
458
|
+
RequestingSocket);
|
|
459
|
+
}))
|
|
460
|
+
return;
|
|
461
|
+
if (HandleAndLog(TEXT("HandlePlayAnimMontage"), [&]() {
|
|
462
|
+
return HandlePlayAnimMontage(RequestId, Action, Payload,
|
|
463
|
+
RequestingSocket);
|
|
464
|
+
}))
|
|
465
|
+
return;
|
|
466
|
+
if (HandleAndLog(TEXT("HandleSetupRagdoll"), [&]() {
|
|
467
|
+
return HandleSetupRagdoll(RequestId, Action, Payload,
|
|
468
|
+
RequestingSocket);
|
|
469
|
+
}))
|
|
470
|
+
return;
|
|
471
|
+
// Material graph operations
|
|
472
|
+
if (HandleAndLog(TEXT("HandleAddMaterialTextureSample"), [&]() {
|
|
473
|
+
return HandleAddMaterialTextureSample(RequestId, Action, Payload,
|
|
474
|
+
RequestingSocket);
|
|
475
|
+
}))
|
|
476
|
+
return;
|
|
477
|
+
if (HandleAndLog(TEXT("HandleAddMaterialExpression"), [&]() {
|
|
478
|
+
return HandleAddMaterialExpression(RequestId, Action, Payload,
|
|
479
|
+
RequestingSocket);
|
|
480
|
+
}))
|
|
481
|
+
return;
|
|
482
|
+
if (HandleAndLog(TEXT("HandleCreateMaterialNodes"), [&]() {
|
|
483
|
+
return HandleCreateMaterialNodes(RequestId, Action, Payload,
|
|
484
|
+
RequestingSocket);
|
|
485
|
+
}))
|
|
486
|
+
return;
|
|
487
|
+
// Sequencer operations
|
|
488
|
+
if (HandleAndLog(TEXT("HandleAddSequencerKeyframe"), [&]() {
|
|
489
|
+
return HandleAddSequencerKeyframe(RequestId, Action, Payload,
|
|
490
|
+
RequestingSocket);
|
|
491
|
+
}))
|
|
492
|
+
return;
|
|
493
|
+
if (HandleAndLog(TEXT("HandleManageSequencerTrack"), [&]() {
|
|
494
|
+
return HandleManageSequencerTrack(RequestId, Action, Payload,
|
|
495
|
+
RequestingSocket);
|
|
496
|
+
}))
|
|
497
|
+
return;
|
|
498
|
+
if (HandleAndLog(TEXT("HandleAddCameraTrack"), [&]() {
|
|
499
|
+
return HandleAddCameraTrack(RequestId, Action, Payload,
|
|
500
|
+
RequestingSocket);
|
|
501
|
+
}))
|
|
502
|
+
return;
|
|
503
|
+
if (HandleAndLog(TEXT("HandleAddAnimationTrack"), [&]() {
|
|
504
|
+
return HandleAddAnimationTrack(RequestId, Action, Payload,
|
|
505
|
+
RequestingSocket);
|
|
506
|
+
}))
|
|
507
|
+
return;
|
|
508
|
+
if (HandleAndLog(TEXT("HandleAddTransformTrack"), [&]() {
|
|
509
|
+
return HandleAddTransformTrack(RequestId, Action, Payload,
|
|
510
|
+
RequestingSocket);
|
|
511
|
+
}))
|
|
512
|
+
return;
|
|
513
|
+
|
|
514
|
+
// Delegate asset/control/blueprint/sequence actions to their handlers
|
|
515
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
516
|
+
TEXT("ProcessAutomationRequest: Checking HandleAssetAction"));
|
|
517
|
+
if (HandleAndLog(TEXT("HandleAssetAction"), [&]() {
|
|
518
|
+
return HandleAssetAction(RequestId, Action, Payload,
|
|
519
|
+
RequestingSocket);
|
|
520
|
+
})) {
|
|
521
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
522
|
+
TEXT("HandleAssetAction consumed request"));
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
UE_LOG(
|
|
526
|
+
LogMcpAutomationBridgeSubsystem, Verbose,
|
|
527
|
+
TEXT("ProcessAutomationRequest: Checking HandleControlActorAction"));
|
|
528
|
+
if (HandleAndLog(TEXT("HandleControlActorAction"), [&]() {
|
|
529
|
+
return HandleControlActorAction(RequestId, Action, Payload,
|
|
530
|
+
RequestingSocket);
|
|
531
|
+
})) {
|
|
532
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
533
|
+
TEXT("HandleControlActorAction consumed request"));
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
UE_LOG(
|
|
537
|
+
LogMcpAutomationBridgeSubsystem, Verbose,
|
|
538
|
+
TEXT("ProcessAutomationRequest: Checking HandleControlEditorAction"));
|
|
539
|
+
if (HandleAndLog(TEXT("HandleControlEditorAction"), [&]() {
|
|
540
|
+
return HandleControlEditorAction(RequestId, Action, Payload,
|
|
541
|
+
RequestingSocket);
|
|
542
|
+
})) {
|
|
543
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
544
|
+
TEXT("HandleControlEditorAction consumed request"));
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
548
|
+
TEXT("ProcessAutomationRequest: Checking HandleUiAction"));
|
|
549
|
+
if (HandleAndLog(TEXT("HandleUiAction"), [&]() {
|
|
550
|
+
return HandleUiAction(RequestId, Action, Payload, RequestingSocket);
|
|
551
|
+
})) {
|
|
552
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
553
|
+
TEXT("HandleUiAction consumed request"));
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
557
|
+
TEXT("ProcessAutomationRequest: Checking HandleBlueprintAction "
|
|
558
|
+
"(late)"));
|
|
559
|
+
if (HandleAndLog(TEXT("HandleBlueprintAction (late)"), [&]() {
|
|
560
|
+
return HandleBlueprintAction(RequestId, Action, Payload,
|
|
561
|
+
RequestingSocket);
|
|
562
|
+
})) {
|
|
563
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
564
|
+
TEXT("HandleBlueprintAction (late) consumed request"));
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
568
|
+
TEXT("ProcessAutomationRequest: Checking HandleSequenceAction"));
|
|
569
|
+
if (HandleAndLog(TEXT("HandleSequenceAction"), [&]() {
|
|
570
|
+
return HandleSequenceAction(RequestId, Action, Payload,
|
|
571
|
+
RequestingSocket);
|
|
572
|
+
})) {
|
|
573
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
574
|
+
TEXT("HandleSequenceAction consumed request"));
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (HandleAndLog(TEXT("HandleEffectAction"), [&]() {
|
|
578
|
+
return HandleEffectAction(RequestId, Action, Payload,
|
|
579
|
+
RequestingSocket);
|
|
580
|
+
}))
|
|
581
|
+
return;
|
|
582
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
583
|
+
TEXT("ProcessAutomationRequest: Checking "
|
|
584
|
+
"HandleAnimationPhysicsAction"));
|
|
585
|
+
if (HandleAndLog(TEXT("HandleAnimationPhysicsAction"), [&]() {
|
|
586
|
+
return HandleAnimationPhysicsAction(RequestId, Action, Payload,
|
|
587
|
+
RequestingSocket);
|
|
588
|
+
})) {
|
|
589
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Verbose,
|
|
590
|
+
TEXT("HandleAnimationPhysicsAction consumed request"));
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
if (HandleAndLog(TEXT("HandleAudioAction"), [&]() {
|
|
594
|
+
return HandleAudioAction(RequestId, Action, Payload,
|
|
595
|
+
RequestingSocket);
|
|
596
|
+
}))
|
|
597
|
+
return;
|
|
598
|
+
if (HandleAndLog(TEXT("HandleLightingAction"), [&]() {
|
|
599
|
+
return HandleLightingAction(RequestId, Action, Payload,
|
|
600
|
+
RequestingSocket);
|
|
601
|
+
}))
|
|
602
|
+
return;
|
|
603
|
+
if (HandleAndLog(TEXT("HandlePerformanceAction"), [&]() {
|
|
604
|
+
return HandlePerformanceAction(RequestId, Action, Payload,
|
|
605
|
+
RequestingSocket);
|
|
606
|
+
}))
|
|
607
|
+
return;
|
|
608
|
+
if (HandleAndLog(TEXT("HandleBuildEnvironmentAction"), [&]() {
|
|
609
|
+
return HandleBuildEnvironmentAction(RequestId, Action, Payload,
|
|
610
|
+
RequestingSocket);
|
|
611
|
+
}))
|
|
612
|
+
return;
|
|
613
|
+
if (HandleAndLog(TEXT("HandleControlEnvironmentAction"), [&]() {
|
|
614
|
+
return HandleControlEnvironmentAction(RequestId, Action, Payload,
|
|
615
|
+
RequestingSocket);
|
|
616
|
+
}))
|
|
617
|
+
return;
|
|
618
|
+
|
|
619
|
+
// Additional consolidated tool handlers
|
|
620
|
+
if (HandleAndLog(TEXT("HandleSystemControlAction"), [&]() {
|
|
621
|
+
return HandleSystemControlAction(RequestId, Action, Payload,
|
|
622
|
+
RequestingSocket);
|
|
623
|
+
}))
|
|
624
|
+
return;
|
|
625
|
+
if (HandleAndLog(TEXT("HandleConsoleCommandAction"), [&]() {
|
|
626
|
+
return HandleConsoleCommandAction(RequestId, Action, Payload,
|
|
627
|
+
RequestingSocket);
|
|
628
|
+
}))
|
|
629
|
+
return;
|
|
630
|
+
if (HandleAndLog(TEXT("HandleInspectAction"), [&]() {
|
|
631
|
+
return HandleInspectAction(RequestId, Action, Payload,
|
|
632
|
+
RequestingSocket);
|
|
633
|
+
}))
|
|
634
|
+
return;
|
|
635
|
+
|
|
636
|
+
// 1. Editor Authoring & Graph Editing
|
|
637
|
+
if (HandleAndLog(TEXT("HandleBlueprintGraphAction"), [&]() {
|
|
638
|
+
return HandleBlueprintGraphAction(RequestId, Action, Payload,
|
|
639
|
+
RequestingSocket);
|
|
640
|
+
}))
|
|
641
|
+
return;
|
|
642
|
+
if (HandleAndLog(TEXT("HandleNiagaraGraphAction"), [&]() {
|
|
643
|
+
return HandleNiagaraGraphAction(RequestId, Action, Payload,
|
|
644
|
+
RequestingSocket);
|
|
645
|
+
}))
|
|
646
|
+
return;
|
|
647
|
+
if (HandleAndLog(TEXT("HandleMaterialGraphAction"), [&]() {
|
|
648
|
+
return HandleMaterialGraphAction(RequestId, Action, Payload,
|
|
649
|
+
RequestingSocket);
|
|
650
|
+
}))
|
|
651
|
+
return;
|
|
652
|
+
if (HandleAndLog(TEXT("HandleBehaviorTreeAction"), [&]() {
|
|
653
|
+
return HandleBehaviorTreeAction(RequestId, Action, Payload,
|
|
654
|
+
RequestingSocket);
|
|
655
|
+
}))
|
|
656
|
+
return;
|
|
657
|
+
if (HandleAndLog(TEXT("HandleWorldPartitionAction"), [&]() {
|
|
658
|
+
return HandleWorldPartitionAction(RequestId, Action, Payload,
|
|
659
|
+
RequestingSocket);
|
|
660
|
+
}))
|
|
661
|
+
return;
|
|
662
|
+
if (HandleAndLog(TEXT("HandleRenderAction"), [&]() {
|
|
663
|
+
return HandleRenderAction(RequestId, Action, Payload,
|
|
664
|
+
RequestingSocket);
|
|
665
|
+
}))
|
|
666
|
+
return;
|
|
667
|
+
|
|
668
|
+
// 2. Execution & Build / Test Pipeline
|
|
669
|
+
if (HandleAndLog(TEXT("HandlePipelineAction"), [&]() {
|
|
670
|
+
return HandlePipelineAction(RequestId, Action, Payload,
|
|
671
|
+
RequestingSocket);
|
|
672
|
+
}))
|
|
673
|
+
return;
|
|
674
|
+
if (HandleAndLog(TEXT("HandleTestAction"), [&]() {
|
|
675
|
+
return HandleTestAction(RequestId, Action, Payload,
|
|
676
|
+
RequestingSocket);
|
|
677
|
+
}))
|
|
678
|
+
return;
|
|
679
|
+
|
|
680
|
+
// 3. Observability, Logs, Debugging & History
|
|
681
|
+
if (HandleAndLog(TEXT("HandleLogAction"), [&]() {
|
|
682
|
+
return HandleLogAction(RequestId, Action, Payload,
|
|
683
|
+
RequestingSocket);
|
|
684
|
+
}))
|
|
685
|
+
return;
|
|
686
|
+
if (HandleAndLog(TEXT("HandleDebugAction"), [&]() {
|
|
687
|
+
return HandleDebugAction(RequestId, Action, Payload,
|
|
688
|
+
RequestingSocket);
|
|
689
|
+
}))
|
|
690
|
+
return;
|
|
691
|
+
if (HandleAndLog(TEXT("HandleAssetQueryAction"), [&]() {
|
|
692
|
+
return HandleAssetQueryAction(RequestId, Action, Payload,
|
|
693
|
+
RequestingSocket);
|
|
694
|
+
}))
|
|
695
|
+
return;
|
|
696
|
+
if (HandleAndLog(TEXT("HandleInsightsAction"), [&]() {
|
|
697
|
+
return HandleInsightsAction(RequestId, Action, Payload,
|
|
698
|
+
RequestingSocket);
|
|
699
|
+
}))
|
|
700
|
+
return;
|
|
701
|
+
|
|
702
|
+
// Unhandled action
|
|
703
|
+
bDispatchHandled = true;
|
|
704
|
+
ConsumedHandlerLabel = TEXT("SendAutomationError (unknown action)");
|
|
705
|
+
SendAutomationError(
|
|
706
|
+
RequestingSocket, RequestId,
|
|
707
|
+
FString::Printf(TEXT("Unknown automation action: %s"), *Action),
|
|
708
|
+
TEXT("UNKNOWN_ACTION"));
|
|
709
|
+
} catch (const std::exception &E) {
|
|
710
|
+
UE_LOG(LogMcpAutomationBridgeSubsystem, Error,
|
|
711
|
+
TEXT("Unhandled exception processing automation request %s: %s"),
|
|
712
|
+
*RequestId, ANSI_TO_TCHAR(E.what()));
|
|
713
|
+
bDispatchHandled = true;
|
|
714
|
+
ConsumedHandlerLabel = TEXT("Exception handler");
|
|
715
|
+
SendAutomationError(
|
|
716
|
+
RequestingSocket, RequestId,
|
|
717
|
+
FString::Printf(TEXT("Internal error: %s"), ANSI_TO_TCHAR(E.what())),
|
|
718
|
+
TEXT("INTERNAL_ERROR"));
|
|
719
|
+
} catch (...) {
|
|
720
|
+
UE_LOG(
|
|
721
|
+
LogMcpAutomationBridgeSubsystem, Error,
|
|
722
|
+
TEXT("Unhandled unknown exception processing automation request %s"),
|
|
723
|
+
*RequestId);
|
|
724
|
+
bDispatchHandled = true;
|
|
725
|
+
ConsumedHandlerLabel = TEXT("Exception handler (unknown)");
|
|
726
|
+
SendAutomationError(RequestingSocket, RequestId,
|
|
727
|
+
TEXT("Internal error (unknown)."),
|
|
728
|
+
TEXT("INTERNAL_ERROR"));
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// ProcessPendingAutomationRequests() intentionally implemented in the
|
|
734
|
+
// primary subsystem translation unit (McpAutomationBridgeSubsystem.cpp)
|
|
735
|
+
// to ensure the linker emits the symbol into the module's object file.
|