,,用Python实现QQ游戏大家来找茬辅助工具

,,用Python实现QQ游戏大家来找茬辅助工具

这是一个大家在QQ里找茬(美女找茬)的辅助插件。它发展的原因是我看到我爸爸天天玩这个游戏,分数4000多负。本来想写一个很简单的东西,但是因为过程中父亲的多次嘲讽,不得不尽力完善,最后形成了一个小产品。

很久没有写过技术相关的文章了。这次写一个有趣的,关于一个有趣的游戏——QQ,关于一个有趣的语言——Python,关于一个有趣的库——Qt。

这是一个大家在QQ里找茬(美女找茬)的辅助插件。它发展的原因是我看到我爸爸天天玩这个游戏,分数4000多负。他玩游戏有他的乐趣,他不太在乎输赢。我这么做只是自娱自乐,顺便问问他好不好。毕竟我们程序员很难在父母面前露一手。本来想写一个很简单的东西,但是因为过程中父亲的多次嘲讽,不得不尽力完善,最后形成了一个小产品。

我接触Python是在2010年。遇见你很短,去年用它写了一些小玩意。离职前,我带着一个Python wxPython的工作工具离开了以前的公司,这个工具相当流行。换了公司后,我努力学习C Qt。我后悔当初选择wxPython而不是PyQt,没能一脉相承。Qt用的时间越长,就得越来越喜欢。写这个东西正好用上了。

话不多说,言归正传。这不是一个完整的代码解释,只是过程中一些技术的分享,包括一些后来被放弃的技术点。刚开始的时候,搜索这些东西还挺费劲的。这里做个笔记,后来者或许能找到收益。

上一张图片:

据说这是游戏中出现次数最多的MM。和QQ有什么关系?

辅助工具在游戏中增加了两个按钮。点击“比较”,自动找到“故障”,用一个蓝色小方框标识。单击“清除”清除标识。

游戏窗口探索

你得用PyWin32库,就是windows接口的Python包,VC基本上能做什么就做什么。

下载地址:http://sourceforge.net/projects/pywin32/,但是你不能直接点击下载图标,否则会是一个Readme.txt,点击“浏览所有文件”找到需要的版本。

#coding=gbk导入win32gui

Game _ hwnd=win32 GUI . findwindow(' # 32770 ','让我们来找茬')打印game _ hwnd

QQ是一个对话窗口,类为“#32770”。桌面上有很多这样的窗口,所以配上了“让我们挑毛病”的标题。因为是中文,所以第一行指定使用gbk编码,否则找不到或者操作有错误。

游戏图片提取

屏幕捕捉用于提取图片。找到窗口后,将其带到前面,然后对窗口进行屏幕截图。屏幕捕获使用众所周知的Python图像库(PIL)库。

导入图像抓取导入win32con

Win32 GUI。Showwindow (Game _ HWND,Win32Con。SW _ Restore) #截图只有强制显示界面后才可以。Win32 GUI。SetForegroundWindow(Game _ HWND)#将游戏窗口带到最前面# Crop获取全貌Game _ Rect=Win32GUI。GetWindowRect (Game _ HWND)

src _ image=image grab . grab((game _ rect[0]9,game _ rect [1] 190,game _ rect [2]-9,game _ rect[1]190 450))# src _ image . show()#分别裁剪左右两边的内容图片

right_box=(517,0,517 500,450)

image _ left=src _ image . crop(left _ box)

image _ right=src _ image . crop(right _ box)# image _ left . show()# image _ right . show()

上面使用的坐标只是为了演示代码而填充的。其实用的是可变参数,分辨率要区分。

PIL是一个强大的Python图形库(使用文档),也将用于后面的对比分析。ImageGrab是PIL的一个模块,用于捕获图像。不带参数的ImageGrab.grab()进行全屏截图,返回一个Image对象。也可以用一个元组作为参数来指定要截取的范围(左上点和右下点的坐标)。两张截图都没有鼠标指针。还有一个ImageGrab.grabclipboard()可以从系统剪贴板中收集图像。

得到图像Image后,可以使用show()方法,用系统默认的图像查看工具打开,方便调试,或者用save(文件名)保存为文件,打开对应的Image.open(文件名)。

