Skip to content

Commit

Permalink
加入配置导入导出功能,优化保护罩检测机制 按实际使用时间记录
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyJiangWJ committed Jan 10, 2020
1 parent ca2cb05 commit d69a32f
Show file tree
Hide file tree
Showing 16 changed files with 6,455 additions and 50 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
- `新增` 加入自动识别基于控件还是图像分析的开关,好友数较多的直接使用基于图像分析即可
- `20191221-新增` 支持支付宝手势密码解锁,勾选 `支付宝是否锁定` 然后填入手势顺序经过的九宫格数字,每个数字都需要填写,比如手势为简单的Z 则输入`1235789`
- `20191221-新增` 截图权限相关默认 `获取截图等待时间` 是500毫秒,如果经常失败请修改该值 改大一些
- `20200110-新增` 加入配置导出和导入的功能,通过AES加密,默认密码是device.getAndroidId(),因此仅本机可用。如果需要跨设备或者免费版和Pro版之间备份,自行获取device.getAndroidId()然后根据提示输入即可

# 使用

Expand All @@ -63,6 +64,8 @@
- 常用配置都在基本配置中,可以设置悬浮窗颜色 位置等
- 运行配置后右上角菜单可以重置所有配置信息为默认值
- 运行配置后可以看到百度API调用总次数和剩余次数
- 配置导出导入功能,点击右上角菜单即可导出当前配置到local_config.cfg中,默认已加密加密密码为device.getAndriodId() 如果需要在免费版和付费版AutoJS之间同步 需要自行输入密码
- 运行时数据导出导入功能同上所述

![基本配置](./resources/config-1.png)

