@akiojin/unity-mcp-server 2.33.0 → 2.37.1
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/README.md +30 -5
- package/package.json +9 -4
- package/src/core/config.js +241 -242
- package/src/core/projectInfo.js +15 -0
- package/src/core/transports/HybridStdioServerTransport.js +78 -75
- package/src/handlers/addressables/AddressablesAnalyzeToolHandler.js +45 -47
- package/src/handlers/addressables/AddressablesBuildToolHandler.js +32 -33
- package/src/handlers/addressables/AddressablesManageToolHandler.js +74 -75
- package/src/handlers/component/ComponentFieldSetToolHandler.js +419 -419
- package/src/handlers/index.js +437 -437
- package/src/handlers/input/InputGamepadToolHandler.js +162 -0
- package/src/handlers/input/InputKeyboardToolHandler.js +127 -0
- package/src/handlers/input/InputMouseToolHandler.js +188 -0
- package/src/handlers/input/InputSystemControlToolHandler.js +63 -64
- package/src/handlers/input/InputTouchToolHandler.js +178 -0
- package/src/handlers/playmode/PlaymodePlayToolHandler.js +36 -23
- package/src/handlers/playmode/PlaymodeStopToolHandler.js +32 -21
- package/src/handlers/test/TestGetStatusToolHandler.js +37 -10
- package/src/handlers/test/TestRunToolHandler.js +36 -35
- package/src/lsp/LspProcessManager.js +18 -12
- package/src/utils/editorState.js +42 -0
- package/src/utils/testResultsCache.js +70 -0
- package/src/handlers/input/InputGamepadSimulateToolHandler.js +0 -116
- package/src/handlers/input/InputKeyboardSimulateToolHandler.js +0 -79
- package/src/handlers/input/InputMouseSimulateToolHandler.js +0 -107
- package/src/handlers/input/InputTouchSimulateToolHandler.js +0 -142
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
2
|
+
|
|
3
|
+
const actionProperties = {
|
|
4
|
+
action: {
|
|
5
|
+
type: 'string',
|
|
6
|
+
enum: ['button', 'stick', 'trigger', 'dpad'],
|
|
7
|
+
description: 'The gamepad action to perform'
|
|
8
|
+
},
|
|
9
|
+
button: {
|
|
10
|
+
type: 'string',
|
|
11
|
+
description: 'Button name (a/cross, b/circle, x/square, y/triangle, start, select, etc.)'
|
|
12
|
+
},
|
|
13
|
+
buttonAction: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
enum: ['press', 'release'],
|
|
16
|
+
description: 'Button action (press or release)'
|
|
17
|
+
},
|
|
18
|
+
stick: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
enum: ['left', 'right'],
|
|
21
|
+
description: 'Which analog stick to control'
|
|
22
|
+
},
|
|
23
|
+
x: {
|
|
24
|
+
type: 'number',
|
|
25
|
+
minimum: -1,
|
|
26
|
+
maximum: 1,
|
|
27
|
+
description: 'Horizontal axis value for stick (-1 to 1)'
|
|
28
|
+
},
|
|
29
|
+
y: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
minimum: -1,
|
|
32
|
+
maximum: 1,
|
|
33
|
+
description: 'Vertical axis value for stick (-1 to 1)'
|
|
34
|
+
},
|
|
35
|
+
trigger: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
enum: ['left', 'right'],
|
|
38
|
+
description: 'Which trigger to control'
|
|
39
|
+
},
|
|
40
|
+
value: {
|
|
41
|
+
type: 'number',
|
|
42
|
+
minimum: 0,
|
|
43
|
+
maximum: 1,
|
|
44
|
+
description: 'Trigger pressure value (0 to 1)'
|
|
45
|
+
},
|
|
46
|
+
direction: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
enum: ['up', 'down', 'left', 'right', 'none'],
|
|
49
|
+
description: 'D-pad direction'
|
|
50
|
+
},
|
|
51
|
+
holdSeconds: {
|
|
52
|
+
type: 'number',
|
|
53
|
+
minimum: 0,
|
|
54
|
+
description: 'Automatically reset stick/button/trigger/dpad after this many seconds'
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
function validateGamepadAction(params, context = 'action') {
|
|
59
|
+
if (!params || typeof params !== 'object') {
|
|
60
|
+
throw new Error(`${context} must be an object`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { action, button, x, y, value, direction, holdSeconds } = params;
|
|
64
|
+
|
|
65
|
+
if (!action) {
|
|
66
|
+
throw new Error(`${context}: action is required`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
switch (action) {
|
|
70
|
+
case 'button':
|
|
71
|
+
if (!button) {
|
|
72
|
+
throw new Error(`${context}: button is required for button action`);
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
case 'stick':
|
|
76
|
+
if (x === undefined || y === undefined) {
|
|
77
|
+
throw new Error(`${context}: x and y values are required for stick action`);
|
|
78
|
+
}
|
|
79
|
+
if (x < -1 || x > 1 || y < -1 || y > 1) {
|
|
80
|
+
throw new Error(`${context}: stick values must be between -1 and 1`);
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case 'trigger':
|
|
84
|
+
if (value === undefined) {
|
|
85
|
+
throw new Error(`${context}: value is required for trigger action`);
|
|
86
|
+
}
|
|
87
|
+
if (value < 0 || value > 1) {
|
|
88
|
+
throw new Error(`${context}: trigger value must be between 0 and 1`);
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
case 'dpad':
|
|
92
|
+
if (!direction) {
|
|
93
|
+
throw new Error(`${context}: direction is required for dpad action`);
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
throw new Error(`${context}: invalid action ${action}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (holdSeconds !== undefined && holdSeconds < 0) {
|
|
101
|
+
throw new Error(`${context}: holdSeconds must be zero or positive`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Handler for the input_gamepad tool
|
|
107
|
+
*/
|
|
108
|
+
export class InputGamepadToolHandler extends BaseToolHandler {
|
|
109
|
+
constructor(unityConnection) {
|
|
110
|
+
super(
|
|
111
|
+
'input_gamepad',
|
|
112
|
+
'Gamepad input (buttons/sticks/triggers/dpad) with batching and auto-hold.',
|
|
113
|
+
{
|
|
114
|
+
type: 'object',
|
|
115
|
+
properties: {
|
|
116
|
+
...actionProperties,
|
|
117
|
+
actions: {
|
|
118
|
+
type: 'array',
|
|
119
|
+
description: 'Batch multiple gamepad actions executed in order',
|
|
120
|
+
items: {
|
|
121
|
+
type: 'object',
|
|
122
|
+
properties: { ...actionProperties },
|
|
123
|
+
required: ['action']
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
anyOf: [{ required: ['action'] }, { required: ['actions'] }]
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
this.unityConnection = unityConnection;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
validate(params) {
|
|
134
|
+
const { actions } = params;
|
|
135
|
+
|
|
136
|
+
if (Array.isArray(actions)) {
|
|
137
|
+
if (actions.length === 0) {
|
|
138
|
+
throw new Error('actions must contain at least one entry');
|
|
139
|
+
}
|
|
140
|
+
actions.forEach((action, index) => validateGamepadAction(action, `actions[${index}]`));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (actions !== undefined && !Array.isArray(actions)) {
|
|
145
|
+
throw new Error('actions must be an array');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
validateGamepadAction(params);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async execute(params) {
|
|
152
|
+
if (!this.unityConnection.isConnected()) {
|
|
153
|
+
await this.unityConnection.connect();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const hasBatch = Array.isArray(params.actions) && params.actions.length > 0;
|
|
157
|
+
const payload = hasBatch ? { actions: params.actions } : params;
|
|
158
|
+
|
|
159
|
+
const result = await this.unityConnection.sendCommand('input_gamepad', payload);
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
2
|
+
|
|
3
|
+
const actionProperties = {
|
|
4
|
+
action: {
|
|
5
|
+
type: 'string',
|
|
6
|
+
enum: ['press', 'release', 'type', 'combo'],
|
|
7
|
+
description: 'The keyboard action to perform'
|
|
8
|
+
},
|
|
9
|
+
key: {
|
|
10
|
+
type: 'string',
|
|
11
|
+
description: 'The key to press/release (for press/release actions)'
|
|
12
|
+
},
|
|
13
|
+
keys: {
|
|
14
|
+
type: 'array',
|
|
15
|
+
items: { type: 'string' },
|
|
16
|
+
description: 'Array of keys for combo action'
|
|
17
|
+
},
|
|
18
|
+
text: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'Text to type (for type action)'
|
|
21
|
+
},
|
|
22
|
+
typingSpeed: {
|
|
23
|
+
type: 'number',
|
|
24
|
+
description: 'Milliseconds per character when typing'
|
|
25
|
+
},
|
|
26
|
+
holdSeconds: {
|
|
27
|
+
type: 'number',
|
|
28
|
+
minimum: 0,
|
|
29
|
+
description: 'Automatically release after this many seconds (press/combo)'
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function validateKeyboardAction(params, context = 'action') {
|
|
34
|
+
if (!params || typeof params !== 'object') {
|
|
35
|
+
throw new Error(`${context} must be an object`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const { action, key, keys, text, holdSeconds } = params;
|
|
39
|
+
|
|
40
|
+
if (!action) {
|
|
41
|
+
throw new Error(`${context}: action is required`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
switch (action) {
|
|
45
|
+
case 'press':
|
|
46
|
+
case 'release':
|
|
47
|
+
if (!key) {
|
|
48
|
+
throw new Error(`${context}: key is required for ${action} action`);
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case 'type':
|
|
52
|
+
if (!text) {
|
|
53
|
+
throw new Error(`${context}: text is required for type action`);
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
case 'combo':
|
|
57
|
+
if (!keys || !Array.isArray(keys) || keys.length === 0) {
|
|
58
|
+
throw new Error(`${context}: keys array is required for combo action`);
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`${context}: invalid action ${action}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (holdSeconds !== undefined && holdSeconds < 0) {
|
|
66
|
+
throw new Error(`${context}: holdSeconds must be zero or positive`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Handler for the input_keyboard tool
|
|
72
|
+
*/
|
|
73
|
+
export class InputKeyboardToolHandler extends BaseToolHandler {
|
|
74
|
+
constructor(unityConnection) {
|
|
75
|
+
super(
|
|
76
|
+
'input_keyboard',
|
|
77
|
+
'Keyboard input (press/release/type/combo) with batching and auto-hold.',
|
|
78
|
+
{
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {
|
|
81
|
+
...actionProperties,
|
|
82
|
+
actions: {
|
|
83
|
+
type: 'array',
|
|
84
|
+
description: 'Batch multiple keyboard actions executed in order',
|
|
85
|
+
items: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: { ...actionProperties },
|
|
88
|
+
required: ['action']
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
anyOf: [{ required: ['action'] }, { required: ['actions'] }]
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
this.unityConnection = unityConnection;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
validate(params) {
|
|
99
|
+
const { actions } = params;
|
|
100
|
+
|
|
101
|
+
if (Array.isArray(actions)) {
|
|
102
|
+
if (actions.length === 0) {
|
|
103
|
+
throw new Error('actions must contain at least one entry');
|
|
104
|
+
}
|
|
105
|
+
actions.forEach((action, index) => validateKeyboardAction(action, `actions[${index}]`));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (actions !== undefined && !Array.isArray(actions)) {
|
|
110
|
+
throw new Error('actions must be an array');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
validateKeyboardAction(params);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async execute(params) {
|
|
117
|
+
if (!this.unityConnection.isConnected()) {
|
|
118
|
+
await this.unityConnection.connect();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const hasBatch = Array.isArray(params.actions) && params.actions.length > 0;
|
|
122
|
+
const payload = hasBatch ? { actions: params.actions } : params;
|
|
123
|
+
|
|
124
|
+
const result = await this.unityConnection.sendCommand('input_keyboard', payload);
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
2
|
+
|
|
3
|
+
const actionProperties = {
|
|
4
|
+
action: {
|
|
5
|
+
type: 'string',
|
|
6
|
+
enum: ['move', 'click', 'drag', 'scroll', 'button'],
|
|
7
|
+
description: 'The mouse action to perform'
|
|
8
|
+
},
|
|
9
|
+
x: {
|
|
10
|
+
type: 'number',
|
|
11
|
+
description: 'X coordinate for move action'
|
|
12
|
+
},
|
|
13
|
+
y: {
|
|
14
|
+
type: 'number',
|
|
15
|
+
description: 'Y coordinate for move action'
|
|
16
|
+
},
|
|
17
|
+
absolute: {
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
description: 'Whether coordinates are absolute or relative (default: true)'
|
|
20
|
+
},
|
|
21
|
+
button: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
enum: ['left', 'right', 'middle'],
|
|
24
|
+
description: 'Mouse button for click/drag/button actions'
|
|
25
|
+
},
|
|
26
|
+
buttonAction: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
enum: ['press', 'release'],
|
|
29
|
+
description: 'Button action for button presses'
|
|
30
|
+
},
|
|
31
|
+
clickCount: {
|
|
32
|
+
type: 'number',
|
|
33
|
+
description: 'Number of clicks (for double/triple click)'
|
|
34
|
+
},
|
|
35
|
+
startX: {
|
|
36
|
+
type: 'number',
|
|
37
|
+
description: 'Start X for drag action'
|
|
38
|
+
},
|
|
39
|
+
startY: {
|
|
40
|
+
type: 'number',
|
|
41
|
+
description: 'Start Y for drag action'
|
|
42
|
+
},
|
|
43
|
+
endX: {
|
|
44
|
+
type: 'number',
|
|
45
|
+
description: 'End X for drag action'
|
|
46
|
+
},
|
|
47
|
+
endY: {
|
|
48
|
+
type: 'number',
|
|
49
|
+
description: 'End Y for drag action'
|
|
50
|
+
},
|
|
51
|
+
deltaX: {
|
|
52
|
+
type: 'number',
|
|
53
|
+
description: 'Horizontal scroll delta'
|
|
54
|
+
},
|
|
55
|
+
deltaY: {
|
|
56
|
+
type: 'number',
|
|
57
|
+
description: 'Vertical scroll delta'
|
|
58
|
+
},
|
|
59
|
+
holdSeconds: {
|
|
60
|
+
type: 'number',
|
|
61
|
+
minimum: 0,
|
|
62
|
+
description: 'Automatically release button after this many seconds'
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
function validateMouseAction(params, context = 'action') {
|
|
67
|
+
if (!params || typeof params !== 'object') {
|
|
68
|
+
throw new Error(`${context} must be an object`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const {
|
|
72
|
+
action,
|
|
73
|
+
x,
|
|
74
|
+
y,
|
|
75
|
+
startX,
|
|
76
|
+
startY,
|
|
77
|
+
endX,
|
|
78
|
+
endY,
|
|
79
|
+
button,
|
|
80
|
+
buttonAction,
|
|
81
|
+
holdSeconds,
|
|
82
|
+
deltaX,
|
|
83
|
+
deltaY
|
|
84
|
+
} = params;
|
|
85
|
+
|
|
86
|
+
if (!action) {
|
|
87
|
+
throw new Error(`${context}: action is required`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
switch (action) {
|
|
91
|
+
case 'move':
|
|
92
|
+
if (x === undefined || y === undefined) {
|
|
93
|
+
throw new Error(`${context}: x and y coordinates are required for move action`);
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
case 'drag':
|
|
97
|
+
if (
|
|
98
|
+
startX === undefined ||
|
|
99
|
+
startY === undefined ||
|
|
100
|
+
endX === undefined ||
|
|
101
|
+
endY === undefined
|
|
102
|
+
) {
|
|
103
|
+
throw new Error(`${context}: startX, startY, endX, and endY are required for drag action`);
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
case 'click':
|
|
107
|
+
// button optional (defaults to left)
|
|
108
|
+
break;
|
|
109
|
+
case 'scroll':
|
|
110
|
+
if (deltaX === undefined && deltaY === undefined) {
|
|
111
|
+
throw new Error(`${context}: deltaX or deltaY is required for scroll action`);
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
case 'button':
|
|
115
|
+
if (!button) {
|
|
116
|
+
throw new Error(`${context}: button is required for button action`);
|
|
117
|
+
}
|
|
118
|
+
if (!buttonAction) {
|
|
119
|
+
throw new Error(`${context}: buttonAction is required for button action`);
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
default:
|
|
123
|
+
throw new Error(`${context}: invalid action ${action}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (holdSeconds !== undefined && holdSeconds < 0) {
|
|
127
|
+
throw new Error(`${context}: holdSeconds must be zero or positive`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Handler for the input_mouse tool
|
|
133
|
+
*/
|
|
134
|
+
export class InputMouseToolHandler extends BaseToolHandler {
|
|
135
|
+
constructor(unityConnection) {
|
|
136
|
+
super(
|
|
137
|
+
'input_mouse',
|
|
138
|
+
'Mouse input (move/click/drag/scroll/button) with batching and auto-hold.',
|
|
139
|
+
{
|
|
140
|
+
type: 'object',
|
|
141
|
+
properties: {
|
|
142
|
+
...actionProperties,
|
|
143
|
+
actions: {
|
|
144
|
+
type: 'array',
|
|
145
|
+
description: 'Batch multiple mouse actions executed in order',
|
|
146
|
+
items: {
|
|
147
|
+
type: 'object',
|
|
148
|
+
properties: { ...actionProperties },
|
|
149
|
+
required: ['action']
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
anyOf: [{ required: ['action'] }, { required: ['actions'] }]
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
this.unityConnection = unityConnection;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
validate(params) {
|
|
160
|
+
const { actions } = params;
|
|
161
|
+
|
|
162
|
+
if (Array.isArray(actions)) {
|
|
163
|
+
if (actions.length === 0) {
|
|
164
|
+
throw new Error('actions must contain at least one entry');
|
|
165
|
+
}
|
|
166
|
+
actions.forEach((action, index) => validateMouseAction(action, `actions[${index}]`));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (actions !== undefined && !Array.isArray(actions)) {
|
|
171
|
+
throw new Error('actions must be an array');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
validateMouseAction(params);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async execute(params) {
|
|
178
|
+
if (!this.unityConnection.isConnected()) {
|
|
179
|
+
await this.unityConnection.connect();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const hasBatch = Array.isArray(params.actions) && params.actions.length > 0;
|
|
183
|
+
const payload = hasBatch ? { actions: params.actions } : params;
|
|
184
|
+
|
|
185
|
+
const result = await this.unityConnection.sendCommand('input_mouse', payload);
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -4,77 +4,76 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
|
4
4
|
* Handler for the input_system_control tool
|
|
5
5
|
*/
|
|
6
6
|
export class InputSystemControlToolHandler extends BaseToolHandler {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
parameters: {
|
|
20
|
-
type: 'object',
|
|
21
|
-
description: 'Parameters for the specific operation'
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
required: ['operation']
|
|
25
|
-
}
|
|
26
|
-
);
|
|
27
|
-
this.unityConnection = unityConnection;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
validate(params) {
|
|
31
|
-
const { operation, parameters } = params;
|
|
32
|
-
|
|
33
|
-
if (!operation) {
|
|
34
|
-
throw new Error('operation is required');
|
|
7
|
+
constructor(unityConnection) {
|
|
8
|
+
super('input_system_control', 'Main handler for Input System operations', {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
operation: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
enum: ['keyboard', 'mouse', 'gamepad', 'touch', 'sequence', 'get_state'],
|
|
14
|
+
description: 'The input operation to perform'
|
|
15
|
+
},
|
|
16
|
+
parameters: {
|
|
17
|
+
type: 'object',
|
|
18
|
+
description: 'Parameters for the specific operation'
|
|
35
19
|
}
|
|
20
|
+
},
|
|
21
|
+
required: ['operation']
|
|
22
|
+
});
|
|
23
|
+
this.unityConnection = unityConnection;
|
|
24
|
+
}
|
|
36
25
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
throw new Error(`Invalid operation: ${operation}. Must be one of: ${validOperations.join(', ')}`);
|
|
40
|
-
}
|
|
26
|
+
validate(params) {
|
|
27
|
+
const { operation, parameters } = params;
|
|
41
28
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
throw new Error(`parameters are required for operation: ${operation}`);
|
|
45
|
-
}
|
|
29
|
+
if (!operation) {
|
|
30
|
+
throw new Error('operation is required');
|
|
46
31
|
}
|
|
47
32
|
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
const validOperations = ['keyboard', 'mouse', 'gamepad', 'touch', 'sequence', 'get_state'];
|
|
34
|
+
if (!validOperations.includes(operation)) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Invalid operation: ${operation}. Must be one of: ${validOperations.join(', ')}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
50
39
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
40
|
+
// Operation-specific validation
|
|
41
|
+
if (operation !== 'get_state' && !parameters) {
|
|
42
|
+
throw new Error(`parameters are required for operation: ${operation}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
55
45
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
case 'keyboard':
|
|
59
|
-
command = 'simulate_keyboard_input';
|
|
60
|
-
break;
|
|
61
|
-
case 'mouse':
|
|
62
|
-
command = 'simulate_mouse_input';
|
|
63
|
-
break;
|
|
64
|
-
case 'gamepad':
|
|
65
|
-
command = 'simulate_gamepad_input';
|
|
66
|
-
break;
|
|
67
|
-
case 'touch':
|
|
68
|
-
command = 'simulate_touch_input';
|
|
69
|
-
break;
|
|
70
|
-
case 'sequence':
|
|
71
|
-
command = 'create_input_sequence';
|
|
72
|
-
break;
|
|
73
|
-
case 'get_state':
|
|
74
|
-
command = 'get_current_input_state';
|
|
75
|
-
break; }
|
|
46
|
+
async execute(params) {
|
|
47
|
+
const { operation, parameters = {} } = params;
|
|
76
48
|
|
|
77
|
-
|
|
78
|
-
|
|
49
|
+
// Ensure connected
|
|
50
|
+
if (!this.unityConnection.isConnected()) {
|
|
51
|
+
await this.unityConnection.connect();
|
|
79
52
|
}
|
|
53
|
+
|
|
54
|
+
let command;
|
|
55
|
+
switch (operation) {
|
|
56
|
+
case 'keyboard':
|
|
57
|
+
command = 'input_keyboard';
|
|
58
|
+
break;
|
|
59
|
+
case 'mouse':
|
|
60
|
+
command = 'input_mouse';
|
|
61
|
+
break;
|
|
62
|
+
case 'gamepad':
|
|
63
|
+
command = 'input_gamepad';
|
|
64
|
+
break;
|
|
65
|
+
case 'touch':
|
|
66
|
+
command = 'input_touch';
|
|
67
|
+
break;
|
|
68
|
+
case 'sequence':
|
|
69
|
+
command = 'create_input_sequence';
|
|
70
|
+
break;
|
|
71
|
+
case 'get_state':
|
|
72
|
+
command = 'get_current_input_state';
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const result = await this.unityConnection.sendCommand(command, parameters);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
80
79
|
}
|