@maaxyz/maa-node 0.0.1-alpha.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.
Files changed (105) hide show
  1. package/agent/maatouch/universal/maatouch +0 -0
  2. package/agent/minicap/arm64-v8a/bin/minicap +0 -0
  3. package/agent/minicap/arm64-v8a/bin/minicap-nopie +0 -0
  4. package/agent/minicap/arm64-v8a/lib/android-21/minicap.so +0 -0
  5. package/agent/minicap/arm64-v8a/lib/android-22/minicap.so +0 -0
  6. package/agent/minicap/arm64-v8a/lib/android-23/minicap.so +0 -0
  7. package/agent/minicap/arm64-v8a/lib/android-24/minicap.so +0 -0
  8. package/agent/minicap/arm64-v8a/lib/android-25/minicap.so +0 -0
  9. package/agent/minicap/arm64-v8a/lib/android-26/minicap.so +0 -0
  10. package/agent/minicap/arm64-v8a/lib/android-27/minicap.so +0 -0
  11. package/agent/minicap/arm64-v8a/lib/android-28/minicap.so +0 -0
  12. package/agent/minicap/arm64-v8a/lib/android-29/minicap +0 -0
  13. package/agent/minicap/arm64-v8a/lib/android-29/minicap-nopie +0 -0
  14. package/agent/minicap/arm64-v8a/lib/android-29/minicap.so +0 -0
  15. package/agent/minicap/arm64-v8a/lib/android-30/minicap.so +0 -0
  16. package/agent/minicap/arm64-v8a/lib/android-31/minicap.so +0 -0
  17. package/agent/minicap/armeabi-v7a/bin/minicap +0 -0
  18. package/agent/minicap/armeabi-v7a/bin/minicap-nopie +0 -0
  19. package/agent/minicap/armeabi-v7a/lib/android-10/minicap.so +0 -0
  20. package/agent/minicap/armeabi-v7a/lib/android-14/minicap.so +0 -0
  21. package/agent/minicap/armeabi-v7a/lib/android-15/minicap.so +0 -0
  22. package/agent/minicap/armeabi-v7a/lib/android-16/minicap.so +0 -0
  23. package/agent/minicap/armeabi-v7a/lib/android-17/minicap.so +0 -0
  24. package/agent/minicap/armeabi-v7a/lib/android-18/minicap.so +0 -0
  25. package/agent/minicap/armeabi-v7a/lib/android-19/minicap.so +0 -0
  26. package/agent/minicap/armeabi-v7a/lib/android-21/minicap.so +0 -0
  27. package/agent/minicap/armeabi-v7a/lib/android-22/minicap.so +0 -0
  28. package/agent/minicap/armeabi-v7a/lib/android-23/minicap.so +0 -0
  29. package/agent/minicap/armeabi-v7a/lib/android-24/minicap.so +0 -0
  30. package/agent/minicap/armeabi-v7a/lib/android-25/minicap.so +0 -0
  31. package/agent/minicap/armeabi-v7a/lib/android-26/minicap.so +0 -0
  32. package/agent/minicap/armeabi-v7a/lib/android-27/minicap.so +0 -0
  33. package/agent/minicap/armeabi-v7a/lib/android-28/minicap.so +0 -0
  34. package/agent/minicap/armeabi-v7a/lib/android-29/minicap +0 -0
  35. package/agent/minicap/armeabi-v7a/lib/android-29/minicap-nopie +0 -0
  36. package/agent/minicap/armeabi-v7a/lib/android-29/minicap.so +0 -0
  37. package/agent/minicap/armeabi-v7a/lib/android-30/minicap.so +0 -0
  38. package/agent/minicap/armeabi-v7a/lib/android-31/minicap.so +0 -0
  39. package/agent/minicap/armeabi-v7a/lib/android-9/minicap.so +0 -0
  40. package/agent/minicap/x86/bin/minicap +0 -0
  41. package/agent/minicap/x86/bin/minicap-nopie +0 -0
  42. package/agent/minicap/x86/lib/android-14/minicap.so +0 -0
  43. package/agent/minicap/x86/lib/android-15/minicap.so +0 -0
  44. package/agent/minicap/x86/lib/android-16/minicap.so +0 -0
  45. package/agent/minicap/x86/lib/android-17/minicap.so +0 -0
  46. package/agent/minicap/x86/lib/android-18/minicap.so +0 -0
  47. package/agent/minicap/x86/lib/android-19/minicap.so +0 -0
  48. package/agent/minicap/x86/lib/android-21/minicap.so +0 -0
  49. package/agent/minicap/x86/lib/android-22/minicap.so +0 -0
  50. package/agent/minicap/x86/lib/android-23/minicap.so +0 -0
  51. package/agent/minicap/x86/lib/android-24/minicap.so +0 -0
  52. package/agent/minicap/x86/lib/android-25/minicap.so +0 -0
  53. package/agent/minicap/x86/lib/android-26/minicap.so +0 -0
  54. package/agent/minicap/x86/lib/android-27/minicap.so +0 -0
  55. package/agent/minicap/x86/lib/android-28/minicap.so +0 -0
  56. package/agent/minicap/x86/lib/android-29/minicap +0 -0
  57. package/agent/minicap/x86/lib/android-29/minicap-nopie +0 -0
  58. package/agent/minicap/x86/lib/android-29/minicap.so +0 -0
  59. package/agent/minicap/x86/lib/android-31/minicap.so +0 -0
  60. package/agent/minicap/x86_64/bin/minicap +0 -0
  61. package/agent/minicap/x86_64/bin/minicap-nopie +0 -0
  62. package/agent/minicap/x86_64/lib/android-21/minicap.so +0 -0
  63. package/agent/minicap/x86_64/lib/android-22/minicap.so +0 -0
  64. package/agent/minicap/x86_64/lib/android-23/minicap.so +0 -0
  65. package/agent/minicap/x86_64/lib/android-24/minicap.so +0 -0
  66. package/agent/minicap/x86_64/lib/android-25/minicap.so +0 -0
  67. package/agent/minicap/x86_64/lib/android-26/minicap.so +0 -0
  68. package/agent/minicap/x86_64/lib/android-27/minicap.so +0 -0
  69. package/agent/minicap/x86_64/lib/android-28/minicap.so +0 -0
  70. package/agent/minicap/x86_64/lib/android-29/minicap +0 -0
  71. package/agent/minicap/x86_64/lib/android-29/minicap-nopie +0 -0
  72. package/agent/minicap/x86_64/lib/android-29/minicap.so +0 -0
  73. package/agent/minicap/x86_64/lib/android-31/minicap.so +0 -0
  74. package/agent/minitouch/arm64-v8a/minitouch +0 -0
  75. package/agent/minitouch/armeabi/minitouch +0 -0
  76. package/agent/minitouch/armeabi-v7a/minitouch +0 -0
  77. package/agent/minitouch/x86/minitouch +0 -0
  78. package/agent/minitouch/x86_64/minitouch +0 -0
  79. package/dist/context.d.ts +52 -0
  80. package/dist/controller.d.ts +105 -0
  81. package/dist/global.d.ts +10 -0
  82. package/dist/index.d.ts +9 -0
  83. package/dist/index.js +1028 -0
  84. package/dist/job.d.ts +23 -0
  85. package/dist/maa.d.ts +376 -0
  86. package/dist/pi.d.ts +9 -0
  87. package/dist/pipeline.d.ts +249 -0
  88. package/dist/resource.d.ts +36 -0
  89. package/dist/tasker.d.ts +128 -0
  90. package/dist/types.d.ts +27 -0
  91. package/package.json +33 -0
  92. package/scripts/build.mjs +20 -0
  93. package/src/context.ts +78 -0
  94. package/src/controller.ts +366 -0
  95. package/src/global.ts +49 -0
  96. package/src/index.ts +9 -0
  97. package/src/job.ts +68 -0
  98. package/src/maa.d.ts +376 -0
  99. package/src/maa.js +27 -0
  100. package/src/pi.ts +62 -0
  101. package/src/pipeline.ts +694 -0
  102. package/src/resource.ts +173 -0
  103. package/src/tasker.ts +231 -0
  104. package/src/types.ts +31 -0
  105. package/tsconfig.json +9 -0
