欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    最近在開(kāi)發(fā)蘑菇博客的時(shí)候,需要啟動(dòng)的服務(wù)比較多,比如nginx,solr,redis,mysql等,我就想著在Windows平臺(tái)能不能編寫個(gè)腳本,讓它們一鍵啟動(dòng)

    當(dāng)然小伙伴可以把它們注冊(cè)成系統(tǒng)服務(wù),然后設(shè)置開(kāi)機(jī)自啟,更加省時(shí)省力,現(xiàn)在做的是將他們寫在bat腳本上

    啟動(dòng)腳本格式

    # /b 代表后臺(tái)啟動(dòng)
    start /b  server

    編寫腳本

    我們首先創(chuàng)建一個(gè) startup.bat文件,然后輸出下面的內(nèi)容

    start /d  java -jar zipkin.jar

    這樣他就會(huì)幫我們啟動(dòng)zipikin服務(wù)了,我們?cè)O(shè)置多個(gè),即可完成項(xiàng)目的一鍵啟動(dòng)

    start  java -jar E:/Software/Zipkin/zipkin.jar
    start  E:/Software/nginx/nginx.exe
    start  E:/Software/redis/Redis-x64-3.2.100/redis-server.exe
    start  E:/Software/xampp/tomcat/bin/startup.bat
    start  E:/Software/xampp/mysql/bin/mysqld.exe

    本教程為新手學(xué)習(xí)python教程
    廢話少說(shuō),下面開(kāi)始python教程
    我們先用tkinter搭建好腳本的基本界面

    私信小編01即可獲取大量Python學(xué)習(xí)資源

    import tkinter as tk#[size=3]首先導(dǎo)入tkinter,需要事先用pip安裝進(jìn)python里(方法自行百度)[/size]
     
    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")#設(shè)置背景圖片,最好是800*500和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 BT_onCreat():
        print("初始化。。。")
    #入口,這行代碼需要一直都待在腳本的最底下
    #設(shè)置字典
    hwnd_title = dict()
    init_window()

    (不過(guò)在圖片上疊加控件其實(shí)有更好的方案,使控件的背景為透明的,但是那篇文章的代碼運(yùn)行不來(lái))
    運(yùn)行效果

    現(xiàn)在我們?yōu)辄c(diǎn)擊 初始化 按鈕添加一些事項(xiàng)
    讓他在被點(diǎn)擊的時(shí)候識(shí)別當(dāng)前的游戲窗口
    (因?yàn)槲矣玫氖?6jb大廳登錄的游戲,抓取句柄的時(shí)候可以根據(jù)他的title來(lái)區(qū)別游戲窗口)
    這里我偷了個(gè)懶,利用該登錄器游戲窗口的title來(lái)獲取

    更改上面的導(dǎo)入庫(kù)和 BT_onCreat()方法

    import win32com.client as wc,win32gui as wg,threading as xc,time,tkinter as tk,win32api as wa,win32con as wn#需要事先用pip安裝pywin32插件進(jìn)python里(方法自行百度)
     
    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")#設(shè)置背景圖片,最好是800*500和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 BT_onCreat():
        global is_run,Znum,t1,t2,t3
        Znum = 0#當(dāng)前已經(jīng)登陸的游戲賬號(hào)數(shù)量
        wg.EnumWindows(get_all_hwnd, 0)
        for h,t in hwnd_title.items():
            if "4399" in t:#根據(jù)title里包含的 4399 來(lái)提取游戲窗口
                hwnd = t.split("|")[3]
                name = t.split("|")[2]
                print("賬號(hào):" + name + "句柄:" + hwnd)
                Znum = Znum + 1
                hwnd = int(hwnd)#將句柄轉(zhuǎn)化為int,因?yàn)榫浔菑臉?biāo)題獲取的string,導(dǎo)致了類型錯(cuò)誤,我就是被這個(gè)坑了好久。。
                if Znum==1:#為每一個(gè)游戲界面創(chuàng)建一個(gè)單獨(dú)的操作線程,為了方便用global傳遞,沒(méi)有用exec。
                    t1 = xc.Thread(target=Con,args=(hwnd,name,Znum))
                elif Znum==2:
                    t2 = xc.Thread(target=Con,args=(hwnd,name,Znum))
                elif Znum==3:
                    t3 = xc.Thread(target=Con,args=(hwnd,name,Znum))
                init_control(Znum,name)
    #下面再添加幾個(gè)方法進(jìn)去
    #獲取句柄用的
    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)})
    #為每一個(gè)線程創(chuàng)建一個(gè)對(duì)應(yīng)的控件來(lái)控制線程的運(yùn)行
    def init_control(Znum,name):
        global cs,wd,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("未運(yùn)行")'.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 Con(hwnd,name,xc):
    print("啟動(dòng)成功")
    #多選框點(diǎn)擊事件
    def BT_onRun1():
        global v1,tx1,t1,ct1
        if v1.get()==1:#判斷是否被選中
            ct1=0
            tx1.set('正運(yùn)行')
            t1.start()
        else:
            ct1=1#用來(lái)控制線程終止
            tx1.set('未運(yùn)行')  
    def BT_onRun2():
        global v2,tx2,ct2
        if v2.get()==1:#判斷是否被選中
            ct2=0
            tx2.set('正運(yùn)行')
            t2.start()
        else:
            ct2 = 1
            tx2.set('未運(yùn)行')
    def BT_onRun3():
        global v3,tx3,ct3
        if v3.get()==1:#判斷是否被選中
            ct3=0
            tx3.set('正運(yùn)行')
            t3.start()
        else:
            ct3=1
            tx3.set('未運(yùn)行')
    #入口,這行代碼需要一直都待在腳本的最底下
    #設(shè)置字典
    hwnd_title = dict()
    init_window()

    運(yùn)行后,點(diǎn)擊初始化的效果

    可以看到,當(dāng)只有一個(gè)游戲窗口的時(shí)候,腳本就自動(dòng)識(shí)別出了該游戲窗口。(目前最多識(shí)別3個(gè),且不能二次點(diǎn)擊初始化,否則會(huì)報(bào)錯(cuò)。聽(tīng)說(shuō)用exce動(dòng)態(tài)封裝線程時(shí)可以用dict來(lái)接收,而目前二次識(shí)別也有了大致方案)

    并在勾選 未運(yùn)行 旁邊的 框框 時(shí),運(yùn)行對(duì)應(yīng)的線程。


    接下來(lái)就要到腳本的線程模塊了,而有過(guò)py基礎(chǔ)的人都知道,py的線程是沒(méi)有stopThread的
    但我們將要實(shí)現(xiàn)如何控制腳本執(zhí)行游戲操作的線程,讓它收放自如

    下面教程開(kāi)始
    因?yàn)榻酉聛?lái)的腳本是精簡(jiǎn)過(guò)的,和上次帖子略有不同,以這次帖子為準(zhǔn)
    我們先像上個(gè)帖子一樣搭建好一個(gè)界面的代碼,以此作為平臺(tái)

    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("未運(yùn)行")'.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])#用來(lái)控制進(jìn)程
        #lock = jc.Lock()#用來(lái)給進(jìn)程運(yùn)行順序排序,防止顯示錯(cuò)亂,打包成exe時(shí)可以去除(如果出現(xiàn)錯(cuò)誤 windos 什么的就改成lock = jc.Manager.Lock() 這樣就可以了,或者刪掉Manager)
        #lock不穩(wěn)定,棄用
        for h,t in hwnd_title.items():
            if "4399" in t:
                hwnd = t.split("|")[3]
                name = t.split("|")[2]
                print("賬號(hào):" + 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("運(yùn)行成功")
        #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("運(yùn)行中")'.format(Znum))
            exec('p{}.start()'.format(Znum))
        else:
            conT[Znum]=1
            exec('tx{}.set("未運(yùn)行")'.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()


    成功識(shí)別后,我們勾上運(yùn)行的鉤子
    成功的話會(huì)在終端顯示 成功運(yùn)行

    這次我在onCreat方法里封裝需要發(fā)送給進(jìn)程的數(shù)據(jù)
    然后在onRunMain中動(dòng)態(tài)拼裝進(jìn)程并啟動(dòng)它

    再讓產(chǎn)生的子進(jìn)程來(lái)生成守護(hù)線程,讓守護(hù)線程去操控游戲

    然后子進(jìn)程循環(huán)檢測(cè)我們是不是發(fā)出了停止命令,如果線程檢測(cè)到我們發(fā)出了停止的命令

    自身的代碼就執(zhí)行完了,然后帶動(dòng)他產(chǎn)生的守護(hù)線程也被kill掉了。
    這樣就可以實(shí)現(xiàn)多線程的隨時(shí)停止了



    代碼還巧妙借用了exec指令的“特性”:輸出變量只能在該方法內(nèi)可見(jiàn),一旦該方法被重啟,變量就沒(méi)了
    也就是說(shuō),如果我們直接用 p1 = jc.Process(target=Con,args=(D1,conT))來(lái)產(chǎn)生進(jìn)程
    那么在進(jìn)程結(jié)束后,需要用 del p1來(lái)清除掉進(jìn)程的“尸體”,然后再重新創(chuàng)建它



    設(shè)置的Con方法代碼,讓它會(huì)自己生產(chǎn)守護(hù)線程

    def Con(hwnd,Znum,conT,l):
        #設(shè)置守護(hù)線程
        time.sleep(1)
        exec('t{} = xc.Thread(target=RunMain,args=(hwnd,Znum))'.format(Znum))#依靠Znum(游戲賬號(hào)分配到的id)來(lái)動(dòng)態(tài)生成不同的線程
        exec('t{}.setDaemon(True)'.format(Znum))
        exec('t{}.start()'.format(Znum))
        while True:#開(kāi)始接收我們是否發(fā)出了停止的命令
            if conT[Znum] == 0:
                time.sleep(1)
            else:
                break
        print('進(jìn)程' + str(Znum) +':已退出')

    再補(bǔ)充它生產(chǎn)出的子線程所執(zhí)行的方法(不可用)

    def RunMain(hwnd,Znum):
        RM=0#運(yùn)行次數(shù),因?yàn)橛枚噙M(jìn)程后無(wú)法向用戶節(jié)目輸出,所以已棄用
        hdc=wg.GetWindowDC(int(hwnd))#獲取目標(biāo)頁(yè)游(flash)的hdc,用來(lái)獲取指定坐標(biāo)的顏色
        while True:
            while str(wg.GetPixel(hdc,919,280))!=str(10248996):#檢測(cè)游戲角色是否處在房間界面(初始需要用戶手動(dòng)將游戲角色進(jìn)入房間界面),用于檢測(cè)游戲角色是否退出了副本回到了游戲房間
                print("房間")
                doClick(hwnd,5,5)
                time.sleep(1)
            if Chose_FB(hwnd,hdc) == 1:#查看當(dāng)前兩個(gè)副本中又那個(gè)副本開(kāi)放,其實(shí)這個(gè)設(shè)計(jì)并不合理,如果當(dāng)前沒(méi)副本開(kāi)放就出bug了,不過(guò)我只會(huì)在有副本開(kāi)放才會(huì)運(yùn)行這個(gè)腳本對(duì)吧-,-
                FB_MS(hwnd,hdc)#啟動(dòng)1號(hào)副本方案
            else:
                FB_JD(hwnd,hdc)#二號(hào)副本方案
            RM = RM + 1

    當(dāng)然,,現(xiàn)在由于主題和篇幅原因,我就不補(bǔ)充副本的流程方法了, 但這樣可能會(huì)導(dǎo)致運(yùn)行時(shí)報(bào)錯(cuò)
    我們可以將它刪減成

    def RunMain(hwnd,Znum):
        white True:
            print("我在運(yùn)行")
            time.sleep(1)

    這樣在勾選運(yùn)行的時(shí)候,
    終端就會(huì)不停地顯示 我在運(yùn)行
    直到我們把運(yùn)行的鉤子取消后,就不會(huì)再顯示了(線程被kill掉了)

    熟悉按鍵精靈的大佬們都應(yīng)該用過(guò)一個(gè)叫大漠的插件
    但先講不依賴大漠的情況下,用微軟官方的指令來(lái)實(shí)現(xiàn)腳本的操作

    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("未運(yùn)行")'.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])
        for h,t in hwnd_title.items():
            if "4399" in t:
                hwnd = t.split("|")[3]
                name = t.split("|")[2]
                print("賬號(hào):" + 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 all_run(Znum):
        while Znum >0:
            exec('t{}.start()'.format(Znum))
            Znum = Znum - 1
     
     
    #操作類--------------------------------------------------------------------------------------------------------------
    def climb(hwnd,jl,fx):
        if fx==1:#右邊
            #適應(yīng)方向及防止無(wú)效
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None)
            wa.SendMessage(hwnd,wn.WM_KEYUP,68,None)
            #1.3=1屏距
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None)
            time.sleep(jl*1.3)
            wa.SendMessage(hwnd,wn.WM_KEYUP,68,None)
        else:
            #適應(yīng)方向及防止無(wú)效
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,65,None)
            wa.SendMessage(hwnd,wn.WM_KEYUP,65,None)
            #1.3=1屏距
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,65,None)
            time.sleep(jl*1.3)
            wa.SendMessage(hwnd,wn.WM_KEYUP,65,None)
    def doAngle(hwnd,jd):
        for i in range(jd):
            time.sleep(0.05)
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,87,None)
            wa.SendMessage(hwnd,wn.WM_KEYUP,87,None)
    def doClick(hwnd,cx,cy):
        long_position = wa.MAKELONG(cx, cy)
        wa.SendMessage(hwnd, wn.WM_LBUTTONDOWN, wn.MK_LBUTTON, long_position)
        wa.SendMessage(hwnd, wn.WM_LBUTTONUP, wn.MK_LBUTTON, long_position)
    def doFire(hwnd,ld):
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,66,None)#先摁大
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,69,None)#先摁技能
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,97,None)
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,98,None)
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,97,None)#11大招
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,100,None)
        wa.SendMessage(hwnd,wn.WM_KEYDOWN,32,None)
        time.sleep(ld * 0.04)
        wa.SendMessage(hwnd,wn.WM_KEYUP,32,None)
     
     
    #游戲流程處理類---------------------------------------------------------------------------------------------------------
    def Chose_FB(hwnd,hdc):
        doClick(hwnd,600,200)#打開(kāi)菜單
        time.sleep(1)
        doClick(hwnd,626,188)#單人副本
        time.sleep(1)
        while True:
            doClick(hwnd,5,5)
            if str(wg.GetPixel(hdc,244,237))==str(2041582):
                doClick(hwnd,289,243)#魔石
                FBn=1
                break
            elif str(wg.GetPixel(hdc,337,278))==str(13298869):
                doClick(hwnd,292,299)#技能丹
                FBn=2
                break
        time.sleep(1)
        doClick(hwnd,726,501)#難度
        time.sleep(1)
        doClick(hwnd,504,563)#確定
        time.sleep(1)
        doClick(hwnd,951,491)
        return(FBn)
    def FB_MS(hwnd,hdc):
        time.sleep(24)
        while str(wg.GetPixel(hdc,497,169))!=str(5418993):#回合檢測(cè)
            doClick(hwnd,5,5)
            time.sleep(0.5)
        while True:
            doClick(hwnd,5,5)
            colx=wg.GetPixel(hdc,917,486)
            if str(colx)==str(36645):
                print("位置1")
                JD=18
                break
            else:
                print("位置2")
                climb(hwnd,0.5,0)
                JD=25
                break
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,69,None)#波谷專用
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,80,None)#第一次pass
        time.sleep(5)
        for i in range(2):
            while str(wg.GetPixel(hdc,497,169))!=str(5418993):#回合檢測(cè)
                doClick(hwnd,5,5)
                time.sleep(0.5)
            wa.SendMessage(hwnd, wn.WM_KEYDOWN, 65, None)
            wa.SendMessage(hwnd, wn.WM_KEYUP, 65, None)
            doFire(hwnd,20)
        time.sleep(6)
        doAngle(hwnd,JD)
        time.sleep(10)
        while True:
            #回合循環(huán)
            cs = 0
            while str(wg.GetPixel(hdc,497,169))!=str(5418993):#回合檢測(cè)
                if cs>=20:#超時(shí)退出
                    break
                else:
                    doClick(hwnd,5,5)
                    time.sleep(1)
                    cs=cs+1
            #退出
            if cs==20:
                print("退出副本")
                break
            else:
                doFire(hwnd,20)       
    def FB_JD(hwnd,hdc):
        while True:
            cs = 0
            cg = 0
            while str(wg.GetPixel(hdc,497,169))!=str(5418993):#回合檢測(cè)
                if cs>=20:#超時(shí)退出
                    cg=1
                    cs=0
                    break
                else:
                    doClick(hwnd,5,5)
                    time.sleep(1)
                    cs=cs+1
            if cg==1:
                break
            else:
                doFire(hwnd,60)
     
    #程序流程模塊類----------------------------------------------------------------------------------------------------------
    def RunMain(hwnd):
        RM=0
        hdc=wg.GetWindowDC(hwnd)
        while True:
            while str(wg.GetPixel(hdc,919,280))!=str(10248996):#房間檢測(cè)
                print("房間")
                doClick(hwnd,5,5)
                time.sleep(1)
            if Chose_FB(hwnd,hdc) == 1:
                FB_MS(hwnd,hdc)
            else:
                FB_JD(hwnd,hdc)
            RM = RM + 1
    def Con(Data,conT):
        #設(shè)置守護(hù)線程
        Znum = Data[0]
        print(str(Data[0]))
        hwnd = Data[1]
        time.sleep(1)
        exec('t{} = xc.Thread(target=RunMain,args=(hwnd,))'.format(Znum))
        exec('t{}.setDaemon(True)'.format(Znum))
        exec('t{}.start()'.format(Znum))
        while True:
            if conT[Znum] == 0:
                time.sleep(1)
            else:
                break
        print('進(jìn)程' + str(Znum) +':已退出')
     
     
    def onRunMan(Znum):
        if onRunMan2(Znum) == 1:
            conT[Znum]=0
            exec('tx{}.set("運(yùn)行中")'.format(Znum))
            exec('p{} = jc.Process(target=Con,args=(D{},conT))'.format(Znum,Znum))
            exec('p{}.daemon=True'.format(Znum))
            exec('p{}.start()'.format(Znum))
        else:
            conT[Znum]=1
            #exec('del p{}'.format(Znum))
            exec('tx{}.set("未運(yùn)行")'.format(Znum))
    def onRunMan2(Znum):
        if Znum ==1:
            return v1.get()
        elif Znum == 2:
            return v2.get()
        elif Znum ==3:
            return v3.get()
    def onRunMan3(Znum):
        if Znum ==1:
            if p1.is_alive:
                return(1)
            else:
                return(0)
        elif Znum == 2:
            if p2.is_alive:
                return(1)
            else:
                return(0)
        elif Znum ==3:
            if p3.is_alive:
                return(1)
            else:
                return(0)
    def BT_onRun1():
        onRunMan(1)
    def BT_onRun2():
        onRunMan(2)
    def BT_onRun3():
        onRunMan(3)
     
    if __name__ == '__main__':
        hwnd_title = dict()
        init_window()

    我已經(jīng)將模塊代碼用--區(qū)分開(kāi)來(lái)
    之前我們講過(guò)了 窗口界面 和 程序線程

    重點(diǎn)在于 操作類

    負(fù)責(zé)向指定游戲窗口發(fā)生鼠標(biāo)點(diǎn)擊命令的方法

    def doClick(hwnd,cx,cy):
        long_position = wa.MAKELONG(cx, cy)#模擬鼠標(biāo)指針 傳送到指定坐標(biāo)
        wa.SendMessage(hwnd, wn.WM_LBUTTONDOWN, wn.MK_LBUTTON, long_position)#模擬鼠標(biāo)按下
        wa.SendMessage(hwnd, wn.WM_LBUTTONUP, wn.MK_LBUTTON, long_position)#模擬鼠標(biāo)彈起

    這個(gè)方法把原本復(fù)雜的代碼壓縮了,于是我們要點(diǎn)擊游戲界面的時(shí)候,就可以調(diào)用該方法來(lái)實(shí)現(xiàn),比如
    doClick(目標(biāo)窗口句柄,x坐標(biāo),y坐標(biāo))
    是不是就有內(nèi)味了?

    再看看其他方法

    def climb(hwnd,jl,fx):
        if fx==1:#右邊
            #適應(yīng)方向及防止無(wú)效
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None)
            wa.SendMessage(hwnd,wn.WM_KEYUP,68,None)
            #1.3秒=1屏距
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None)
            time.sleep(jl*1.3)
            wa.SendMessage(hwnd,wn.WM_KEYUP,68,None)
        else:
            #適應(yīng)方向及防止無(wú)效
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,65,None)
            wa.SendMessage(hwnd,wn.WM_KEYUP,65,None)
            #1.3=1屏距
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,65,None)
            time.sleep(jl*1.3)
            wa.SendMessage(hwnd,wn.WM_KEYUP,65,None)
    def doAngle(hwnd,jd):
        for i in range(jd):
            time.sleep(0.05)
            wa.SendMessage(hwnd,wn.WM_KEYDOWN,87,None)
            wa.SendMessage(hwnd,wn.WM_KEYUP,87,None)
    def doFire(hwnd,ld):
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,66,None)#先摁大招
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,69,None)#先摁技能
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,97,None)
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,98,None)#如果有大招,
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,97,None)#11大招
        wa.SendMessage(hwnd,wn.WM_KEYFIRST,100,None)
        wa.SendMessage(hwnd,wn.WM_KEYDOWN,32,None)#空格蓄力
        time.sleep(ld * 0.04)#每蓄力1力度約用時(shí)0.04秒,受游戲延遲和電腦性能會(huì)有誤差,總體可以接受,也可以改成識(shí)別力度條(更精準(zhǔn),但因?yàn)榱Χ葪l顏色不純干擾暫且擱置方案)
        wa.SendMessage(hwnd,wn.WM_KEYUP,32,None)#松開(kāi)空格

    這里的方法基本都是發(fā)送一些鍵盤操作的集合
    比如說(shuō)
    方法climb是用來(lái)控制游戲中人物的爬行,
    方法doAngle是用來(lái)調(diào)整游戲中人物發(fā)射炮彈的角度
    方法doFire就是操作游戲人物發(fā)動(dòng)攻擊
    總結(jié)以上方法,模擬鍵盤按鍵有3條指令

    wa.SendMessage(游戲窗口句柄,wn.WM_KEYDOWN,按鍵碼,None)
         wa.SendMessage(游戲窗口句柄,wn.WM_KEYUP,按鍵碼,None)
    wa.SendMessage(游戲窗口句柄,wn.WM_KEYFIRST,按鍵碼,None)

    它們分別是向游戲窗口發(fā)送 摁下指定按鍵 彈起指定按鍵 和集合摁下和彈起一體的 點(diǎn)擊指定按鍵
    但需要注意的是
    如果需要重復(fù)點(diǎn)擊一個(gè)按鍵的時(shí)候,千萬(wàn)不要用 點(diǎn)擊指定按鍵 這個(gè)代碼
    這樣會(huì)產(chǎn)生一個(gè)bug,相當(dāng)于按下了按鍵卻沒(méi)有彈起,導(dǎo)致失控
    需要像doAngle方法那樣,使用按下和彈起來(lái)保證不會(huì)出bug

    然后再到游戲取色
    因?yàn)闆](méi)有提取的必要,我就沒(méi)有單獨(dú)分離出來(lái)
    取色需要用到hdc(想知道hdc的可以去百度 hdc和hwnd)

    hdc=wg.GetWindowDC(int(hwnd))

    ↑利用hwnd來(lái)獲取hdc

    color = wg.GetPixel(hdc,x坐標(biāo),y坐標(biāo))

    ↑獲取指定點(diǎn)的顏色
    細(xì)心的小伙伴們可以發(fā)現(xiàn)
    在每個(gè)獲取顏色的代碼附近都有doClick的調(diào)用
    那是因?yàn)榉乐褂脩酎c(diǎn)擊了游戲界面后又點(diǎn)擊了其他地方,導(dǎo)致游戲窗口失焦,所以使用doClick強(qiáng)制激活窗口

    這里需要注意一點(diǎn)
    因?yàn)檫@個(gè)游戲官方允許使用腳本,所以微軟官方的指令是可以用的
    否則的話可以嘗試用大漠插件或者別的插件來(lái)發(fā)送硬件級(jí)別的模擬按鍵信息

    下面講解調(diào)用大漠插件的方法
    大漠插件下載:點(diǎn)我下載
    注意:大漠插件是32位的,所以調(diào)用時(shí)必須使用32位的py,不然會(huì)報(bào)錯(cuò)
    下載好后把里面的dm.dll放在和腳本同一個(gè)目錄下
    使用

    import win32com.client
      
      
    dm = win32com.client.Dispatch('dm.dmsoft')  #調(diào)用大漠插件
    print(dm.ver())#輸出版本號(hào)

    就可以成功地調(diào)用大漠插件并輸出版本號(hào)
    綁定窗口

    dm_ret = dm.BindWindow(hwnd,"gdi", "windows", "windows", 0)

    綁定字典

    dm.setDict(0, '字典.txt')#把字典文件放到和腳本同一個(gè)目錄下
    dm.useDict(0)

    可以說(shuō),在成功注冊(cè)了大漠插件后
    它的使用代碼基本和它里面自帶的說(shuō)明書里面的使用代碼一致了
    需要的小伙伴可以多看看它自帶的說(shuō)明書


    不過(guò)dm.dll經(jīng)常被defender報(bào)毒。。。導(dǎo)致我想用都用不了

    雖然大漠的識(shí)別系統(tǒng)很強(qiáng)大,但畢竟是閉源付費(fèi),還強(qiáng)制得換成32位python。。
    還是少用為妙

網(wǎng)站首頁(yè)   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有