
    j%                        d Z ddlZddlZddlZddlZddlZddlmZ  ej                         dz  dz  Z	 ej                         dz  dz  Z
dZdZd	Zdadad
edefdZdedz  fdZdedz  fdZdefdZd
edefdZdedefdZd%dededefdZdefdZd&dededefdZdededefdZdededefd Zd!efd"Zd# Ze d$k(  r e        yy)'u   
手机操作后台 Worker
监听 ~/.hermes/phone_tasks/ 目录，执行任务，结果写到 ~/.hermes/phone_results/

🔴 核心原则：所有操作必须在虚拟屏执行，绝不触碰主屏 (Display 0)
    N)Pathz.hermesphone_tasksphone_resultszlocalhost:15556z/usr/local/bin/scrcpyz/usr/bin/adbcmdreturnc                 z    t        j                  ddt        d| gddd      }|j                  j	                         S )u   执行 adb shell 命令adbz-sshellT   )capture_outputtexttimeout)
subprocessrunSERIALstdoutstrip)r   results     ,/home/ubuntu/.hermes/scripts/phone_worker.py	adb_shellr      s:    ^^	fgs+$F ==      c                      t        d      } | j                  d      D ]>  }t        j                  d|      }|st	        |j                  d            }|dk7  s<|c S  y)u/   获取当前虚拟屏 ID（非 0 的 Display）z#dumpsys display | grep 'Display Id'
zDisplay Id=(\d+)   r   N)r   splitresearchintgroup)outputlinematchdids       r   get_virtual_display_idr$   $   s\    <=FT" 		-t4ekk!n%Cax
 r   c                  Z   t        dt        j                  d       d       t        j                  ddt
        gdd       t        j                  d	       t        j                  t        d
t
        ddgi t        j                  dt        it        j                  t        j                        at        d      D ]K  } t        j                  d	       t               }|s%t        dt        j                  d       d|        |c S  t        dt        j                  d       d       y)u)   创建隐藏虚拟屏，返回 Display ID[%H:%M:%Su   ] 创建虚拟屏...r	   connectT
   )r   r   r   z--serialz--new-display=1080x2400z--render-driver=softwareADB)envr   stderru%   ] ✅ 虚拟屏创建成功: Display u   ] ❌ 虚拟屏创建失败N)printtimestrftimer   r   r   sleepPopenSCRCPY_PATHosenvironADB_PATHDEVNULLscrcpy_processranger$   )_r#   s     r   create_virtual_displayr:   0   s     
