Compare commits

...

2 commits

Author SHA1 Message Date
bb481f6b8b 日志分析器默认打开最后一页
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-11-27 23:26:42 +08:00
0bfc88a3b0 scrcpy代码改进 2024-11-27 23:20:30 +08:00
4 changed files with 18 additions and 190 deletions

View file

@ -1,5 +1,4 @@
import functools
import socket
import struct
from time import sleep
from typing import TYPE_CHECKING
@ -48,17 +47,6 @@ class ControlSender:
"""
return struct.pack("!BIII", action, keycode, repeat, 0)
@inject(const.TYPE_INJECT_TEXT)
def text(self, text: str) -> bytes:
"""
Send text to device
Args:
text: text to send
"""
buffer = text.encode("utf-8")
return struct.pack(">i", len(buffer)) + buffer
@inject(const.TYPE_INJECT_TOUCH_EVENT)
def touch(
self, x: int, y: int, action: int = const.ACTION_DOWN, touch_id: int = -1
@ -95,170 +83,6 @@ class ControlSender:
buttons,
)
@inject(const.TYPE_INJECT_SCROLL_EVENT)
def scroll(self, x: int, y: int, h: int, v: int) -> bytes:
"""
Scroll screen
Args:
x: horizontal position
y: vertical position
h: horizontal movement
v: vertical movement
"""
x, y = max(x, 0), max(y, 0)
return struct.pack(
">iiHHii",
int(x),
int(y),
int(self.parent.resolution[0]),
int(self.parent.resolution[1]),
int(h),
int(v),
)
@inject(const.TYPE_BACK_OR_SCREEN_ON)
def back_or_turn_screen_on(self, action: int = const.ACTION_DOWN) -> bytes:
"""
If the screen is off, it is turned on only on ACTION_DOWN
Args:
action: ACTION_DOWN | ACTION_UP
"""
return struct.pack(">B", action)
@inject(const.TYPE_EXPAND_NOTIFICATION_PANEL)
def expand_notification_panel(self) -> bytes:
"""
Expand notification panel
"""
return b""
@inject(const.TYPE_EXPAND_SETTINGS_PANEL)
def expand_settings_panel(self) -> bytes:
"""
Expand settings panel
"""
return b""
@inject(const.TYPE_COLLAPSE_PANELS)
def collapse_panels(self) -> bytes:
"""
Collapse all panels
"""
return b""
def get_clipboard(self, copy_key=const.COPY_KEY_NONE) -> str:
"""
Get clipboard
"""
# Since this function need socket response, we can't auto inject it any more
s: socket.socket = self.parent.control_socket
with self.parent.control_socket_lock:
# Flush socket
s.setblocking(False)
while True:
try:
s.recv(1024)
except BlockingIOError:
break
s.setblocking(True)
# Read package
package = struct.pack(">BB", const.TYPE_GET_CLIPBOARD, copy_key)
s.send(package)
(code,) = struct.unpack(">B", s.recv(1))
assert code == 0
(length,) = struct.unpack(">i", s.recv(4))
return s.recv(length).decode("utf-8")
@inject(const.TYPE_SET_CLIPBOARD)
def set_clipboard(self, text: str, paste: bool = False) -> bytes:
"""
Set clipboard
Args:
text: the string you want to set
paste: paste now
"""
buffer = text.encode("utf-8")
return struct.pack(">?i", paste, len(buffer)) + buffer
@inject(const.TYPE_SET_SCREEN_POWER_MODE)
def set_screen_power_mode(self, mode: int = const.POWER_MODE_NORMAL) -> bytes:
"""
Set screen power mode
Args:
mode: POWER_MODE_OFF | POWER_MODE_NORMAL
"""
return struct.pack(">b", mode)
@inject(const.TYPE_ROTATE_DEVICE)
def rotate_device(self) -> bytes:
"""
Rotate device
"""
return b""
def swipe(
self,
start_x: int,
start_y: int,
end_x: int,
end_y: int,
move_step_length: int = 5,
move_steps_delay: float = 0.005,
) -> None:
"""
Swipe on screen
Args:
start_x: start horizontal position
start_y: start vertical position
end_x: start horizontal position
end_y: end vertical position
move_step_length: length per step
move_steps_delay: sleep seconds after each step
:return:
"""
self.touch(start_x, start_y, const.ACTION_DOWN)
next_x = start_x
next_y = start_y
if end_x > self.parent.resolution[0]:
end_x = self.parent.resolution[0]
if end_y > self.parent.resolution[1]:
end_y = self.parent.resolution[1]
decrease_x = True if start_x > end_x else False
decrease_y = True if start_y > end_y else False
while True:
if decrease_x:
next_x -= move_step_length
if next_x < end_x:
next_x = end_x
else:
next_x += move_step_length
if next_x > end_x:
next_x = end_x
if decrease_y:
next_y -= move_step_length
if next_y < end_y:
next_y = end_y
else:
next_y += move_step_length
if next_y > end_y:
next_y = end_y
self.touch(next_x, next_y, const.ACTION_MOVE)
if next_x == end_x and next_y == end_y:
self.touch(next_x, next_y, const.ACTION_UP)
break
sleep(move_steps_delay)
def tap(self, x, y, hold_time: float = 0.07) -> None:
"""
Tap on screen

