local cjson = require "cjson" -- 导入 JSON 库
-- 获取当前设备下的任务、设备、账号、PKG相关信息
function getTaskAccountList()
local serialNumber = device.serial_number()
-- 执行HTTP GET请求
local code, head,body = http.get("http://xclick.munimob.com/paocai/automation/getTaskAccountList?serialNumber=" ..serialNumber)
-- 等待响应
sys.msleep(5000)
if (code == 200) then
result = json.decode(body)
if(result.code == 1) then
return result.data
end
end
end
-- 修改执行状态
function updateTaskDeviceTwo(id,pkgLog,accountLog)
-- 执行HTTP GET请求
-- 创建 JSON 请求体
local requestBody = cjson.encode({
taskDeviceId = id,
pkgLog = pkgLog,
accountLog = accountLog
})
-- 执行 HTTP POST 请求
local headers = {
["Content-Type"] = "application/json"
}
-- 发送 POST 请求
local code, head, body = http.post("http://xclick.munimob.com/paocai/automation/updateTaskDeviceTwo", 50, headers,requestBody)
-- 等待响应
sys.msleep(2000)
if (code == 200) then
-- 解析 JSON 响应
local result = json.decode(body)
if (result.code == 1) then
return "success"
end
end
end
-- 修改执行状态
function updateTaskDevice(id)
-- 执行HTTP GET请求
-- 创建 JSON 请求体
local requestBody = cjson.encode({
taskDeviceId = id
})
-- 执行 HTTP POST 请求
local headers = {
["Content-Type"] = "application/json"
}
-- 发送 POST 请求
local code, head, body = http.post("http://xclick.munimob.com/paocai/automation/updateTaskDevice", 50, headers,requestBody)
-- 等待响应
sys.msleep(2000)
if (code == 200) then
-- 解析 JSON 响应
local result = json.decode(body)
if (result.code == 1) then
return "success"
end
end
end
-- mzSslAtId 修改赋值
function setMzSslAtId(id,content)
-- 执行HTTP GET请求
local code, head,body = http.get("http://xclick.munimob.com/paocai/receipt/updateContent?id=" ..id .."&type=5&content=" ..content)
-- 等待响应
sys.msleep(2000)
if (code == 200) then
result = json.decode(body)
if(result.code == 1) then
return "success"
end
end
end
-- 修改账号状态
function updateStatus(id)
-- 执行HTTP GET请求
local code, head,body = http.get("http://xclick.munimob.com/paocai/automation/updateStatus/" ..id .."/0/3")
-- 等待响应
sys.msleep(2000)
if (code == 200) then
result = json.decode(body)
if(result.code == 1) then
return "success"
end
end
end
-- 启动AppStore
function startAppStore()
sys.toast("启动AppStore")
sys.msleep(2000)
app.quit(app.front_bid())
sys.msleep(2000)
app.run('com.apple.AppStore')
sys.msleep(15000)
welcome()
end
function welcome()
-- 判断是否有欢迎弹框
if screen.is_colors({
--继续定位
{231, 1960, 0x007aff},
{937, 1957, 0x007aff},
--图标定位
{618, 342, 0x1bc1fb},
{626, 510, 0x1c84f4}
}, 90) then
nLog("欢迎弹框匹配!")
-- 点击继续
touch.tap(635, 1950)
sys.msleep(3000)
else
nLog("欢迎弹框不匹配!")
sys.msleep(2000)
end
-- 判断是否有随时通知弹框
if screen.is_colors({
--继续定位
{312, 1961, 0x007aff},
{1007, 1978, 0x007aff},
--随知定位
{222, 1182, 0x000000},
{1019, 1192, 0x000000}
}, 90) then
nLog("随时通知弹框匹配!")
-- 点击以后再说
touch.tap(626, 2129)
sys.msleep(3000)
else
nLog("随时通知弹框不匹配!")
sys.msleep(2000)
end
end
-- 模拟登录流程
function loginAccount(account)
--启动AppStore
startAppStore()
-- 点击头像
touch.tap(1121,264)
sys.msleep(2000)
--点击输入账号
touch.tap(420,464)
sys.msleep(2000)
key.send_text(account.userAccount, 10)
--点击输入密码
sys.msleep(2000)
touch.tap(396,596)
sys.msleep(2000)
key.send_text(account.passWord, 10)
sys.msleep(2000)
--点击登录
touch.tap(380,832)
sys.msleep(45000)
--判断是否是安全验证
if screen.is_colors({
{ 625, 432, 0x007aff}, -- 如果坐标 (509, 488) 的颜色与 0xec1c23 相似度在 90% 以上
{ 737, 1968, 0x007aff} -- 同时坐标 (521, 433) 的颜色与 0xd0d2d2 相似度在 90% 以上
}, 90) then -- 则匹配
nLog("安全验证匹配!")
-- 点击其他选项
touch.tap(625,2120)
sys.msleep(2000)
--点击不升级
touch.tap(809,1340)
sys.msleep(45000)
--点击完成
touch.tap(1152,212)
sys.msleep(10000)
-- 登录成功,返回成功
return "success"
else
nLog("安全验证不匹配!")
-- 判断是否是继续输入密码
if screen.is_colors({
--右上角登录
{326, 394, 0x000000},
-- 忘记密码
{920, 382, 0x000000}
}, 90) then
nLog("继续输入密码匹配!")
--匹配然后继续输入密码
key.send_text(account.passWord, 10)
sys.msleep(2000)
-- 点击右上角登录
touch.tap(1125,204)
sys.msleep(15000)
else
nLog("继续输入密码不匹配!")
sys.msleep(4000)
end
-- 判断是否是账户停用
if screen.is_colors({
--验字
{522, 1034, 0x000000},
-- 失败
{711, 1048, 0x000000}
}, 90) then
nLog("验证失败弹框匹配!")
-- 点击好
touch.tap(618, 1264)
sys.msleep(2000)
-- 点击取消
touch.tap(108, 198)
sys.msleep(2000)
-- 点击完成
touch.tap(1125, 195)
sys.msleep(2000)
return "deactivate"
else
nLog("验证失败弹框不匹配!")
sys.msleep(2000)
end
-- 判断是否是解锁账户
if screen.is_colors({
--解锁账户
{320, 1268, 0x007aff},
-- 取消
{861, 1300, 0x007aff}
}, 90) then
nLog("Apple ID锁定弹框匹配!")
-- 返回锁定
return "locked"
else
nLog("Apple ID锁定弹框不匹配!")
--点击完成
touch.tap(1152,212)
sys.msleep(5000)
-- 登录成功,返回成功
return "success"
end
end
return "unknown"
end
-- 下载 AppStore 中的 pkg 应用(示意)
function performTask(account)
-- 需要执行的pkg
local pkgList = account.pendingPkgList
for i, pkgs in ipairs(pkgList) do
local pkg = pkgList[i]
--APP地址打开
nLog("https://itunes.apple.com/app/id" .. pkg)
app.open_url("https://itunes.apple.com/app/id" .. pkg,50)
sys.msleep(8000)
welcome()
--点击获取
if screen.is_colors({
--如果安装获取按钮在下方
{588, 1000, 0x007aff}
}, 90) then
nLog("获取按钮匹配!")
--点击获取
touch.tap(596,968)
else
nLog("获取按钮不匹配!")
--不匹配可能会是小云朵
if screen.is_colors({
--如果安装获取按钮在下方
{505, 937, 0x007aff},
{503, 999, 0x007aff},
{540, 966, 0x007aff},
{468, 969, 0x007aff},
}, 90) then
nLog("小云朵按钮匹配!")
--点击获取
touch.tap(508, 966)
else
nLog("获取按钮在上方!")
touch.tap(584,510)
end
end
sys.msleep(22000)
-- 判断是否有下方安装
if screen.is_colors({
--安装按钮
{540,2096, 0x007aff}
}, 90) then
nLog("安装按钮匹配!")
sys.msleep(3000)
--点击下方安装
touch.tap(616,2100)
sys.msleep(12000)
else
nLog("安装按钮不匹配!")
end
-- 判断是否未登录上
if screen.is_colors({
{98, 210, 0x007aff},
{1154, 218, 0x007aff},
{286, 366, 0x000000},
{930, 390, 0x000000},
{846, 784, 0x007aff},
{666, 778, 0x007aff},
}, 90) then
nLog("未登录账号弹框匹配!")
--点击取消
touch.tap(112, 210)
sys.msleep(2000)
-- 重启AppStore
restartAppStore()
--重新登录
loginAccount(account)
table.insert(pendingPkgs, pkg)
-- 跳过本次循环
goto continue
else
nLog("登录账号弹框不匹配!")
end
::continue::
-- 判断是否是继续输入密码
if screen.is_colors({
--登录
{548, 1272, 0x007aff},
-- 忘记密码
{713, 1408, 0x007aff}
}, 90) then
nLog("继续输入密码匹配!")
--匹配然后继续输入密码
key.send_text(account.passWord, 20)
sys.msleep(3000)
-- 点击登录
touch.tap(621,1268)
sys.msleep(25000)
else
nLog("继续输入密码不匹配!")
end
-- 判断是否有弹框
if screen.is_colors({
--始终需要
{320, 1300, 0x007aff},
-- 15分钟后需要
{973, 1332, 0x007aff}
}, 90) then
nLog("弹框匹配!")
-- 点击15分钟后需要
touch.tap(805,1316)
sys.msleep(10000)
else
nLog("弹框不匹配!")
sys.msleep(2000)
-- 判断有存储密码弹框
if screen.is_colors({
--存储
{376, 1280, 0x007aff},
-- 以后再说
{917, 1300, 0x007aff}
}, 90) then
nLog("存储密码弹框匹配!")
-- 点击存储
touch.tap(416,1284)
sys.msleep(8000)
else
nLog("存储密码弹框不匹配!")
sys.msleep(2000)
end
end
--服务条款
if screen.is_colors({
--中间你字开头
{288, 1104, 0x000000},
-- 进行结尾
{709, 1156, 0x080708}
}, 90) then
nLog("服务条款弹框匹配!")
-- 点击好
touch.tap(817,1312)
sys.msleep(25000)
-- 点击同意
touch.tap(1126,206)
sys.msleep(5000)
else
nLog("服务条款弹框不匹配!")
sys.msleep(2000)
end
--无法安装
if screen.is_colors({
--好
{608, 1236, 0x007aff}
}, 90) then
nLog("无法安装弹框匹配!")
-- 点击好
touch.tap(616, 1224)
sys.msleep(3000)
else
nLog("无法安装弹框不匹配!")
sys.msleep(25000)
--无法安装
if screen.is_colors({
--好
{608, 1236, 0x007aff}
}, 90) then
nLog("无法安装弹框匹配!")
-- 点击好
touch.tap(616, 1224)
sys.msleep(3000)
end
end
-- 上报
installProcess(account,pkg)
end
end
function installProcess(account,pkg)
nLog("上报开始")
local isSucessPkg
local result = uploadReeipt(account.id,pkg)
if result ~= null then
if result ~= "error" then
nLog("账号: " .. account.userAccount ..",票据:" ..result ..",获取票据成功!!!")
local mzSslId = string.match(result, "mz_at_ssl%-(%d+)=")
nLog("获取mz_at_ssl_id:" ..mzSslId)
-- 上报成功
isSucessPkg = {accountId = account.id, pkg = pkg, isReceipt = 1}
else
table.insert(pendingPkgs, pkg)
-- 上报失败
isSucessPkg = {accountId = account.id, pkg = pkg, isReceipt = 2}
end
else
table.insert(pendingPkgs, pkg)
-- 未获取到票据
isSucessPkg = {accountId = account.id, pkg = pkg, isReceipt = 3}
end
local jsonStr = cjson.encode(isSucessPkg)
table.insert(pkgResult, jsonStr) -- 插入 pkgList 的 JSON 字符串
nLog("上报结束")
sys.msleep(3000)
end
-- 清空文件和请求
function deleteReceipt()
-- 票据存储文件目录
local file_path = "/tmp/cc_appstore_db.txt"
os.remove(file_path)
end
-- 上报
function uploadReeipt(appleConfigId,pkg)
-- 票据文件路径
local file_path = "/tmp/cc_appstore_db.txt"
--os.remove(file_path)
-- 打开文件
local file = io.open(file_path, "r")
-- 检查文件是否成功打开
if file then
-- 读取文件内容
local content = file:read("*a") -- 读取整个文件内容
-- 打印文件内容
nLog("文件内容: " .. content)
local items = {}
for item in string.gmatch(content, "([^&]+)") do
table.insert(items, item)
end
local json_data = {
ua = items[1],
mzAtSsl = items[3],
pkg = pkg,
appleConfigId = appleConfigId
}
local json_str = json.encode(json_data)
local url = "http://paocai.munimob123.com/paocai/receipt/saveMzAtSsl"
local code, _, body = http.post(url, 50, {}, json_str)
sys.msleep(2000)
if code == 200 then
local result = json.decode(body)
if result.code == 1 then
nLog("上报成功:" .. json_str, 3)
os.remove(file_path)
return json_str
else
nLog("上报失败:" .. result.msg)
os.remove(file_path)
return "error"
end
else
nLog("请求失败,状态码:" .. code)
-- 查询是否已经存在数据
os.remove(file_path)
-- 重启App Store
restartAppStore()
end
-- 关闭文件
file:close()
else
-- 如果文件无法打开,打印错误信息
nLog("无法打开文件: " .. file_path)
end
end
-- 退出登录
function logoutAccount()
sys.msleep(2000)
nLog("退出登录开始")
--点击返回
touch.tap(56,88)
sys.msleep(4000)
--点击右上角头像
touch.tap(1132,254)
sys.msleep(5000)
--touch.on(469, 1097):move(477, 773):off()
--sys.msleep(2000)
--点击下方退出登录
touch.tap(224,1984)
sys.msleep(1000)
touch.tap(204,1848)
sys.msleep(3000)
--点击右上角完成
touch.tap(1129,208)
sys.msleep(2000)
nLog("退出登录完成")
end
function restartPkg(account)
if #pendingPkgs > 0 then
nLog("漏上报的pkg:" .. table.concat(pendingPkgs, ", "))
account.pendingPkgList = pendingPkgs
performTask(account)
pendingPkgs = {}
end
end
-- 重启appstore
function restartAppStore()
--退出AppStore
app.close('com.apple.AppStore')
sys.msleep(3000)
-- 启动App Store
startAppStore()
end
-- 主流程
local task = getTaskAccountList();
local account_list = task.appleIdConfigs
local current_index = 1
accountResult = {}
pkgResult = {}
pendingPkgs = {}
while current_index <= #account_list do
local acc = account_list[current_index]
nLog("正在处理账号: " .. acc.userAccount)
-- 清空请求
deleteReceipt()
nLog("清空请求完成")
local result = loginAccount(acc)
--local result ="success"
local accountJson
if result == "success" then
--安装软件
performTask(acc)
sys.msleep(5000)
-- 检查有没有漏上报的票据,重试
restartPkg(acc)
sys.msleep(5000)
-- 重新启动App Store
restartAppStore()
-- 模拟退出登录
logoutAccount()
sys.msleep(3000)
accountJson = {id = acc.id, status = 1}
-- 增加账号状态
current_index = current_index + 1
elseif result == "locked" then
accountJson = {id = acc.id, status = 2}
current_index = current_index + 1
elseif result == "deactivate" then
-- 账号停用
accountJson = {id = acc.id, status = 4}
--修改停用状态
updateStatus(acc.id)
current_index = current_index + 1
else
accountJson = {id = acc.id, status = 3}
-- 未知页面可人工介入
current_index = current_index + 1
end
-- 修改当前设备执行状态
local accountFinalString = cjson.encode(accountJson)
local pkgFinalString = "[" .. table.concat(pkgResult, ",") .. "]"
updateTaskDeviceTwo(task.taskDevice.id,pkgFinalString,accountFinalString)
accountResult = {}
pkgResult = {}
end
updateTaskDevice(task.taskDevice.id)
nLog("全部账号处理完成", 5)
最新发布