@@ -0,0 +1,36 @@
1
+ import { Job, JobSource } from './job';
2
+ import maa from './maa';
3
+ import { CustomActionCallback, CustomRecognizerCallback } from './types';
4
+ export type ResourceNotify = {
5
+ res_id: maa.ResId;
6
+ path: string;
7
+ } & ({
8
+ msg: 'StartLoading';
9
+ } | {
10
+ msg: 'LoadingCompleted' | 'LoadingFailed';
11
+ hash: string;
12
+ });
13
+ export declare class ResourceBase {
14
+ #private;
15
+ handle: maa.ResourceHandle;
16
+ notify(message: string, details_json: string): maa.MaybePromise<void>;
17
+ set parsed_notify(cb: (msg: ResourceNotify) => maa.MaybePromise<void>);
18
+ constructor(handle: maa.ResourceHandle);
19
+ destroy(): void;
20
+ set inference_device(id: keyof typeof maa.InferenceDevice | number);
21
+ set inference_execution_provider(provider: keyof typeof maa.InferenceExecutionProvider);
22
+ register_custom_recognizer(name: string, func: CustomRecognizerCallback): void;
23
+ unregister_custom_recognizer(name: string): void;
24
+ clear_custom_recognizer(): void;
25
+ register_custom_action(name: string, func: CustomActionCallback): void;
26
+ unregister_custom_action(name: string): void;
27
+ clear_custom_action(): void;
28
+ post_path(path: string): Job<maa.ResId, JobSource<maa.ResId>>;
29
+ clear(): void;
30
+ get loaded(): boolean;
31
+ get hash(): string | null;
32
+ get task_list(): string[] | null;
33
+ }
34
+ export declare class Resource extends ResourceBase {
35
+ constructor();
36
+ }
@@ -0,0 +1,128 @@
1
+ import { ControllerBase } from './controller';
2
+ import { Job, JobSource } from './job';
3
+ import maa from './maa';
4
+ import { ResourceBase } from './resource';
5
+ type TaskDetail = ReturnType<TaskerBase['task_detail']>;
6
+ declare class TaskJob extends Job<maa.TaskId, JobSource<maa.TaskId>> {
7
+ #private;
8
+ constructor(tasker: TaskerBase, source: JobSource<maa.TaskId>, id: maa.TaskId);
9
+ get(): {
10
+ entry: string;
11
+ nodes: ({
12
+ name: string;
13
+ reco: {
14
+ name: string;
15
+ algorithm: string;
16
+ hit: boolean;
17
+ box: maa.Rect;
18
+ detail: string;
19
+ raw: ArrayBuffer;
20
+ draws: ArrayBuffer[];
21
+ } | null;
22
+ completed: boolean;
23
+ } | null)[];
24
+ status: maa.Status;
25
+ } | null;
26
+ wait(): Promise<this> & {
27
+ status: Promise<maa.Status>;
28
+ done: Promise<boolean>;
29
+ succeeded: Promise<boolean>;
30
+ failed: Promise<boolean>;
31
+ } & {
32
+ get: () => Promise<TaskDetail>;
33
+ };
34
+ }
35
+ export type TaskerNotify = {
36
+ task_id: maa.TaskId;
37
+ entry: string;
38
+ hash: string;
39
+ uuid: string;
40
+ } & ({
41
+ msg: 'Task.Started' | 'Task.Completed' | 'Task.Failed';
42
+ } | {
43
+ msg: 'Debug.RecognitionResult' | 'Debug.Hit';
44
+ current: string;
45
+ recognition: {
46
+ reco_id: maa.RecoId;
47
+ name: string;
48
+ /**
49
+ * Won't be `null` for msg `Debug.Hit`
50
+ */
51
+ box: maa.FlatRect | null;
52
+ detail: string;
53
+ };
54
+ } | {
55
+ msg: 'Focus.ReadyToRun' | 'Focus.Completed' | 'Debug.ReadyToRun' | 'Debug.Completed';
56
+ current: string;
57
+ node: {
58
+ node_id: maa.NodeId;
59
+ name: string;
60
+ reco_id: maa.RecoId;
61
+ times: number;
62
+ completed: boolean;
63
+ };
64
+ } | {
65
+ msg: 'Debug.ListToRecognize' | 'Debug.MissAll';
66
+ current: string;
67
+ list: string[];
68
+ });
69
+ export declare class TaskerBase {
70
+ #private;
71
+ handle: maa.TaskerHandle;
72
+ notify(message: string, details_json: string): maa.MaybePromise<void>;
73
+ set parsed_notify(cb: (msg: TaskerNotify) => maa.MaybePromise<void>);
74
+ constructor(handle: maa.TaskerHandle);
75
+ destroy(): void;
76
+ bind(slave: ControllerBase | ResourceBase): void;
77
+ post_pipeline(entry: string, param?: Record<string, unknown>): TaskJob;
78
+ get inited(): boolean;
79
+ get running(): boolean;
80
+ post_stop(): TaskJob;
81
+ get resource(): ResourceBase | null;
82
+ get controller(): ControllerBase | null;
83
+ clear_cache(): void;
84
+ recognition_detail(id: maa.RecoId): {
85
+ name: string;
86
+ algorithm: string;
87
+ hit: boolean;
88
+ box: maa.Rect;
89
+ detail: string;
90
+ raw: ArrayBuffer;
91
+ draws: ArrayBuffer[];
92
+ } | null;
93
+ node_detail(id: maa.NodeId): {
94
+ name: string;
95
+ reco: {
96
+ name: string;
97
+ algorithm: string;
98
+ hit: boolean;
99
+ box: maa.Rect;
100
+ detail: string;
101
+ raw: ArrayBuffer;
102
+ draws: ArrayBuffer[];
103
+ } | null;
104
+ completed: boolean;
105
+ } | null;
106
+ task_detail(id: maa.TaskId): {
107
+ entry: string;
108
+ nodes: ({
109
+ name: string;
110
+ reco: {
111
+ name: string;
112
+ algorithm: string;
113
+ hit: boolean;
114
+ box: maa.Rect;
115
+ detail: string;
116
+ raw: ArrayBuffer;
117
+ draws: ArrayBuffer[];
118
+ } | null;
119
+ completed: boolean;
120
+ } | null)[];
121
+ status: maa.Status;
122
+ } | null;
123
+ latest_node(task: string): maa.NodeId | null;
124
+ }
125
+ export declare class Tasker extends TaskerBase {
126
+ constructor();
127
+ }
128
+ export {};
@@ -0,0 +1,27 @@
1
+ import { Context } from './context';
2
+ import maa from './maa';
3
+ export interface CustomRecognizerSelf {
4
+ context: Context;
5
+ id: maa.TaskId;
6
+ task: string;
7
+ name: string;
8
+ param: unknown;
9
+ image: maa.ImageData;
10
+ roi: maa.Rect;
11
+ }
12
+ export interface CustomActionSelf {
13
+ context: Context;
14
+ id: maa.TaskId;
15
+ task: string;
16
+ name: string;
17
+ param: unknown;
18
+ recoId: maa.RecoId;
19
+ box: maa.Rect;
20
+ }
21
+ type CustomCallback<Self, Ret> = (this: Self, self: Self) => maa.MaybePromise<Ret>;
22
+ export type CustomRecognizerCallback = CustomCallback<CustomRecognizerSelf, [
23
+ out_box: maa.Rect,
24
+ out_detail: string
25
+ ] | null>;
26
+ export type CustomActionCallback = CustomCallback<CustomActionSelf, boolean>;
27
+ export {};
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@maaxyz/maa-node",
3
+ "author": "nekosu",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/index.d.ts",
6
+ "scripts": {
7
+ "build": "node scripts/build.mjs && tsc"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git://github.com/MaaXYZ/MaaFramework.git"
12
+ },
13
+ "engines": {
14
+ "node": ">= 20.0.0"
15
+ },
16
+ "devDependencies": {
17
+ "@trivago/prettier-plugin-sort-imports": "^4.3.0",
18
+ "@tsconfig/node20": "^20.1.4",
19
+ "@types/node": "^20",
20
+ "esbuild": "^0.21.5",
21
+ "prettier": "^3.3.2",
22
+ "typescript": "^5.4.5"
23
+ },
24
+ "version": "0.0.1-alpha.2",
25
+ "optionalDependencies": {
26
+ "@maaxyz/maa-node-darwin-arm64": "0.0.1-alpha.2",
27
+ "@maaxyz/maa-node-darwin-x64": "0.0.1-alpha.2",
28
+ "@maaxyz/maa-node-linux-arm64": "0.0.1-alpha.2",
29
+ "@maaxyz/maa-node-linux-x64": "0.0.1-alpha.2",
30
+ "@maaxyz/maa-node-win32-arm64": "0.0.1-alpha.2",
31
+ "@maaxyz/maa-node-win32-x64": "0.0.1-alpha.2"
32
+ }
33
+ }
@@ -0,0 +1,20 @@
1
+ import { build } from 'esbuild'
2
+ import { copyFileSync, mkdirSync } from 'fs'
3
+
4
+ build({
5
+ entryPoints: ['src/index.ts'],
6
+ outdir: 'dist',
7
+ platform: 'node',
8
+ external: [
9
+ '@maaxyz/maa-node-win32-x64',
10
+ '@maaxyz/maa-node-win32-arm64',
11
+ '@maaxyz/maa-node-linux-x64',
12
+ '@maaxyz/maa-node-linux-arm64',
13
+ '@maaxyz/maa-node-darwin-x64',
14
+ '@maaxyz/maa-node-darwin-arm64'
15
+ ],
16
+ bundle: true
17
+ })
18
+
19
+ mkdirSync('dist', { recursive: true })
20
+ copyFileSync('src/maa.d.ts', 'dist/maa.d.ts')
package/src/context.ts ADDED
@@ -0,0 +1,78 @@
1
+ import * as maa from './maa'
2
+ import { TaskerBase } from './tasker'
3
+
4
+ export class Context {
5
+ handle: maa.ContextHandle
6
+ #tasker: TaskerBase
7
+
8
+ constructor(handle: maa.ContextHandle) {
9
+ this.handle = handle
10
+ this.#tasker = new TaskerBase(maa.context_get_tasker(this.handle))
11
+ }
12
+
13
+ async run_pipeline(entry: string, pipeline_override: Record<string, unknown> = {}) {
14
+ const id = await maa.context_run_pipeline(
15
+ this.handle,
16
+ entry,
17
+ JSON.stringify(pipeline_override)
18
+ )
19
+ return this.#tasker.task_detail(id)
20
+ }
21
+
22
+ async run_recognition(
23
+ entry: string,
24
+ image: ArrayBuffer | Buffer,
25
+ pipeline_override: Record<string, unknown> = {}
26
+ ) {
27
+ if (image instanceof Buffer) {
28
+ image = image.buffer
29
+ }
30
+ const id = await maa.context_run_recognition(
31
+ this.handle,
32
+ entry,
33
+ JSON.stringify(pipeline_override),
34
+ image
35
+ )
36
+ return this.#tasker.recognition_detail(id)
37
+ }
38
+
39
+ async run_action(
40
+ entry: string,
41
+ box: maa.Rect,
42
+ reco_detail: string,
43
+ pipeline_override: Record<string, unknown> = {}
44
+ ) {
45
+ const id = await maa.context_run_action(
46
+ this.handle,
47
+ entry,
48
+ JSON.stringify(pipeline_override),
49
+ box,
50
+ reco_detail
51
+ )
52
+ return this.#tasker.node_detail(id)
53
+ }
54
+
55
+ override_pipeline(pipeline_override: Record<string, unknown>) {
56
+ if (!maa.context_override_pipeline(this.handle, JSON.stringify(pipeline_override))) {
57
+ throw 'Context override_pipeline failed'
58
+ }
59
+ }
60
+
61
+ override_next(name: string, next: string[]) {
62
+ if (!maa.context_override_next(this.handle, name, next)) {
63
+ throw 'Context override_next failed'
64
+ }
65
+ }
66
+
67
+ get task_id() {
68
+ return maa.context_get_task_id(this.handle)
69
+ }
70
+
71
+ get tasker() {
72
+ return this.#tasker
73
+ }
74
+
75
+ clone() {
76
+ return new Context(maa.context_clone(this.handle))
77
+ }
78
+ }
@@ -0,0 +1,366 @@
1
+ import path from 'path'
2
+
3
+ import { Job, JobSource } from './job'
4
+ import maa, { ImageData } from './maa'
5
+
6
+ class ImageJob extends Job<maa.CtrlId, JobSource<maa.CtrlId>> {
7
+ #ctrl: ControllerBase
8
+
9
+ constructor(ctrl: ControllerBase, source: JobSource<maa.CtrlId>, id: maa.CtrlId) {
10
+ super(source, id)
11
+
12
+ this.#ctrl = ctrl
13
+ }
14
+
15
+ get() {
16
+ if (this.done) {
17
+ return this.#ctrl.cached_image
18
+ } else {
19
+ return null
20
+ }
21
+ }
22
+
23
+ wait() {
24
+ const superPro = super.wait()
25
+ const pro = superPro as typeof superPro & {
26
+ get: () => Promise<ArrayBuffer | null>
27
+ }
28
+ pro.get = () => {
29
+ return new Promise(resolve => {
30
+ pro.then(self => {
31
+ resolve(self.get())
32
+ })
33
+ })
34
+ }
35
+ return pro
36
+ }
37
+ }
38
+
39
+ export type ControllerNotify =
40
+ | ({
41
+ adb: string
42
+ address: string
43
+ } & (
44
+ | {
45
+ msg: 'UUIDGot'
46
+ uuid: string
47
+ }
48
+ | {
49
+ msg: 'UUIDGetFailed'
50
+ }
51
+ | {
52
+ msg: 'ConnectSuccess'
53
+ }
54
+ | {
55
+ msg: 'ConnectFailed'
56
+ why: 'ConnectFailed' | 'UUIDGetFailed'
57
+ }
58
+ | {
59
+ msg:
60
+ | 'ScreencapInited'
61
+ | 'ScreencapInitFailed'
62
+ | 'TouchinputInited'
63
+ | 'TouchinputInitFailed'
64
+ }
65
+ ))
66
+ | {
67
+ msg: 'Action.Started' | 'Action.Completed' | 'Action.Failed'
68
+ ctrl_id: maa.CtrlId
69
+ uuid: string
70
+ }
71
+
72
+ export class ControllerBase {
73
+ handle: maa.ControllerHandle
74
+ #source: JobSource<maa.CtrlId>
75
+
76
+ notify(message: string, details_json: string): maa.MaybePromise<void> {}
77
+
78
+ set parsed_notify(cb: (msg: ControllerNotify) => maa.MaybePromise<void>) {
79
+ this.notify = (msg, details) => {
80
+ return cb({
81
+ msg: msg.replace(/^Controller\./, '') as any,
82
+ ...JSON.parse(details)
83
+ })
84
+ }
85
+ }
86
+
87
+ constructor(handle: maa.ControllerHandle) {
88
+ this.handle = handle
89
+ this.#source = {
90
+ status: id => maa.controller_status(this.handle, id),
91
+ wait: id => maa.controller_wait(this.handle, id)
92
+ }
93
+ }
94
+
95
+ destroy() {
96
+ maa.controller_destroy(this.handle)
97
+ }
98
+
99
+ set screenshot_target_long_side(value: number) {
100
+ if (!maa.controller_set_option_screenshot_target_long_side(this.handle, value)) {
101
+ throw 'Controller set screenshot_target_long_side failed'
102
+ }
103
+ }
104
+
105
+ set screenshot_target_short_side(value: number) {
106
+ if (!maa.controller_set_option_screenshot_target_short_side(this.handle, value)) {
107
+ throw 'Controller set screenshot_target_short_side failed'
108
+ }
109
+ }
110
+
111
+ set screenshot_use_raw_size(value: boolean) {
112
+ if (!maa.controller_set_option_screenshot_use_raw_size(this.handle, value)) {
113
+ throw 'Controller set screenshot_use_raw_size failed'
114
+ }
115
+ }
116
+
117
+ set recording(value: boolean) {
118
+ if (!maa.controller_set_option_recording(this.handle, value)) {
119
+ throw 'Controller set recording failed'
120
+ }
121
+ }
122
+
123
+ post_connection() {
124
+ return new Job(this.#source, maa.controller_post_connection(this.handle))
125
+ }
126
+
127
+ post_click(x: number, y: number) {
128
+ return new Job(this.#source, maa.controller_post_click(this.handle, x, y))
129
+ }
130
+
131
+ post_swipe(x1: number, y1: number, x2: number, y2: number, duration: number) {
132
+ return new Job(
133
+ this.#source,
134
+ maa.controller_post_swipe(this.handle, x1, y1, x2, y2, duration)
135
+ )
136
+ }
137
+
138
+ post_press_key(keycode: number) {
139
+ return new Job(this.#source, maa.controller_post_press_key(this.handle, keycode))
140
+ }
141
+
142
+ post_input_text(text: string) {
143
+ return new Job(this.#source, maa.controller_post_input_text(this.handle, text))
144
+ }
145
+
146
+ post_start_app(intent: string) {
147
+ return new Job(this.#source, maa.controller_post_start_app(this.handle, intent))
148
+ }
149
+
150
+ post_stop_app(intent: string) {
151
+ return new Job(this.#source, maa.controller_post_stop_app(this.handle, intent))
152
+ }
153
+
154
+ post_touch_down(contact: number, x: number, y: number, pressure: number) {
155
+ return new Job(
156
+ this.#source,
157
+ maa.controller_post_touch_down(this.handle, contact, x, y, pressure)
158
+ )
159
+ }
160
+
161
+ post_touch_move(contact: number, x: number, y: number, pressure: number) {
162
+ return new Job(
163
+ this.#source,
164
+ maa.controller_post_touch_move(this.handle, contact, x, y, pressure)
165
+ )
166
+ }
167
+
168
+ post_touch_up(contact: number) {
169
+ return new Job(this.#source, maa.controller_post_touch_up(this.handle, contact))
170
+ }
171
+
172
+ post_screencap() {
173
+ return new ImageJob(this, this.#source, maa.controller_post_screencap(this.handle))
174
+ }
175
+
176
+ get connected() {
177
+ return maa.controller_connected(this.handle)
178
+ }
179
+
180
+ get cached_image() {
181
+ return maa.controller_cached_image(this.handle)
182
+ }
183
+
184
+ get uuid() {
185
+ return maa.controller_get_uuid(this.handle)
186
+ }
187
+ }
188
+
189
+ export class AdbController extends ControllerBase {
190
+ constructor(
191
+ adb_path: string,
192
+ address: string,
193
+ screencap_methods: maa.ScreencapOrInputMethods,
194
+ input_methods: maa.ScreencapOrInputMethods,
195
+ config: string,
196
+ agent?: string
197
+ ) {
198
+ let ws: WeakRef<this>
199
+ const h = maa.adb_controller_create(
200
+ adb_path,
201
+ address,
202
+ screencap_methods,
203
+ input_methods,
204
+ config,
205
+ agent ?? AdbController.agent_path(),
206
+ (message, details_json) => {
207
+ ws.deref()?.notify(message, details_json)
208
+ }
209
+ )
210
+ if (!h) {
211
+ throw 'AdbController create failed'
212
+ }
213
+ super(h)
214
+ ws = new WeakRef(this)
215
+ }
216
+
217
+ static agent_path() {
218
+ return path.join(__dirname, '..', 'agent')
219
+ }
220
+
221
+ static async find(adb?: string) {
222
+ return maa.find_adb(adb ?? null)
223
+ }
224
+ }
225
+
226
+ export class Win32Controller extends ControllerBase {
227
+ constructor(
228
+ hwnd: maa.DesktopHandle | null,
229
+ screencap_methods: maa.ScreencapOrInputMethods,
230
+ input_methods: maa.ScreencapOrInputMethods
231
+ ) {
232
+ let ws: WeakRef<this>
233
+ const h = maa.win32_controller_create(
234
+ hwnd ?? ('0' as maa.DesktopHandle),
235
+ screencap_methods,
236
+ input_methods,
237
+ (message, details_json) => {
238
+ ws.deref()?.notify(message, details_json)
239
+ }
240
+ )
241
+ if (!h) {
242
+ throw 'Win32Controller create failed'
243
+ }
244
+ super(h)
245
+ ws = new WeakRef(this)
246
+ }
247
+
248
+ static find() {
249
+ return maa.find_desktop()
250
+ }
251
+ }
252
+
253
+ export class DbgController extends ControllerBase {
254
+ constructor(read_path: string, write_path: string, type: maa.Uint64, config: string) {
255
+ let ws: WeakRef<this>
256
+ const h = maa.dbg_controller_create(
257
+ read_path,
258
+ write_path,
259
+ type,
260
+ config,
261
+ (message, details_json) => {
262
+ ws.deref()?.notify(message, details_json)
263
+ }
264
+ )
265
+ if (!h) {
266
+ throw 'DbgController create failed'
267
+ }
268
+ super(h)
269
+ ws = new WeakRef(this)
270
+ }
271
+ }
272
+
273
+ export abstract class CustomControllerActor {
274
+ abstract connect(): maa.MaybePromise<boolean>
275
+ abstract request_uuid(): maa.MaybePromise<string | null>
276
+ abstract start_app(intent: string): maa.MaybePromise<boolean>
277
+ abstract stop_app(intent: string): maa.MaybePromise<boolean>
278
+ abstract screencap(): maa.MaybePromise<ImageData | null>
279
+ abstract click(x: number, y: number): maa.MaybePromise<boolean>
280
+ abstract swipe(
281
+ x1: number,
282
+ y1: number,
283
+ x2: number,
284
+ y2: number,
285
+ duration: number
286
+ ): maa.MaybePromise<boolean>
287
+ abstract touch_down(
288
+ contact: number,
289
+ x: number,
290
+ y: number,
291
+ pressure: number
292
+ ): maa.MaybePromise<boolean>
293
+ abstract touch_move(
294
+ contact: number,
295
+ x: number,
296
+ y: number,
297
+ pressure: number
298
+ ): maa.MaybePromise<boolean>
299
+ abstract touch_up(contact: number): maa.MaybePromise<boolean>
300
+ abstract press_key(keycode: number): maa.MaybePromise<boolean>
301
+ abstract input_text(text: string): maa.MaybePromise<boolean>
302
+ }
303
+
304
+ export class CustomControllerActorDefaultImpl extends CustomControllerActor {
305
+ connect(): maa.MaybePromise<boolean> {
306
+ return false
307
+ }
308
+ request_uuid(): maa.MaybePromise<string | null> {
309
+ return null
310
+ }
311
+ start_app(intent: string): maa.MaybePromise<boolean> {
312
+ return false
313
+ }
314
+ stop_app(intent: string): maa.MaybePromise<boolean> {
315
+ return false
316
+ }
317
+ screencap(): maa.MaybePromise<ImageData | null> {
318
+ return null
319
+ }
320
+ click(x: number, y: number): maa.MaybePromise<boolean> {
321
+ return false
322
+ }
323
+ swipe(
324
+ x1: number,
325
+ y1: number,
326
+ x2: number,
327
+ y2: number,
328
+ duration: number
329
+ ): maa.MaybePromise<boolean> {
330
+ return false
331
+ }
332
+ touch_down(contact: number, x: number, y: number, pressure: number): maa.MaybePromise<boolean> {
333
+ return false
334
+ }
335
+ touch_move(contact: number, x: number, y: number, pressure: number): maa.MaybePromise<boolean> {
336
+ return false
337
+ }
338
+ touch_up(contact: number): maa.MaybePromise<boolean> {
339
+ return false
340
+ }
341
+ press_key(keycode: number): maa.MaybePromise<boolean> {
342
+ return false
343
+ }
344
+ input_text(text: string): maa.MaybePromise<boolean> {
345
+ return false
346
+ }
347
+ }
348
+
349
+ export class CustomController extends ControllerBase {
350
+ constructor(actor: CustomControllerActor) {
351
+ let ws: WeakRef<this>
352
+ const h = maa.custom_controller_create(
353
+ (action, ...param) => {
354
+ return (actor[action] as any)(...param)
355
+ },
356
+ (message, details_json) => {
357
+ ws.deref()?.notify(message, details_json)
358
+ }
359
+ )
360
+ if (!h) {
361
+ throw 'CustomController create failed'
362
+ }
363
+ super(h)
364
+ ws = new WeakRef(this)
365
+ }
366
+ }