Expand Down
128 changes: 125 additions & 3 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @Author: TonyJiangWJ
* @Date: 2019-12-09 20:42:08
* @Last Modified by: TonyJiangWJ
* @Last Modified time: 2019-12-30 16:40:51
* @Last Modified time: 2020-01-09 11:00:38
* @Description:
*/
"ui";
Expand Down Expand Up @@ -153,6 +153,7 @@ if (!inRunningMode) {
// 传递给commonFunction 避免二次引用config.js
const storage_name = CONFIG_STORAGE_NAME
let commonFunctions = require('./lib/CommonFunction.js')
let AesUtil = require('./lib/AesUtil.js')
// 初始化list 为全局变量
let whiteList = [], wateringBlackList = [], helpBallColorList = []
const setScrollDownUiVal = function () {
Expand Down Expand Up @@ -449,7 +450,7 @@ if (!inRunningMode) {
</horizontal>
{/* 是否永不停止 */}
<vertical id="neverStopContainer">
<text text="永不停止模式请不要全天24小时运行,具体见README.md"/>
<text text="永不停止模式请不要全天24小时运行,具体见README" />
<horizontal gravity="center">
<checkbox id="isNeverStopChkBox" text="是否永不停止" />
<horizontal padding="10 0" id="reactiveTimeContainer" gravity="center" layout_weight="75">
Expand Down Expand Up @@ -697,7 +698,7 @@ if (!inRunningMode) {
<text text="保护罩:" layout_weight="20" />
<input inputType="text" id="usingProtectContentInpt" layout_weight="80" />
</horizontal>
<text text="通过运行 util/悬浮窗框位置.js 可以获取对应位置信息"/>
<text text="通过运行 util/悬浮窗框位置.js 可以获取对应位置信息" />
<horizontal gravity="center">
<text text="校验排行榜分析范围:" layout_weight="20" />
<input inputType="text" id="rankCheckRegion" layout_weight="80" />
Expand Down Expand Up @@ -746,9 +747,16 @@ if (!inRunningMode) {
// 创建选项菜单(右上角)
ui.emitter.on("create_options_menu", menu => {
menu.add("全部重置为默认")
menu.add("从配置文件中读取")
menu.add("将配置导出")
menu.add("导出运行时数据")
menu.add("导入运行时数据")
})
// 监听选项菜单点击
ui.emitter.on("options_item_selected", (e, item) => {
let local_config_path = files.cwd() + '/local_config.cfg'
let runtime_store_path = files.cwd() + '/runtime_store.cfg'
let aesKey = device.getAndroidId()
switch (item.getTitle()) {
case "全部重置为默认":
confirm('确定要将所有配置重置为默认值吗?').then(ok => {
Expand All @@ -762,6 +770,120 @@ if (!inRunningMode) {
}
})
break
case "从配置文件中读取":
confirm('确定要从local_config.cfg中读取配置吗?').then(ok => {
if (ok) {
try {
if (files.exists(local_config_path)) {
const refillConfigs = function (configStr) {
let local_config = JSON.parse(configStr)
Object.keys(default_config).forEach(key => {
let defaultValue = local_config[key]
if (typeof defaultValue === 'undefined') {
defaultValue = default_config[key]
}
config[key] = defaultValue
storageConfig.put(key, defaultValue)
})
resetUiValues()
}
let configStr = AesUtil.decrypt(files.read(local_config_path), aesKey)
if (!configStr) {
toastLog('local_config.cfg解密失败, 请尝试输入秘钥')
dialogs.rawInput('请输入秘钥,可通过device.getAndroidId()获取')
.then(key => {
if (key) {
key = key.trim()
configStr = AesUtil.decrypt(files.read(local_config_path), key)
if (configStr) {
refillConfigs(configStr)
} else {
toastLog('秘钥不正确,无法解析')
}
}
})
} else {
refillConfigs(configStr)
}
} else {
toastLog('local_config.cfg不存在无法导入')
}
} catch (e) {
toastLog(e)
}
}
})
break
case "将配置导出":
confirm('确定要将配置导出到local_config.cfg吗?此操作会覆盖已有的local_config数据').then(ok => {
if (ok) {
Object.keys(default_config).forEach(key => {
console.verbose(key + ': ' + config[key])
})
try {
let configString = AesUtil.encrypt(JSON.stringify(config), aesKey)
files.write(local_config_path, configString)
toastLog('配置信息导出成功,刷新目录即可,local_config.cfg内容已加密仅本机可用,除非告知秘钥')
} catch (e) {
toastLog(e)
}

}
})
break
case "导出运行时数据":
confirm('确定要将运行时数据导出到runtime_store.cfg吗?此操作会覆盖已有的数据').then(ok => {
if (ok) {
try {
let runtimeStorageStr = AesUtil.encrypt(commonFunctions.exportRuntimeStorage(), aesKey)
files.write(runtime_store_path, runtimeStorageStr)
} catch (e) {
toastLog(e)
}
}
})
break
case "导入运行时数据":
confirm('确定要将从runtime_store.cfg导入运行时数据吗?此操作会覆盖已有的数据').then(ok => {
if (ok) {
if (files.exists(runtime_store_path)) {
let encrypt_content = files.read(runtime_store_path)
const resetRuntimeStore = function (runtimeStorageStr) {
if (commonFunctions.importRuntimeStorage(runtimeStorageStr)) {
resetUiValues()
return true
}
toastLog('导入运行配置失败,无法读取正确信息')
return false
}
try {
let decrypt = AesUtil.decrypt(encrypt_content, aesKey)
if (!decrypt) {
toastLog('runtime_store.cfg解密失败, 请尝试输入秘钥')
dialogs.rawInput('请输入秘钥,可通过device.getAndroidId()获取')
.then(key => {
if (key) {
key = key.trim()
decrypt = AesUtil.decrypt(encrypt_content, key)
if (decrypt) {
resetRuntimeStore(decrypt)
} else {
toastLog('秘钥不正确,无法解析')
}
}
})
} else {
resetRuntimeStore(decrypt)
}
} catch (e) {
toastLog(e)
}
} else {
toastLog('配置信息不存在,无法导入')
}
}
})
break
}
e.consumed = true
})
Expand Down
2 changes: 2 additions & 0 deletions core/Ant_forest.js
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,8 @@ function Ant_forest () {
_collect_any = false
if (_lost_someone) {
warnInfo('上一次收取有漏收,再次收集', true)
automator.back()
_commonFunctions.getAndUpdateSpringboard('lost_someone')
} else {
debugInfo(['获取到的倒计时时间:{}', _min_countdown])
if (_min_countdown > 0) {
Expand Down
10 changes: 6 additions & 4 deletions core/BaseScanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,16 @@ const BaseScanner = function () {
}
}

this.recordCurrentProtected = function (name) {
this.recordCurrentProtected = function (name, timeout) {
if (name) {
_commonFunctions.addNameToProtect(name)
_commonFunctions.addNameToProtect(name, timeout)
return
}
let title = textContains('的蚂蚁森林')
.findOne(_config.timeout_findOne)
.text().match(/(.*)的蚂蚁森林/)
if (title) {
_commonFunctions.addNameToProtect(title[1])
_commonFunctions.addNameToProtect(title[1], timeout)
} else {
errorInfo(['获取好友名称失败,无法加入保护罩列表,请检查好友首页文本"XXX的蚂蚁森林"是否存在'])
}
Expand Down Expand Up @@ -225,7 +225,9 @@ const BaseScanner = function () {
}
}
debugInfo(['using time:{}-{} rows: yesterday[{}] target[{}]', (isToday ? '今天' : '昨天'), usingTime || time, yesterdayRow, targetRow], true)
this.recordCurrentProtected(name)
let timeout = isToday ? new Date(formatDate(new Date(new Date().getTime() + 24 * 3600000), 'yyyy/MM/dd ') + usingTime)
: new Date(formatDate(new Date(), 'yyyy/MM/dd ') + usingTime)
this.recordCurrentProtected(name, timeout)
return true
} else {
debugInfo('not found using protect info')
Expand Down
6 changes: 3 additions & 3 deletions core/FriendListScanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @Author: TonyJiangWJ
* @Date: 2019-11-11 09:17:29
* @Last Modified by: TonyJiangWJ
* @Last Modified time: 2019-12-18 15:28:29
* @Last Modified time: 2020-01-08 11:41:23
* @Description: 基于控件识别可收取信息
*/
let _widgetUtils = typeof WidgetUtils === 'undefined' ? require('../lib/WidgetUtils.js') : WidgetUtils
Expand Down Expand Up @@ -472,7 +472,7 @@ FriendListScanner.prototype.collectTargetFriend = function (obj) {
automator.back()
return
}
debugInfo('准备开始收取')
debugInfo(['准备开始收取好友:「{}」', obj.name])
let temp = this.protectDetect(_package_name, obj.name)
let preGot
let preE
Expand Down Expand Up @@ -529,7 +529,7 @@ FriendListScanner.prototype.collectTargetFriend = function (obj) {
helpCollect: gotEnergy
})
} else {
debugInfo("帮助好友:" + obj.name + " 回收能量 " + gotEnergy + "g")
logInfo("帮助好友:" + obj.name + " 回收能量 " + gotEnergy + "g")
}
}
} catch (e) {
Expand Down
33 changes: 25 additions & 8 deletions core/ImgBasedFriendListScanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @Author: TonyJiangWJ
* @Date: 2019-11-11 09:17:29
* @Last Modified by: TonyJiangWJ
* @Last Modified time: 2019-12-30 04:36:20
* @Last Modified time: 2020-01-10 19:06:07
* @Description: 基于图像识别控件信息
*/
importClass(com.tony.BitCheck)
Expand Down Expand Up @@ -208,6 +208,7 @@ const ImgBasedFriendListScanner = function () {
BaseScanner.call(this)
this.threadPool = null
this.min_countdown_pixels = 10
this.resolved_pixels = {}

this.init = function (option) {
this.current_time = option.currentTime || 0
Expand All @@ -223,6 +224,7 @@ const ImgBasedFriendListScanner = function () {
this.increased_energy = 0
this.min_countdown = 10000
this.min_countdown_pixels = 10
this.resolved_pixels = {}
debugInfo('图像分析即将开始')
return this.collecting()
}
Expand Down Expand Up @@ -253,7 +255,7 @@ const ImgBasedFriendListScanner = function () {
}

this.reachBottom = function (grayImg) {
let virtualButtonHeight = _config.virtualButtonHeight | 0
let virtualButtonHeight = _config.virtualButtonHeight || 0
let height = device.height - virtualButtonHeight
for (let startY = 5; startY < 50; startY++) {
let colorGreen = grayImg.getBitmap().getPixel(10, height - startY) >> 8 & 0xFF
Expand All @@ -266,6 +268,8 @@ const ImgBasedFriendListScanner = function () {
this.collecting = function () {
let screen = null
let grayScreen = null
let screenForDetectCollect = null
let screenForDetectHelp = null
// console.show()
let countingDownContainers = []
let count = 0
Expand All @@ -275,13 +279,16 @@ const ImgBasedFriendListScanner = function () {
screen = _commonFunctions.checkCaptureScreenPermission(false, 5)
// 重新复制一份
let tmpImg = images.copy(screen)
screenForDetectCollect = images.copy(screen)
screenForDetectHelp = images.copy(screen)
grayScreen = images.grayscale(tmpImg)
tmpImg.recycle()
debugInfo('获取到screen' + (screen === null ? '失败' : '成功'))
screen.recycle()
let countdown = new Countdown()
let waitForCheckPoints = []
if (_config.help_friend) {
let helpPoints = this.sortAndReduce(this.detectHelp(screen))
let helpPoints = this.sortAndReduce(this.detectHelp(screenForDetectHelp))
if (helpPoints && helpPoints.length > 0) {
waitForCheckPoints = waitForCheckPoints.concat(helpPoints.map(
helpPoint => {
Expand All @@ -293,7 +300,7 @@ const ImgBasedFriendListScanner = function () {
)
}
}
let collectPoints = this.sortAndReduce(this.detectCollect(screen))
let collectPoints = this.sortAndReduce(this.detectCollect(screenForDetectCollect))
if (collectPoints && collectPoints.length > 0) {
waitForCheckPoints = waitForCheckPoints.concat(collectPoints.map(
collectPoint => {
Expand Down Expand Up @@ -340,7 +347,7 @@ const ImgBasedFriendListScanner = function () {
debugInfo('倒计时中:' + JSON.stringify(point) + ' 像素点总数:' + point.same)
// 直接标记执行完毕 将OCR请求交给异步处理
countdownLatch.countDown()
if (_config.useOcr) {
if (_config.useOcr && !_config.is_cycle) {
let countdownImg = images.clip(grayScreen, point.left, point.top, point.right - point.left, point.bottom - point.top)
let base64String = null
try {
Expand All @@ -353,6 +360,12 @@ const ImgBasedFriendListScanner = function () {
errorInfo('存储倒计时图片失败:' + e)
}
if (base64String) {
if (that.resolved_pixels[point.same]) {
debugInfo(['该像素点总数[{}]已校验过,倒计时值为:{}', point.same, that.resolved_pixels[point.same + 'count']])
return
} else {
debugInfo(['该像素点总数[{}]未校验', point.same])
}
if (point.same > (_config.ocrThresold || 2900) && that.min_countdown >= 2) {
// 百度识图API获取文本
let result = BaiduOcrUtil.recoginze(base64String)
Expand All @@ -362,6 +375,9 @@ const ImgBasedFriendListScanner = function () {
debugInfo('百度识图结果:' + JSON.stringify(filter))
countdownLock.lock()
let countdown = parseInt(filter[0].words)
// 标记该像素点总数的图片已处理过
that.resolved_pixels[point.same] = true
that.resolved_pixels[point.same + 'count'] = countdown
if (countdown < that.min_countdown) {
debugInfo('设置最小倒计时:' + countdown)
that.min_countdown = countdown
Expand Down Expand Up @@ -433,7 +449,8 @@ const ImgBasedFriendListScanner = function () {
} else {
hasNext = count < (_config.friendListScrollTime || 30)
}
screen.recycle()
screenForDetectCollect.recycle()
screenForDetectHelp.recycle()
grayScreen.recycle()
// 每5次滑动判断一次是否在排行榜中
if (hasNext && count % 5 == 0 && !_widgetUtils.friendListWaiting()) {
Expand Down Expand Up @@ -595,7 +612,7 @@ ImgBasedFriendListScanner.prototype.collectTargetFriend = function (obj) {
if (skip) {
return this.returnToListAndCheck()
}
debugInfo('准备开始收取')
debugInfo(['准备开始收取好友:「{}」', obj.name])
let temp = this.protectDetect(_package_name, obj.name)
let preGot
let preE
Expand Down Expand Up @@ -651,7 +668,7 @@ ImgBasedFriendListScanner.prototype.collectTargetFriend = function (obj) {
helpCollect: gotEnergy
})
} else {
debugInfo("帮助好友:" + obj.name + " 回收能量 " + gotEnergy + "g")
logInfo("帮助好友:" + obj.name + " 回收能量 " + gotEnergy + "g")
}
}
} catch (e) {
Expand Down
Loading

0 comments on commit d69a32f

Please sign in to comment.