Skip to content

Commit

Permalink
初始化项目
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyJiangWJ committed Apr 25, 2020
0 parents commit 7ae9bb1
Show file tree
Hide file tree
Showing 39 changed files with 4,305 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.DS_Store
*.zip
*.log
*.ign.js
339 changes: 339 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

# 简介
579 changes: 579 additions & 0 deletions config.js

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions extends/ExternalUnlockDevice-demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module.exports = function (obj) {
this.__proto__ = obj

this.unlock = function (password) {
// 自行定制化解锁方式,这里展示PIN密码的解锁
if (typeof password !== 'string') throw new Error('密码应为字符串!')
// 模拟按键
let button = null
for (let i = 0; i < password.length; i++) {
let key_id = 'com.android.systemui:id/key' + password[i]
if ((button = id(key_id).findOne(_config.timeout_findOne)) !== null) {
button.click()
}
sleep(100)
}
// 解锁完毕后返回check_lock方法,模块自动判断是否成功
return this.check_lock()
}


/**
* 一般情况下仅仅重写unlock即可,点亮、滑动、校验等等都在Unlock中实现了通用方式
* 但是如果机型特殊,可以直接重写run_unlock()方法
* 在run_unlock中编写自己的解锁方式
*/
this.run_unlock = function () {
// 在这个里面编写解锁逻辑
}

/**
* 又或者只有某一个小方法不适用,可以只修改对应的方法即可
* 具体方法见Unlock中定义的方法 比如failed、check_unlock、swipe_layer等等
*/

}
43 changes: 43 additions & 0 deletions lib/AesUtil.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* @Author: TonyJiangWJ
* @Date: 2020-01-08 17:07:28
* @Last Modified by: TonyJiangWJ
* @Last Modified time: 2020-01-10 17:48:09
* @Description: AES加密工具
*/
let CryptoJS = require('./crypto-js.js')

function AesUtil () {
this.key = device.getAndroidId()
}

AesUtil.prototype.encrypt = function (message, key) {
key = key || this.key
if (key.length !== 8 && key.length !== 16 && key.length !== 32) {
console.error('密码长度不正确必须为8/16/32位')
return null
}
return CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(key), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
}

AesUtil.prototype.decrypt = function(encrypt, key) {
key = key || this.key
if (key.length !== 8 && key.length !== 16 && key.length !== 32) {
console.error('密码长度不正确必须为8/16/32位')
return null
}
try {
return CryptoJS.AES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(key), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8)
} catch (e) {
console.error('秘钥不正确无法解密')
return null
}
}

module.exports = new AesUtil()
32 changes: 32 additions & 0 deletions lib/AlipayUnlocker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
let { config: _config } = require('../config.js')(runtime, this)
let WidgetUtils = require('./WidgetUtils.js')(runtime, this)
let automator = require('./Automator.js')(runtime, this)

const AlipayUnlocker = function () {
}
AlipayUnlocker.prototype.drawGestureByPassword = function (lockBounds) {
let password = _config.alipay_lock_password
let boxWidth = (lockBounds.right - lockBounds.left) / 3
let boxHeight = (lockBounds.bottom - lockBounds.top) / 3
let positions = password.split('').map(p => {
let checkVal = parseInt(p) - 1
return { r: parseInt(checkVal / 3), c: parseInt(checkVal % 3) }
}).map(p => {
return [parseInt(lockBounds.left + (0.5 + p.c) * boxWidth), parseInt(lockBounds.top + (0.5 + p.r) * boxHeight)]
})
gesture(220 * positions.length, positions)
}

AlipayUnlocker.prototype.unlockAlipay = function () {
let gestureButton = WidgetUtils.widgetGetOne('验证手势', 2000)
if (gestureButton) {
automator.clickCenter(gestureButton)
sleep(500)
}
let lockView = WidgetUtils.widgetGetById('.*lockView.*')
if (lockView) {
this.drawGestureByPassword(lockView.bounds())
}
}

module.exports = new AlipayUnlocker()
230 changes: 230 additions & 0 deletions lib/Automator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
/*
* @Author: TonyJiangWJ
* @Date: 2020-04-25 11:57:51
* @Last Modified by: TonyJiangWJ
* @Last Modified time: 2020-04-25 16:11:50
* @Description:
*/

