吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5103|回复: 19
上一主题 下一主题
收起左侧

[Python 原创] [Python] 【Python3】教你写页游自动化Python脚本 2.线程篇(模仿某键精灵)

[复制链接]
跳转到指定楼层
楼主
DDFer 发表于 2019-12-22 23:12 回帖奖励
本帖最后由 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()


成功识别后,我们勾上运行的钩子
成功的话会在终端显示 成功运行

这次我在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)
不过好像多数杀毒软件都报毒,但用了那么久也没什么异常,且它功能强大,又是免费的,,有能力的大佬就帮忙,分析一波吧
祝各路大神冬至节快乐
我们下篇见

免费评分

参与人数 8吾爱币 +12 热心值 +7 收起 理由
ttrtty5 + 1 + 1 谢谢@Thanks!
seal77 + 1 谢谢@Thanks!
George_0759 + 1 + 1 用心讨论,共获提升!
wdxm2008 + 1 + 1 用心讨论,共获提升!
wxue + 1 + 1 谢谢@Thanks!
yjn866y + 1 + 1 我很赞同!
生如上善若水 + 1 + 1 能出个如何登录论坛自动回帖的吗?谢谢
苏紫方璇 + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| DDFer 发表于 2019-12-24 08:40 |楼主
stone009 发表于 2019-12-23 09:24
有没有Python手机脚本的教程呀?

手机的话我记得好像在找资料的时候见过一个帖子
不过脚本是在电脑上执行的,通过adb实现获取屏幕颜色和模拟点击和拖动
下次看看还能不能找到,找到就在下下期整理出来吧
沙发
一人之下123456 发表于 2019-12-22 23:32
3#
生如上善若水 发表于 2019-12-23 00:00
学习了,谢谢分享,
能出个如何登录论坛自动回帖的吗?谢谢
4#
吾爱007 发表于 2019-12-23 00:24
感谢分享
5#
goblin0427 发表于 2019-12-23 00:26
感谢大佬分享
6#
1983 发表于 2019-12-23 00:33
你真是个精灵鬼,握手听你!了
7#
twostudy 发表于 2019-12-23 00:42
用到很多东西啊,值得收藏下来慢慢钻研!
8#
diyikuai 发表于 2019-12-23 05:38
学习了,技术牛逼
9#
yjn866y 发表于 2019-12-23 07:37
学习了,,给分、
10#
Assass 发表于 2019-12-23 08:18
刚开始学python,看的一脸懵逼
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 17:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表