View file

@ -8,19 +8,20 @@ from typing import Any, Callable, Optional
import numpy as np
from mower import __rootdir__
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.device.adb_client.const import KeyCode
from mower.utils.device.adb_client.core import Client as ADBClient
from mower.utils.device.adb_client.socket import Socket
from mower.utils.log import logger
from mower.utils.path import get_path
from mower.utils.vector import sm, va
from . import const
from .control import ControlSender
SCR_PATH = "/data/local/tmp/scrcpy-server.jar"
SCR_VER = "2.7"
swipe_update_result = None
@ -93,7 +94,7 @@ class Client:
"""
Start server and get the connection
"""
cmdline = f"CLASSPATH={SCR_PATH} app_process / com.genymobile.scrcpy.Server 2.7 video=false audio=false control=true tunnel_forward=true"
cmdline = f"CLASSPATH={SCR_PATH} app_process / com.genymobile.scrcpy.Server {SCR_VER} video=false audio=false control=true tunnel_forward=true"
if self.displayid is not None:
cmdline += f" display_id={self.displayid}"
self.__server_stream: Socket = self.client.stream_shell(cmdline)
@ -109,16 +110,12 @@ class Client:
"""
Deploy server to android device
"""
server_file_path = __rootdir__ / "vendor" / "scrcpy-server-v2.7"
server_file_path = get_path(f"@install/mower/vendor/scrcpy-server-v{SCR_VER}")
server_buf = server_file_path.read_bytes()
self.client.push(SCR_PATH, server_buf)
self.__start_server()
def __init_server_connection(self) -> None:
"""
Connect to android server, there will be two sockets, video and control socket.
This method will set: video_socket, control_socket, resolution variables
"""
try:
self.control_socket = self.client.stream("localabstract:scrcpy")
except socket.timeout:
@ -176,7 +173,12 @@ class Client:
while try_count < 3:
try:
return f(self, *args, **kwargs)
except (ConnectionResetError, BrokenPipeError, ConnectionAbortedError):
except (
ConnectionResetError,
BrokenPipeError,
ConnectionAbortedError,
) as e:
logger.debug_exception(e)
self.stop()
time.sleep(1)
self.check_adb_alive()

View file