Grab得到一个包含左右图片的Image对象,然后用crop(box)方法裁剪出指定区域,分别得到左右游戏图片。

对比获得两图内容不同的区域

自然想到把两张图剪成N个小图对比。如果左右统一区域对应的小图不相等,则为“胡茬”区域。唯一的问题是如何判断两张图的内容不一致?

一开始觉得会比较麻烦,直到发现了Image.histogram()函数,用来获取图像的颜色直方图。平时也喜欢摄影。我知道直方图可以表示一张图片中各种亮度(或颜色)的数量。两张自然图的直方图基本上是不一样的,除非两张图是对称的,颜色是一样的,只是排列不一样。但即便如此,如果继续将两幅图进行分割,其子图的直方图也会有所不同。直方图是一种从图形到数值的转换。通过比较两个图形的颜色值,就可以知道是否存在差异。

对于RBG彩色格式的图像,histogram()函数将返回长度为768的数组,其中0-255表示红色0-255,256-511表示绿色0-255,512-767表示蓝色0-255。数值表示该颜色的像素数。因此,直方图()列表的所有成员的总和等于修改图像的像素值x 3。

编写一个函数来获得两个图形之间的数值差异:

Ef compare(image_a,image_b):“”返回两个图形的差值。

返回两个图形中红色、绿色和蓝色之差的总和' ' histogram_a=image_a.histogram()

histogram _ b=image _ b . histogram()if len(histogram _ a)!=768或len(histogram_b)!=768:不返回

对于xrange(0,256)中的I,red_a=0 red_b=0:

red_a=histogram_a[i 0] * i

red_b=histogram_b[i 0] * i

diff_red=0 if red_a red_b 0:

diff _ red=ABS(red _ a-red_b)* 10000/max(red _ a,red _ b)

对于xrange(0,256)中的I,green_a=0 green_b=0:

green_a=histogram_a[i 256] * i

green_b=histogram_b[i 256] * i

diff_green=0如果green_a green_b 0:

diff _ green=ABS(green _ a-green_b)* 10000/max(green _ a,green _ b)

对于xrange(0,256)中的I,blue_a=0 blue_b=0:

blue_a=histogram_a[i 512] * i

blue_b=histogram_b[i 512] * i

diff_blue=0 if blue_a blue_b 0:

diff _ blue=ABS(blue _ a-blue_b)* 10000/max(blue _ a,blue _ b)

返回红色差分、绿色差分、蓝色差分

将函数返回的红、绿、蓝的差值相加。如果超过预先设定的阈值2000,则说明面积不同。这个计算方法有点“土”,但是对于这次要解决的问题很有效,所以没有进一步改进。

将左右大图切割成若干小图进行比较结果=[[0 for a in xrange (0,50)] for b in xrange (0,45)] for col in xrange (0,50):

对于xrange(0,45)中的行:

clip_box=(列* 10,行* 10,(列1) * 10,(行1) * 10)

clip _ image _ left=image _ left . crop(clip _ box)

clip _ image _ right=image _ right . crop(剪辑框)

clip _ diff=self . compare(clip _ image _ left,clip_image_right)

if sum(clip_diff) 2000:

结果[行][列]=1

大图是500x450,分为10x10个块,定义了一个50x45的两位数组来存储结果。比较后,差值大于阈值的数组区域标记为1。

在游戏的两边标记不同的区域。

一开始我是用PyWin32的一些函数直接在游戏窗口手柄上画的,但是我对Windows编程并不熟悉,也不知道如何解决游戏本身重画后擦掉我标记的问题。后来我搬到了Qt。用Qt创建一个和游戏大小一样透明的QWidget窗口,叠加在游戏窗口上,用遮罩画出标记。标记的数据已经记录在结果数组中,在指定位置画一个正方形表示该区域从左到右不同。注意不要在两个方块之间画边界,避免太多方块干扰游戏。除了标记之外,还绘制了两个按钮来触发比较和擦除。

Ef paintEvent(self,event): #重置蒙版图像self.pixmap.fill()

