下图是某游戏的合成灯笼界面脚本精灵,通过拖拽把相同的灯笼合成更高一级的灯笼。我想用脚本来自动合成,完全自动化。
下图是实现后的效果:
通过脚本大大提高合成速度!
其实这里并不是用到反编译和逆向的知识,只是用了按键精灵写了模拟合成的脚本,本篇文章就先讲按键精灵的使用吧,反编译的其他知识后面我会逐一分享,因为这个按键精灵也是我这段时间折腾的一部分。
进入正题
折腾吧。
环境要求与即将使用的工具
环境版本
操作系统
本人的mac是双系统(MacOSX和Win7),按键精灵脚本需要在Windows开发
按键精灵手机助手 for Windows
娜娜项目网每日更新创业和副业项目
网址:nanaxm.cn 点击前往娜娜项目网
站 长 微 信: nanadh666
3.5.2
按键精灵iOS版
1.5.2
手机系统
iPhone7 iOS11 需要越狱
思路
一开始我的做法:
怎么让脚本知道是两个相同的灯笼,然后又怎么模拟灯笼拖拽去合并?我想到了按键精灵,早起用过电脑版的用来辅助游戏,想不到现在有手机版的了!所以想看看怎么弄,我基本也是从零学起的。
了解按键精灵 iOS 版可以模拟我们人手的任何触摸指令,我就有信心做这个合成判断了,按键精灵的代码是MQ语言,有相关手册大家可以去看。
思路是把 12 个灯笼区域分割成 12 个区域,坐标存放在数组中,然后拿每一个灯笼来和第一个灯笼比较特征,特征相同就触发模拟拖拽合并。
另一种做法:用冒泡算法不判断色点,简单粗暴每个格子都移动合并,不管是不是相同灯笼,没想到效率更高!代码更简单效率更快!
实现代码
这里只列出核心代码,具体代码见:github
()
ShowMessage "启动脚本。。。。。"
// 横屏
//x
//|__ y
Dim offsetX = 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
TouchMove firstDengLong(0,0),firstDengLong(0,1), 1//将ID=2的触点花200毫秒移动至500,500坐标
TouchUp 1//松开弹起ID=1的触点
// TracePrint "移动力"
End Function
// 拖拽合并
Function heBingDengLongTouch(x1, y1, x2, y2)
TracePrint "----------------------------"
TouchDown x1,y1, 1//按住屏幕上的100,100坐标不放,并设置此触点ID=1
TouchMove x2, y2, 1//将ID=1的触点花200毫秒移动至500,500坐标
TouchUp 1//松开弹起ID=1的触点
End Function
// 关
Function closeX()
// 免费升级的点击
//各种弹层的关闭处理
End Function
Function closeComm()
// 也是各种弹层的关闭处理
End Function
Function isInGameWindow()
// 是否在游戏窗口的判断
End Function
// 广告处理
Function adProcc()
// 各种广告处理。。。。
TracePrint "开始广告处理................"
// 存在倒计时形式的x按钮
// 误入横版的app store 显示页面
End Function
// 脚本主函数
Function heBingDengLongMain()
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 个格子单元的横纵距离,也叫格子与格子之间的偏移量吧,这个是根据屏幕分辨率来算的,大屏小屏的手机是不同的。
我这个脚本没有做到适应多屏幕兼容,按键精灵有自动兼容多分辨率的函数,我就没实现了,是用的 iPhone7 Pro 的1920×108 的分辨率,换个手机就不准了哦。这里主要讲思路。
firstDengLong 是指第一灯笼的特征。
然后下面有一个嵌套 For 循环,就是通过偏移量算出 12 个格子的坐标点,用来比色的点。放在 dengLongArr 数组里面。
然后翻代码看最底部。
isInGameWindow()是判断当前窗口是否在游戏界面,先讲是的情况,会进入到 heBingDengLongMain()就是合并灯笼的主主函数。
首先执行 closeX ()和 closeComm()是为了关闭游戏界面的离线收益遮罩层,因为经常会弹出翻倍和升级提示的窗口,不关闭触摸就失效了。总之人的操作是什么顺序逻辑的,脚本也是根据各种情况来做判断的。
然后进入具体合并逻辑hebingDengLong(),通过数组的遍历,逐个拿出来和第一个灯笼的特征比较,如果特征一样证明是相同级别的灯笼可以合并。
模拟拖拽的代码就在heBingDengLongTouch()里面,知道源坐标点和目的坐标点就能实现拖拽啦。
核心就是每一个灯笼来和第一灯笼比较。合并后再在heBingDengLongMain()里面有一个 moveToFirst (ii) 的操作,就是保证每个灯笼有机会移动至第一个格子,有被拿来比较的机会。
虽然是实现了,但是效率太低,后面我用了另外的代码实现,不需要比较特征,简单粗暴高效的做法,不判断是否相同灯笼,直接每每合并得了,反而更快!代码在 hebingDengLong2()方法里面。类似冒泡算法。
不在游戏窗口的情况时就判断是否在看广告的界面的处理,经常会误点击到广告,或者某些升级灯笼的弹窗需要来看广告提高进度,是一种判断策略吧,某些广告看了收益高某些广告弹窗就直接 close X 掉。
然后广告处理部分也是抓取关闭按钮特征来判断,具体代码见 github。
额外
shell 定时任务
其实上面的动图之所有每隔几秒都有离线收益拿是因为我利用了游戏的一个bug 实现的,这里我就不透漏 bug 了,我手机里面运行着 shell 的定时任务的脚本才能每隔几秒就收获离线收益。
这里我分享一下 iOS 手机里面怎么使用定时任务吧。
linux 的定时任务是通过 crontab 来配置的,而 iOS 是通过 LaunchDaemons 来实现的。配置文件写在/Library/LaunchDaemons/下面。
比如我的配置文件(com.apple.mycrontest.plist)这样定义:
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.mycrontest.plist</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/var/root/myshelltest.sh</string>
</array>
<key>StartInterval</key>
<integer>1</integer>
</dict>
</plist>
以上配置文件指出每隔10秒执行一次/var/root/myshelltest.sh脚本。至于shell 脚本里面写了啥我就不说了,是实现离线收益的方式。
打开手机 terminal 命令行软件,没有的话去 cydia 搜索相关资源下载。
然后启动配置文件命令如下:
launchctl load /Library/LaunchDaemons/com.apple.mycrontest.plist
需要 root 权限。
就会定时执行 /var/root/myshelltest.sh 啦。
如果想关闭定时任务则:
launchctl unload /Library/LaunchDaemons/com.apple.mycrontest.plist
通过 shell 脚本和按键精灵脚本,实现了自动离线收益和自动合并灯笼的需求!
这是本人第一次写按键精灵脚本,没想到折腾一番还能搞出点花样~
因为有了这一次成果,我才有更大的需求脚本精灵,想改游戏逻辑,这就需要用到逆向和 iOS 开发的知识了,致使我一步步折腾并入坑……..
– End –
看雪ID:麦麦2020
*本文由看雪论坛 麦麦2020原创,转载请注明来自看雪社区。
娜娜项目网每日更新创业和副业项目
网址:nanaxm.cn 点击前往娜娜项目网
站 长 微 信: nanadh666