@ -1,4 +1,4 @@
import{_ as U,a as X}from"./IosArrowForward.js";import{ar as w,as as v,av as x,au as b,a_ as q,bS as A,ay as T,B as O,ax as G,b0 as J,D as Q,b as W,j as I,aC as Y,H as p,z as Z,c as F,bH as ee,r as C,s as oe,w as re,bu as E,bv as i,bt as _,bw as s,bC as V,bD as M,bo as r,F as S,by as N,bE as H,bx as te,i as le,aX as ne,b3 as se,k as ie}from"./_plugin-vue_export-helper.js";import{ak as ae}from"./main.js";import{S as de,_ as ce}from"./Scrollbar.js";import{_ as ue,a as me}from"./Slider.js";import{_ as ve}from"./Image.js";import"./get-slot.js";import"./utils.js";import"./use-locale.js";import"./download.js";const be=w([v("list",`
import{_ as U,a as X}from"./IosArrowForward.js";import{ar as $,as as v,av as x,au as b,a_ as q,bS as A,ay as T,B as O,ax as G,b0 as J,D as Q,b as W,j as I,aC as Y,H as p,z as Z,c as F,bH as ee,r as C,s as oe,w as re,bu as E,bv as i,bt as _,bw as s,bC as V,bD as M,bo as r,F as S,by as N,bE as H,bx as te,i as le,aX as ne,b3 as se,k as ie}from"./_plugin-vue_export-helper.js";import{ak as ae}from"./main.js";import{S as de,_ as ce}from"./Scrollbar.js";import{_ as ue,a as me}from"./Slider.js";import{_ as ve}from"./Image.js";import"./get-slot.js";import"./utils.js";import"./use-locale.js";import"./download.js";const be=$([v("list",`
--n-merged-border-color: var(--n-border-color);
--n-merged-color: var(--n-color);
--n-merged-color-hover: var(--n-color-hover);
@ -12,7 +12,7 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as w,as as v,av as x,a
list-style-type: none;
color: var(--n-text-color);
background-color: var(--n-merged-color);
`,[x("show-divider",[v("list-item",[w("&:not(:last-child)",[b("divider",`
`,[x("show-divider",[v("list-item",[$("&:not(:last-child)",[b("divider",`
background-color: var(--n-merged-border-color);
`)])])]),x("clickable",[v("list-item",`
cursor: pointer;
@ -21,7 +21,7 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as w,as as v,av as x,a
border-radius: var(--n-border-radius);
`),x("hoverable",[v("list-item",`
border-radius: var(--n-border-radius);
`,[w("&:hover",`
`,[$("&:hover",`
background-color: var(--n-merged-color-hover);
`,[b("divider",`
background-color: transparent;
@ -33,7 +33,7 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as w,as as v,av as x,a
padding: 12px 0;
box-sizing: border-box;
transition: border-color .3s var(--n-bezier);
`,[w("&:not(:last-child)",`
`,[$("&:not(:last-child)",`
border-bottom: 1px solid var(--n-merged-border-color);
`)]),v("list-item",`
position: relative;
@ -70,4 +70,4 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as w,as as v,av as x,a
--n-merged-color-hover: var(--n-color-hover-popover);
--n-merged-color: var(--n-color-popover);
--n-merged-border-color: var(--n-border-color-popover);
`))]),pe=Object.assign(Object.assign({},T.props),{size:{type:String,default:"medium"},bordered:Boolean,clickable:Boolean,hoverable:Boolean,showDivider:{type:Boolean,default:!0}}),K=Z("n-list"),_e=O({name:"List",props:pe,setup(e){const{mergedClsPrefixRef:o,inlineThemeDisabled:t,mergedRtlRef:u}=G(e),m=J("List",u,o),l=T("List","-list",be,ae,e,o);Q(K,{showDividerRef:W(e,"showDivider"),mergedClsPrefixRef:o});const f=I(()=>{const{common:{cubicBezierEaseInOut:g},self:{fontSize:z,textColor:n,color:d,colorModal:R,colorPopover:B,borderColor:k,borderColorModal:D,borderColorPopover:P,borderRadius:y,colorHover:$,colorHoverModal:j,colorHoverPopover:h}}=l.value;return{"--n-font-size":z,"--n-bezier":g,"--n-text-color":n,"--n-color":d,"--n-border-radius":y,"--n-border-color":k,"--n-border-color-modal":D,"--n-border-color-popover":P,"--n-color-modal":R,"--n-color-popover":B,"--n-color-hover":$,"--n-color-hover-modal":j,"--n-color-hover-popover":h}}),c=t?Y("list",void 0,f,e):void 0;return{mergedClsPrefix:o,rtlEnabled:m,cssVars:t?void 0:f,themeClass:c==null?void 0:c.themeClass,onRender:c==null?void 0:c.onRender}},render(){var e;const{$slots:o,mergedClsPrefix:t,onRender:u}=this;return u==null||u(),p("ul",{class:[`${t}-list`,this.rtlEnabled&&`${t}-list--rtl`,this.bordered&&`${t}-list--bordered`,this.showDivider&&`${t}-list--show-divider`,this.hoverable&&`${t}-list--hoverable`,this.clickable&&`${t}-list--clickable`,this.themeClass],style:this.cssVars},o.header?p("div",{class:`${t}-list__header`},o.header()):null,(e=o.default)===null||e===void 0?void 0:e.call(o),o.footer?p("div",{class:`${t}-list__footer`},o.footer()):null)}}),fe=O({name:"ListItem",setup(){const e=F(K,null);return e||ee("list-item","`n-list-item` must be placed in `n-list`."),{showDivider:e.showDividerRef,mergedClsPrefix:e.mergedClsPrefixRef}},render(){const{$slots:e,mergedClsPrefix:o}=this;return p("li",{class:`${o}-list-item`},e.prefix?p("div",{class:`${o}-list-item__prefix`},e.prefix()):null,e.default?p("div",{class:`${o}-list-item__main`},e):null,e.suffix?p("div",{class:`${o}-list-item__suffix`},e.suffix()):null,this.showDivider&&p("div",{class:`${o}-list-item__divider`}))}}),ge={style:{"text-align":"center",margin:"0"}},De={__name:"DebugConsole",setup(e){const o=F("axios"),t=C([]),u=C(""),m=C([]),l=C(0),f=C(null);oe(()=>{o.get("/debug/log").then(({data:n})=>{t.value=n}),c("runtime.log")});function c(n){l.value=0,u.value=n,o.get(`/debug/log/${n}`).then(({data:d})=>{m.value=d})}const g=I(()=>{var n;return(n=m.value[l.value])==null?void 0:n.screenshot}),z=I(()=>`/debug/screenshot/${g.value}`);return re(l,()=>{var n;(n=f.value)==null||n.scrollTo({top:0})}),(n,d)=>{const R=fe,B=_e,k=de,D=ve,P=me,y=ne,$=se,j=ce,h=ue;return _(),E(h,{style:{width:"100%",height:"100%",gap:"0","overflow-y":"hidden"}},{default:i(()=>[s(k,{style:{width:"220px"}},{default:i(()=>[s(B,{hoverable:"",clickable:"",bordered:""},{default:i(()=>[(_(!0),V(S,null,M(r(t),a=>(_(),E(R,{onClick:L=>c(a)},{default:i(()=>[ie(H(a),1)]),_:2},1032,["onClick"]))),256))]),_:1})]),_:1}),s(h,{vertical:"",style:{flex:"1",height:"100%",overflow:"hidden"}},{default:i(()=>[N("h2",ge,H(r(u)),1),r(g)?(_(),E(D,{key:0,src:r(z),alt:r(g),width:"100%",style:{"max-height":"50%"},"object-fit":"scale-down"},null,8,["src","alt"])):te("",!0),s(k,{ref_key:"log_scroll",ref:f,style:{width:"100%"},"content-style":"font-size: 16px; user-select: text; padding: 0 12px"},{default:i(()=>{var a;return[(_(!0),V(S,null,M((a=r(m)[r(l)])==null?void 0:a.log,L=>(_(),V("div",null,[N("code",null,H(L),1)]))),256))]}),_:1},512),s(h,{align:"center",style:{padding:"0 12px 6px"}},{default:i(()=>[s(P,{style:{flex:"1"},value:r(l),"onUpdate:value":d[0]||(d[0]=a=>le(l)?l.value=a:null),min:0,max:r(m).length-1,"format-tooltip":a=>r(m)[a].time},null,8,["value","max","format-tooltip"]),s(j,null,{default:i(()=>[s($,{disabled:r(l)==0,onClick:d[1]||(d[1]=a=>l.value--)},{icon:i(()=>[s(y,null,{default:i(()=>[s(r(U))]),_:1})]),_:1},8,["disabled"]),s($,{disabled:r(l)==r(m).length-1,onClick:d[2]||(d[2]=a=>l.value++)},{icon:i(()=>[s(y,null,{default:i(()=>[s(r(X))]),_:1})]),_:1},8,["disabled"])]),_:1})]),_:1})]),_:1})]),_:1})}}};export{De as default};
`))]),pe=Object.assign(Object.assign({},T.props),{size:{type:String,default:"medium"},bordered:Boolean,clickable:Boolean,hoverable:Boolean,showDivider:{type:Boolean,default:!0}}),K=Z("n-list"),_e=O({name:"List",props:pe,setup(e){const{mergedClsPrefixRef:o,inlineThemeDisabled:t,mergedRtlRef:m}=G(e),c=J("List",m,o),l=T("List","-list",be,ae,e,o);Q(K,{showDividerRef:W(e,"showDivider"),mergedClsPrefixRef:o});const f=I(()=>{const{common:{cubicBezierEaseInOut:g},self:{fontSize:z,textColor:n,color:d,colorModal:R,colorPopover:B,borderColor:k,borderColorModal:D,borderColorPopover:P,borderRadius:w,colorHover:y,colorHoverModal:j,colorHoverPopover:h}}=l.value;return{"--n-font-size":z,"--n-bezier":g,"--n-text-color":n,"--n-color":d,"--n-border-radius":w,"--n-border-color":k,"--n-border-color-modal":D,"--n-border-color-popover":P,"--n-color-modal":R,"--n-color-popover":B,"--n-color-hover":y,"--n-color-hover-modal":j,"--n-color-hover-popover":h}}),u=t?Y("list",void 0,f,e):void 0;return{mergedClsPrefix:o,rtlEnabled:c,cssVars:t?void 0:f,themeClass:u==null?void 0:u.themeClass,onRender:u==null?void 0:u.onRender}},render(){var e;const{$slots:o,mergedClsPrefix:t,onRender:m}=this;return m==null||m(),p("ul",{class:[`${t}-list`,this.rtlEnabled&&`${t}-list--rtl`,this.bordered&&`${t}-list--bordered`,this.showDivider&&`${t}-list--show-divider`,this.hoverable&&`${t}-list--hoverable`,this.clickable&&`${t}-list--clickable`,this.themeClass],style:this.cssVars},o.header?p("div",{class:`${t}-list__header`},o.header()):null,(e=o.default)===null||e===void 0?void 0:e.call(o),o.footer?p("div",{class:`${t}-list__footer`},o.footer()):null)}}),fe=O({name:"ListItem",setup(){const e=F(K,null);return e||ee("list-item","`n-list-item` must be placed in `n-list`."),{showDivider:e.showDividerRef,mergedClsPrefix:e.mergedClsPrefixRef}},render(){const{$slots:e,mergedClsPrefix:o}=this;return p("li",{class:`${o}-list-item`},e.prefix?p("div",{class:`${o}-list-item__prefix`},e.prefix()):null,e.default?p("div",{class:`${o}-list-item__main`},e):null,e.suffix?p("div",{class:`${o}-list-item__suffix`},e.suffix()):null,this.showDivider&&p("div",{class:`${o}-list-item__divider`}))}}),ge={style:{"text-align":"center",margin:"0"}},De={__name:"DebugConsole",setup(e){const o=F("axios"),t=C([]),m=C(""),c=C([]),l=C(0),f=C(null);oe(()=>{o.get("/debug/log").then(({data:n})=>{t.value=n}),u("runtime.log")});function u(n){m.value=n,o.get(`/debug/log/${n}`).then(({data:d})=>{l.value=0,c.value=d,l.value=c.value.length-1})}const g=I(()=>{var n;return(n=c.value[l.value])==null?void 0:n.screenshot}),z=I(()=>`/debug/screenshot/${g.value}`);return re(l,()=>{var n;(n=f.value)==null||n.scrollTo({top:0})}),(n,d)=>{const R=fe,B=_e,k=de,D=ve,P=me,w=ne,y=se,j=ce,h=ue;return _(),E(h,{style:{width:"100%",height:"100%",gap:"0","overflow-y":"hidden"}},{default:i(()=>[s(k,{style:{width:"220px"}},{default:i(()=>[s(B,{hoverable:"",clickable:"",bordered:""},{default:i(()=>[(_(!0),V(S,null,M(r(t),a=>(_(),E(R,{onClick:L=>u(a)},{default:i(()=>[ie(H(a),1)]),_:2},1032,["onClick"]))),256))]),_:1})]),_:1}),s(h,{vertical:"",style:{flex:"1",height:"100%",overflow:"hidden"}},{default:i(()=>[N("h2",ge,H(r(m)),1),r(g)?(_(),E(D,{key:0,src:r(z),alt:r(g),width:"100%",style:{"max-height":"50%"},"object-fit":"scale-down"},null,8,["src","alt"])):te("",!0),s(k,{ref_key:"log_scroll",ref:f,style:{width:"100%"},"content-style":"font-size: 16px; user-select: text; padding: 0 12px"},{default:i(()=>{var a;return[(_(!0),V(S,null,M((a=r(c)[r(l)])==null?void 0:a.log,L=>(_(),V("div",null,[N("code",null,H(L),1)]))),256))]}),_:1},512),s(h,{align:"center",style:{padding:"0 12px 6px"}},{default:i(()=>[s(P,{style:{flex:"1"},"show-tooltip":"",value:r(l),"onUpdate:value":d[0]||(d[0]=a=>le(l)?l.value=a:null),min:0,max:r(c).length-1,"format-tooltip":a=>r(c)[a].time},null,8,["value","max","format-tooltip"]),s(j,null,{default:i(()=>[s(y,{disabled:r(l)==0,onClick:d[1]||(d[1]=a=>l.value--)},{icon:i(()=>[s(w,null,{default:i(()=>[s(r(U))]),_:1})]),_:1},8,["disabled"]),s(y,{disabled:r(l)==r(c).length-1,onClick:d[2]||(d[2]=a=>l.value++)},{icon:i(()=>[s(w,null,{default:i(()=>[s(r(X))]),_:1})]),_:1},8,["disabled"])]),_:1})]),_:1})]),_:1})]),_:1})}}};export{De as default};

View file

@ -14,10 +14,11 @@ onMounted(() => {
})
function get_log(log) {
log_frame.value = 0
current_log.value = log
axios.get(`${import.meta.env.VITE_HTTP_URL}/debug/log/${log}`).then(({ data }) => {
log_frame.value = 0
log_content.value = data
log_frame.value = log_content.value.length - 1
})
}
@ -66,6 +67,7 @@ watch(log_frame, () => {
<n-flex align="center" style="padding: 0 12px 6px">
<n-slider
style="flex: 1"
show-tooltip
v-model:value="log_frame"
:min="0"
:max="log_content.length - 1"