| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #!/usr/bin/env node
- const { execSync } = require('child_process')
- const path = require('path')
- const config = require(path.join(__dirname, '..', '..', 'configs', 'config.js'))
- const projectRoot = path.resolve(__dirname, '..', '..')
- /** 从 config 解析并返回 adb 可执行文件路径 */
- function getAdbPath() {
- return config.adbPath?.path
- ? path.resolve(projectRoot, config.adbPath.path)
- : path.join(projectRoot, 'lib', 'scrcpy-adb', 'adb.exe')
- }
- /** 根据 deviceId 返回 adb -s 参数前缀,无设备时返回空串 */
- function getDeviceFlag(deviceId) {
- return deviceId && deviceId.includes(':') ? `-s ${deviceId} ` : ''
- }
- /** 执行 adb shell 命令 */
- function runShell(adbPath, deviceFlag, shellArgs, timeout = 1000) {
- const quoted = adbPath.includes(' ') ? `"${adbPath}"` : adbPath
- execSync(`${quoted} ${deviceFlag}shell ${shellArgs}`, { encoding: 'utf-8', timeout })
- }
- /** 执行 adb shell 并返回标准输出 */
- function runShellWithOutput(adbPath, deviceFlag, shellArgs, timeout = 1000) {
- const quoted = adbPath.includes(' ') ? `"${adbPath}"` : adbPath
- return execSync(`${quoted} ${deviceFlag}shell ${shellArgs}`, { encoding: 'utf-8', timeout })
- }
- /** 处理 tap:点击坐标 */
- function handleTap(adbPath, argv) {
- const coordX = argv[3]
- const coordY = argv[4]
- const deviceId = argv[5] || ''
- if (!coordX || !coordY) process.exit(1)
- const flag = getDeviceFlag(deviceId)
- runShell(adbPath, flag, `input tap ${coordX} ${coordY}`, 1000)
- }
- /** 根据方向与距离计算滑动的起止坐标(基于屏幕中心),返回 [startX, startY, endX, endY] */
- function getSwipeCoordsByDirection(direction, distance, centerX, centerY) {
- const half = Math.floor(distance / 2)
- switch (direction) {
- case 'up-down':
- return [centerX, centerY - half, centerX, centerY + half]
- case 'down-up':
- return [centerX, centerY + half, centerX, centerY - half]
- case 'left-right':
- return [centerX - half, centerY, centerX + half, centerY]
- case 'right-left':
- return [centerX + half, centerY, centerX - half, centerY]
- default:
- process.exit(1)
- }
- }
- /** 处理 swipe:按方向与距离从屏幕中心滑动 */
- function handleSwipe(adbPath, argv) {
- const direction = argv[3]
- const distance = parseInt(argv[4], 10)
- const duration = parseInt(argv[5], 10)
- const deviceId = argv[6] || ''
- if (!direction || !distance || !duration) process.exit(1)
- const flag = getDeviceFlag(deviceId)
- const sizeOut = runShellWithOutput(adbPath, flag, 'wm size', 1000)
- const sizeMatch = sizeOut.match(/(\d+)x(\d+)/)
- const centerX = Math.floor(parseInt(sizeMatch[1], 10) / 2)
- const centerY = Math.floor(parseInt(sizeMatch[2], 10) / 2)
- const [startX, startY, endX, endY] = getSwipeCoordsByDirection(direction, distance, centerX, centerY)
- runShell(adbPath, flag, `input swipe ${startX} ${startY} ${endX} ${endY} ${duration}`, 2000)
- }
- /** 处理 swipe-coords:按坐标滑动 */
- function handleSwipeCoords(adbPath, argv) {
- const x1 = argv[3]
- const y1 = argv[4]
- const x2 = argv[5]
- const y2 = argv[6]
- const duration = argv[7] || 300
- const deviceId = argv[8] || ''
- if (!x1 || !y1 || !x2 || !y2) process.exit(1)
- const flag = getDeviceFlag(deviceId)
- runShell(adbPath, flag, `input swipe ${x1} ${y1} ${x2} ${y2} ${duration}`, 2000)
- }
- /** 处理 keyevent:按键 */
- function handleKeyevent(adbPath, argv) {
- const keyCode = argv[3]
- const deviceId = argv[4] || ''
- if (!keyCode) process.exit(1)
- const flag = getDeviceFlag(deviceId)
- runShell(adbPath, flag, `input keyevent ${keyCode}`, 1000)
- }
- /** 处理 text:输入文本 */
- function handleText(adbPath, argv) {
- const text = argv[3]
- const deviceId = argv[4] || ''
- if (text === undefined) process.exit(1)
- const flag = getDeviceFlag(deviceId)
- const escaped = String(text).replace(/"/g, '\\"').replace(/\$/g, '\\$').replace(/`/g, '\\`')
- runShell(adbPath, flag, `input text "${escaped}"`, 5000)
- }
- const action = process.argv[2]
- if (!action) process.exit(1)
- const adbPath = getAdbPath()
- switch (action) {
- case 'tap':
- handleTap(adbPath, process.argv)
- break
- case 'swipe':
- handleSwipe(adbPath, process.argv)
- break
- case 'swipe-coords':
- handleSwipeCoords(adbPath, process.argv)
- break
- case 'keyevent':
- handleKeyevent(adbPath, process.argv)
- break
- case 'text':
- handleText(adbPath, process.argv)
- break
- default:
- process.exit(1)
- }
- process.exit(0)
|