iOS自动化脚本教程
Posted Cydia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS自动化脚本教程相关的知识,希望对你有一定的参考价值。
下图是某游戏的合成灯笼界面,通过拖拽把相同的灯笼合成更高一级的灯笼。我想用脚本来自动合成,完全自动化。
下图是实现后的效果
脚本执行后
其实这里并不是用到反编译和逆向的知识,
只是用了按键精灵写了模拟合成的脚本,因为这个按键精灵也是我这段时间折腾的一部分。
环境要求与即将使用的工具
环境 | 版本 |
---|---|
操作系统 | 本人的mac是双系统(MacOSX和win7),按键精灵脚本需要在windows开发 |
手机系统 | ios11-14 需要越狱 |
思路
怎么让脚本知道是两个相同的灯笼,然后又怎么模拟灯笼拖拽去合并?
我想到了按键精灵,早起用过电脑版的用来辅助游戏,
想不到现在有手机版的了!所以想看看怎么弄,
我基本也是从零学起的。了解按键精灵IOS版 可以模拟我们人手的任何触摸指令,
我就有信心做这个合成判断了,按键精灵的代码是MQ语言,有相关手册大家可以去看。
思路是把12个灯笼区域分割成12个区域,坐标存放在数组中,
然后拿每一个灯笼来和第一个灯笼比较特征,特征相同就触发模拟拖拽合并。
另一种做法:用冒泡算法不判断色点,简单粗暴每个格子都移动合并,
不管是不是相同灯笼,没想到效率更高!代码更简单效率更快!
实现代码
ShowMessage"启动脚本。。。。。"
// 横屏
//x
//|__ y
DimoffsetX = 260
Dim offsetY = 292
Dim CloseXPoint = array(988,2010)
// 3 个特征点 array(y, x)
Dim point1 = array(876, 760)
Dim point2 = array(833,777)
Dim point3 = array(894,757)
// 第一个灯笼的特征
Dim firstDengLong = array(array(point1(0), point1(1), GetPixelColor(point1(0), point1(1))), array(point2(0), point2(1), GetPixelColor(point2(0), point2(1))), array(point3(0), point3(1), GetPixelColor(point3(0), point3(1))) )
Dim dengLongArr = array()
Dim i=0,count=0
// 所有灯笼的比较坐标点,12个 [[[5,3],[3,1]] , [[5,3],[3,1]]]
// 12 次循环
For i = 0 To 2
dim j = 0
For j = 0 To 3
dengLongArr(count) = array()
// 类似 dengLongArr[count][0]
dengLongArr(count, 0) = Array(firstDengLong(0, 0) - i * offsetX, firstDengLong(0, 1) + j * offsetY)
dengLongArr(count, 1) = Array(firstDengLong(1, 0) - i * offsetX, firstDengLong(1, 1) + j * offsetY)
dengLongArr(count, 2) = Array(firstDengLong(2, 0) - i * offsetX, firstDengLong(2, 1) + j * offsetY)
count = count + 1
Next
Next
// 合并灯笼
Function heBingDengLong()
i = 0
j = 0
// 第一个灯笼的特征
Dim firstDengLong = array(array(point1(0), point1(1), GetPixelColor(point1(0), point1(1))), array(point2(0), point2(1), GetPixelColor(point2(0), point2(1))), array(point3(0), point3(1), GetPixelColor(point3(0), point3(1))) )
Dim currDengLongColorArr = array()
// 11 次循环
For i = 0 To 11
currDengLongColorArr = array( GetPixelColor(dengLongArr(i,0,0), dengLongArr(i,0,1)), GetPixelColor(dengLongArr(i,1,0), dengLongArr(i,1,1)), GetPixelColor(dengLongArr(i,2,0), dengLongArr(i,2,1)))
For j = 1 To 11
closeX ()
closeComm()
TracePrint "这一点"
dim str = dengLongArr(j,0,0)&"|"& dengLongArr(j,0,1) & "|" & currDengLongColorArr(0) & "-101010," & dengLongArr(j,1,0)&"|"& dengLongArr(j,1,1) & "|" & currDengLongColorArr(1) & "-101010," & dengLongArr(j,2,0)&"|"& dengLongArr(j,2,1) & "|" & currDengLongColorArr(2) & "-101010"
If Not(i = j) and CmpColorEx(str, 0.9 ) = 1 Then
TracePrint str & "找到没有" & i+1 & "->" & j+1
// 合并灯笼
heBingDengLongTouch (dengLongArr(i,0,0), dengLongArr(i,0,1), dengLongArr(j,0,0), dengLongArr(j,0,1))
//EndScript
//Exit For
Else
//TracePrint 0
End If
Next
Next
End Function
Function hebingDengLong2()
i = 0
j = 0
Dim temp
// 11 次循环
For i = 0 To 10
closeX ()
closeComm()
temp = i
For j = 0 To 10
heBingDengLongTouch (dengLongArr(temp,0,0), dengLongArr(temp,0,1), dengLongArr(j,0,0), dengLongArr(j,0,1))
temp = j
Next
Next
End Function
// 移动指定灯笼到第一位置
Function moveToFirst(number)
TracePrint "----------------------------" & number
TouchDown dengLongArr(number-1,0,0),dengLongArr(number-1,0,1), 1//按住屏幕上的100,100坐标不放,并设置此触点ID=1
TouchMovefirstDengLong(0,0),firstDengLong(0,1), 1//将ID=2的触点花200毫秒移动至500,500坐标
TouchUp1//松开弹起ID=1的触点
// TracePrint "移动力"
EndFunction
// 拖拽合并
FunctionheBingDengLongTouch(x1, y1, x2, y2)
TracePrint"----------------------------"
TouchDownx1,y1, 1//按住屏幕上的100,100坐标不放,并设置此触点ID=1
TouchMovex2, y2, 1//将ID=1的触点花200毫秒移动至500,500坐标
TouchUp1//松开弹起ID=1的触点
EndFunction
// 关
FunctioncloseX()
// 免费升级的点击
//各种弹层的关闭处理
EndFunction
FunctioncloseComm()
// 也是各种弹层的关闭处理
EndFunction
FunctionisInGameWindow()
// 是否在游戏窗口的判断
EndFunction
// 广告处理
FunctionadProcc()
// 各种广告处理。。。。
TracePrint"开始广告处理................"
// 存在倒计时形式的x按钮
// 误入横版的app store 显示页面
EndFunction
// 脚本主函数
FunctionheBingDengLongMain()
For ii = 1 To 12
closeX ()
closeComm()
If hasShadowWindow() = False Then
// 原始的判断逻辑,效率低
hebingDengLong()
// 如果想用第二种合并处理逻辑的话,上面的For可以去掉,下面的moveToFirst()也要去掉
//hebingDengLong2()
moveToFirst (ii)
Else
TracePrint "不合并"
End If
Next
End Function
If isInGameWindow() = False Then
TracePrint "不在游戏界面"
ShowMessage "不在游戏界面"
Delay 2000
adProcc()
Else
heBingDengLongMain()
End If
思路:
首先我用按键精灵窗口里面的抓抓功能取点,
取第一张图片中第一个灯笼“SKR”的特征,
我采用三个色点来作为一个灯笼的特征。
第一个单元的3 个特征点坐标:
Dim point1 = array(876, 760)
Dim point2 = array(833,777)
Dim point3 = array(894,757)
然后
Dim offsetX = 260
Dim offsetY = 292
指的是12个格子单元的横纵距离,也叫格子与格子之间的偏移量吧,这个是根据屏幕分辨率来算的,大屏小屏的手机是不同的,
我这个脚本没有做到适应多屏幕兼容,按键精灵有自动兼容多分辨率的函数,我就没实现了,是用的1920×108的分辨率,换个手机就不准了哦。这里主要讲思路。
firstDengLong是指第一灯笼的特征。
然后下面有一个嵌套For循环,就是通过偏移量算出12个格子的坐标点,
用来比色的点。放在dengLongArr数组里面。
然后翻代码看最底部。
isInGameWindow()是判断当前窗口是否在游戏界面,先讲是的情况,会进入到heBingDengLongMain()就是合并灯笼的主主函数。首先执行closeX ()和 closeComm()是为了关闭游戏界面的离线收益遮罩层,因为经常会弹出翻倍和升级提示的窗口,不关闭触摸就失效了。总之人的操作是什么顺序逻辑的,脚本也是根据各种情况来做判断的。
然后进入具体合并逻辑hebingDengLong(),通过数组的遍历,逐个拿出来和第一个灯笼的特征比较,如果特征一样证明是相同级别的灯笼可以合并,
模拟拖拽的代码就在heBingDengLongTouch()里面,知道源坐标点和目的坐标点就能实现拖拽啦。
核心就是每一个灯笼来和第一灯笼比较。
合并后再在heBingDengLongMain()里面有一个
moveToFirst (ii)的操作,就是保证每个灯笼有机会移动至第一个格子,
有被拿来比较的机会。虽然是实现了,但是效率太低,
后面我用了另外的代码实现,不需要比较特征,简单粗暴高效的做法,不判断是否相同灯笼,直接每每合并得了,反而更快!代码在hebingDengLong2()方法里面。类似冒泡算法。
不再游戏窗口的情况时就判断是否在看广告的界面的处理,经常会误点击到广告,或者某些升级灯笼的弹窗需要来看广告提高进度,是一种判断策略吧,
某些广告看了收益高某些广告弹窗就直接close X掉。
——————————————分界线分界线——————————————
——————————————分界线分界线——————————————
插件:
Autotouch
Activator
在开始之前呢,有必要简单聊聊.lua脚本,其实没必要搞得太复杂,简单理解就是用autotouch录制完执行动作之后生成的脚本文件,比如下面的操作:
我进行了以下的操作:右划——左划——点击打开文件夹。
之后就会生成一个脚本,进到autotouch的records文件夹就能看到:
找到生成的脚本文件,点击打开:
如下:
里面的语句乍一看似乎很复杂,其实我们可以将其分成4个部分来看:
第一部分:激活相关程序,这里是激活桌面;
第二部分:右划操作;
第三部分:左划;
第四部分:点击。
观察代码发现,以上操作主要用到了四个命令语句,即:
touchdown——按下手指;
touchmove——手指移动至;
touchup——抬起手指;
usleep——间隔多少时间(单位:微秒)。
所以我们只要能够把握以上命令的规范,就能轻易写出需要的脚本,
那么下面就是规范,以下教程可以学习...
touchDown(id, x, y)——在屏幕的(x, y)坐标按下。
id: 手指的编号,按需填写;
x: 屏幕x坐标;
y: 屏幕y坐标。
例子:
touchDown(0, 100, 200);——在坐标(100, 200)处按下。
touchMove(id, x, y)——移动手指到(x, y)坐标。
id: 手指的编号,按需填写;
x: 屏幕x坐标;
y: 屏幕y坐标;
例子:
touchDown(0, 100, 200);——在坐标(100, 200)处按下,
touchMove(0, 200, 200);——移动手指到坐标(200, 200)处。
touchUp(id, x, y)——从(x, y)坐标抬起按下的手指。
id: 手指的编号,按需填写;
x: 屏幕x坐标;
y: 屏幕y坐标;
例子:
touchDown(0, 100, 200);——在坐标(100, 200)处按下,
touchMove(0, 200, 200);——移动手指到坐标(200, 200)处,
touchUp(0, 200, 200);——在坐标(200, 200)处抬起按下的手指。
usleep(microseconds)——停顿若干个微秒,即1/1000000秒。
例子:
usleep(1000000);——停顿1秒。
补充开启和关闭命令语句:
appActivate(appIdentifier)——用appIdentifier激活指定应用。
appIdentifier: 应用标识,如"com.apple.mobilesafari";
例子:
appActivate("com.apple.mobilesafari");——激活safari
appKill(appIdentifier)——用appIdentifier关闭指定应用。
appIdentifier: 应用标识,如"com.apple.mobilesafari";
例子:
appKill("com.apple.mobilesafari");——关闭运行着的safari
、、、
好啦,明白了以上语句后应该就能自己编写脚本啦,多说句如果不能理解、获取不了屏幕坐标的,可以音量键-呼出autotouch录制,然后点相应位置获取坐标。
下面说说定时打卡的流程,我不贴自己的脚本了,毕竟屏幕大小不同锁屏密码不同脚本也会有很大的差异,有兴趣的自己录制/编写吧。如果嫌语句太复杂,可以分批录制然后自行合并修改脚本。
1、解除屏幕锁定:
激活系统界面——上划呼出密码锁——按顺序点按密码解锁。
2、打卡:
激活打卡程序——按流程点击打卡。
3、关闭打卡程序:
关闭
4、锁定屏幕:
双击锁屏(可选)。
注意!间隔的存在很重要!每两个操作之间必须插入间隔语句,间隔语句要适当延长以避免偶尔的不准确!
那么操作脚本有了,如何定时运行呢?
先借助activator创建计划事件(时间及循环):
然后在autotouch运行设置里选定即可:
说说会遇到的问题和注意事项:
首先是定位、数据的不稳定有可能会跟不上操作流以至整个流程失败,解决方法是适当延长间隔时间!
第二个是安全问题,你的设备会在一天的某两个时段(上班和下班)自动解锁。
第三,以上流程因为加上了开屏解锁的操作,所以如果设备在开屏状态下(例如你正好在玩手机时)会失效。
以上结合XX定位更香,该教程只是作为抛砖引玉用。
好啦,以上就是本期所有的内容了,喜欢请点赞,好用请转发。
end
以上是关于iOS自动化脚本教程的主要内容,如果未能解决你的问题,请参考以下文章