本文来源吾爱破解论坛
本帖最后由 DDFer 于 2020-1-1 23:17 编辑
自学py写的第一个脚本
本教程为新手向
更新:修复了在关闭进程后无法二次开启进程的bug
时隔3天我又回来辣
因为发现原本要介绍的模型套进脚本里用不了,
连夜肝读网上的帖子,终于构建了一个可以使用的新模型,并顺便精简了一下代码(中途出现无数次奇怪的报错)
在此感谢无数个精华帖子的作者(太多了就不点名了)
让我一夜间学会了一个新概念
不多BB,下面教程开始
因为接下来的脚本是精简过的,和上次帖子略有不同,以这次帖子为准
我们先像上个帖子一样搭建好一个界面的代码,以此作为平台
[Python] 纯文本查看 复制代码
import win32com.client as wc,win32gui as wg,threading as xc,time,tkinter as tk,win32api as wa,win32con as wn,multiprocessing as jc def init_window(): global cs,wd wd = tk.Tk() cs = tk.Canvas(wd, width = 800, height = 500, bg = 'white') wd.minsize(800, 500) # 最小尺寸 wd.maxsize(800, 500) wd.title('DDTHelper') pic = tk.PhotoImage(file="pic.png") cs.create_image(400,250,image = pic) cs.pack() bt = tk.Button(wd, text='初始化', bg=('white'), font=('微软雅黑',20), width=155, height=48, command=BT_onCreat) bt.pack() cs.create_window(530,70, width=155, height=48, window=bt) wd.mainloop() def init_control(Znum,name): global v1,v2,v3,tx1,t2,tx2,t3,tx3,txn1,txn2,txn3 if Znum==1: v1=tk.IntVar() tx1=tk.StringVar() #txn1=tk.StringVar() elif Znum==2: v2=tk.IntVar() tx2=tk.StringVar() #txn2=tk.StringVar() elif Znum==3: v3=tk.IntVar() tx3=tk.StringVar() #txn3=tk.StringVar() exec('tx{}.set("未运行")'.format(Znum)) exec('lb{} = tk.Label(wd,text="{}",bg=("#ffffff"),font=("微软雅黑",20))'.format(Znum,name)) #exec('lbn{} = tk.Label(wd,textvariable=txn{},bg=("#ffffff"),font=("微软雅黑",10))'.format(Znum,Znum)) exec('cb{} = tk.Checkbutton(wd,textvariable=tx{},bg=("#ffffff"),font=("微软雅黑",10),variable = v{}, height=5,width = 0,command=BT_onRun{})'.format(Znum,Znum,Znum,Znum)) exec('cb{}.pack()'.format(Znum)) exec('lb{}.pack()'.format(Znum)) #exec('lbn{}.pack()'.format(Znum)) Ytmp=Znum*100 Ytmp=Ytmp+70 exec('cs.create_window(630,{},width=0,height=0,window=lb{})'.format(Ytmp,Znum)) Ytmp=Ytmp+40 #exec('cs.create_window(630,{},width=35,height=25,window=lbn{})'.format(Ytmp,Znum)) exec('cs.create_window(710,{},width=70,height=25,window=cb{})'.format(Ytmp,Znum)) def BT_onCreat(): global Znum,D1,D2,D3,conT Znum = 0 wg.EnumWindows(get_all_hwnd, 0) conT=jc.Manager().Array("i",[3,0,0,0])#用来控制进程 #lock = jc.Lock()#用来给进程运行顺序排序,防止显示错乱,打包成exe时可以去除(如果出现错误 windos 什么的就改成lock = jc.Manager.Lock() 这样就可以了,或者删掉Manager) #lock不稳定,弃用 for h,t in hwnd_title.items(): if "4399" in t: hwnd = t.split("|")[3] name = t.split("|")[2] print("账号:" + name + "句柄:" + hwnd) Znum = Znum + 1 hwnd = int(hwnd) init_control(Znum,name) if Znum==1: D1 = jc.Manager().Array("i",[1,hwnd]) elif Znum==2: D2 = jc.Manager().Array("i",[2,hwnd]) elif Znum==3: D3 = jc.Manager().Array("i",[3,hwnd]) def get_all_hwnd(hwnd,mouse): if wg.IsWindow(hwnd) and wg.IsWindowEnabled(hwnd) and wg.IsWindowVisible(hwnd): hwnd_title.update({hwnd:wg.GetWindowText(hwnd)}) def Con(data,conT): #l.acquire()#锁 #try: print("运行成功") #finally: #l.release() def onRunMan(Znum): if onRunMan2(Znum) == 1: conT[Znum]=0 exec('p{} = jc.Process(target=Con,args=(D{},conT))'.format(Znum,Znum)) exec('p{}.daemon=True'.format(Znum)) exec('tx{}.set("运行中")'.format(Znum)) exec('p{}.start()'.format(Znum)) else: conT[Znum]=1 exec('tx{}.set("未运行")'.format(Znum)) def onRunMan2(Znum): if Znum ==1: return v1.get() elif Znum == 2: return v2.get() elif Znum ==3: return v3.get() def BT_onRun1(): onRunMan(1) def BT_onRun2(): onRunMan(2) def BT_onRun3(): onRunMan(3) if __name__ == '__main__': hwnd_title = dict() init_window()
3.png (248.86 KB, 下载次数: 1)
下载附件 保存到相册
成功识别后,我们勾上运行的钩子
成功的话会在终端显示 成功运行
这次我在onCreat方法里封装需要发送给进程的数据
然后在onRunMain中动态拼装进程并启动它
再让产生的子进程来生成守护线程,让守护线程去操控游戏
然后子进程循环检测我们是不是发出了停止命令,如果线程检测到我们发出了停止的命令
自身的代码就执行完了,然后带动他产生的守护线程也被kill掉了。
这样就可以实现多线程的随时停止了
代码还巧妙借用了exec指令的“特性”:输出变量只能在该方法内可见,一旦该方法被重启,变量就没了
也就是说,如果我们直接用 p1 = jc.Process(target=Con,args=(D1,conT))来产生进程
那么在进程结束后,需要用 del p1来清除掉进程的“尸体”,然后再重新创建它
设置的Con方法代码,让它会自己生产守护线程
[Python] 纯文本查看 复制代码
def Con(hwnd,Znum,conT,l): #设置守护线程 time.sleep(1) exec('t{} = xc.Thread(target=RunMain,args=(hwnd,Znum))'.format(Znum))#依靠Znum(游戏账号分配到的id)来动态生成不同的线程 exec('t{}.setDaemon(True)'.format(Znum)) exec('t{}.start()'.format(Znum)) while True:#开始接收我们是否发出了停止的命令 if conT[Znum] == 0: time.sleep(1) else: break print('进程' + str(Znum) +':已退出')
再补充它生产出的子线程所执行的方法(不可用)
[Ruby] 纯文本查看 复制代码
def RunMain(hwnd,Znum): RM=0#运行次数,因为用多进程后无法向用户节目输出,所以已弃用 hdc=wg.GetWindowDC(int(hwnd))#获取目标页游(flash)的hdc,用来获取指定坐标的颜色 while True: while str(wg.GetPixel(hdc,919,280))!=str(10248996):#检测游戏角色是否处在房间界面(初始需要用户手动将游戏角色进入房间界面),用于检测游戏角色是否退出了副本回到了游戏房间 print("房间") doClick(hwnd,5,5) time.sleep(1) if Chose_FB(hwnd,hdc) == 1:#查看当前两个副本中又那个副本开放,其实这个设计并不合理,如果当前没副本开放就出bug了,不过我只会在有副本开放才会运行这个脚本对吧-,- FB_MS(hwnd,hdc)#启动1号副本方案 else: FB_JD(hwnd,hdc)#二号副本方案 RM = RM + 1
当然,,现在由于主题和篇幅原因,我就不补充副本的流程方法了, 但这样可能会导致运行时报错
我们可以将它删减成
[Python] 纯文本查看 复制代码
def RunMain(hwnd,Znum): white True: print("我在运行") time.sleep(1)
这样在勾选运行的时候,
终端就会不停的显示 我在运行
直到我们把运行的钩子取消后,就不会再显示了(线程被kill掉了)
这次的教程就到这里结束了。。
完整的实例已经在最新的帖子里面贴出来了:点我跳转
为了让各路大神能原汁原味的跑这个脚本
我补上我用的登录器的下载地址:http://t.cn/AikKziQX (压缩包密码:www.52pojie.cn)
不过好像多数杀毒软件都报毒,但用了那么久也没什么异常,且它功能强大,又是免费的,,有能力的大佬就帮忙,分析一波吧
祝各路大神冬至节快乐
我们下篇见
版权声明:
本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。
- 上一篇:
- 下一篇: 按用户爬取美拍视频