之前用python3做游戏自动化脚本,用过很多东西,然后最终有一套完整的方案。在这里随便阐述一下核心思路:
游戏辅助的窗体设计方面:
不需要pyqt这种大型软件,写小工具用自带的tkinter就行了。当然,并不是自己纯手敲代码,是通过拖拽来实现的。怎么,你还不知道tkinter可以界面拖拽生成代码就行VB一样"htmlcode">
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # File : 简单热键.py # Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------ # Date : 2020/3/4 import win32con import ctypes import ctypes.wintypes from threading import Thread,activeCount, enumerate from time import sleep,time class Hotkey(Thread): user32 = ctypes.windll.user32 hkey_list = {} hkey_flags = {} #按下 hkey_running = {} #启停 _reg_list = {} #待注册热键信息 def regiskey(self, hwnd=None, flagid=0, fnkey=win32con.MOD_ALT, vkey=win32con.VK_F9): # 注册热键,默认一个alt+F9 return self.user32.RegisterHotKey(hwnd, flagid, fnkey, vkey) def get_reginfo(self): return self._reg_list def get_id(self,func): self_id = None for id in self.get_reginfo(): if self.get_reginfo()[id]["func"] == func: self_id = id break if self_id: self.hkey_running[self_id] = True return self_id def get_running_state(self,self_id): if self.hkey_running.get(self_id): return self.hkey_running[self_id] else: return False def reg(self,key,func,args=None): id = int(str(round(time()*10))[-6:]) fnkey = key[0] vkey = key[1] info = { "fnkey":fnkey, "vkey":vkey, "func":func, "args":args } self._reg_list[id] = info # print(info) #这里待注册的信息 sleep(0.1) return id def fast_reg(self,id,key = (0,win32con.VK_HOME),func = lambda:print('热键注册开始')): if not self.regiskey(None, id, key[0], key[1]): print("热键注册失败") return None self.hkey_list[id] = func self.hkey_flags[id] = False return id def callback(self): def inner(self = self): for flag in self.hkey_flags: self.hkey_flags[flag] = False while True: for id, func in self.hkey_list.items(): if self.hkey_flags[id]: args = self._reg_list[id]["args"] if args: # print(args) #这里打印传入给注册函数的参数 thread_it(func,*args) else: thread_it(func) self.hkey_flags[id] = False return inner def run(self): for id in self._reg_list: reg_info = self._reg_list[id] fnkey = reg_info["fnkey"] vkey = reg_info["vkey"] func = reg_info["func"] self.fast_reg(id,(fnkey, vkey), func) fn = self.callback() thread_it(fn) # 启动监听热键按下线程 try: msg = ctypes.wintypes.MSG() while True: if self.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0: if msg.message == win32con.WM_HOTKEY: if msg.wParam in self.hkey_list: self.hkey_flags[msg.wParam] = True self.user32.TranslateMessage(ctypes.byref(msg)) self.user32.DispatchMessageA(ctypes.byref(msg)) finally: for id in self.hkey_list: self.user32.UnregisterHotKey(None, id) def thread_it(func, *args): t = Thread(target=func, args=args) t.setDaemon(True) t.start() def jump(func,hotkey): self_id = hotkey.get_id(func) while hotkey.get_running_state(self_id): print(f"{self_id : } 你正在1秒1次的跳动") sleep(1) def stop_jump(start_id,hotkey): hotkey.hkey_running[start_id] = False print(f"{start_id} 即将停止") sleep(1) print(f'当前线程列表:{activeCount()}', enumerate()) def main(): hotkey = Hotkey() start_id = hotkey.reg(key = (win32con.MOD_ALT,win32con.VK_HOME),func=jump,args=(jump,hotkey)) #alt home键 开始 hotkey.reg(key = (0,win32con.VK_END),func=stop_jump,args=(start_id,hotkey)) #alt end键 结束 hotkey.start() #启动热键主线程 print(f"当前总线程数量:{activeCount()}") print('当前线程列表:', enumerate()) print('热键注册初始化完毕,尝试按组合键alt+Home 或者单键END看效果') if __name__ == '__main__': main()
以下是旧的代码,用起来比较麻烦。
#!/usr/bin/env python3 # _*_ coding: utf-8 _*_ # File : demo.py # Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------ # Date : 2019/6/28 import win32con import ctypes import ctypes.wintypes from threading import Thread, Timer, activeCount, enumerate from time import sleep h_ids = [i for i in range(2)] # 创建两个热键序列 h_keys = {i: False for i in h_ids} # 初始化所有热键序列的标志符为False h_dict = {} # 初始化一个空的字典,记录id与func class Hotkey(Thread): # 创建一个Thread的扩展类 user32 = ctypes.windll.user32 # 加载user32.dll # global h_ids, h_keys,h_dict def regiskey(self, hwnd=None, flagid=0, fnkey=win32con.MOD_ALT, vkey=win32con.VK_F9): # 注册热键,默认一个alt+F9 return self.user32.RegisterHotKey(hwnd, flagid, fnkey, vkey) def callback(self, id, func): h_dict[id] = func # 这个id对应这个func,没有就是新增,有就是修改 def inner(): for key, value in h_dict.items(): print(f'总的热键池:{h_ids},当前热键序号:{key}, 当前热键功能:{value},当前热键状态:{h_keys[h_ids[key]]}') while True: for key, value in h_dict.items(): if h_keys[h_ids[key]]: thread_it(value) # 另外开线程执行value h_keys[h_ids[key]] = False return inner def run(self): # print(self.user32) if not self.regiskey(None,h_ids[0],win32con.MOD_ALT,win32con.VK_F9): # 注册快捷键alt+F9并判断是否成功,该热键用于执行一次需要执行的内容。 print(f"热键注册失败! id{h_ids[0]}") # 返回一个错误信息 if not self.regiskey(None,h_ids[1],0,win32con.VK_F10): # 注册快捷键F10并判断是否成功,该热键用于结束程序,且最好这么结束,否则影响下一次注册热键。 print(f"热键注册失败! id{h_ids[1]}") # 以下为检测热键是否被按下,并在最后释放快捷键 try: msg = ctypes.wintypes.MSG() while True: if self.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0: if msg.message == win32con.WM_HOTKEY: if msg.wParam in h_ids: h_keys[msg.wParam] = True self.user32.TranslateMessage(ctypes.byref(msg)) self.user32.DispatchMessageA(ctypes.byref(msg)) finally: for i in h_ids: self.user32.UnregisterHotKey(None, i) # 必须得释放热键,否则下次就会注册失败,所以当程序异常退出,没有释放热键, # 那么下次很可能就没办法注册成功了,这时可以换一个热键测试 def thread_it(func, *args): t = Thread(target=func, args=args) t.setDaemon(True) t.start() def settimeout(func, sec): def inner(): func() Timer(sec, inner).start() thread_it(inner) def setinterval(func, sec, tmrname, flag=True): global timer_dict timer_dict[tmrname] = flag print("已设置tqtimer启用状态为:{}".format(flag)) def inner(): global timer_dict if timer_dict[tmrname]: func() Timer(sec, inner).start() thread_it(inner) def clearinterval(timername): global timer_dict timer_dict[timername] = False flag = timer_dict[timername] print("已设置tqtimer启用状态为:{}".format(flag)) def test_start(): print("按下了开始键...the programe is running") def test_stop(): print("按下了停止键...the programe is stopped") def run_ok(): hotkey = Hotkey() hotkey.start() fn = hotkey.callback(0, test_start) fn = hotkey.callback(1, test_stop) thread_it(fn) sleep(0.5) count = activeCount() print(f"当前总线程数量:{count}") print('当前线程列表:', enumerate()) print('热键注册初始化完毕,尝试按组合键alt+F9 或者单键F10看效果') while True: pass if __name__ == '__main__': run_ok()
这里是没弄界面的源码,所以我就把主线程死循环阻塞了。运行后按alt+F9会打印按下了开始键,按F10会打印按下了停止键。
如果你在tkinter里面跑,直接把run_ok函数后面的while True:pass删掉,然后在init函数里面加入run_ok()就行了。这里指的用PAGE设计的tkinter程序哈!
那么窗体创建完毕就会自动阻塞主线程,其他监控热键的线程随主线程结束。启动期间独立运行互不干扰。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 群星《前途海量 电影原声专辑》[FLAC/分轨][227.78MB]
- 张信哲.1992-知道新曲与精丫巨石】【WAV+CUE】
- 王翠玲.1995-ANGEL【新艺宝】【WAV+CUE】
- 景冈山.1996-我的眼里只有你【大地唱片】【WAV+CUE】
- 群星《八戒 电影原声带》[320K/MP3][188.97MB]
- 群星《我的阿勒泰 影视原声带》[320K/MP3][139.47MB]
- 纪钧瀚《胎教古典音乐 钢琴与大提琴的沉浸时光》[320K/MP3][148.91MB]
- 刘雅丽.2001-丽花皇后·EMI精选王【EMI百代】【FLAC分轨】
- 齐秦.1994-黄金十年1981-1990CHINA.TOUR.LIVE精丫上华】【WAV+CUE】
- 群星.2008-本色·百代音乐人创作专辑【EMI百代】【WAV+CUE】
- 群星.2001-同步过冬AVCD【环球】【WAV+CUE】
- 群星.2020-同步过冬2020冀待晴空【环球】【WAV+CUE】
- 沈雁.1986-四季(2012梦田复刻版)【白云唱片】【WAV+CUE】
- 纪钧瀚《胎教古典音乐 钢琴与大提琴的沉浸时光》[FLAC/分轨][257.88MB]
- 《国语老歌 怀旧篇 3CD》[WAV/分轨][1.6GB]