module.exports = function (__runtime__, scope) {
let { config: _config } = require('../config.js')(__runtime__, scope)
let _logUtils = require('./LogUtils.js')(__runtime__, scope)
const hasRootPermission = function () {
return files.exists("/sbin/su") || files.exists("/system/xbin/su") || files.exists("/system/bin/su")
}

if (typeof scope.Automator === 'undefined') {
const _automator = (device.sdkInt < 24 || hasRootPermission()) ? new Automation_root() : new Automation()
scope.Automator = {
click: function (x, y) {
return _automator.click(x, y)
},
clickCenter: function (obj) {
return _automator.click(obj.bounds().centerX(), obj.bounds().centerY())
},
swipe: function (x1, y1, x2, y2, duration) {
return _automator.swipe(x1, y1, x2, y2, duration)
},
gesture: function (duration, points) {
return _automator.gesture(duration, points)
},
back: function () {
return _automator.back()
},
lockScreen: function () {
return _automator.lockScreen()
},
scrollDown: function (speed) {
if (_config.useCustomScrollDown) {
return _automator.scrollDown(speed)
} else {
return scrollDown()
}
},
scrollUpAndDown: function (speed) {
if (_config.useCustomScrollDown) {
return _automator.scrollUpAndDown(speed)
} else {
let deviceHeight = _config.device_height || 1900
// 手势下拉
_automator.swipe(400, parseInt(deviceHeight / 3), 600, parseInt(deviceHeight / 3 * 2), 150)
sleep(200)
scrollDown()
}
},
clickBack: function (forceBack) {
return _automator.clickBack(forceBack)
},
clickClose: function () {
return _automator.clickClose()
},
enterFriendList: function () {
return _automator.enterFriendList()
}
}
}
return scope.Automator


function CommonAutomation () {
this.scrollDown = function (speed) {
let millis = speed || _config.scrollDownSpeed || 500
let deviceHeight = _config.device_height || 1900
let bottomHeight = _config.bottomHeight || 250
let x = parseInt(_config.device_width / 2)
this.swipe(x, deviceHeight - bottomHeight, x + 100, parseInt(deviceHeight / 5), millis)
}

this.scrollUpAndDown = function (speed) {
let millis = parseInt((speed || _config.scrollDownSpeed || 500) / 2)

let deviceHeight = _config.device_height || 1900
let bottomHeight = _config.bottomHeight || 250
let x = parseInt(_config.device_width / 2)
// 下拉
this.swipe(x, parseInt(deviceHeight / 3), x + 100, parseInt(deviceHeight / 3 * 2), millis)
sleep(millis + 20)
this.swipe(x, deviceHeight - bottomHeight, x + 100, parseInt(deviceHeight / 5), millis)
}

this.clickBack = function (forceBack) {
let hasButton = false
if (descEndsWith('返回').exists()) {
descEndsWith('返回')
.findOne(_config.timeout_findOne)
.click()
hasButton = true
} else if (textEndsWith('返回').exists()) {
textEndsWith('返回')
.findOne(_config.timeout_findOne)
.click()
hasButton = true
} else if (forceBack) {
this.back()
}
if (hasButton) {
sleep(200)
}
return hasButton
}

this.clickClose = function () {
let hasButton = false
if (descEndsWith('关闭').exists()) {
descEndsWith('关闭')
.findOne(_config.timeout_findOne)
.click()
hasButton = true
} else if (textEndsWith('关闭').exists()) {
textEndsWith('关闭')
.findOne(_config.timeout_findOne)
.click()
hasButton = true
}
if (hasButton) {
sleep(200)
}
return hasButton
}

this.enterFriendList = function (tryCount) {
tryCount = tryCount || 1
if (descEndsWith(_config.enter_friend_list_ui_content).exists()) {
descEndsWith(_config.enter_friend_list_ui_content)
.findOne(_config.timeout_findOne)
.click()
} else if (textEndsWith(_config.enter_friend_list_ui_content).exists()) {
textEndsWith(_config.enter_friend_list_ui_content)
.findOne(_config.timeout_findOne)
.click()
} else {
if (tryCount > 3) {
return
}
_logUtils.warnInfo(['未找到 查看更多好友 等待一秒钟后重试, 尝试次数:{}', tryCount])
// 未找到查看更多好友,等待1秒钟后重试
sleep(1000)
this.enterFriendList(++tryCount)
}
sleep(200)
}
}
function Automation_root () {
CommonAutomation.call(this)

this.check_root = function () {
if (!(files.exists("/sbin/su") || files.exists("/system/xbin/su") || files.exists("/system/bin/su"))) throw new Error("未获取ROOT权限")
}

this.click = function (x, y) {
this.check_root()
return (shell("input tap " + x + " " + y, true).code === 0)
}

this.swipe = function (x1, y1, x2, y2, duration) {
this.check_root()
return (shell("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration, true).code === 0)
}

this.gesture = function (duration, points) {
this.check_root()
let len = points.length,
step = duration / len,
start = points.shift()

// 使用 RootAutomator 模拟手势,仅适用于安卓5.0及以上
let ra = new RootAutomator()
ra.touchDown(start[0], start[1])
sleep(step)
points.forEach(function (el) {
ra.touchMove(el[0], el[1])
sleep(step)
})
ra.touchUp()
ra.exit()
return true
}

this.back = function () {
this.check_root()
return (shell("input keyevent KEYCODE_BACK", true).code === 0)
}

this.lockScreen = function () {
return (shell("input keyevent 26", true).code === 0)
}

}

function Automation () {
CommonAutomation.call(this)

this.click = function (x, y) {
return click(x, y)
}

this.swipe = function (x1, y1, x2, y2, duration) {
return swipe(x1, y1, x2, y2, duration)
}

this.gesture = function (duration, points) {
return gesture(duration, points)
}

this.back = function () {
return back()
}

/**
* 下拉状态栏,点击锁屏按钮
*/
this.lockScreen = function () {
swipe(500, 10, 500, 1000, 500)
swipe(500, 10, 500, 1000, 500)
// 点击锁屏按钮
click(parseInt(_config.lock_x), parseInt(_config.lock_y))
}

}

}
Loading

0 comments on commit 7ae9bb1

Please sign in to comment.