200行Python实现能上天和太阳肩并肩的连连看外挂程序
作者:三级狗 长不帅的程序猿小哥哥 Python爱好者社区专栏作者
文章出处:https://www.zhihu.com/question/275611095/answer/407984155
https://v.qq.com/txp/iframe/player.html?vid=i13418oero3&width=500&height=375&auto=0
https://v.qq.com/txp/iframe/player.html?vid=d1341rtq6fl&width=500&height=375&auto=0
Python写的连连看外挂,图二时间间隔设置成了0,效果有点吓人。用的是简单的opencv图像识别结合连连看的算法,如果关注度足够,我会回来补上具体的实现思路和源码地址。(开源了已经)希望不会接到腾讯爸爸的律师函?
先手动来条华丽的分割线
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这刚刚有了知乎账号不到两周还,第一次在知乎回答,不到两天的时间,快破800的点赞,440的收藏,130的关注,66的感谢,还有100多条五花八门的评论着实是吓到我了。刚刷到这个问题的时候就觉得小猪佩奇都能赞到3k+,那我是不是也可以?就尝试性的发了这个外挂出来,看来冲击力实在不小,都有人私信问我是不是骗子了,吓得我赶紧回来补上约定好的实现思路和源码连接。承蒙大家厚爱,现在我来好好回答一下这个问题。
源码
源码连接:记得点star哦~
https://github.com/TheThreeDog/Auto-Lianliankan
这个小外挂用python2写出来有将近半年了,挂到github上的版本我想用python3重构,当时只写了个开头后来不了了之了。这篇回答发出来,关注度如此之高,这才想起来我的github上挂的是半喇项目,尴尬我的今天趁下班时间赶紧写完了python3的版本,并且把思路代码都理了理。如果觉得还不错就给个star,毕竟还年轻,虚荣心比较强,谢谢!
需要使劲敲黑板强调一下的是:Github上的项目里带了一个连连看的游戏,那个外挂就是用来破解这个游戏的,如果想破解QQ的连连看,就把config.py里的配置改成QQ连连看对应的配置,但配置是多少我本人不做提供。如果你自己搞出来了,建议你自己偷着乐就好了,不要大肆宣扬,如果你一定要张牙舞爪的到处显摆... 我确实也没啥脾气,毕竟我自己也正在这样做。
实现思路
下面的内容,伸手党可以不用看了,毕竟大家更感兴趣的,肯定是上面那个链接。
项目一共350行左右的源码,注释150行,是的,实现起来比你想象的简单的多。接下来我用我的方式讲解一下这个外挂是怎么实现的,尽可能简洁,让绝大部分人都能听懂。
首先,我们先想想人类是怎么玩连连看这个游戏的?
游戏开始,纵览全局,一眼扫到能够相连的两个相同的图片,就用鼠标去点,先点第一个,再点第二个,随着“撕拉”一道闪电两个方块随即爆炸,爽的不要不要,以此类推直到游戏结束,通过以上的操作可以细化出这样几个点来:
图片要相同。这个我们人类可以一眼分辨出来
两个点可以连通。很多人玩到现在也不是很清楚怎样能连,怎样不能,反正看了就知道,具体是啥硬性规则也并不是特别清楚。
点击,鼠标一个一个的点,如果刚点过的两个图片相同并且可以连通,就是“撕拉”一道闪电让你爽一下。
回到问题,人类是这样玩的?那机类能不能也这么玩?
答案是肯定的,计算机运算速度那么快,如果能想办法让他用和人类一样的思路去操作,那我们岂不是能轻易享受到“撕拉撕拉”的快感?而唯一需要我们做的,就是躺好,让她自己动。哦它!错别字!
想到这问题就清晰一些了,我们想让电脑按照我们的方式去执行和我们一样的操作,借助CPU发热的淫威,达到我们人类难以企及的速度,就是酱紫。那么计算机怎么像我们一样思考和操作呢?回到上面分析出的三点:
它要能认出屏幕上相同的图片。
它要知道某俩图片能不能相连。
它要能像人一样去对着屏幕啪啪啪....地点击。
就像把大象装进冰箱一样,让电脑代替人脑,需要的也就是这么简单的三步。
第一步:它要能认出屏幕上相同的图片。
程序它如何能认识屏幕中的游戏中的一个一个的小方块呢?你肯定想到了图像识
别,屏幕中间一个个的小方块是很有规律的,也有明显并且规律性的色值的梯度变化,通过一些图像识别的算法一定可以让程序认出屏幕上的小方块来。没错,但这样做很麻烦,这里我一定要跟在座的提一下:无论是产品设计还是编码实现,一定要遵循一个核心原则:大道至简!什么叫大道至简?意思就是复杂的我也不会。
那简单的怎么做?首先,找到游戏窗体的位置(windows API),然后从屏幕上截张图(PIL),游戏窗体顶点的横纵坐标各加上一个数字,就找到了游戏区域(图中绿框),然后,通过图像切片的方式,从点C开始,分别以方块宽度为高度为步长,把图像切割成n个小块,然后再比较这些图片是否相等,一样的就用同样的数字标识,空白就用0,就这样简单粗暴地完成了第一步。
至于我怎么知道方块的宽度高度,还有从顶点到游戏区域的距离?这个我是截图拿PS看的,不然还拿尺子量么。。。
第二步:判断两张图是否能够相连
图像转化成数据了,数据改怎么进行处理?
这里就得扯一下连连看的算法了,它的算法和它的规则关联度很大,它的规则是和拐点相关的:两个方块的通路上,最多可以有两个拐点,如果用两个拐点还连不上,那他们就不能连通。落实在算法上其实很好写也:两个点能否直连是很好判断的,只需要判断两点之间的通路上是不是都为0就可以。那么两点通过一个拐点连通的情况,就是其中一点到拐点,再从拐点到另一点两个直连的判断。那么两个拐点的情况,就是一个点到拐点的直连+一个拐点到另一点的单拐点的情况进行判断。这样写下来,几乎全是嵌套调用,最后全部都集中在直线的校验上。
第三步:如果能够相连,模拟鼠标点击屏幕
第二部判断出的两个点可以相连,那需要程序点击一下两个点就可以,通过刚才的判断两个点的坐标是可以知道的,那只需要再向两个坐标发送鼠标点击的时间就可以。这里通过python win32的API就可以实现模拟,贴心的答主已经在源码开头附上pywin32下载链接了。
最后,重复以上步骤
电脑会以惊人的速度向你反馈“撕拉撕拉”的快感。这里请允许我再装个逼,上面的视频2我搞错了,是时间间隔0.01秒的情况,真实的0间隔效果是酱紫的:
https://v.qq.com/txp/iframe/player.html?vid=x13419w5fla&width=500&height=375&auto=0
一些闲蛋
接下来就是一些闲扯的内容了,是我的一些看法和讨论,可能没什么技术含量和价值,不喜勿喷。
说好的图像识别呢?
相信很多人看了思路和源码一定很失望,根本没有什么高端的算法和逻辑,说好的图像识别,也就是用了一下opencv的函数比较了一下图像是否相等。当然,外挂确实实现了还很吊炸天。理想状态下当然是通过图像识别找出相同的图片然后分析计算然后执行自动消除的操作。但是不那么做的理由我在上面也说过了,我确实不会....-_-||
程序中可改进的地方还有很多
1、这个外挂程序的局限性比较大,从我上面的分析就可以知道很多都是基于固定坐标来算的,那其实只要腾讯爸爸把这个游戏做的支持缩放,这个外挂也就跪了。但是腾讯没有,自打我有记忆以来,这游戏怕是有15年没更新了,600*800的像素在我同事的外星人上显示地像个幼儿版本。可能是看不上这一天两万人的用户量吧,还是开发新版本的欢乐斗地主更挣钱。
2、如果速度设置的较慢,让别人先赢了,将是一件比较尴尬的事情,别人赢了你再点击屏幕已经无效了,但是程序继续运行仍然会让鼠标在对应的位置点来点去。你还没法移动它去停止程序,你鼠标还没挪走呢,就又给你挪到其他位置了。此处应该设置个中断机智,能够随时停止程序的。
3、我在程序中使用的是opencv+numpy进行的图片读取,切片,还有图片是否相等的校验。后来同事给我提供了一种思路:1、PIL本身就可以进行图片切片,2、operater.eq()可以校验两个对象是否一致,用来校验切片出来的图像是完全可以的。 这样的话根本就不需要opencv和numpy,什么图像识别,根本不需要的,如果那么做,代码量还可以比现在更精简。
关于外挂
关于外挂有很多中办法实现,我说几种主流的,大家评论里也已经多得五花八门了,
1、其中很大一部分,也是绝大多是外挂的主流做法,就是直接在本机改内存。你的游戏运行在我这里,代码就得加载到我的内存里运行,那么内存里的数据再抽象,总有高手能给它鼓捣出来。就比如说这个连连看,我也可以通过读取内存的手段直接拿到它方块布局的数据,直接把这个数据全改成0,那立马就赢了。但这样做很麻烦,这里我一定要跟在座的提一下:无论是产品设计还是编码实现,一定要遵循一个核心原则:大道至简!什么叫大道至简?意思就是复杂的我真的不会。。。
有一些游戏数据必须要在本地进行处理的,很容易遇到这种外挂,比如地下城与勇士无限刷图啦,更比如吃鸡,就说吃鸡,这样的第一人称射击游戏,打一枪子弹中没中,不可能放到服务器去判断,一是判断不过来,二是受网络的影响实时性根本达不到要求。所以你一枪子弹打出去中没中,一定是放在本地进行计算的,既然是在本地内存里,一旦防范不到位那就有人能给你改,我们所谓的“飞天遁地锁血金身”什么的。像LOL就不多存在这样类型的外挂,一方面肯定是反外挂投入的力度大,另一方面就是因为你的操作全部都是由服务器来进行计算并反馈的,不存在太多本地数据篡改的风险。
2、另一种外挂,不在本机改内存,而是通过网络去骗数据,常见于数据协议被黑客窃取或破解,那他就可以按照协议格式发伪造的数据,来骗服务器。这种外挂我见过的比如GTA5 online版本,当时答主的舍友花50块买的外挂,头上一个劲儿的往出冒钱,外挂弄出的钱,退出后重新登录会消失,但是如果这些钱用来买了资产,那资产就实打实的是你的了。看上去也是很爽,感觉那外挂应该是了窃取某个加钱的接口,然后发模拟数据一个劲儿的刷。
3、再有,就是我的这种外挂,用程序来模拟用户的某些操作,类似于按键精灵的意思,得益于计算机优秀的运算速度,往往能达到人类不可能达到的水平。除了我这个连连看,还有之前微信跳一跳的外挂也是如此。而这种外挂也很难防范,有些时候程序无法判断操作是来源于用户还是代码。
关于攻防
我是这个外挂的作者,所以也想说说关于如何防范这个外挂,以下来说说我替鹅厂想的一些法子来阻止我这个外挂。
1、最行之有效:窗体缩放。如果这个游戏的窗体可以缩放,那我这个外挂基本上算是废了,除非你每次玩的时候都能缩成固定的大小,并且每次保证都一样。如果真的修改地支持窗体的缩放了,那我的外挂就不得不通过真正的图像识别来搞了。当然,那样会很麻烦....我不会。
2、检测时间间隔,如果每次间隔都一样,则视为外挂。这属于比较蠢的办法之一,你是不知道python中生成个随机数有多简单,随便弄个0.5~2秒随机,那家伙比真人还真!
3、通过驱动级别的检测,看是否有鼠标输入。这个原理很简单,实现起来很难。让程序的代码深入驱动底层去检测,如果没有捕获到鼠标点击,但是程序却收到了鼠标事件,说明这次点击时程序模拟的,直接过滤掉。但是这样做的代价很大,驱动底层的windwos编程带来的可能是巨大的兼容性难题,XP、win7、win10很有可能不一样。与其这样,干嘛还在每天2W用户量的连连看上面较劲,投入人力物力去开发欢乐斗地主不是更好么。
当然,鹅厂是完全有这样的能力和技术手段的。答主曾经遇到过一个windows键盘监听器,用C++钩子实现的全局键盘监听,可以监听一切用户输入。但腾讯QQ的登录框的密码,则是完全兼听不到的,这说明腾讯在此处做了比钩子更加底层的安全处理,也就是驱动级别的处理。题外话:银行官网登录时让下载的安全控件也可以提供这种级别的保护的,四大行只有一个会被钩子监听到按键输入,是哪一个我就不说了,曾经提交过反馈,不知现在处理了没有。
这个外挂其他语言能不能做
可以!答案是一定可以,这其中用到的技术没有一个是非python干不了了,只能说用其他语言,可能代码量多少的问题,比如我python用了200行有效代码,可能go需要300行? C++400行? java2000行? 大概这个行情吧。
哦,当然不是任何语言都可以,html和css就不行。
关于评论和私信
我刚刚才加入知乎,第一次回答有如此的关注度肯定是开心的,但是大家不要再在私信和评论里一口一个大佬大神了,又是问我要代码,又是问我推荐学习路线,问我推荐书籍的。作为程序员拿着不到5K的月薪,这么搞得我心里着实很慌。
还有问我要连连看源码的,这个视频中的连连看是腾讯QQ的连连看,不是我写的,所以你要连连看源码的话....我还真的有:王者荣耀风格的连连看。(https://github.com/TheThreeDog/PictureMatching)这个也就是我外挂项目中捆绑销售的连连看游戏,Qt C++做的,如果能加上“撕拉”的闪电,就更好了。拿去看看就行了,别拿去充当什么课设毕设,这游戏硬让我学弟妹们拿去给三四个人做毕设了,后果....
虽然我原本压根没打算入知乎的坑,但是一波儿回答让我吸了这么多赞还是蛮开心的,如果说问我出名后想做什么事情的话,我想可能是先给自己搞个头像?
PS:呀!刚才又看了一下,评论里没有叫大佬大神的哈, 飘了飘了~~
关于代码中不给针对QQ连连看的数据
外挂这种东西一定会多多少少损害到其他公司的商业利益,虽然鹅厂还轮不到我来考虑人家的商业利益,但是我仍然不希望外挂的配置代码从我手中散播出去。代码的开源一是为了交流和学习,二是为了Github上多多的star(不要脸到我自己都怕)。我也不扯什么伦理道德,我能做的,就只是管好自己。作为原作者也希望大家都能够做到:不要在公开场合散布有关破解QQ游戏连连看的配置信息,不要将此代码用于任何商业用途。
还有就是答主内心比较脆弱,以上言论 有何不妥欢迎随时交流探讨,但是谢绝辱骂。
洋洋洒洒墨迹完,已经深夜了,祝大家好梦,就这样。
点击阅读原文查看本文源码,记得点star哦~
Python爱好者社区历史文章大合集:
Python爱好者社区历史文章列表(每周append更新一次)
关注后在公众号内回复“课程”即可获取:
小编的Python入门免费视频课程!!!
【最新免费微课】小编的Python快速上手matplotlib可视化库!!!
崔老师爬虫实战案例免费学习视频。
陈老师数据分析报告制作免费学习视频。
玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。