本文记一次用python制作win10游戏辅助制作的实践,总结一些制作辅助常用的手段。为啥做辅助去了?这要从周末打游戏的时候说起。终于升级到90级了,可以去“考古”了,然而考古的过程枯燥无味,基本上就是重复以下过程:
可以看到,考古的过程的固定的模式。受到工作中自动化测试的启发,为什么不能将这一过程自动化呢?经过深思熟虑,总结了一下这个过程中可能遇到的难点:
面对考古出来极品神装与元宝的诱惑,面对游戏辅助背后的秘密,面对摆在面前的“业余界难题”,强烈的好奇心让我踏上探索的征程。
经过查找资料与探索,要完成这一系列自动化操作,需要用到的技术点有:
秉着业务驱动技术的思想,我们先从最简单的需求开始。
需求:已知游戏界面如下,想要实现的需求,每隔1s重复打开关闭背包。
红框地方是背包按钮
要想实现以上功能,需要以下几步:
要想实现一边浏览网页一边运行后台脚本,就需要定位游戏所在的窗口句柄,所谓窗口句柄可以理解成窗口的uuid。
要获取窗口句柄值,这边用到了《按键抓抓辅助工具》
将其拖动到指定窗口就可以获取到指定窗口的句柄值。
大漠综合插件(dm.dll)采用vc6.0编写,是一款集前后台,文字识别,图色,键鼠,窗口,内存,DX,Call等功能于一身的综合插件。主要用于按键精灵、简单游、易语言等辅助制作工具,具有识别速度超级快的特点! 采用COM接口编写,适用于所有语言调用。
由《按键抓抓辅助工具》得到游戏窗口句柄值为2297008
可以用以下python代码实现
import win32com.client
import time
# 窗口句柄值
hwnd = 2297008
# 准备大漠插件
dm = win32com.client.Dispatch('dm.dmsoft')
# 绑定窗口
dm.BindWindow(hwnd, "normal", "windows", "windows", 0)
# 背包坐标
x, y = 841, 751
# 封装点击事件
def click(dm, x, y):
dm.MoveTo(x, y)
dm.LeftClick()
while 1:
time.sleep(1)
click(dm, x, y)
BindWindow,MoveTo,LeftClick方法可以查询大漠文档获取使用方法。
需求:以下是游戏界面,红框是符咒,具有双倍经验的加成,限时1小时,1小时过去后要使用f12快捷键吃符咒。
要想实现以上功能,最简单的方法就是sleep 1小时,但是这么实现存在问题就是脚本启动的时候不知道是不是吃了符咒。比较优雅的实现方式是用图像识别的方式实现:
《按键抓抓辅助工具》自带图像截取的功能,我们先将符咒图片截取保存下来作为基准图片。
首先需要截取指定窗口
获取到符咒图像后保存
符咒图像就保存下来了
import win32com.client
import time
# 窗口句柄值
hwnd = 2297008
# 准备大漠插件
dm = win32com.client.Dispatch('dm.dmsoft')
# 绑定窗口
dm.BindWindow(hwnd, "dx2", "windows", "windows", 0)
# 识别区域
x1, y1, x2, y2 = 800, 180, 1020, 650
# 相似度
sim = 0.9
while 1:
time.sleep(0.5)
is_ok, x, y = dm.FindPic(x1, y1, x2, y2, 'D:\software\按键抓抓\screen\\fuzhou.bmp', "000000", sim, 0)
if is_ok == -1:
print("符咒失效")
# 按f12
dm.KeyPress(123)
print("吃符咒")
用到的接口如下:
123是f12的虚拟键码,具体见:https://www.cnblogs.com/del/archive/2007/12/07/987364.html
需求:判断游戏中人物是否移动
红框是坐标数值,如果该区域,在指定的时间内(秒),图像数据一直不变,就说明静止,否则就为移动
由《按键抓抓辅助工具》得到游戏坐标区域左上角和右下角坐标为(948, 156),(1017, 169)
import win32com.client
import time
# 窗口句柄值
hwnd = 2297008
# 准备大漠插件
dm = win32com.client.Dispatch('dm.dmsoft')
# 绑定窗口
dm.BindWindow(hwnd, "dx2", "windows", "windows", 0)
# 坐标区域
x1, y1, x2, y2 = 948, 156, 1017, 169
while 1:
time.sleep(0.1)
is_ok = dm.IsDisplayDead(x1, y1, x2, y2, 1)
if is_ok == 0:
print("移动中")
else:
print("静止中")
需求:判断游戏血量是否健康,如果不健康,自动按f1吃药
这个需求难点就是如何判断血量是否健康,这边使用这种方法实现:
看见游戏左上角血条了吗,假如血条的30%的地方颜色由红色转为灰色,那么我们认为她血量不健康。
另一种方法是使用cheat engine读取血量的内存地址,找到基地址直接读内存,这个难度较高,有兴趣的同学可以读一下这个文章:https://www.cnblogs.com/gd-luojialin/p/7789569.html
import win32com.client
import time
# 窗口句柄值
hwnd = 2297008
# 准备大漠插件
dm = win32com.client.Dispatch('dm.dmsoft')
# 绑定窗口
dm.BindWindow(hwnd, "dx2", "windows", "windows", 0)
# 是否需要吃药,如果
def is_eat_drug(dm):
col = dm.GetColor(107, 65)
if col[0] != "6" or col[2] != "3" or col[4] != "3":
return True
return False
while 1:
time.sleep(1)
res = is_eat_drug(dm)
if res:
print("需要吃药了")
else:
print("血量健康")
如果血量健康,107, 65坐标返回的颜色值为,663f3f,一旦不健康,就不是这个值了。
如何获取某一点的颜色值呢,强大的《按键抓抓辅助工具》就可以解决
大漠插件还有很多好玩的功能,具体可以看看文档,这些功能配合多线程就可以弄出强大的自动化辅助工具,想体验的同学可以试试呀!
最终脚本 github:https://github.com/tdx1997tdx/kungfu_script