更多功能请看 https://coczhushou.github.io/
为什么要开源呢?我并没有太多时间可以花在辅助上,今年一月以后,就没加过新功能,除了修bug和更新一些图片识别代码。考虑之后,想着还有其他coc辅助开发爱好者,他们可能会对这个辅助有兴趣,我就开源给大家分享吧。如果别人能从源码中获得点帮助,感觉也算做了一件好事。
我接触按键精灵时间并不长,也就是从去年8 9月份开始用,所以代码中很有可能会有些地方实现得不好,请大家指点。而且今年以来我就不关注按键精灵有什么更新,也有可能代码里有些我自己实现的东西按键精灵已经提供了。但是,我对自己的垒码技巧还是有自信的,有些地方还是可以拿出来和大家分享(xianbai)的。
代码还没有来得整理,可能有点乱,如果有人感兴趣读代码,我可以整理一下,写点注释。如果没有,我就不费那个力了。
代码在此
干货
先说说几个经验,如果大家有更好的解决办法,欢迎讨论
如何判断捐兵请求
第一反应是做字库,每个兵种做几个关键字,比如”蓝胖“,”法“什么的。但是,但是,按键精灵的字库很烂,真的很烂,不是一般的烂,识别起来问题很多。错误率非常高。我做0-9这十个字的字库时都要哭了,别说二十几个兵种了。那咋办?怎么办呢?
答案是用多点找色。这个识别请求比字库靠谱多了。怎么找?我研究了一下几个主流安卓模拟,发现coc的字体在这些模拟器里都是一样的。所以,我可以发个聊天信息,把兵种都说出来;兵种名字间用个豆腐块符号分割,比如“▍蛮 ▍弓 ▍法 ▍巨 ▍”;然后截图;然后找豆腐块,两个豆腐块之间就是一个兵种名字的图片;对每个兵种名字的图片,扫描每行,在每行上找到字的边缘,在边缘两边各取一个像素,然后把这些像素合起来做这个字的多点找色匹配值。当然,这些都是用脚本完成的,并不费力。有兴趣可以看看源码里CreateWordPatterns这个函数。
还有一些细节,比如同一兵种不同叫法,“胖“和”巨“,是要识别成同一种兵的。再比如,辅助得区分"龙"和“小龙”,“蓝胖”和“胖”,“巨石投手"和“石”,需要对找到的字符做一下匹配优先级,比如小龙的优先级比龙高。最后需要识别“随”和“不”字。“随”字好理解,很多请求是“随便”,”随意“,对这种请求,辅助也需要识别一下,然后按照设定捐默认的兵种;识别“不”字是因为有些请求是“不要胖子”这样的,智能的辅助是不会捐胖子找茬的。
有些地方还没有做得太细,比如十本十一本发“狗球”,明显是要一狗一球,但是现在还不会识别已经捐了多少,如果没有狗就会全部捐球。。但是辅助还是有一点智能的,它会优先捐体积大的,如果有狗,会优先捐狗;同样道理“弓法”优先捐法。另一种情况是请求里带有数量的,比如“五法二胖”,目前也没办法精确满足。
但是从实际的状况看,效果已经非常好了。在一个活跃部落,二十四小时可以捐3000的人口。部落战时也不用担心不在线没法及时给兵。
捐兵实现里还有其他的一些细节,比如捐完自动补兵,向上翻页找请求之类的,没什么好讲的。
如何判断资源采集里有多少资源
这个我是花了不少功夫的。
首先要判断采集器的等级,如果放到最大,采集器的等级很好判断,但是这样的话很难确定采集器的坐标,这个坐标会关系到下兵的位置。最好是把画面缩放到最小,再判断采集器的位置。
缩放到最小麻烦的地方在于coc画面有一些平滑处理,在上下边缘还有颜色渐变(变暗)。平滑处理会使物品在移动非整数像素后,物品上同一个地方的像素颜色发生变化。如果知道一点图片缩放知识,知道显示的图片是插值的,就会理解。这样一来,如果对一个采集器做好了多点找色的匹配模板,很可能换个位置就找不到了。这也是为啥多点找色要找周围色彩相近的地方取点做匹配,而且匹配颜色的每个分量要给一个范围的原因。问题是,coc的采集器,尤其是10级11级12级金矿采集器,在缩到最小后,他们之间的差别都在色彩变化非常剧烈的地方,就是那堆金灿灿的的地方。匹配模板不好找阿。
为了解决这个问题,我花了不少时间,最后写了一个python程序,比较同样等级采集器的十几张不同截图,然后自动生成一个使所有图片都能匹配的多点找色匹配值。这样,对不同等级的采集器总算能区分得很准了。等级低的金水采集器(低于7级)由于资源不多,我就不管了。但是黑水是宝贵的,1级采集器都会识别。
第二个难点是判断采集器里到底有百分之几的资源。我们知道金水采集器的上限从12级往下依次是200000, 150000, 100000, 75000, 50000,…采集器里资源大概有多少百分比是可以通过外观判断的。网上有教怎么判断外观,但是没有给出具体数值范围。我通过大量实验(对,我就是这么勤劳)总结出了大致范围。黑水采集器有四种状态,每种状态的资源百分百比大概是:0-10% 10%-25% 25%-50% 50%-100%。金水采集器有五种状态,资源百分比大概是:0-4% 5%-35% 36%-65% 65%-95% 96%-100%。 金水采集器被抢的话大约会损失50%的资源(这个似乎和大本等级差值没什么关系)。黑水被抢是75%,比如,6级黑水采集器容量是1800,所以经常看到死鱼的采集器里能抢到1800*75%=1350黑。
判断百分比其实比判断资源采集器等级还难。因为地图缩小后,显示资源百分比的地方是很小很小的一块,肉眼都不一定能看出区别来。金矿采集器尤其困难,半满和大半满看上去一样,识别率实在太低,我只好曲线救国,用圣水采集器的百分比,反推金水采集器的百分比----他们经常是差不多的。但是黑水和圣水百分比是精确判断的。
为什么要判断得这么准?因为这个辅助需要智能下兵,并非像某些辅助四面一框下兵,傻子都知道不是人在下兵。这个辅助,如果不是太纠结下兵频率,是看不出来是辅助在下兵的。所有的兵都下在资源采集器或者大本边上,目的明确。需要准确识别的另外一个原因是,闪黑的时候,至少知道能闪到多少黑吧?对着空黑水矿闪,怎么看怎么傻。
如何判断死鱼
找坟墓,超过15个坟墓就假设它是死鱼。
如何判断打还是不打
这个可以设置的,比如只打死鱼不打活鱼;比如采集器资源超过多少才打,采集器还必须是在外面,藏在里面的不算;再比如要不要打外置大本。
如何定位建筑
之前说到定位建筑需要缩放到最小。这个是因为我刚开始开发的时候,地图缩放到最小,左右两边是正好没法移动的,只有上下可以移动,这样建筑坐标就好确定,只需要将地图移到最上端,找到建筑坐标;再将地图移到最下端,找到另一些建筑坐标,加个竖直方向的偏移量就可以了。但是,但是,某个版本以后变了,缩放到最小后,地图左右两边还有少许空间,而留的这少许空间还不是一个固定值;据我观察,是一个登录时确定的随机值。也就是缩放比例的最小值和以前不一样了,是一个不确定的值了。
我严重怀疑这个变化是supercell故意给辅助找麻烦的。不然为啥缩放比例最小值每次登陆还不一样?
当时想了一个办法解决了这个问题,在地图缩放到最小时,左右移动地图直到两边,算出左右移动的距离,然后折算出当前的缩放率,用这个缩放率来校正截图,并且用来校正找到的建筑物的坐标。代码里有调用SetScreenScale,就是干这个的。有一个问题,怎么算移动距离呢?办法就是当地图在最左时,在画面上选一行,在这行上选几个点,读取它们的像素,当作多点找色的匹配值;然后右移地图,移动后再找那几个点,算出移动了多少距离。只靠一行可能不准,那就多找几行,问题是由于识别错误,每行给出的移动距离可能不尽相同。那就对移动距离投个票,选票数最多的移动距离。
建筑物用多点找色来找,和确定采集器等级的方法差不多。目前判断的建筑物有:采集器,大本和防空炮台。防空炮台是给八本龙流冲杯用的。
进攻的时候,建筑物边缘一格内是不能下兵的,会有红色的阴影在草地上。通过判断草地的颜色,就可以知道哪里是建筑物的边缘。
把上述的都识别了以后,辅助可以把整个地图画出来,标注出找到的建筑和整个阵的轮廓。
一些细节:
地图是45度的
这个增加了游戏的真实感,但是也加大了辅助的处理难度,最后建筑物坐标都得转换成45度的坐标系。
“点击或按住屏幕可以派出部队”
不知道大家进攻的时候有没有留意到这句话。这句话在屏幕下方靠近底部的位置。有的时候,它非常恶心的挡住了那个位置上的大本或者其他建筑。所以辅助如果没有找到大本,会稍微移动一下屏幕,再判断一次大本的位置和等级。
下雪特效
冬天建筑屋会覆盖上一层雪,这真是蛋疼,我不得不修改多点找色的匹配值。
如何判断哪些草坪可以下兵
用多点找色会比较麻烦,很可能不准,因为草的颜色是复杂变化的。而且还必须区分开被红线覆盖的草坪。我的办法是,在地图每个小块的正中选一个小片,统计里面有多少个像素是在指定的颜色范围里的(绿色),如果大于40%,就算草皮。这样做的效果非常好,准确度很高。
一些小技巧
统计用户数
发布以后,按键精灵并没有告诉我有多少人用我的辅助。但是我有我的办法。有个命令叫URL.Get可以发送一个HTTP请求。这一利用这个。怎么做?有一些网站给其他的网站提供流量统计服务,比如友盟。这些网站会要求客户在他们的网页里嵌入一段程序,这段程序会发一个请求给那个网站,所以每当用户打开客户的网页,就会发一个请求给那个网站,那个网站会记下来谁来访问了,把搜集的访问统计一下,就是客户网页的访问次数了。有的时候客户的网页上可能不能嵌入程序(不允许运行javascript),如果是这样的话,流量统计网站就得让客户网页直接发HTTP请求给他们,比如客户在他们的网站上放一个用户不可见的图片,然后图片地址是指向流量统计网站的。我们也可以利用这个,假装用户打开了一个页面,主动发请求,地址就是这个不可见图片的地址。
说了这么多不理解也没关系。办法就是:1.在https://statcounter.com注册一个账号(不要钱,提供一个邮箱地址即可)。 2.建一个project。 3.在设置里选默认的安装指南。 4.选”基本“的选项,然后在显示的一堆代码里找到一个类似于//c.statcounter.com/1222323/0/12312323/0/的地址。 5.在按键精灵脚本的开始位置写一行URL.Get “http://c.statcounter.com/1222323/0/12312323/0/”(注意加上http;最好另起一个线程调用这个,因为这个调用会比较慢,在主线程里会卡)。可以只发一次,也可以每天发一次,取决于要不要统计日活跃用户。 6.登陆statcounter.com就可以看到用户统计了,时间,IP,甚至连用户在哪里都给你在地图上画出来。
statcounter.com网站提供有中文翻译,虽然很烂。不行就找中文的流量统计网站,大致思路是一样的。
辅助死了怎么办
辅助其实不怎么死,安卓模拟器也不怎么死机了。之前倒是经常发生模拟器死机现象,现在不知为啥稳定了很多,可能模拟器优化了吧,我辅助的代码确实是一点没变。但是无论如何,如果要长时间挂机(一周甚至一个月),万一挂死了要重启挂会相当麻烦和耽误事的。解决办法就是,让辅助定期给电脑上另外一个程序发心跳(heartbeat),如果那个程序长时间没收到heartbeat,就重启模拟器,然后等模拟器重启了再自动重启辅助。这样就需要两个额外的东西,一个是电脑上运行的监视程序,辅助可以通过IP地址10.0.2.2和电脑上的监视程序通信(做安卓开发的应该知道);另外一个是“开机自动启动辅助”的app,我不知道按键精灵手机版现在有没有提供开机自动运行的功能,但我当时是自己做了一个的app,开机后会自动运行辅助。这个app还会自动点击跳过广告和开始运行等按钮----我相当于自己做了个按键精灵╮(╯_╰)╭
初衷是要确保辅助长时间运行,但是后来发现辅助和模拟器相当稳定,连跑一周都没有问题,这些东西都不需要了。可是有些遗迹还在代码里没有删掉。
自动识别游戏运行包
有些辅助需要在设置里指定游戏版本,这个真是十分没有必要。因为不同版本的游戏运行包名字都是com.supercell.clashofclans.xxxx(除了最近的腾讯版),xxxx可以是uc,可以是kunlun,或者是其他别的。简单的扫描手机里所有的安装包,然后找到名字是以com.supercell.clashofclans开头的那就是游戏的运行包了。shanhai插件提供了扫描安装包的功能。当然,如果安装了多个游戏版本,还是要选运行哪个版本的。