#创建一个用于绘制的QPainter,描边粗细为2个像素# Qt form上已经事先铺好了一张蓝色的背景图,所以在浇铸了蒙版图案后,标记线为蓝色p=QPainter(self.pixmap)

p.setPen(QPen(QBrush(QColor(0,0,0)),2))

for row in xrange(len(self . result)):for col in xrange(len(self . result[0]):if self . result[row][col]!=0: #设置一个基点,避免难看的算术base _ l _ x=self . anchor _ left _ xself . clip _ width * col

base_r_x=self。ANCHOR_RIGHT_X自我。剪辑_宽度*列

base_y=self。ANCHOR_Y自我。剪辑高度*行

Row==0或self。result [row-1] [col]==0: #如果是第一行,或者上面的网格是空的,就画一个上面的p. Drawline (base _ l _ x,base _ y,base _ l _ xself。Clip _ width,base _ y)。

P.drawline (base _ r _ x,base _ y,base _ r _ xself.clip _ width,base _ y)如果row==len (self。结果)-1或自我。result [row1] [col]==0: #如果是最后一行,或者下方网格为空,则画一条下方的p. drawline (base _ l _ x,base _ yself.clip _ height,base _ l _ xself.clip _ width,base _ yself.clip _ height)。

p.drawLine(base_r_x,base_y self。CLIP_HEIGHT,base_r_x self。CLIP_WIDTH,base _ y self . CLIP _ height)If col==0或self.result [row] [col-1]==0: #如果是第一列,或者左侧网格为空,则绘制左侧P. Drawline (base _ l _ x,Base _ y,base _ l _ x,Base _ y

页(page的缩写)drawline (base _ r _ x,base _ y,base _ r _ x,base _ y self。clip _ height)如果col==len (self。结果[0])-1或自身。result [row] [col 1]==0: #如果是第一列,或者右网格为空,则画一条右p . Drawline(base _ l _ xself.clip _ width,base _ y,base _ l _ xself . clip _ width,base _ yself.clip _ height)。

p.drawLine(base_r_x self。CLIP_WIDTH,base_y,base_r_x self。CLIP_WIDTH,base_y self。剪辑_高度)

#在遮罩上绘制按钮区域,防止按钮被遮罩遮挡而看不到p . fill rect(self . BTN _ compare . geometry()、qrush (qcolor (0,0,0)))

p . fill rect(self . BTN _ toggle . geometry(),QBrush(QColor(0,0,0)))

#使用蒙版图像作为蒙版self . set mask(q bitmap(self . pixmap))

我这里没有替换变量。太麻烦了。把算法看清楚就行了。

让PyQt程序在任务栏隐藏

为了防止PyQt程序出现在任务栏中,构造QWidget设置这些属性。

self.setWindowFlags(Qt。FramelessWindowHint | Qt。WindowStaysOnTopHint | Qt。Popup | Qt。工具)

让PyQt程序加入系统托盘和资源文件来使用。

PyQt添加托盘菜单非常简单,只有几行代码。

创建托盘self.icon=QIcon(':\icon.png ')

自我。trayicon=qsystemtrayicon(自我)自我。trayicon.seticon (self。icon)自我。trayicon.settooltip (u' QQ故障查找助手')self.trayIcon.show()

#托盘泡泡消息self.trayIcon.showMessage(u'QQ找茬助手',u'QQ找茬助手一直处于待机状态,进入游戏后可以激活')

#托盘菜单self.action=QAction(u '退出QQ故障查找助手',self,triggered=sys.exit) #点击后调用sys.exit()命令,即退出self . menu=q menu(self)self . menu . addaction(self . action)self .托盘图标. set上下文菜单(self

我最初使用的托盘图标是一个。ico文件,而执行脚本可以正常显示,但是打包成exe后在托盘上显示为空白图标,用Python的idle工具编译运行也是空白的。经过多次尝试,我发现PyQt的托盘图标无法使用。ico文件,不然就是空白,换成png格式的素材也没问题!

PyQt资源文件打包

Qt在。qrc格式来管理素材,代码以available的形式引用资源文件中的素材:\xxx\xxx.png,PyQt中也支持。

我在这里创建了一个resources.qrc文件。

!DOCTYPE RCC RCC版本=' 1.0 ' qresource fileicon.png/file/qresource/RCC

然后使用

pyrc C4 resources . qrc resources . py

命令,把资源文件变成python模块,并在代码中导入资源,那么就可以这样使用图像素材了。

self.icon=QIcon(':\icon.png ')

打包成可执行程序。

这个工具是给别人用的,当然不能作为py脚本发布。我用cx_Freeze把它打包成可执行程序。

为此,编写一个包命令脚本convert2exe.py

#!Python #coding=gbk # python to exe脚本# # Install CX _ Freeze # exe python convert 2 exe . py build #会自动生成构建目录,其下的所有文件都必须打包# import sys from CX _ freeze导入设置,可执行

如果sys.platform=='win32 ',base=None:

base='Win32GUI '

buildOptions=dict(

压缩=真)

设置(

name='ZhaoChaAssistant ',version='1.0 ',description='ZhaoChaAssistant ',options=dict(build _ exe=build options),executables=[Executable(' ZhaoChaAssistant . py ',base=base,icon='icon.ico')])

最后,执行一个命令

python convert2exe.py构建

然后在当前路径下会创建一个构建目录,打包后的程序会在exe.win-amd64-2.7的其中一个目录下,运行exe就可以执行,就像Python一样。可惜这个包太大了,整个目录都到了30M。

为了让exe程序有一个好看的图标,在最后一行的executables参数中指定了icon='icon.ico ',所以最好使用多页。ico格式(16x16,32x32,48x48.)为这个图标,这样程序就可以在各种显示环境(桌面、文件夹)下有原生显示。

如果打包时必须使用独立的资源,可以在buildOptions字典的参数中添加一个include_files=['xxx.dat']配置,这样在打包时python脚本目录中的xxx.dat文件就会被复制到exe目录中。不写就要手动复制。

提示:Python有自己的绝对路径

Python中有一个神奇的变量,可以得到脚本本身的名字,但是转换成exe后就失效了。这时候你就得用sys.executable来获取可执行程序的名字。你可以用hasattr(sys,' frozen ')来判断你是否被打包了。下面是一个便于采用绝对路径的函数:

import sys def module _ path():if hasattr(sys,' freezed '):return OS . path . dirname(OS . path . abspath(unicode(sys . executable,sys.getfilesystemencoding()))return OS . path . dirname(OS . path . abspath(unicode(_ _ file _ _,sys . getfile systemencoding()))

结束语

Python大概是程序员最好的玩具了,什么都可以粘在一起。每天写点小玩意就完美了。

本文中所有的第三方模块都可以通过Google下载。有些库没有Win7 64位的原始版本(比如PIL),但是可以访问。

http://www.lfd.uci.edu/~gohlke/pythonlibs/

下载别人编的也很方便。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • webqq网页版登录入口,web版qq登录
  • webqq网页版登录入口,web版qq登录,WebQQ最新登陆协议的用法
  • qq邮箱收不到epic邮件,epicqq邮箱显示无效
  • QQ群课堂怎么设置回放,qq的群课堂怎么回放
  • 企业qq聊天记录找回,腾讯企点聊天记录怎么恢复
  • QQ空间评论特效,
  • qq空间回复特效怎么设置,,完美实现仿QQ空间评论回复特效
  • QQ强制聊天网页版,qq强制聊天器网页版
  • QQ强制聊天网页版,qq强制聊天器网页版,QQ强制聊天功能代码(加强版,兼容QQ2010)
  • QQ尾巴病毒,qq尾巴病毒是什么
  • QQ尾巴病毒,qq尾巴病毒是什么,QQ尾巴病毒核心技术的实现
  • QQ封号漏洞,腾讯的威胁
  • QQ封号漏洞,腾讯的威胁,惊!QQ新漏洞 腾讯3亿用户遭受威胁 附说明
  • qq密码被盗怎么找回,最简单的方法,qq密码被盗了怎么找回来吗密保手机也改了
  • qq密码被盗怎么找回,最简单的方法,qq密码被盗了怎么找回来吗密保手机也改了,QQ密码被盗怎么办 (教你如何找回QQ密码)
  • 留言与评论(共有 条评论)
       
    验证码: