unreal-engine-mcp-server 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -1
- package/.github/release-drafter-config.yml +51 -0
- package/.github/workflows/greetings.yml +5 -1
- package/.github/workflows/labeler.yml +2 -1
- package/.github/workflows/publish-mcp.yml +2 -4
- package/.github/workflows/release-drafter.yml +3 -2
- package/.github/workflows/release.yml +3 -3
- package/CHANGELOG.md +109 -0
- package/CONTRIBUTING.md +1 -1
- package/GEMINI.md +115 -0
- package/Public/Plugin_setup_guide.mp4 +0 -0
- package/README.md +166 -200
- package/dist/automation/bridge.d.ts +1 -2
- package/dist/automation/bridge.js +24 -23
- package/dist/automation/connection-manager.d.ts +1 -0
- package/dist/automation/connection-manager.js +10 -0
- package/dist/automation/message-handler.js +5 -4
- package/dist/automation/request-tracker.d.ts +4 -0
- package/dist/automation/request-tracker.js +11 -3
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/dist/graphql/loaders.d.ts +64 -0
- package/dist/graphql/loaders.js +117 -0
- package/dist/graphql/resolvers.d.ts +3 -3
- package/dist/graphql/resolvers.js +33 -30
- package/dist/graphql/server.js +3 -1
- package/dist/graphql/types.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +13 -2
- package/dist/server-setup.d.ts +0 -1
- package/dist/server-setup.js +0 -40
- package/dist/tools/actors.d.ts +58 -24
- package/dist/tools/actors.js +22 -6
- package/dist/tools/assets.d.ts +19 -71
- package/dist/tools/assets.js +28 -22
- package/dist/tools/base-tool.d.ts +4 -4
- package/dist/tools/base-tool.js +1 -1
- package/dist/tools/blueprint.d.ts +45 -61
- package/dist/tools/blueprint.js +43 -14
- package/dist/tools/consolidated-tool-definitions.js +2 -1
- package/dist/tools/consolidated-tool-handlers.js +96 -110
- package/dist/tools/dynamic-handler-registry.d.ts +11 -9
- package/dist/tools/dynamic-handler-registry.js +17 -95
- package/dist/tools/editor.d.ts +19 -193
- package/dist/tools/editor.js +11 -2
- package/dist/tools/environment.d.ts +8 -14
- package/dist/tools/foliage.d.ts +18 -143
- package/dist/tools/foliage.js +4 -2
- package/dist/tools/handlers/actor-handlers.d.ts +1 -1
- package/dist/tools/handlers/actor-handlers.js +14 -13
- package/dist/tools/handlers/asset-handlers.js +454 -454
- package/dist/tools/handlers/sequence-handlers.d.ts +1 -1
- package/dist/tools/handlers/sequence-handlers.js +24 -13
- package/dist/tools/introspection.d.ts +1 -1
- package/dist/tools/introspection.js +1 -1
- package/dist/tools/landscape.d.ts +16 -116
- package/dist/tools/landscape.js +7 -3
- package/dist/tools/level.d.ts +22 -103
- package/dist/tools/level.js +26 -18
- package/dist/tools/lighting.d.ts +54 -7
- package/dist/tools/lighting.js +9 -5
- package/dist/tools/materials.d.ts +1 -1
- package/dist/tools/materials.js +5 -1
- package/dist/tools/niagara.js +37 -2
- package/dist/tools/performance.d.ts +0 -1
- package/dist/tools/performance.js +0 -1
- package/dist/tools/physics.js +5 -1
- package/dist/tools/sequence.d.ts +24 -24
- package/dist/tools/sequence.js +13 -0
- package/dist/tools/ui.d.ts +0 -2
- package/dist/types/automation-responses.d.ts +115 -0
- package/dist/types/automation-responses.js +2 -0
- package/dist/types/responses.d.ts +249 -0
- package/dist/types/responses.js +2 -0
- package/dist/types/tool-interfaces.d.ts +135 -135
- package/dist/types/tool-types.d.ts +2 -0
- package/dist/unreal-bridge.js +4 -4
- package/dist/utils/command-validator.js +7 -5
- package/dist/utils/error-handler.d.ts +24 -2
- package/dist/utils/error-handler.js +58 -23
- package/dist/utils/normalize.d.ts +7 -4
- package/dist/utils/normalize.js +12 -10
- package/dist/utils/path-security.d.ts +2 -0
- package/dist/utils/path-security.js +24 -0
- package/dist/utils/response-factory.d.ts +4 -4
- package/dist/utils/response-factory.js +15 -21
- package/dist/utils/response-validator.js +88 -73
- package/dist/utils/unreal-command-queue.d.ts +2 -0
- package/dist/utils/unreal-command-queue.js +8 -1
- package/docs/Migration-Guide-v0.5.0.md +1 -9
- package/docs/handler-mapping.md +4 -2
- package/docs/testing-guide.md +2 -2
- package/package.json +12 -6
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +298 -33
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +7 -8
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +229 -319
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +98 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +24 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +96 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +52 -5
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +5 -268
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +57 -2
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -1
- package/scripts/run-all-tests.mjs +25 -20
- package/server.json +3 -2
- package/src/automation/bridge.ts +27 -25
- package/src/automation/connection-manager.ts +18 -0
- package/src/automation/message-handler.ts +33 -8
- package/src/automation/request-tracker.ts +39 -7
- package/src/config.ts +1 -1
- package/src/constants.ts +7 -0
- package/src/graphql/loaders.ts +244 -0
- package/src/graphql/resolvers.ts +47 -49
- package/src/graphql/server.ts +3 -1
- package/src/graphql/types.ts +3 -0
- package/src/index.ts +15 -2
- package/src/resources/assets.ts +5 -4
- package/src/server/tool-registry.ts +3 -3
- package/src/server-setup.ts +3 -37
- package/src/tools/actors.ts +77 -44
- package/src/tools/animation.ts +1 -0
- package/src/tools/assets.ts +76 -65
- package/src/tools/base-tool.ts +3 -3
- package/src/tools/blueprint.ts +170 -104
- package/src/tools/consolidated-tool-definitions.ts +2 -1
- package/src/tools/consolidated-tool-handlers.ts +129 -150
- package/src/tools/dynamic-handler-registry.ts +22 -140
- package/src/tools/editor.ts +43 -29
- package/src/tools/environment.ts +21 -27
- package/src/tools/foliage.ts +28 -25
- package/src/tools/handlers/actor-handlers.ts +16 -17
- package/src/tools/handlers/asset-handlers.ts +484 -484
- package/src/tools/handlers/sequence-handlers.ts +85 -62
- package/src/tools/introspection.ts +7 -7
- package/src/tools/landscape.ts +34 -28
- package/src/tools/level.ts +100 -80
- package/src/tools/lighting.ts +25 -20
- package/src/tools/materials.ts +9 -3
- package/src/tools/niagara.ts +44 -2
- package/src/tools/performance.ts +1 -2
- package/src/tools/physics.ts +7 -1
- package/src/tools/sequence.ts +42 -26
- package/src/tools/ui.ts +1 -3
- package/src/types/automation-responses.ts +119 -0
- package/src/types/responses.ts +355 -0
- package/src/types/tool-interfaces.ts +135 -135
- package/src/types/tool-types.ts +4 -0
- package/src/unreal-bridge.ts +71 -26
- package/src/utils/command-validator.ts +47 -5
- package/src/utils/error-handler.ts +128 -45
- package/src/utils/normalize.test.ts +162 -0
- package/src/utils/normalize.ts +38 -16
- package/src/utils/path-security.ts +43 -0
- package/src/utils/response-factory.ts +29 -24
- package/src/utils/response-validator.ts +103 -87
- package/src/utils/safe-json.test.ts +90 -0
- package/src/utils/unreal-command-queue.ts +13 -1
- package/src/utils/validation.test.ts +184 -0
- package/tests/test-animation.mjs +358 -33
- package/tests/test-asset-graph.mjs +311 -0
- package/tests/test-audio.mjs +314 -116
- package/tests/test-behavior-tree.mjs +327 -144
- package/tests/test-blueprint-graph.mjs +343 -12
- package/tests/test-control-editor.mjs +85 -53
- package/tests/test-graphql.mjs +58 -8
- package/tests/test-input.mjs +349 -0
- package/tests/test-inspect.mjs +291 -61
- package/tests/test-landscape.mjs +304 -48
- package/tests/test-lighting.mjs +428 -0
- package/tests/test-manage-level.mjs +70 -51
- package/tests/test-performance.mjs +539 -0
- package/tests/test-sequence.mjs +82 -46
- package/tests/test-system.mjs +72 -33
- package/tests/test-wasm.mjs +98 -8
- package/vitest.config.ts +35 -0
- package/.github/release-drafter.yml +0 -148
- package/dist/prompts/index.d.ts +0 -21
- package/dist/prompts/index.js +0 -217
- package/dist/tools/blueprint/helpers.d.ts +0 -29
- package/dist/tools/blueprint/helpers.js +0 -182
- package/src/prompts/index.ts +0 -249
- package/src/tools/blueprint/helpers.ts +0 -189
- package/tests/test-blueprint-events.mjs +0 -35
- package/tests/test-extra-tools.mjs +0 -38
- package/tests/test-render.mjs +0 -33
- package/tests/test-search-assets.mjs +0 -66
|
@@ -8,8 +8,8 @@ export interface StandardActionResponse<T = any> {
|
|
|
8
8
|
success: boolean;
|
|
9
9
|
data?: T;
|
|
10
10
|
warnings?: string[];
|
|
11
|
-
error?: {
|
|
12
|
-
code
|
|
11
|
+
error?: string | {
|
|
12
|
+
code?: string;
|
|
13
13
|
message: string;
|
|
14
14
|
[key: string]: unknown;
|
|
15
15
|
} | null;
|
|
@@ -53,48 +53,48 @@ export interface SourceControlState {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export interface IAssetTools {
|
|
56
|
-
importAsset(params: { sourcePath: string; destinationPath: string; overwrite?: boolean; save?: boolean }): Promise<
|
|
57
|
-
createFolder(path: string): Promise<
|
|
58
|
-
duplicateAsset(params: { sourcePath: string; destinationPath: string; overwrite?: boolean }): Promise<
|
|
59
|
-
renameAsset(params: { sourcePath: string; destinationPath: string }): Promise<
|
|
60
|
-
moveAsset(params: { sourcePath: string; destinationPath: string }): Promise<
|
|
61
|
-
deleteAssets(params: { paths: string[]; fixupRedirectors?: boolean; timeoutMs?: number }): Promise<
|
|
62
|
-
searchAssets(params: { classNames?: string[]; packagePaths?: string[]; recursivePaths?: boolean; recursiveClasses?: boolean; limit?: number }): Promise<
|
|
63
|
-
saveAsset(assetPath: string): Promise<
|
|
64
|
-
findByTag(params: { tag: string; value?: string }): Promise<
|
|
65
|
-
getDependencies(params: { assetPath: string; recursive?: boolean }): Promise<
|
|
66
|
-
getMetadata(params: { assetPath: string }): Promise<
|
|
67
|
-
getSourceControlState(params: { assetPath: string }): Promise<SourceControlState |
|
|
68
|
-
analyzeGraph(params: { assetPath: string; maxDepth?: number }): Promise<
|
|
69
|
-
createThumbnail(params: { assetPath: string; width?: number; height?: number }): Promise<
|
|
70
|
-
setTags(params: { assetPath: string; tags: string[] }): Promise<
|
|
71
|
-
generateReport(params: { directory: string; reportType?: string; outputPath?: string }): Promise<
|
|
72
|
-
validate(params: { assetPath: string }): Promise<
|
|
73
|
-
generateLODs(params: { assetPath: string; lodCount: number; reductionSettings?: Record<string, unknown> }): Promise<
|
|
56
|
+
importAsset(params: { sourcePath: string; destinationPath: string; overwrite?: boolean; save?: boolean }): Promise<StandardActionResponse>;
|
|
57
|
+
createFolder(path: string): Promise<StandardActionResponse>;
|
|
58
|
+
duplicateAsset(params: { sourcePath: string; destinationPath: string; overwrite?: boolean }): Promise<StandardActionResponse>;
|
|
59
|
+
renameAsset(params: { sourcePath: string; destinationPath: string }): Promise<StandardActionResponse>;
|
|
60
|
+
moveAsset(params: { sourcePath: string; destinationPath: string }): Promise<StandardActionResponse>;
|
|
61
|
+
deleteAssets(params: { paths: string[]; fixupRedirectors?: boolean; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
62
|
+
searchAssets(params: { classNames?: string[]; packagePaths?: string[]; recursivePaths?: boolean; recursiveClasses?: boolean; limit?: number }): Promise<StandardActionResponse>;
|
|
63
|
+
saveAsset(assetPath: string): Promise<StandardActionResponse>;
|
|
64
|
+
findByTag(params: { tag: string; value?: string }): Promise<StandardActionResponse>;
|
|
65
|
+
getDependencies(params: { assetPath: string; recursive?: boolean }): Promise<StandardActionResponse>;
|
|
66
|
+
getMetadata(params: { assetPath: string }): Promise<StandardActionResponse>;
|
|
67
|
+
getSourceControlState(params: { assetPath: string }): Promise<SourceControlState | StandardActionResponse>;
|
|
68
|
+
analyzeGraph(params: { assetPath: string; maxDepth?: number }): Promise<StandardActionResponse>;
|
|
69
|
+
createThumbnail(params: { assetPath: string; width?: number; height?: number }): Promise<StandardActionResponse>;
|
|
70
|
+
setTags(params: { assetPath: string; tags: string[] }): Promise<StandardActionResponse>;
|
|
71
|
+
generateReport(params: { directory: string; reportType?: string; outputPath?: string }): Promise<StandardActionResponse>;
|
|
72
|
+
validate(params: { assetPath: string }): Promise<StandardActionResponse>;
|
|
73
|
+
generateLODs(params: { assetPath: string; lodCount: number; reductionSettings?: Record<string, unknown> }): Promise<StandardActionResponse>;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export interface ISequenceTools {
|
|
77
|
-
create(params: { name: string; path?: string; timeoutMs?: number }): Promise<
|
|
78
|
-
open(params: { path: string }): Promise<
|
|
79
|
-
addCamera(params: { spawnable?: boolean; path?: string }): Promise<
|
|
80
|
-
addActor(params: { actorName: string; createBinding?: boolean; path?: string }): Promise<
|
|
81
|
-
addActors(params: { actorNames: string[]; path?: string }): Promise<
|
|
82
|
-
removeActors(params: { actorNames: string[]; path?: string }): Promise<
|
|
83
|
-
getBindings(params: { path?: string }): Promise<
|
|
84
|
-
addSpawnableFromClass(params: { className: string; path?: string }): Promise<
|
|
85
|
-
play(params: { path?: string; startTime?: number; loopMode?: 'once' | 'loop' | 'pingpong' }): Promise<
|
|
86
|
-
pause(params?: { path?: string }): Promise<
|
|
87
|
-
stop(params?: { path?: string }): Promise<
|
|
88
|
-
setSequenceProperties(params: { path?: string; frameRate?: number; lengthInFrames?: number; playbackStart?: number; playbackEnd?: number }): Promise<
|
|
89
|
-
getSequenceProperties(params: { path?: string }): Promise<
|
|
90
|
-
setPlaybackSpeed(params: { speed: number; path?: string }): Promise<
|
|
91
|
-
list(params: { path?: string }): Promise<
|
|
92
|
-
duplicate(params: { path: string; destinationPath: string }): Promise<
|
|
93
|
-
rename(params: { path: string; newName: string }): Promise<
|
|
94
|
-
deleteSequence(params: { path: string }): Promise<
|
|
95
|
-
getMetadata(params: { path: string }): Promise<
|
|
96
|
-
listTracks(params: { path: string }): Promise<
|
|
97
|
-
setWorkRange(params: { path?: string; start: number; end: number }): Promise<
|
|
77
|
+
create(params: { name: string; path?: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
78
|
+
open(params: { path: string }): Promise<StandardActionResponse>;
|
|
79
|
+
addCamera(params: { spawnable?: boolean; path?: string }): Promise<StandardActionResponse>;
|
|
80
|
+
addActor(params: { actorName: string; createBinding?: boolean; path?: string }): Promise<StandardActionResponse>;
|
|
81
|
+
addActors(params: { actorNames: string[]; path?: string }): Promise<StandardActionResponse>;
|
|
82
|
+
removeActors(params: { actorNames: string[]; path?: string }): Promise<StandardActionResponse>;
|
|
83
|
+
getBindings(params: { path?: string }): Promise<StandardActionResponse>;
|
|
84
|
+
addSpawnableFromClass(params: { className: string; path?: string }): Promise<StandardActionResponse>;
|
|
85
|
+
play(params: { path?: string; startTime?: number; loopMode?: 'once' | 'loop' | 'pingpong' }): Promise<StandardActionResponse>;
|
|
86
|
+
pause(params?: { path?: string }): Promise<StandardActionResponse>;
|
|
87
|
+
stop(params?: { path?: string }): Promise<StandardActionResponse>;
|
|
88
|
+
setSequenceProperties(params: { path?: string; frameRate?: number; lengthInFrames?: number; playbackStart?: number; playbackEnd?: number }): Promise<StandardActionResponse>;
|
|
89
|
+
getSequenceProperties(params: { path?: string }): Promise<StandardActionResponse>;
|
|
90
|
+
setPlaybackSpeed(params: { speed: number; path?: string }): Promise<StandardActionResponse>;
|
|
91
|
+
list(params: { path?: string }): Promise<StandardActionResponse>;
|
|
92
|
+
duplicate(params: { path: string; destinationPath: string }): Promise<StandardActionResponse>;
|
|
93
|
+
rename(params: { path: string; newName: string }): Promise<StandardActionResponse>;
|
|
94
|
+
deleteSequence(params: { path: string }): Promise<StandardActionResponse>;
|
|
95
|
+
getMetadata(params: { path: string }): Promise<StandardActionResponse>;
|
|
96
|
+
listTracks(params: { path: string }): Promise<StandardActionResponse>;
|
|
97
|
+
setWorkRange(params: { path?: string; start: number; end: number }): Promise<StandardActionResponse>;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
export interface IAssetResources {
|
|
@@ -102,118 +102,118 @@ export interface IAssetResources {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
export interface IBlueprintTools {
|
|
105
|
-
createBlueprint(params: { name: string; blueprintType?: string; savePath?: string; parentClass?: string; properties?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
106
|
-
modifyConstructionScript(params: { blueprintPath: string; operations: any[]; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
107
|
-
addComponent(params: { blueprintName: string; componentType: string; componentName: string; attachTo?: string; transform?: Record<string, unknown>; properties?: Record<string, unknown>; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
108
|
-
waitForBlueprint(blueprintRef: string | string[], timeoutMs?: number): Promise<
|
|
109
|
-
getBlueprint(params: { blueprintName: string; timeoutMs?: number }): Promise<
|
|
110
|
-
getBlueprintInfo(params: { blueprintPath: string; timeoutMs?: number }): Promise<
|
|
111
|
-
probeSubobjectDataHandle(opts?: { componentClass?: string }): Promise<
|
|
112
|
-
setBlueprintDefault(params: { blueprintName: string; propertyName: string; value: unknown }): Promise<
|
|
113
|
-
addVariable(params: { blueprintName: string; variableName: string; variableType: string; defaultValue?: any; category?: string; isReplicated?: boolean; isPublic?: boolean; variablePinType?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
114
|
-
removeVariable(params: { blueprintName: string; variableName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
115
|
-
renameVariable(params: { blueprintName: string; oldName: string; newName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
116
|
-
addEvent(params: { blueprintName: string; eventType: string; customEventName?: string; parameters?: Array<{ name: string; type: string }>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
117
|
-
removeEvent(params: { blueprintName: string; eventName: string; customEventName?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
118
|
-
addFunction(params: { blueprintName: string; functionName: string; inputs?: Array<{ name: string; type: string }>; outputs?: Array<{ name: string; type: string }>; isPublic?: boolean; category?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
119
|
-
setVariableMetadata(params: { blueprintName: string; variableName: string; metadata: Record<string, unknown>; timeoutMs?: number }): Promise<
|
|
120
|
-
renameVariable(params: { blueprintName: string; oldName: string; newName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
121
|
-
addConstructionScript(params: { blueprintName: string; scriptName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<
|
|
122
|
-
compileBlueprint(params: { blueprintName: string; saveAfterCompile?: boolean }): Promise<
|
|
123
|
-
getBlueprintSCS(params: { blueprintPath: string; timeoutMs?: number }): Promise<
|
|
124
|
-
addSCSComponent(params: { blueprintPath: string; componentClass: string; componentName: string; parentComponent?: string; meshPath?: string; materialPath?: string; timeoutMs?: number }): Promise<
|
|
125
|
-
removeSCSComponent(params: { blueprintPath: string; componentName: string; timeoutMs?: number }): Promise<
|
|
126
|
-
reparentSCSComponent(params: { blueprintPath: string; componentName: string; newParent: string; timeoutMs?: number }): Promise<
|
|
127
|
-
setSCSComponentTransform(params: { blueprintPath: string; componentName: string; location?: [number, number, number]; rotation?: [number, number, number]; scale?: [number, number, number]; timeoutMs?: number }): Promise<
|
|
128
|
-
setSCSComponentProperty(params: { blueprintPath: string; componentName: string; propertyName: string; propertyValue: any; timeoutMs?: number }): Promise<
|
|
129
|
-
addNode(params: { blueprintName: string; nodeType: string; graphName?: string; functionName?: string; variableName?: string; nodeName?: string; eventName?: string; memberClass?: string; posX?: number; posY?: number; timeoutMs?: number }): Promise<
|
|
130
|
-
connectPins(params: { blueprintName: string; sourceNodeGuid: string; targetNodeGuid: string; sourcePinName?: string; targetPinName?: string; timeoutMs?: number }): Promise<
|
|
105
|
+
createBlueprint(params: { name: string; blueprintType?: string; savePath?: string; parentClass?: string; properties?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
106
|
+
modifyConstructionScript(params: { blueprintPath: string; operations: any[]; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
107
|
+
addComponent(params: { blueprintName: string; componentType: string; componentName: string; attachTo?: string; transform?: Record<string, unknown>; properties?: Record<string, unknown>; compile?: boolean; save?: boolean; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
108
|
+
waitForBlueprint(blueprintRef: string | string[], timeoutMs?: number): Promise<StandardActionResponse>;
|
|
109
|
+
getBlueprint(params: { blueprintName: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
110
|
+
getBlueprintInfo(params: { blueprintPath: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
111
|
+
probeSubobjectDataHandle(opts?: { componentClass?: string }): Promise<StandardActionResponse>;
|
|
112
|
+
setBlueprintDefault(params: { blueprintName: string; propertyName: string; value: unknown }): Promise<StandardActionResponse>;
|
|
113
|
+
addVariable(params: { blueprintName: string; variableName: string; variableType: string; defaultValue?: any; category?: string; isReplicated?: boolean; isPublic?: boolean; variablePinType?: Record<string, unknown>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
114
|
+
removeVariable(params: { blueprintName: string; variableName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
115
|
+
renameVariable(params: { blueprintName: string; oldName: string; newName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
116
|
+
addEvent(params: { blueprintName: string; eventType: string; customEventName?: string; parameters?: Array<{ name: string; type: string }>; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
117
|
+
removeEvent(params: { blueprintName: string; eventName: string; customEventName?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
118
|
+
addFunction(params: { blueprintName: string; functionName: string; inputs?: Array<{ name: string; type: string }>; outputs?: Array<{ name: string; type: string }>; isPublic?: boolean; category?: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
119
|
+
setVariableMetadata(params: { blueprintName: string; variableName: string; metadata: Record<string, unknown>; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
120
|
+
renameVariable(params: { blueprintName: string; oldName: string; newName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
121
|
+
addConstructionScript(params: { blueprintName: string; scriptName: string; timeoutMs?: number; waitForCompletion?: boolean; waitForCompletionTimeoutMs?: number }): Promise<StandardActionResponse>;
|
|
122
|
+
compileBlueprint(params: { blueprintName: string; saveAfterCompile?: boolean }): Promise<StandardActionResponse>;
|
|
123
|
+
getBlueprintSCS(params: { blueprintPath: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
124
|
+
addSCSComponent(params: { blueprintPath: string; componentClass: string; componentName: string; parentComponent?: string; meshPath?: string; materialPath?: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
125
|
+
removeSCSComponent(params: { blueprintPath: string; componentName: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
126
|
+
reparentSCSComponent(params: { blueprintPath: string; componentName: string; newParent: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
127
|
+
setSCSComponentTransform(params: { blueprintPath: string; componentName: string; location?: [number, number, number]; rotation?: [number, number, number]; scale?: [number, number, number]; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
128
|
+
setSCSComponentProperty(params: { blueprintPath: string; componentName: string; propertyName: string; propertyValue: any; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
129
|
+
addNode(params: { blueprintName: string; nodeType: string; graphName?: string; functionName?: string; variableName?: string; nodeName?: string; eventName?: string; memberClass?: string; posX?: number; posY?: number; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
130
|
+
connectPins(params: { blueprintName: string; sourceNodeGuid: string; targetNodeGuid: string; sourcePinName?: string; targetPinName?: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
export interface ILevelTools {
|
|
134
|
-
listLevels(): Promise<
|
|
135
|
-
getLevelSummary(levelPath?: string): Promise<
|
|
134
|
+
listLevels(): Promise<StandardActionResponse>;
|
|
135
|
+
getLevelSummary(levelPath?: string): Promise<StandardActionResponse>;
|
|
136
136
|
registerLight(levelPath: string | undefined, info: { name: string; type: string; details?: Record<string, unknown> }): void;
|
|
137
|
-
exportLevel(params: { levelPath?: string; exportPath: string; note?: string; timeoutMs?: number }): Promise<
|
|
138
|
-
importLevel(params: { packagePath: string; destinationPath?: string; streaming?: boolean; timeoutMs?: number }): Promise<
|
|
139
|
-
saveLevelAs(params: { sourcePath?: string; targetPath: string }): Promise<
|
|
140
|
-
deleteLevels(params: { levelPaths: string[] }): Promise<
|
|
141
|
-
loadLevel(params: { levelPath: string; streaming?: boolean; position?: [number, number, number] }): Promise<
|
|
142
|
-
saveLevel(params: { levelName?: string; savePath?: string }): Promise<
|
|
143
|
-
createLevel(params: { levelName: string; template?: 'Empty' | 'Default' | 'VR' | 'TimeOfDay'; savePath?: string }): Promise<
|
|
144
|
-
addSubLevel(params: { parentLevel?: string; subLevelPath: string; streamingMethod?: 'Blueprint' | 'AlwaysLoaded' }): Promise<
|
|
145
|
-
streamLevel(params: { levelPath?: string; levelName?: string; shouldBeLoaded: boolean; shouldBeVisible?: boolean; position?: [number, number, number] }): Promise<
|
|
146
|
-
setupWorldComposition(params: { enableComposition: boolean; tileSize?: number; distanceStreaming?: boolean; streamingDistance?: number }): Promise<
|
|
147
|
-
editLevelBlueprint(params: { eventType: 'BeginPlay' | 'EndPlay' | 'Tick' | 'Custom'; customEventName?: string; nodes?: Array<{ nodeType: string; position: [number, number]; connections?: string[] }> }): Promise<
|
|
148
|
-
createSubLevel(params: { name: string; type: 'Persistent' | 'Streaming' | 'Lighting' | 'Gameplay'; parent?: string }): Promise<
|
|
149
|
-
setWorldSettings(params: { gravity?: number; worldScale?: number; gameMode?: string; defaultPawn?: string; killZ?: number }): Promise<
|
|
150
|
-
setLevelBounds(params: { min: [number, number, number]; max: [number, number, number] }): Promise<
|
|
151
|
-
buildNavMesh(params: { rebuildAll?: boolean; selectedOnly?: boolean }): Promise<
|
|
152
|
-
setLevelVisibility(params: { levelName: string; visible: boolean }): Promise<
|
|
153
|
-
setWorldOrigin(params: { location: [number, number, number] }): Promise<
|
|
154
|
-
createStreamingVolume(params: { levelName: string; position: [number, number, number]; size: [number, number, number]; streamingDistance?: number }): Promise<
|
|
155
|
-
setLevelLOD(params: { levelName: string; lodLevel: number; distance: number }): Promise<
|
|
137
|
+
exportLevel(params: { levelPath?: string; exportPath: string; note?: string; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
138
|
+
importLevel(params: { packagePath: string; destinationPath?: string; streaming?: boolean; timeoutMs?: number }): Promise<StandardActionResponse>;
|
|
139
|
+
saveLevelAs(params: { sourcePath?: string; targetPath: string }): Promise<StandardActionResponse>;
|
|
140
|
+
deleteLevels(params: { levelPaths: string[] }): Promise<StandardActionResponse>;
|
|
141
|
+
loadLevel(params: { levelPath: string; streaming?: boolean; position?: [number, number, number] }): Promise<StandardActionResponse>;
|
|
142
|
+
saveLevel(params: { levelName?: string; savePath?: string }): Promise<StandardActionResponse>;
|
|
143
|
+
createLevel(params: { levelName: string; template?: 'Empty' | 'Default' | 'VR' | 'TimeOfDay'; savePath?: string }): Promise<StandardActionResponse>;
|
|
144
|
+
addSubLevel(params: { parentLevel?: string; subLevelPath: string; streamingMethod?: 'Blueprint' | 'AlwaysLoaded' }): Promise<StandardActionResponse>;
|
|
145
|
+
streamLevel(params: { levelPath?: string; levelName?: string; shouldBeLoaded: boolean; shouldBeVisible?: boolean; position?: [number, number, number] }): Promise<StandardActionResponse>;
|
|
146
|
+
setupWorldComposition(params: { enableComposition: boolean; tileSize?: number; distanceStreaming?: boolean; streamingDistance?: number }): Promise<StandardActionResponse>;
|
|
147
|
+
editLevelBlueprint(params: { eventType: 'BeginPlay' | 'EndPlay' | 'Tick' | 'Custom'; customEventName?: string; nodes?: Array<{ nodeType: string; position: [number, number]; connections?: string[] }> }): Promise<StandardActionResponse>;
|
|
148
|
+
createSubLevel(params: { name: string; type: 'Persistent' | 'Streaming' | 'Lighting' | 'Gameplay'; parent?: string }): Promise<StandardActionResponse>;
|
|
149
|
+
setWorldSettings(params: { gravity?: number; worldScale?: number; gameMode?: string; defaultPawn?: string; killZ?: number }): Promise<StandardActionResponse>;
|
|
150
|
+
setLevelBounds(params: { min: [number, number, number]; max: [number, number, number] }): Promise<StandardActionResponse>;
|
|
151
|
+
buildNavMesh(params: { rebuildAll?: boolean; selectedOnly?: boolean }): Promise<StandardActionResponse>;
|
|
152
|
+
setLevelVisibility(params: { levelName: string; visible: boolean }): Promise<StandardActionResponse>;
|
|
153
|
+
setWorldOrigin(params: { location: [number, number, number] }): Promise<StandardActionResponse>;
|
|
154
|
+
createStreamingVolume(params: { levelName: string; position: [number, number, number]; size: [number, number, number]; streamingDistance?: number }): Promise<StandardActionResponse>;
|
|
155
|
+
setLevelLOD(params: { levelName: string; lodLevel: number; distance: number }): Promise<StandardActionResponse>;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
export interface IEditorTools {
|
|
159
159
|
isInPIE(): Promise<boolean>;
|
|
160
160
|
ensureNotInPIE(): Promise<void>;
|
|
161
|
-
playInEditor(timeoutMs?: number): Promise<
|
|
162
|
-
stopPlayInEditor(): Promise<
|
|
163
|
-
pausePlayInEditor(): Promise<
|
|
164
|
-
pauseInEditor(): Promise<
|
|
165
|
-
buildLighting(): Promise<
|
|
166
|
-
setViewportCamera(location?: { x: number; y: number; z: number } | [number, number, number] | null | undefined, rotation?: { pitch: number; yaw: number; roll: number } | [number, number, number] | null | undefined): Promise<
|
|
167
|
-
setCameraSpeed(speed: number): Promise<
|
|
168
|
-
setFOV(fov: number): Promise<
|
|
169
|
-
takeScreenshot(filename?: string, resolution?: string): Promise<
|
|
170
|
-
resumePlayInEditor(): Promise<
|
|
171
|
-
stepPIEFrame(steps?: number): Promise<
|
|
172
|
-
startRecording(options?: { filename?: string; frameRate?: number; durationSeconds?: number; metadata?: Record<string, unknown> }): Promise<
|
|
173
|
-
stopRecording(): Promise<
|
|
174
|
-
createCameraBookmark(name: string): Promise<
|
|
175
|
-
jumpToCameraBookmark(name: string): Promise<
|
|
176
|
-
setEditorPreferences(category: string | undefined, preferences: Record<string, unknown>): Promise<
|
|
177
|
-
setViewportResolution(width: number, height: number): Promise<
|
|
178
|
-
executeConsoleCommand(command: string): Promise<
|
|
161
|
+
playInEditor(timeoutMs?: number): Promise<StandardActionResponse>;
|
|
162
|
+
stopPlayInEditor(): Promise<StandardActionResponse>;
|
|
163
|
+
pausePlayInEditor(): Promise<StandardActionResponse>;
|
|
164
|
+
pauseInEditor(): Promise<StandardActionResponse>;
|
|
165
|
+
buildLighting(): Promise<StandardActionResponse>;
|
|
166
|
+
setViewportCamera(location?: { x: number; y: number; z: number } | [number, number, number] | null | undefined, rotation?: { pitch: number; yaw: number; roll: number } | [number, number, number] | null | undefined): Promise<StandardActionResponse>;
|
|
167
|
+
setCameraSpeed(speed: number): Promise<StandardActionResponse>;
|
|
168
|
+
setFOV(fov: number): Promise<StandardActionResponse>;
|
|
169
|
+
takeScreenshot(filename?: string, resolution?: string): Promise<StandardActionResponse>;
|
|
170
|
+
resumePlayInEditor(): Promise<StandardActionResponse>;
|
|
171
|
+
stepPIEFrame(steps?: number): Promise<StandardActionResponse>;
|
|
172
|
+
startRecording(options?: { filename?: string; frameRate?: number; durationSeconds?: number; metadata?: Record<string, unknown> }): Promise<StandardActionResponse>;
|
|
173
|
+
stopRecording(): Promise<StandardActionResponse>;
|
|
174
|
+
createCameraBookmark(name: string): Promise<StandardActionResponse>;
|
|
175
|
+
jumpToCameraBookmark(name: string): Promise<StandardActionResponse>;
|
|
176
|
+
setEditorPreferences(category: string | undefined, preferences: Record<string, unknown>): Promise<StandardActionResponse>;
|
|
177
|
+
setViewportResolution(width: number, height: number): Promise<StandardActionResponse>;
|
|
178
|
+
executeConsoleCommand(command: string): Promise<StandardActionResponse>;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
export interface IEnvironmentTools {
|
|
182
|
-
setTimeOfDay(hour: unknown): Promise<
|
|
183
|
-
setSunIntensity(intensity: unknown): Promise<
|
|
184
|
-
setSkylightIntensity(intensity: unknown): Promise<
|
|
185
|
-
exportSnapshot(params: { path?: unknown; filename?: unknown }): Promise<
|
|
186
|
-
importSnapshot(params: { path?: unknown; filename?: unknown }): Promise<
|
|
187
|
-
cleanup(params?: { names?: unknown }): Promise<
|
|
182
|
+
setTimeOfDay(hour: unknown): Promise<StandardActionResponse>;
|
|
183
|
+
setSunIntensity(intensity: unknown): Promise<StandardActionResponse>;
|
|
184
|
+
setSkylightIntensity(intensity: unknown): Promise<StandardActionResponse>;
|
|
185
|
+
exportSnapshot(params: { path?: unknown; filename?: unknown }): Promise<StandardActionResponse>;
|
|
186
|
+
importSnapshot(params: { path?: unknown; filename?: unknown }): Promise<StandardActionResponse>;
|
|
187
|
+
cleanup(params?: { names?: unknown }): Promise<StandardActionResponse>;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
export interface ILandscapeTools {
|
|
191
|
-
createLandscape(params: { name: string; location?: [number, number, number]; sizeX?: number; sizeY?: number; quadsPerSection?: number; sectionsPerComponent?: number; componentCount?: number; materialPath?: string; enableWorldPartition?: boolean; runtimeGrid?: string; isSpatiallyLoaded?: boolean; dataLayers?: string[] }): Promise<
|
|
192
|
-
sculptLandscape(params: { landscapeName: string; tool: string; brushSize?: number; brushFalloff?: number; strength?: number; location?: [number, number, number]; radius?: number }): Promise<
|
|
193
|
-
paintLandscape(params: { landscapeName: string; layerName: string; position: [number, number, number]; brushSize?: number; strength?: number; targetValue?: number; radius?: number; density?: number }): Promise<
|
|
194
|
-
createProceduralTerrain(params: { name: string; location?: [number, number, number]; subdivisions?: number; heightFunction?: string; material?: string; settings?: Record<string, unknown> }): Promise<
|
|
195
|
-
createLandscapeGrassType(params: { name: string; meshPath: string; density?: number; minScale?: number; maxScale?: number; path?: string; staticMesh?: string }): Promise<
|
|
196
|
-
setLandscapeMaterial(params: { landscapeName: string; materialPath: string }): Promise<
|
|
197
|
-
modifyHeightmap(params: { landscapeName: string; heightData: number[]; minX: number; minY: number; maxX: number; maxY: number; updateNormals?: boolean }): Promise<
|
|
191
|
+
createLandscape(params: { name: string; location?: [number, number, number]; sizeX?: number; sizeY?: number; quadsPerSection?: number; sectionsPerComponent?: number; componentCount?: number; materialPath?: string; enableWorldPartition?: boolean; runtimeGrid?: string; isSpatiallyLoaded?: boolean; dataLayers?: string[] }): Promise<StandardActionResponse>;
|
|
192
|
+
sculptLandscape(params: { landscapeName: string; tool: string; brushSize?: number; brushFalloff?: number; strength?: number; location?: [number, number, number]; radius?: number }): Promise<StandardActionResponse>;
|
|
193
|
+
paintLandscape(params: { landscapeName: string; layerName: string; position: [number, number, number]; brushSize?: number; strength?: number; targetValue?: number; radius?: number; density?: number }): Promise<StandardActionResponse>;
|
|
194
|
+
createProceduralTerrain(params: { name: string; location?: [number, number, number]; subdivisions?: number; heightFunction?: string; material?: string; settings?: Record<string, unknown> }): Promise<StandardActionResponse>;
|
|
195
|
+
createLandscapeGrassType(params: { name: string; meshPath: string; density?: number; minScale?: number; maxScale?: number; path?: string; staticMesh?: string }): Promise<StandardActionResponse>;
|
|
196
|
+
setLandscapeMaterial(params: { landscapeName: string; materialPath: string }): Promise<StandardActionResponse>;
|
|
197
|
+
modifyHeightmap(params: { landscapeName: string; heightData: number[]; minX: number; minY: number; maxX: number; maxY: number; updateNormals?: boolean }): Promise<StandardActionResponse>;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
export interface IFoliageTools {
|
|
201
|
-
addFoliageType(params: { name: string; meshPath: string; density?: number; radius?: number; minScale?: number; maxScale?: number; alignToNormal?: boolean; randomYaw?: boolean; groundSlope?: number }): Promise<
|
|
202
|
-
addFoliage(params: { foliageType: string; locations: Array<{ x: number; y: number; z: number }> }): Promise<
|
|
203
|
-
paintFoliage(params: { foliageType: string; position: [number, number, number]; brushSize?: number; paintDensity?: number; eraseMode?: boolean }): Promise<
|
|
204
|
-
createProceduralFoliage(params: { name: string; bounds?: { location: { x: number; y: number; z: number }; size: { x: number; y: number; z: number } }; foliageTypes?: Array<{ meshPath: string; density: number; minScale?: number; maxScale?: number; alignToNormal?: boolean; randomYaw?: boolean }>; volumeName?: string; position?: [number, number, number]; size?: [number, number, number]; seed?: number; tileSize?: number }): Promise<
|
|
205
|
-
addFoliageInstances(params: { foliageType: string; transforms: Array<{ location: [number, number, number]; rotation?: [number, number, number]; scale?: [number, number, number] }> }): Promise<
|
|
206
|
-
getFoliageInstances(params: { foliageType?: string }): Promise<
|
|
207
|
-
removeFoliage(params: { foliageType?: string; removeAll?: boolean }): Promise<
|
|
208
|
-
createInstancedMesh(params: { name: string; meshPath: string; instances: Array<{ position: [number, number, number]; rotation?: [number, number, number]; scale?: [number, number, number] }>; enableCulling?: boolean; cullDistance?: number }): Promise<
|
|
209
|
-
setFoliageLOD(params: { foliageType: string; lodDistances?: number[]; screenSize?: number[] }): Promise<
|
|
210
|
-
setFoliageCollision(params: { foliageType: string; collisionEnabled?: boolean; collisionProfile?: string; generateOverlapEvents?: boolean }): Promise<
|
|
211
|
-
createGrassSystem(params: { name: string; grassTypes: Array<{ meshPath: string; density: number; minScale?: number; maxScale?: number }>; windStrength?: number; windSpeed?: number }): Promise<
|
|
212
|
-
removeFoliageInstances(params: { foliageType: string; position: [number, number, number]; radius: number }): Promise<
|
|
213
|
-
selectFoliageInstances(params: { foliageType: string; position?: [number, number, number]; radius?: number; selectAll?: boolean }): Promise<
|
|
214
|
-
updateFoliageInstances(params: { foliageType: string; updateTransforms?: boolean; updateMesh?: boolean; newMeshPath?: string }): Promise<
|
|
215
|
-
createFoliageSpawner(params: { name: string; spawnArea: 'Landscape' | 'StaticMesh' | 'BSP' | 'Foliage' | 'All'; excludeAreas?: Array<[number, number, number, number]> }): Promise<
|
|
216
|
-
optimizeFoliage(params: { mergeInstances?: boolean; generateClusters?: boolean; clusterSize?: number; reduceDrawCalls?: boolean }): Promise<
|
|
201
|
+
addFoliageType(params: { name: string; meshPath: string; density?: number; radius?: number; minScale?: number; maxScale?: number; alignToNormal?: boolean; randomYaw?: boolean; groundSlope?: number }): Promise<StandardActionResponse>;
|
|
202
|
+
addFoliage(params: { foliageType: string; locations: Array<{ x: number; y: number; z: number }> }): Promise<StandardActionResponse>;
|
|
203
|
+
paintFoliage(params: { foliageType: string; position: [number, number, number]; brushSize?: number; paintDensity?: number; eraseMode?: boolean }): Promise<StandardActionResponse>;
|
|
204
|
+
createProceduralFoliage(params: { name: string; bounds?: { location: { x: number; y: number; z: number }; size: { x: number; y: number; z: number } }; foliageTypes?: Array<{ meshPath: string; density: number; minScale?: number; maxScale?: number; alignToNormal?: boolean; randomYaw?: boolean }>; volumeName?: string; position?: [number, number, number]; size?: [number, number, number]; seed?: number; tileSize?: number }): Promise<StandardActionResponse>;
|
|
205
|
+
addFoliageInstances(params: { foliageType: string; transforms: Array<{ location: [number, number, number]; rotation?: [number, number, number]; scale?: [number, number, number] }> }): Promise<StandardActionResponse>;
|
|
206
|
+
getFoliageInstances(params: { foliageType?: string }): Promise<StandardActionResponse>;
|
|
207
|
+
removeFoliage(params: { foliageType?: string; removeAll?: boolean }): Promise<StandardActionResponse>;
|
|
208
|
+
createInstancedMesh(params: { name: string; meshPath: string; instances: Array<{ position: [number, number, number]; rotation?: [number, number, number]; scale?: [number, number, number] }>; enableCulling?: boolean; cullDistance?: number }): Promise<StandardActionResponse>;
|
|
209
|
+
setFoliageLOD(params: { foliageType: string; lodDistances?: number[]; screenSize?: number[] }): Promise<StandardActionResponse>;
|
|
210
|
+
setFoliageCollision(params: { foliageType: string; collisionEnabled?: boolean; collisionProfile?: string; generateOverlapEvents?: boolean }): Promise<StandardActionResponse>;
|
|
211
|
+
createGrassSystem(params: { name: string; grassTypes: Array<{ meshPath: string; density: number; minScale?: number; maxScale?: number }>; windStrength?: number; windSpeed?: number }): Promise<StandardActionResponse>;
|
|
212
|
+
removeFoliageInstances(params: { foliageType: string; position: [number, number, number]; radius: number }): Promise<StandardActionResponse>;
|
|
213
|
+
selectFoliageInstances(params: { foliageType: string; position?: [number, number, number]; radius?: number; selectAll?: boolean }): Promise<StandardActionResponse>;
|
|
214
|
+
updateFoliageInstances(params: { foliageType: string; updateTransforms?: boolean; updateMesh?: boolean; newMeshPath?: string }): Promise<StandardActionResponse>;
|
|
215
|
+
createFoliageSpawner(params: { name: string; spawnArea: 'Landscape' | 'StaticMesh' | 'BSP' | 'Foliage' | 'All'; excludeAreas?: Array<[number, number, number, number]> }): Promise<StandardActionResponse>;
|
|
216
|
+
optimizeFoliage(params: { mergeInstances?: boolean; generateClusters?: boolean; clusterSize?: number; reduceDrawCalls?: boolean }): Promise<StandardActionResponse>;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
export interface ITools {
|
package/src/types/tool-types.ts
CHANGED
|
@@ -9,6 +9,10 @@ export interface BaseToolResponse {
|
|
|
9
9
|
message?: string;
|
|
10
10
|
error?: string;
|
|
11
11
|
warning?: string;
|
|
12
|
+
/** Whether this error is retriable (e.g., connection failures) */
|
|
13
|
+
retriable?: boolean;
|
|
14
|
+
/** Scope/context for the error (e.g., 'tool-call/manage_asset') */
|
|
15
|
+
scope?: string;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
// Asset Management Types
|
package/src/unreal-bridge.ts
CHANGED
|
@@ -5,14 +5,59 @@ import { DEFAULT_AUTOMATION_HOST, DEFAULT_AUTOMATION_PORT } from './constants.js
|
|
|
5
5
|
import { UnrealCommandQueue } from './utils/unreal-command-queue.js';
|
|
6
6
|
import { CommandValidator } from './utils/command-validator.js';
|
|
7
7
|
|
|
8
|
+
/** Connection event payload for automation bridge events */
|
|
9
|
+
interface ConnectionEventInfo {
|
|
10
|
+
host?: string;
|
|
11
|
+
port?: number;
|
|
12
|
+
reason?: string;
|
|
13
|
+
error?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Result object from automation requests */
|
|
18
|
+
interface AutomationResult {
|
|
19
|
+
value?: unknown;
|
|
20
|
+
propertyValue?: unknown;
|
|
21
|
+
message?: string;
|
|
22
|
+
warnings?: string[];
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Subsystems feature flags */
|
|
27
|
+
interface SubsystemFlags {
|
|
28
|
+
unrealEditor?: boolean;
|
|
29
|
+
levelEditor?: boolean;
|
|
30
|
+
editorActor?: boolean;
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Engine version result */
|
|
35
|
+
interface EngineVersionResult {
|
|
36
|
+
version?: string;
|
|
37
|
+
major?: number;
|
|
38
|
+
minor?: number;
|
|
39
|
+
patch?: number;
|
|
40
|
+
isUE56OrAbove?: boolean;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Console command response */
|
|
45
|
+
interface ConsoleCommandResponse {
|
|
46
|
+
success?: boolean;
|
|
47
|
+
message?: string;
|
|
48
|
+
error?: string;
|
|
49
|
+
transport?: string;
|
|
50
|
+
[key: string]: unknown;
|
|
51
|
+
}
|
|
52
|
+
|
|
8
53
|
export class UnrealBridge {
|
|
9
54
|
private log = new Logger('UnrealBridge');
|
|
10
55
|
private connected = false;
|
|
11
56
|
private automationBridge?: AutomationBridge;
|
|
12
57
|
private automationBridgeListeners?: {
|
|
13
|
-
connected: (info:
|
|
14
|
-
disconnected: (info:
|
|
15
|
-
handshakeFailed: (info:
|
|
58
|
+
connected: (info: ConnectionEventInfo) => void;
|
|
59
|
+
disconnected: (info: ConnectionEventInfo) => void;
|
|
60
|
+
handshakeFailed: (info: ConnectionEventInfo) => void;
|
|
16
61
|
};
|
|
17
62
|
|
|
18
63
|
// Command queue for throttling
|
|
@@ -35,17 +80,17 @@ export class UnrealBridge {
|
|
|
35
80
|
return;
|
|
36
81
|
}
|
|
37
82
|
|
|
38
|
-
const onConnected = (info:
|
|
83
|
+
const onConnected = (info: ConnectionEventInfo) => {
|
|
39
84
|
this.connected = true;
|
|
40
85
|
this.log.debug('Automation bridge connected', info);
|
|
41
86
|
};
|
|
42
87
|
|
|
43
|
-
const onDisconnected = (info:
|
|
88
|
+
const onDisconnected = (info: ConnectionEventInfo) => {
|
|
44
89
|
this.connected = false;
|
|
45
90
|
this.log.debug('Automation bridge disconnected', info);
|
|
46
91
|
};
|
|
47
92
|
|
|
48
|
-
const onHandshakeFailed = (info:
|
|
93
|
+
const onHandshakeFailed = (info: ConnectionEventInfo) => {
|
|
49
94
|
this.connected = false;
|
|
50
95
|
this.log.warn('Automation bridge handshake failed', info);
|
|
51
96
|
};
|
|
@@ -279,13 +324,13 @@ export class UnrealBridge {
|
|
|
279
324
|
);
|
|
280
325
|
|
|
281
326
|
const success = response.success !== false;
|
|
282
|
-
const rawResult =
|
|
327
|
+
const rawResult: AutomationResult | undefined =
|
|
283
328
|
response.result && typeof response.result === 'object'
|
|
284
329
|
? { ...(response.result as Record<string, unknown>) }
|
|
285
|
-
:
|
|
330
|
+
: undefined;
|
|
286
331
|
const value =
|
|
287
|
-
|
|
288
|
-
|
|
332
|
+
rawResult?.value ??
|
|
333
|
+
rawResult?.propertyValue ??
|
|
289
334
|
(success ? rawResult : undefined);
|
|
290
335
|
|
|
291
336
|
if (success) {
|
|
@@ -297,8 +342,8 @@ export class UnrealBridge {
|
|
|
297
342
|
propertyValue: value,
|
|
298
343
|
transport: 'automation_bridge',
|
|
299
344
|
message: response.message,
|
|
300
|
-
warnings: Array.isArray(
|
|
301
|
-
?
|
|
345
|
+
warnings: Array.isArray(rawResult?.warnings)
|
|
346
|
+
? rawResult.warnings
|
|
302
347
|
: undefined,
|
|
303
348
|
raw: rawResult,
|
|
304
349
|
bridge: {
|
|
@@ -389,10 +434,10 @@ export class UnrealBridge {
|
|
|
389
434
|
);
|
|
390
435
|
|
|
391
436
|
const success = response.success !== false;
|
|
392
|
-
const rawResult =
|
|
437
|
+
const rawResult: AutomationResult | undefined =
|
|
393
438
|
response.result && typeof response.result === 'object'
|
|
394
439
|
? { ...(response.result as Record<string, unknown>) }
|
|
395
|
-
:
|
|
440
|
+
: undefined;
|
|
396
441
|
|
|
397
442
|
if (success) {
|
|
398
443
|
return {
|
|
@@ -401,7 +446,7 @@ export class UnrealBridge {
|
|
|
401
446
|
propertyName,
|
|
402
447
|
message:
|
|
403
448
|
response.message ||
|
|
404
|
-
(typeof
|
|
449
|
+
(typeof rawResult?.message === 'string' ? rawResult.message : undefined),
|
|
405
450
|
transport: 'automation_bridge',
|
|
406
451
|
raw: rawResult,
|
|
407
452
|
bridge: {
|
|
@@ -469,14 +514,14 @@ export class UnrealBridge {
|
|
|
469
514
|
throw new Error('Automation bridge not connected');
|
|
470
515
|
}
|
|
471
516
|
|
|
472
|
-
const pluginResp:
|
|
517
|
+
const pluginResp: ConsoleCommandResponse = await this.automationBridge.sendAutomationRequest(
|
|
473
518
|
'console_command',
|
|
474
519
|
{ command: cmdTrimmed },
|
|
475
520
|
{ timeoutMs: 30000 }
|
|
476
521
|
);
|
|
477
522
|
|
|
478
523
|
if (pluginResp && pluginResp.success) {
|
|
479
|
-
return { ...
|
|
524
|
+
return { ...pluginResp, transport: 'automation_bridge' };
|
|
480
525
|
}
|
|
481
526
|
|
|
482
527
|
const errMsg = pluginResp?.message || pluginResp?.error || 'Plugin execution failed';
|
|
@@ -553,14 +598,14 @@ export class UnrealBridge {
|
|
|
553
598
|
|
|
554
599
|
const bridge = this.getAutomationBridge();
|
|
555
600
|
try {
|
|
556
|
-
const resp
|
|
601
|
+
const resp = await bridge.sendAutomationRequest(
|
|
557
602
|
'system_control',
|
|
558
603
|
{ action: 'get_engine_version' },
|
|
559
604
|
{ timeoutMs: 15000 }
|
|
560
605
|
);
|
|
561
|
-
const raw = resp && typeof resp.result === 'object'
|
|
562
|
-
? (resp.result as
|
|
563
|
-
: (resp?.result ?? resp ?? {}
|
|
606
|
+
const raw: EngineVersionResult = resp && typeof resp.result === 'object'
|
|
607
|
+
? (resp.result as Record<string, unknown>)
|
|
608
|
+
: (resp?.result as Record<string, unknown>) ?? resp ?? {};
|
|
564
609
|
const version = typeof raw.version === 'string' ? raw.version : 'unknown';
|
|
565
610
|
const major = typeof raw.major === 'number' ? raw.major : 0;
|
|
566
611
|
const minor = typeof raw.minor === 'number' ? raw.minor : 0;
|
|
@@ -596,16 +641,16 @@ export class UnrealBridge {
|
|
|
596
641
|
|
|
597
642
|
const bridge = this.getAutomationBridge();
|
|
598
643
|
try {
|
|
599
|
-
const resp
|
|
644
|
+
const resp = await bridge.sendAutomationRequest(
|
|
600
645
|
'system_control',
|
|
601
646
|
{ action: 'get_feature_flags' },
|
|
602
647
|
{ timeoutMs: 15000 }
|
|
603
648
|
);
|
|
604
649
|
const raw = resp && typeof resp.result === 'object'
|
|
605
|
-
? (resp.result as
|
|
606
|
-
: (resp?.result ?? resp ?? {}
|
|
607
|
-
const subs = raw && typeof raw.subsystems === 'object'
|
|
608
|
-
? (raw.subsystems as
|
|
650
|
+
? (resp.result as Record<string, unknown>)
|
|
651
|
+
: (resp?.result as Record<string, unknown>) ?? resp ?? {};
|
|
652
|
+
const subs: SubsystemFlags = raw && typeof raw.subsystems === 'object'
|
|
653
|
+
? (raw.subsystems as SubsystemFlags)
|
|
609
654
|
: {};
|
|
610
655
|
return {
|
|
611
656
|
subsystems: {
|
|
@@ -1,27 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates console commands before execution to prevent dangerous operations.
|
|
3
|
+
* Blocks crash-inducing commands, shell injection, and Python execution.
|
|
4
|
+
*/
|
|
1
5
|
export class CommandValidator {
|
|
6
|
+
/**
|
|
7
|
+
* Commands that can crash the engine or cause severe instability.
|
|
8
|
+
* These are blocked unconditionally.
|
|
9
|
+
*/
|
|
2
10
|
private static readonly DANGEROUS_COMMANDS = [
|
|
3
|
-
|
|
11
|
+
// Engine termination commands
|
|
12
|
+
'quit', 'exit', 'kill', 'crash',
|
|
13
|
+
// Crash-inducing commands
|
|
14
|
+
'r.gpucrash', 'r.crash', 'debug crash', 'forcecrash', 'debug break',
|
|
15
|
+
'assert false', 'check(false)',
|
|
16
|
+
// View buffer commands that can crash on some hardware
|
|
4
17
|
'viewmode visualizebuffer basecolor',
|
|
5
18
|
'viewmode visualizebuffer worldnormal',
|
|
6
|
-
|
|
7
|
-
'buildpaths',
|
|
8
|
-
|
|
19
|
+
// Heavy operations that can cause access violations if systems not initialized
|
|
20
|
+
'buildpaths', 'rebuildnavigation',
|
|
21
|
+
// Heavy debug commands that can stall or crash
|
|
22
|
+
'obj garbage', 'obj list', 'memreport',
|
|
23
|
+
// Potentially destructive without proper setup
|
|
24
|
+
'delete', 'destroy'
|
|
9
25
|
];
|
|
10
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Tokens that indicate shell injection or external system access attempts.
|
|
29
|
+
* Any command containing these is blocked.
|
|
30
|
+
*/
|
|
11
31
|
private static readonly FORBIDDEN_TOKENS = [
|
|
32
|
+
// Shell commands (Windows/Unix)
|
|
12
33
|
'rm ', 'rm-', 'del ', 'format ', 'shutdown', 'reboot',
|
|
13
34
|
'rmdir', 'mklink', 'copy ', 'move ', 'start "', 'system(',
|
|
35
|
+
// Python injection attempts
|
|
14
36
|
'import os', 'import subprocess', 'subprocess.', 'os.system',
|
|
15
37
|
'exec(', 'eval(', '__import__', 'import sys', 'import importlib',
|
|
16
|
-
'with open', 'open('
|
|
38
|
+
'with open', 'open(', 'write(', 'read('
|
|
17
39
|
];
|
|
18
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Patterns that indicate obviously invalid commands.
|
|
43
|
+
* Used to warn about likely typos or invalid input.
|
|
44
|
+
*/
|
|
19
45
|
private static readonly INVALID_PATTERNS = [
|
|
20
46
|
/^\d+$/, // Just numbers
|
|
21
47
|
/^invalid_command/i,
|
|
22
48
|
/^this_is_not_a_valid/i,
|
|
23
49
|
];
|
|
24
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Validates a console command for safety before execution.
|
|
53
|
+
* @param command - The console command string to validate
|
|
54
|
+
* @throws Error if the command is dangerous, contains forbidden tokens, or is invalid
|
|
55
|
+
*/
|
|
25
56
|
static validate(command: string): void {
|
|
26
57
|
if (!command || typeof command !== 'string') {
|
|
27
58
|
throw new Error('Invalid command: must be a non-empty string');
|
|
@@ -55,11 +86,22 @@ export class CommandValidator {
|
|
|
55
86
|
}
|
|
56
87
|
}
|
|
57
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Check if a command looks like an obviously invalid or mistyped command.
|
|
91
|
+
* @param command - The command to check
|
|
92
|
+
* @returns true if the command matches known invalid patterns
|
|
93
|
+
*/
|
|
58
94
|
static isLikelyInvalid(command: string): boolean {
|
|
59
95
|
const cmdTrimmed = command.trim();
|
|
60
96
|
return this.INVALID_PATTERNS.some(pattern => pattern.test(cmdTrimmed));
|
|
61
97
|
}
|
|
62
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Get the priority level of a command for throttling purposes.
|
|
101
|
+
* Lower numbers indicate heavier operations that need more throttling.
|
|
102
|
+
* @param command - The command to evaluate
|
|
103
|
+
* @returns Priority level (1=heavy, 5=medium, 7=default, 8-9=light)
|
|
104
|
+
*/
|
|
63
105
|
static getPriority(command: string): number {
|
|
64
106
|
if (command.includes('BuildLighting') || command.includes('BuildPaths')) {
|
|
65
107
|
return 1; // Heavy operation
|