AdmmJ'((<
=> NNE9f-dBOJJqM  %%	j&*CE_`+rzz+5(+!!!!	N 2Y 

1$&AdmmJ/00UVYUZ[\J 
AdmmJ'((C
DEr   c                  X    t               } | r| a| S t               } | r| a| S t        d      )u*   确保虚拟屏存在，不存在则创建u-   无法创建虚拟屏，拒绝在主屏操作)r$   
DISPLAY_IDr:   RuntimeError)r#   s    r   ensure_virtual_displayr>   N   s<    
 !
"C


 !
"C



F
GGr   c                     t                t        j                  ddt         d|       } d| v rd| vr| j	                  ddt               } t        |       S )uv   
    🔴 核心函数：在虚拟屏执行 shell 命令
    自动替换 input/am 命令，强制指定虚拟屏
    z\binput\s+(tap|swipe|keyevent)input touchscreen -d z \1zam startz	--displayam start --display )r>   r   subr<   replacer   )r   s    r   shell_on_displayrD   a   s_    
 
 &&)

|40C S[3kk*(;J<&HIS>r   xyc                 H    t                t        dt         d|  d|        y)u   在虚拟屏点击r@   z tap  N)r>   r   r<   )rE   rF   s     r   taprI   y   s$    %j\qc1#>?r   packageactivityuric                     t                |rdt         d| d}n|rdt         d|  d| }ndt         d|  d}t        |       y)u   在虚拟屏启动 ApprA   z# -a android.intent.action.VIEW -d ''z -n /z/.MainActivityN)r>   r<   r   )rJ   rK   rL   r   s       r   	start_apprP      sY    
#J</RSVRWWXY	#J<tG9AhZH#J<tG9NKcNr   r   c                 "    t        d|  d       y)u=   通过 ADBKeyboard 输入文字（全局，不区分屏幕）z)am broadcast -a ADB_INPUT_TEXT --es msg 'rN   N)r   )r   s    r   
input_textrR      s    9$qABr   songartistc                    |  d| j                         }t        dd|        t        j                  d       t	        d      }t        j                  dt        j                  |        d|t
        j                        }|D ]w  \  }}}}}	t        |      t        |	      z   d	z  }
|
d
kD  s)t        |      t        |      z   d	z  }t        ||
       t        j                  d	       t	        d      }d|dd
 dc S  dddS )u!   播放音乐 - 在虚拟屏操作rH   zcom.spotify.musiczspotify:search:)rL      z=uiautomator dump /dev/tty 2>/dev/null || dumpsys activity topztext="([^"]*z3[^"]*)"[^>]*bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"      z+dumpsys media_session | grep 'description='TN)successplayingFu   未找到歌曲rY   error)r   rP   r.   r0   r   r   findallescape
IGNORECASEr   rI   )rS   rT   queryxmlmatchesr   x1y1x2y2cycxr   s                r   
play_musicri      s   fAfX$$&E !'@AJJqM S
TCjj		$(([\R]]G
 !( >b"b""gBA%8b'CG#)BBKJJqMLMF#t==> '899r   contactmessagec                 .   t        d       t        j                  d       t        dd       t        j                  d       t	        dd       t        j                  d       t        |        t        j                  d       t	        d	d
       t        j                  d       t	        d	d       t        j                  d       t        |       t        j                  d       t	        dd       t        j                  d       t        d       d| |dS )u$   发微信消息 - 在虚拟屏操作'ime set com.android.adbkeyboard/.AdbIME      ?zcom.tencent.mmz.ui.LauncherUIrW              ?  i  r     333333?  0  3ime set com.tencent.wetype/.plugin.hld.WxHldServiceTrY   sent_tork   r   r.   r0   rP   rI   rR   rj   rk   s     r   send_wechatr|      s     78JJsO  01JJqM SMJJsO wJJsO SMJJqM TNJJsO wJJsO TNJJsO CDGDDr   c                 .   t        d       t        j                  d       t        dd       t        j                  d       t	        dd       t        j                  d       t        |        t        j                  d       t	        d	d
       t        j                  d       t	        d	d       t        j                  d       t        |       t        j                  d       t	        dd       t        j                  d       t        d       d| |dS )u    发QQ消息 - 在虚拟屏操作rm   rn   zcom.tencent.mobileqqz.activity.SplashActivityrW   ro   rp   rq   rr   i  r   rs   rt   ru   rv   rw   Trx   rz   r{   s     r   send_qqr~      s     78JJsO $&@AJJqM SMJJsO wJJsO SMJJqM TNJJsO wJJsO TNJJsO CDGDDr   	task_filec           	         	 t        |       5 }t        j                  |      }ddd       | j                  }j	                  d      }t        dt        j                  d       d| d| d       |dk(  r-t        |j	                  d	d
      |j	                  dd
            }nl|dk(  r-t        |j	                  dd
      |j	                  dd
            }n:|dk(  r-t        |j	                  dd
      |j	                  dd
            }ndd| d}||d<   t        |d<   t        j                  d      |d<   t        t        | dz  d      5 }t        j                  ||dd       ddd       | j                          t        dt        j                  d       d|        y# 1 sw Y   xY w# 1 sw Y   KxY w# t        $ r}t        dt        j                  d       d|        	 dt!        |      | j                  t        j                  d      d}t        t        | j                   dz  d      5 }t        j                  ||dd       ddd       n# 1 sw Y   nxY w| j                          n#  Y nxY wY d}~yY d}~yd}~ww xY w)u   处理单个任务Nactionr&   r'   u   ] 执行任务: z ()ri   rS    rT   r|   rj   rk   r~   Fu   未知操作: r[   task_id
display_idz%Y-%m-%d %H:%M:%Scompleted_atz.jsonwrW   )ensure_asciiindentu   ] ✅ 完成: u   ] ❌ 任务失败: )rY   r\   r   r   )openjsonloadstemgetr-   r.   r/   ri   r|   r~   r<   RESULTS_DIRdumpunlink	Exceptionstr)r   ftaskr   r   r   es          r   process_taskr      sZ   ,)_ 	 99Q<D	  ..(#$--
+,,<WIRxqQR\! 4dhhx6LMF}$ )R!8$((9b:QRFy TXXi4dhhy"6MNF!&>&1JKF $y)|!%/B!C~+7)5 1137 	?1IIfaeA>	? 	$--
+,N7)DE7	  	 ,	? 	?  $--
+,,@DE	 Q$>> $.A B	F ky~~&6e$<<cB Ca		&!%BC C C	D sw   F: F!D'F: 
F.$<F: !F+&F: .F73F: :	J$J(AI55I	I5I!	I54J5I97JJc                     t         j                  dd       t        j                  dd       t        dt	        j
                  d       d       t        dt	        j
                  d       dt                 t        dt	        j
                  d       dt                	 t                t        dt	        j
                  d       dt         d	       	 t        t         j                  d            }|D ]  }t        |        t	        j                  d       F# t        $ rP} t        dt	        j
                  d       d
|         t        dt	        j
                  d       d       Y d } ~ d } ~ ww xY w)NT)parentsexist_okr&   r'   u   ] Phone Worker 启动u   ] 任务目录: u   ] 结果目录: u1   ] 🔒 安全模式：所有操作将在 Display u    执行u#   ] ⚠️ 虚拟屏初始化失败: u    ] 将在首个任务时重试...z*.jsonr   )	TASKS_DIRmkdirr   r-   r.   r/   r>   r<   r   sortedglobr   r0   )r   
task_filesr   s      r   mainr   .  sE   OOD4O0dT2	AdmmJ'((=
>?	AdmmJ'((8
DE	AdmmJ'((8
FGO $--
+,,]^h]iipqr INN845
# 	$I#	$

1	   O$--
+,,OPQsST$--
+,,LMNNOs   "3D 	E5%AE00E5__main__)NN)r   )!__doc__r3   r   r.   r   r   pathlibr   homer   r   r   r2   r5   r<   r7   r   r   r   r$   r:   r>   rD   rI   rP   rR   dictri   r|   r~   r   r   __name__ r   r   <module>r      sw   
   	  DIIK)#m3	diikI%7	% 
!3 !3 !	d
 	d
 <H H&# # 0@3 @3 @s c s CS C
:S :# :t :6%E %Es %Et %EP%ES %E3 %E4 %EP.D .b2 zF r   