11import re
2+ import io
23from pathlib import Path
34from typing import Callable , List , Optional , Tuple , Union
45
56from asyncify import asyncify
67from PIL import Image
7- from maa .controller import AdbController , Win32Controller
8+ from maa .controller import AdbController , Win32Controller , CustomController
89from maa .context import Context , ContextEventSink
910from maa .tasker import Tasker , RecognitionDetail
1011from maa .resource import Resource , ResourceEventSink
1112from maa .toolkit import Toolkit , AdbDevice , DesktopWindow
1213from maa .agent_client import AgentClient
1314from maa .library import Library
1415from maa .event_sink import NotificationType
16+ import numpy as np
1517
16- from ..utils import cvmat_to_image
18+ from ..utils .img_tools import cvmat_to_image , rgb_to_bgr
19+
20+
21+ class MyCustomController (CustomController ):
22+ def __init__ (self , img_bytes : bytes ):
23+ super ().__init__ ()
24+
25+ img = Image .open (io .BytesIO (img_bytes ))
26+ self .ndarray = rgb_to_bgr (np .array (img ))
27+
28+ def connect (self ) -> bool :
29+ return True
30+
31+ def request_uuid (self ) -> str :
32+ return "0"
33+
34+ def screencap (self ) -> np .ndarray :
35+ return self .ndarray
1736
1837
1938class MaaFW :
2039
2140 resource : Optional [Resource ]
22- controller : Union [AdbController , Win32Controller , None ]
41+ controller : Union [AdbController , Win32Controller , CustomController , None ]
2342 tasker : Optional [Tasker ]
2443 agent : Optional [AgentClient ]
2544 context_event_sink : Optional [ContextEventSink ]
@@ -89,6 +108,12 @@ def connect_win32hwnd(
89108
90109 return True , None
91110
111+ def connect_custom_controller (self , img_bytes ) -> Tuple [bool , Optional [str ]]:
112+ self .controller = MyCustomController (img_bytes )
113+ self .controller .post_connection ().wait ()
114+
115+ return True , None
116+
92117 @asyncify
93118 def load_resource (self , dir : List [Path ]) -> Tuple [bool , Optional [str ]]:
94119 if not self .resource :
@@ -149,7 +174,20 @@ def run_task(
149174 if not AgentClient ().register_sink (self .resource , self .controller , self .tasker ):
150175 return False , "Failed to register Agent sink."
151176
152- return self .tasker .post_task (entry , pipeline_override ).wait ().succeeded , None
177+ if isinstance (self .controller , CustomController ):
178+ # disable action
179+ pipeline_override .update (
180+ {entry : {"action" : {"type" : "DoNothing" }, "next" : []}}
181+ )
182+ return (
183+ self .tasker .post_task (entry , pipeline_override ).wait ().succeeded ,
184+ None ,
185+ )
186+ else :
187+ return (
188+ self .tasker .post_task (entry , pipeline_override ).wait ().succeeded ,
189+ None ,
190+ )
153191
154192 @asyncify
155193 def stop_task (self ) -> None :
@@ -176,6 +214,9 @@ def click(self, x, y) -> bool:
176214 if not self .controller :
177215 return False
178216
217+ if isinstance (self .controller , CustomController ):
218+ return False
219+
179220 return self .controller .post_click (x , y ).wait ().succeeded
180221
181222 @asyncify
0 commit comments