UNPKG

@quick-game/cli

Version:

Command line interface for rapid qg development

352 lines (313 loc) 11.7 kB
"use strict";var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");_Object$defineProperty(exports, "__esModule", { value: true });exports.default = void 0;var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));var _from = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/from")); var _adbDevicesEmitter = _interopRequireDefault(require("adb-devices-emitter")); var _adbCommander = _interopRequireDefault(require("adb-commander")); var _recordClient = require("../record-client.js"); var _debuglog = _interopRequireDefault(require("./debuglog")); /** * Copyright (C) 2017, hapjs.org. All rights reserved. */const REMOTE_REVERSE_PORT = 12306; const REMOTE_UP_FORWARD_PORT = 39517; /** * ADB Modules */ class ADBModule { /** * ADBModule constructor * @param option * @param option.localReversePort {number} adb reverse命令使用的端口 */ constructor(option) { this.option = option; // 当前连接的设备列表 sn: { upForwardPortPair:[localPort, remotePort], wsPortPair[localPort, remotePort] } this.currentDeviceMap = new _map.default(); // 用来记录所有当前连接和已拔出的设备列表 this.cachedDeviceMap = new _map.default(); this.DEBUG = (process.env.NODE_DEBUG || '').split(',').includes('adb'); // 记录localUpForwardPort(自增)的端口号, 初始值等于REMOTE_UP_FORWARD_PORT this._localUpForwardPort = REMOTE_UP_FORWARD_PORT; this.commander = _adbCommander.default; this.devicesEmitter = _adbDevicesEmitter.default; this._lastPromise = null; this.emulators = new _map.default(); this.init(); } /** * 注册事件, 开始查询设备 */ init() { (0, _debuglog.default)(`init(): start`); this.devicesEmitter.addEventListener('deviceAdded', (event) => { this._listen(event, this.onDeviceAdded.bind(this)); }); this.devicesEmitter.addEventListener('deviceRemoved', (event) => { this._listen(event, this.onDeviceRemoved.bind(this)); }); this.devicesEmitter.start(); } /** * 确保队列式的调用顺序 * @private */ _listen(event, callback) { if (!this._lastPromise) { this._lastPromise = callback(event); } else { this._lastPromise = this._lastPromise.then( () => { return callback(event); }, () => { return callback(event); } ); } } /** * 取得一个_localUpForwardPort端口数字 * @private */ _getNextLocalForwardPort() { return this._localUpForwardPort++; } /** * 处理每个新增设备 * @desc * 为每一个设备执行以下操作: * 1. adb reverse tcp:${localReversePort} tcp:REMOTE_REVERSE_PORT, * 2. adb forward tcp:${localUpForwardPort} tcp:REMOTE_UP_FORWARD_PORT; * 3. 如果cachedDeviceList中存在当前新增设备, 且状态为已断开, 检查该设备是否 * 已有wsForwardPort端口记录信息, 有则执行adb forward tcp:${wsPair[0]} tcp:${wsPair[1]}; * 4. 为currentList中新增当前设备; * @param event * @param event.sn 设备序列号 */ async onDeviceAdded(event) { const { sn } = event; console.info(`### App Server ### 手机设备(${sn})被连入`); const { result } = await this.commander.getProp(sn); if (result) { this.emulators.set(result.trim(), sn); } const localReversePort = this.option.localReversePort; // 建立reverse设定 const reverseResult = await this.establishADBProxyLink('reverse', [ sn, localReversePort, REMOTE_REVERSE_PORT] ); if (reverseResult.err) { console.error( `### App Server ### onDeviceAdded(): (${sn})建立adb reverse失败(local port: ${localReversePort}, remote port: ${REMOTE_REVERSE_PORT})` ); return; } // 检查cachedDeviceList中的设备状况 let currentDevice = this.cachedDeviceMap.get(sn); (0, _debuglog.default)( `onDeviceAdded():(${sn})\ncachedDevice:\t${(0, _stringify.default)( currentDevice )}\ncachedDeviceList:\t${(0, _stringify.default)((0, _from.default)(this.cachedDeviceMap.entries()))}` ); // 建立forward update port设定 if (!currentDevice || !currentDevice.upForwardPortPair) { currentDevice = { upForwardPortPair: [this._getNextLocalForwardPort(), REMOTE_UP_FORWARD_PORT] }; } const upForwardResult = await this.establishADBProxyLink( 'forward', [sn].concat(currentDevice.upForwardPortPair) ); if (upForwardResult.err) { console.error( `### App Server ### onDeviceAdded(): (${sn})建立adb forward失败(local port: ${ currentDevice.upForwardPortPair[0]}, remote port: ${ currentDevice.upForwardPortPair[1]}) ` ); return; } // 如果有记录的调试端口 为调试web socket建立forward if (currentDevice.wsPortPair) { const debugForwardResult = await this.establishADBProxyLink('forward', [ sn, currentDevice.wsPortPair[0], currentDevice.wsPortPair[1]] ); if (debugForwardResult.err) { console.info( `### App Server ### onDeviceAdded():(${sn}) 建立adb forward失败(local port: ${ currentDevice.wsPortPair[0]}, remote port: ${ currentDevice.wsPortPair[1]})` ); currentDevice.wsPortPair = undefined; } } // 记录当前设备 this.currentDeviceMap.set(sn, currentDevice); this.cachedDeviceMap.set(sn, currentDevice); // 记录发送update http请求需要的ip和端口 await this._writeClientLogFile({ sn, ip: `127.0.0.1`, port: currentDevice.upForwardPortPair[0] }); (0, _debuglog.default)(`onDeviceAdded():(${sn}) end`); } /** * 移除设备事件 */ async onDeviceRemoved(event) { const { sn } = event; console.info(`### App Server ### 手机设备(${sn})被拔出`); this.currentDeviceMap.delete(sn); if (this.DEBUG) { (0, _debuglog.default)( `deviceRemoved():(${sn}) cachedDeviceList: ${(0, _stringify.default)( (0, _from.default)(this.cachedDeviceMap.entries()) )}` ); await this.commander.print(`adb -s ${sn} reverse --list`); await this.commander.print(`adb -s ${sn} forward --list`); } await this._removeItemFromClientLogFile(sn); (0, _debuglog.default)(`deviceRemoved():(${sn}) end`); } /** * 记录一条端口映射条目 */ async _writeClientLogFile(newClient) { try { (0, _recordClient.recordClient)(_recordClient.clientRecordPath, newClient, (msg) => { (0, _debuglog.default)(msg); }); } catch (err) { console.error( `### App Server ### writeClientLogFile(): 写入client.json文件出错: ${err.message}` ); } } /** * 从端口映射记录文件中移除一个条目 */ async _removeItemFromClientLogFile(sn) { try { (0, _recordClient.removeClientBySn)(_recordClient.clientRecordPath, sn, (msg) => { (0, _debuglog.default)(msg); }); } catch (err) { console.error( `### App Server ### _removeItemFromClientLogFile(): 移除client.json设备信息出错: ${err.message}` ); } } /** * 建立Websocket连接的端口映射 * @param sn 设备序列号 * @param remoteWsPort Websocket连接的远程端口号 * @returns {Promise.<{ localWsPort } | { err }>} */ async forwardForWsChannel(sn, remoteWsPort) { let device = this.currentDeviceMap.get(sn); // 暂时localWsPort与remoteWsPort一样; const localWsPort = remoteWsPort; const localReversePort = this.option.localReversePort; if (!sn) { const { err } = await this.setupPortForwarding(localWsPort, remoteWsPort); if (err) { console.error(`### AppApp Server ### forwardForWsChannel(): 创建WebSocket端口映射失败`); return { err }; } return { localWsPort, localReversePort }; } if (!device) { const realSN = this.emulators.get(sn); console.info(`### App Server ### 通过(${sn})查找到设备${realSN}`); device = this.currentDeviceMap.get(realSN); if (device) { sn = realSN; } } if (!device) { console.error(`### App Server ### 获取(${sn})设备信息失败`); return { localWsPort, localReversePort }; } const wsPortPair = device.wsPortPair; // 若之前不存在端口, 说明是第一次连接,否则可以不必设定 if (wsPortPair && wsPortPair[0] === localWsPort && wsPortPair[1] === remoteWsPort) { return { localWsPort, localReversePort }; } const { err } = await this.establishADBProxyLink('forward', [sn, localWsPort, remoteWsPort]); if (err) { console.error(`### AppApp Server ### forwardForWsChannel(): 创建WebSocket端口映射失败`); device.wsPortPair = undefined; return { err }; } device.wsPortPair = [localWsPort, remoteWsPort]; return { localWsPort, localReversePort }; } /** * 建立adb reverse/forward通道 * @param type {string} "reverse"|"forward" * @param args {array} 建立reverse/forward通道所需的参数. e.g. [sn, localPort, devicePort] */ async establishADBProxyLink(type, args) { const result = await this.commander[type](...args); if (this.DEBUG) { (0, _debuglog.default)( `establishADBReverseLink(): (${args[0]}) adb ${type} setup result: ${(0, _stringify.default)( result )}` ); await this.commander.print(`adb -s ${args[0]} ${type} --list`); } if (result.err) { const { err } = await this.setupPortReversing(args[1], args[2]); if (err) { console.error(`### AppApp Server ### setupPortReversing(): 创建adb端口映射失败 ${args[1]} ${args[2]} ${err}`); return { err }; } return {}; } return result; } // Sample function to set up port forwarding async setupPortForwarding(localPort, remotePort) { try { // Check connected devices const { deviceList } = await this.commander.deviceList(); // If no devices are connected, handle it if (deviceList.length === 0) { console.log('No devices connected.'); return; } // Use the first device if multiple are connected const deviceSerial = deviceList[0]; // Forward the port const result = await this.commander.forward(deviceSerial, localPort, remotePort); return result; } catch (error) { console.error('Error forwarding port:', error); } return { err: 'Port forwarding failed' }; } // Sample function to set up port forwarding async setupPortReversing(localPort, remotePort) { try { // Check connected devices const { deviceList } = await this.commander.deviceList(); // If no devices are connected, handle it if (deviceList.length === 0) { console.log('No devices connected.'); return; } // Use the first device if multiple are connected const deviceSerial = deviceList[0]; // Forward the port const result = await this.commander.reverse(deviceSerial, localPort, remotePort); return result; } catch (error) { console.error('Error forwarding port:', error); } return { err: 'Port forwarding failed' }; } }var _default = exports.default = ADBModule;