背景:忆起10年前玩过的网游《热血江湖》。游戏中不定时出现可使用必杀技提示,需要在此时键盘按键(必杀技需根据提示按多个键位)才可使用。
思路一:通过python调用windows大漠插件dm.dll,使用插件中封装好的函数来操作。但是XP系统使用python的win32模块总是报错(可能系统问题),虽然换了win7就正常了,感觉不爽,于是有了思路二。
思路二:PIL定时获取指定位置图片,与按键提示图片对比,如匹配则模拟按对应按键。
上代码结合注释(通过游戏内聊天输入框测试通过):
#coding:utf-8
from ctypes import *
from PIL import ImageGrab, Image
import ctypes
import math
import operator
import time
import win32gui
import win32api
import win32con
import win32com.client
class RECT(ctypes.Structure):
_fields_ = [('left', ctypes.c_int),
('top', ctypes.c_int),
('right', ctypes.c_int),
('bottom', ctypes.c_int)]
def get_image_histogram(imgobj):
return imgobj.histogram()
def pil_image_similarity(h1, h2):
rms = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2, h1, h2)))/len(h1) )
return rms
if __name__=='__main__':
time.sleep(5) #首先休眠5秒,留出时间从cmd窗口切换至游戏窗口
print 'start'
dm = win32com.client.Dispatch('dm.dmsoft' ) #调用大漠插件
h_a = get_image_histogram(Image.open('a.jpg'))
h_d = get_image_histogram(Image.open('d.jpg'))
h_s = get_image_histogram(Image.open('s.jpg'))
HISTS = {'a.jpg': h_a, 'd.jpg': h_d, 's.jpg': h_s}
s = 0 #成功按键计数器
while 1:
try:
rect = RECT()
HWND = win32gui.GetForegroundWindow()#获取当前窗口句柄
ctypes.windll.user32.GetWindowRect(HWND, ctypes.byref(rect))#获取当前窗口坐标
coordinate = (rect.left+385, rect.top+400, rect.right-390, rect.bottom-195)#转换为预截图窗口坐标,根据游戏调整
pic = ImageGrab.grab(coordinate)#截图
pic.save('123.jpg')
pic = Image.open('123.jpg') #将截图对象换成Image对象,这样histogram结果才准确
h_pic = get_image_histogram(pic)
#按键提示的原图片和对应键码值
img_list = {'a.jpg': 65, 'd.jpg': 68, 's.jpg': 83}
for img in img_list.keys():
if(pil_image_similarity(HISTS[img], h_pic)
dm.keypress(img_list[img]) #如匹配则调用大漠插件函数按下对应键
if img=='d.jpg':
s += 1 #成功完成连击,计数器++
print '%s ok' % s
break
except:
pass
time.sleep(1) #游戏按键提示持续2-3秒,休眠一秒节省资源
结局:轻看了这款已入末路,bug百出的游戏。它的防外挂可以识别windows消息模拟按键,除聊天框可以模拟输入成功外,其余均失败。
应对方法:第二天使用了大漠插件的硬件模拟,搞定收工。
备注:实际上整个过程都可以用大漠完成,而且还能兼容当前/非当前窗口、多进程等情况。但用自己写的脚本感觉更cool~
最后:使用大漠插件不要忘记注册dm.dll到电脑中。
背景:忆起10年前玩过的网游《热血江湖》。游戏中不定时出现可使用必杀技提示,需要在此时键盘按键(必杀技需根据提示按多个键位)才可使用。
思路一:通过python调用windows大漠插件dm.dll,使用插件中封装好的函数来操作。但是XP系统使用python的win32模块总是报错(可能系统问题),虽然换了win7就正常了,感觉不爽,于是有了思路二。
思路二:PIL定时获取指定位置图片,与按键提示图片对比,如匹配则模拟按对应按键。
上代码结合注释(通过游戏内聊天输入框测试通过):
#coding:utf-8
from ctypes import *
from PIL import ImageGrab, Image
import ctypes
import math
import operator
import time
import win32gui
import win32api
import win32con
import win32com.client
class RECT(ctypes.Structure):
_fields_ = [('left', ctypes.c_int),
('top', ctypes.c_int),
('right', ctypes.c_int),
('bottom', ctypes.c_int)]
def get_image_histogram(imgobj):
return imgobj.histogram()
def pil_image_similarity(h1, h2):
rms = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2, h1, h2)))/len(h1) )
return rms
if __name__=='__main__':
time.sleep(5) #首先休眠5秒,留出时间从cmd窗口切换至游戏窗口
print 'start'
dm = win32com.client.Dispatch('dm.dmsoft' ) #调用大漠插件
h_a = get_image_histogram(Image.open('a.jpg'))
h_d = get_image_histogram(Image.open('d.jpg'))
h_s = get_image_histogram(Image.open('s.jpg'))
HISTS = {'a.jpg': h_a, 'd.jpg': h_d, 's.jpg': h_s}
s = 0 #成功按键计数器
while 1:
try:
rect = RECT()
HWND = win32gui.GetForegroundWindow()#获取当前窗口句柄
ctypes.windll.user32.GetWindowRect(HWND, ctypes.byref(rect))#获取当前窗口坐标
coordinate = (rect.left+385, rect.top+400, rect.right-390, rect.bottom-195)#转换为预截图窗口坐标,根据游戏调整
pic = ImageGrab.grab(coordinate)#截图
pic.save('123.jpg')
pic = Image.open('123.jpg') #将截图对象换成Image对象,这样histogram结果才准确
h_pic = get_image_histogram(pic)
#按键提示的原图片和对应键码值
img_list = {'a.jpg': 65, 'd.jpg': 68, 's.jpg': 83}
for img in img_list.keys():
if(pil_image_similarity(HISTS[img], h_pic)
dm.keypress(img_list[img]) #如匹配则调用大漠插件函数按下对应键
if img=='d.jpg':
s += 1 #成功完成连击,计数器++
print '%s ok' % s
break
except:
pass
time.sleep(1) #游戏按键提示持续2-3秒,休眠一秒节省资源
结局:轻看了这款已入末路,bug百出的游戏。它的防外挂可以识别windows消息模拟按键,除聊天框可以模拟输入成功外,其余均失败。
应对方法:第二天使用了大漠插件的硬件模拟,搞定收工。
备注:实际上整个过程都可以用大漠完成,而且还能兼容当前/非当前窗口、多进程等情况。但用自己写的脚本感觉更cool~
最后:使用大漠插件不要忘记注册dm.dll到电脑中。