Yee hace 5 años
commit
1622073d83
Se han modificado 1 ficheros con 487 adiciones y 0 borrados
  1. 487
    0
      adb_proto.js

+ 487
- 0
adb_proto.js Ver fichero

@@ -0,0 +1,487 @@
const fs = require('fs');
const spawn = require('child_process').spawn;
const spawnSync = require('child_process').spawnSync;
const path = require('path');
const scanf = require('scanf');
const HTMLParser = require('node-html-parser');

const hw = require(path.join(__dirname, 'GTBOT.node'));

/**
* option: {
* nox_path: E:/nox/Nox,
* open_count: 2,
* close_time: 1000(ms)
* }
*/

class GT_Nox_Command{
/**
* @param {String} noxName 夜神內部Id e.g. Nox_1,Nox_2
* @param {String} noxPath 夜神的安裝位置, 預設為 C:/Program Files (x86)/Nox
*/
constructor(titleTable,option){
this.titleToNoxIdTable = titleTable;
if(typeof option !== "object") option = {};
this.noxPath = option.nox_path?option.nox_path:"C:/Program Files (x86)/Nox";
this.openCount = option.open_count?option.open_count:1;
this.closeTime = option.close_time?option.close_time:1000;

this.nox_command_file = path.join(this.noxPath,"bin","Nox.exe");

this.errorExec = [];
}

nox_command(titleName,option){
let argv_arr = ["-clone:" + this.titleToNoxIdTable[titleName] ];
if(typeof option === "object"){
for(let i in option){
let temp = "-" + i + ":" + option[i];
argv_arr[argv_arr.length] = temp;
}
}
else if(typeof option === "string"){
argv_arr[argv_arr.length] = option;
}

let cmd = spawn(this.nox_command_file, argv_arr, {
detached: true
});
cmd.stdout.on('data', (data) => {
// console.log(`stdout: \n${data}`);
});
cmd.stderr.on('data', (data) => {
// console.log(`stderr: ${data}`);
});
cmd.on('close', (code) => {
// console.log(`child process exited with code $[code]`);
});
}

static checkOpen(title,cb){
let count = 0;
let intervalTemp = setInterval(function(){
let mainW = hw.findWindowEx(0, 0, "Qt5QWindowIcon" , title);
if(mainW){
// init 時會有一個 title 是""的東西
let check1 = hw.findWindowEx(mainW, 0, "Qt5QWindowIcon" , '');
let check2 = hw.findWindowEx(mainW, 0, "Qt5QWindowIcon" , 'default_title_barWindow');
if(check1 === check2){
if(++count > 3){
clearInterval(intervalTemp);
cb();
}
}
}
},1000);
}

open_process(titleName){
if(this.titleToNoxIdTable[titleName] === undefined){
this.errorExec[this.errorExec.length] = titleName;
return;
}
this.nox_command(titleName);
GT_Nox_Command.checkOpen(titleName,function(){
this.finish_open();
}.bind(this));
}

finish_open(){
if(this.open_arr.length <= 0){
let msg = {};
if(this.errorExec.length > 0){
msg.err = this.errorExec.slice(0);;
}
this.finish_open_cb(msg);
this.errorExec = [];
return;
}
else{
let nextOpen = this.open_arr.shift();
this.open_process(nextOpen);
}
}
/**
* 開啟模擬器
* @param {Array || String} titleNameArr 要開啟哪些APK
* @param {Function} cb 開完了,你要做啥
* option{
* cpu:1,
* memory: 960(or 1024),
* resolution: '320x240',
* dpi: 120,
* root:false
* }
*/
openNox(titleNameArr,cb){
let titleArr;
if( Array.isArray(titleNameArr) ){
titleArr = titleNameArr;
}
else if(typeof titleNameArr === "string"){
titleArr = [titleNameArr]
}

this.open_arr = titleArr;
this.finish_open_cb = cb;

for(let i=0;i < this.openCount;i++){
let nextOpen = this.open_arr.shift();
this.open_process(nextOpen,i);
if(this.open_arr.length === 0){
break;
}
}
}
colse_process(closeTitle){
if(this.titleToNoxIdTable[closeTitle] === undefined){
this.errorExec[this.errorExec.length] = closeTitle;
return;
}
this.nox_command(closeTitle,"-quit");
}

/**
* 關閉模擬器
* @param {Array || String} titleNameArr 要關哪些APK
* @param {Function} cb 關完了,你要做啥
*/
closeNox(titleNameArr,cb){
let titleArr;
if( Array.isArray(titleNameArr) ){
titleArr = titleNameArr;
}
else if(typeof titleNameArr === "string"){
titleArr = [titleNameArr]
}
// console.log(cb);
this.activeFlage = true;

let closeCount = 1;
this.colse_process(titleArr[0]);
let closeItl = setInterval(function(){
this.colse_process(titleArr[closeCount]);
closeCount++;
if(closeCount >= titleArr.length){
clearInterval(closeItl);
let msg = {};
if(this.errorExec.length > 0){
msg.err = this.errorExec.slice(0);;
}
this.errorExec = [];
if(typeof cb === 'function'){
cb(msg);
}
}
}.bind(this),this.closeTime);
}

restartNox(titleNameArr,cb){
let titleArr;
if( Array.isArray(titleNameArr) ){
titleArr = titleNameArr;
}
else if(typeof titleNameArr === "string"){
titleArr = [titleNameArr]
}

this.closeNox(titleArr,function(){
setTimeout(()=>{
this.openNox(titleArr,cb);
},5000);
}.bind(this));
}

/**
* 安裝APK
* @param {String} apk_path apk 的絕對位置
*/
install_apk(apk_path){
if(typeof apk_path !== "string"){
console.log("你的apk path呢!");
return;
}
this.nox_command("'-apk:" + apk_path + "'");
}

/**
* 執行某個App,預設開托蘭
* @param {string} appId app的唯一Id
*/
run_app(appId){
if(appId === undefined){
appId = "com.asobimo.toramonline";
}

this.nox_command({package:appId});
}
}

class adb_ctrl{
constructor(option){
this.nox_path = option.nox_path?option.nox_path:"C:/Program Files (x86)/Nox";
this.adb_file = path.join(this.nox_path,"bin","nox_adb.exe");

this.setMultiNoxList.call(this);

// title 對應 Nox_id
/**
* {
* atk01: Nox_1
* }
*/
// this.nox_table = {};
// port 對應 title
/**
* {
* 61025: Nox_1
* }
*/
// this.port_table = {};

this.nox_cmd = new GT_Nox_Command(this.nox_table,option);
// this.connect();
}

openNox(titleArr,cb){
this.nox_cmd.openNox.call(this.nox_cmd,titleArr,cb);
}

closeNox(titleArr,cb){
this.nox_cmd.closeNox.call(this.nox_cmd,titleArr,cb);
}

restartNox(titleArr,cb){
this.nox_cmd.restartNox.call(this.nox_cmd,titleArr,cb);
}

exec_adb_cb(argv,cb){
const status = spawn(this.adb_file, argv);
status.stdout.setEncoding('utf8');
status.stderr.setEncoding('utf8');
let stdout = "";
let err = false;
let errInfo = "";
status.stdout.on('data', (data) => {
stdout += (data + "||");
});

status.stderr.on('data', (data) => {
errInfo += (data + "||");
});

status.on('close', (code) => {
cb({
err: err,
errInfo: errInfo,
data: stdout
});
});
}

exec_adb(argv){
return new Promise( (resolve, reject) => {
const status = spawn(this.adb_file, argv);
status.stdout.setEncoding('utf8');
status.stderr.setEncoding('utf8');
let stdout;
status.stdout.on('data', (data) => {
stdout = data;
// console.log(data);
});

status.stderr.on('data', (data) => {
// console.log("err",data);
resolve({
err: true,
data: data
});
});

status.on('close', (code) => {
resolve({
err: false,
data:stdout
});
});
});
}

delay(time){
return new Promise( (resolve, reject) => {
setTimeout(function(){
resolve();
},time);
});
}

/**
* 找multiNox 路徑
*/
setMultiNoxList(){
let multi_list;
let multi_file = path.join(process.env.LOCALAPPDATA,'MultiPlayerManager','multiplayer.xml');
try{
multi_list = fs.readFileSync(multi_file,{encoding:"utf-8"});
}
catch(e){
console.log(e);
console.log("找不到夜神多工器啦 冠霆要你滾");
scanf("%d");
}
if(multi_list === undefined){
return;
}

let document = HTMLParser.parse(multi_list);

let Instance = document.querySelectorAll("Instance");
this.nox_table = {};
this.port_table = {};
this.title_to_device_table = {};
for(let i=0;i < Instance.length;i++){
let temp = Instance[i].attributes;
if(temp.id === "Nox_0"){
temp.id = "nox";
}
this.nox_table[temp.name] = temp.id;
let yee = fs.readFileSync(this.nox_path + '/bin/BignoxVMS/' + temp.id + '/' + temp.id + '.vbox',{encoding:"utf-8"});
let port = yee.split('<Forwarding name="port2" proto="1" hostip="127.0.0.1" hostport="')[1].slice(0,5);

this.port_table[port] = temp.name;
this.title_to_device_table[temp.name] = port;
}
// console.log(this.nox_table);
// console.log(this.port_table);
}

/**
* adb 初始化, adb 操作時,必做喔
*/
async adb_init(){
// var killServer = spawnSync(this.adb_file, ["kill-server"] ,{encoding: "utf-8"});
let killServer = await this.exec_adb(["kill-server"]);
if(killServer.err){
if(killServer.data.indexOf("server not running") === -1){
console.log("kill出錯啦~");
console.log(killServer);
scanf("%d");
return "err";
}
}
let startServer = await this.exec_adb( ["start-server"] );
if(startServer.err){
console.log("start出錯啦~");
console.log(startServer);
scanf("%d");
return "err";
}
console.log("初始化完成~ 天佑冠霆啦!!");
}

scanNox(){
return new Promise( (resolve, reject) => {
let count = 0;
let max = Object.keys(this.port_table).length;
// console.log("scan囉");
// console.log(Object.keys(this.port_table).length);
function afterScan(data){
count++;
// console.log(count);
// console.log(data);
if(max === count){
resolve();
}
}
for(let i in this.port_table){
this.exec_adb_cb( ["connect","127.0.0.1:" + i] ,afterScan);
}
});
}

/**
* 連結目前所有已開的夜神模擬器
*/
async connect(){
await this.adb_init();
if(this.port_table === undefined){
return "err";
}

await this.scanNox();

var devices = await this.exec_adb( ["devices"] );
// console.log(devices);
if(devices.err){
console.log("devices出錯啦~");
console.log(devices);
scanf("%d");
return "err";
}
let all_devices = devices.data.split("List of devices attached\r\n")[1];
let devices_list = all_devices.split("\tdevice\r\n");
devices_list = devices_list.reverse().slice(1);

this.devices_list = devices_list;
this.devices_count = devices_list.length;
this.installed_count = 0;
// console.log(devices_list);
// console.log("你要更新的裝置數量:" + this.devices_count);
}

async disconnect(){
let killServer = await this.exec_adb(["kill-server"]);
if(killServer.err){
if(killServer.data.indexOf("server not running") === -1){
console.log("kill出錯啦~");
console.log(killServer);
scanf("%d");
return "err";
}
}
}

/**
* 停止toram跟cloneApp 的App
*/
async close_toram(titleName){
let device = this.title_to_device_table[titleName];
if(device === undefined) return {err: "noThis"};
// for(let i=0; i < this.devices_count;i++){
// let status = await this.exec_adb( ["-s", this.devices_list[i] ,"shell","dumpsys activity | grep top-activity"] );
let status = await this.exec_adb( ["-s", "127.0.0.1:" + device ,"shell","am","force-stop","com.asobimo.toramonline"] );
status = await this.exec_adb( ["-s", "127.0.0.1:" + device ,"shell","am","force-stop","com.zhuowang.cloneapp"] );

return {};
// }
// this.nox_cmd.run_app("com.zhuowang.cloneapp:platform.gameplugin.P00");
// this.nox_cmd.run_app();
}
}

module.exports = adb_ctrl;

// let aa = new adb_ctrl({
// nox_path: "F:/Nox",
// open_count: 1,
// });

// let atkArr = [];
// for(let i=1;i< 3;i++){
// atkArr[atkArr.length] = "atk0" + i;
// }

// async function yee(gtadb){
// // await gtadb.adb_init.call(gtadb);
// await gtadb.connect();

// await gtadb.close_toram("atk01");
// await gtadb.close_toram("atk02");
// }

// yee(aa);

Cargando…
Cancelar
Guardar