This tutorial is for beginners to learn python
Less nonsense, let's start the python tutorial
Let's use tkinter to build the basic interface of the script
Private letter Xiaobian 01 can obtain a large number of Python learning resources
import tkinter as tk#[size=3] first import tkinter, and install it into python with pip in advance (the method is Baidu) [/size] def init_window(): global cs,wd wd = tk.Tk() cs = tk.Canvas(wd, width = 800, height = 500, bg = 'white') wd.minsize(800, 500) # Minimum size wd.maxsize(800, 500) #Maximum size to maximize failure wd.title('DDTHelper') pic = tk.PhotoImage(file="pic.png") #Set the background picture, preferably in 800 * 500 and png format cs.create_image(400,250,image = pic) cs.pack() bt = tk.Button(wd, text='initialization', bg=('white'), font=('Microsoft YaHei ',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("initialization...") #Entry, this line of code needs to stay at the bottom of the script all the time #Set dictionary hwnd_title = dict()init_window()
(however, there is a better scheme to overlay controls on the picture to make the background of controls transparent, but the code in that article can't run.)
Operation effect
Now let's add something for clicking the initialize button
Let him identify the current game window when clicked
(because I use the game logged in in the 36jb hall, when I grab the handle, I can distinguish the game window according to its title)
Here I stole a lazy, use the title of the game window of the login to get it Finally, if your time is not very tight and you want to improve quickly, the most important thing is not afraid of hardship. I suggest you can contact Wei: 762459510. That's really good. Many people make rapid progress and need you to be not afraid of hardship! You can add it and have a look~
Change the import library and BT above_ Oncreat() method
import win32com.client as wc,win32gui as wg,threading as xc, time,tkinter as tk,win32api as wa,win32con as wn #You need to use pip to install the pywin32 plug-in into python in advance (the method is Baidu) def init_window(): global cs,wd wd = tk.Tk() cs = tk.Canvas(wd, width = 800, height = 500, bg = 'white') wd.minsize(800, 500) # Minimum size wd.maxsize(800, 500) #Maximum size to maximize failure wd.title('DDTHelper') pic = tk.PhotoImage(file="pic.png") #Set the background picture, preferably in 800 * 500 and png format cs.create_image(400,250,image = pic) cs.pack() bt = tk.Button(wd, text='initialization', bg=('white'), font=('Microsoft YaHei ',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 #Number of currently logged in game accounts wg.EnumWindows(get_all_hwnd, 0) for h,t in hwnd_title.items(): if "4399" in t: #Extract the game window according to the 4399 contained in the title hwnd = t.split("|")[3] name = t.split("|")[2] print("account number:" + name + "Handle:" + hwnd) Znum = Znum + 1 hwnd = int(hwnd) #Convert the handle to int, because the handle is a string obtained from the title, resulting in a type error. I've been trapped by this for a long time.. if Znum==1: #Create a separate operation thread for each game interface. In order to facilitate global transmission, exec is not used. 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) #Next, add a few more methods #Get def for handle_ all_ hwnd(hwnd,mouse): if wg.IsWindow(hwnd) and wg.IsWindowEnabled(hwnd) and wg.IsWindowVisible(hwnd): hwnd_title.update({hwnd:wg.GetWindowText(hwnd)}) #Create a corresponding control for each thread to control the operation of the thread 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("not running")'.format(Znum)) exec('lb{} = tk.Label(wd,text="{}",bg=("#ffffff"), font=("Microsoft YaHei ",20))'.format(Znum,name)) exec('lbn{} = tk.Label(wd,textvariable=txn{}, bg=("#ffffff"),font =" Microsoft YaHei ", 10)) ' .format(Znum,Znum)) exec('cb{} = tk.Checkbutton(wd,textvariable=tx{}, bg=("#ffffff"),font =" Microsoft YaHei ", 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)) #Thread method def Con(hwnd,name,xc): print("Start successful") #Multi box click event def BT_onRun1(): global v1,tx1,t1,ct1 if v1.get()==1: #Judge whether it is selected ct1=0 tx1.set('Running') t1.start() else: ct1=1 #Used to control thread termination tx1.set('not running') def BT_onRun2(): global v2,tx2,ct2 if v2.get()==1: #Judge whether it is selected ct2=0 tx2.set('Running') t2.start() else: ct2 = 1 tx2.set('not running')def BT_onRun3(): global v3,tx3,ct3 if v3.get()==1: #Judge whether it is selected ct3=0 tx3.set('Running') t3.start() else: ct3=1 tx3.set('not running') #Entry, this line of code needs to stay at the bottom of the script all the time #Set dictionary hwnd_title = dict()init_window()
After running, click the initialization effect
It can be seen that when there is only one game window, the script automatically recognizes the game window. (at present, there are at most 3 recognized threads, and you can't click twice to initialize, otherwise an error will be reported. It is said that dict can be used to receive threads when using exec to dynamically encapsulate threads, and at present, there is a general scheme for secondary recognition.)
When the box next to not running is checked, run the corresponding thread.
Next, we will go to the thread module of the script, and people who have had py foundation know that py threads do not have stopThread
But we are going to implement how to control the thread of the script executing game operations and make it retract and play freely
The following tutorial begins
Because the following script is simplified, which is slightly different from the last post, this post shall prevail
Let's build an interface code like the last post, and take it as a platform
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) # Minimum size 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='initialization', bg=('white'), font=('Microsoft YaHei ',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("not running")'.format(Znum)) exec('lb{} = tk.Label(wd,text="{}",bg=("#ffffff"), font=("Microsoft YaHei ",20))'.format(Znum,name)) #exec('lbn{} = tk.Label(wd,textvariable=txn{}, bg=("#ffffff"),font =" Microsoft YaHei ", 10") '. Format (znum, znum)) exec('cb{} = tk.Checkbutton(wd,textvariable=tx{}, bg=("#ffffff"), font=("Microsoft YaHei ",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]) #Used to control the process #lock = jc.Lock()#It is used to sort the running order of processes to prevent display disorder. It can be removed when packaged into exe (If an error occurs windos Change it to something lock = jc.Manager.Lock() That's it, or delete it Manager) #lock unstable, deprecated for h,t in hwnd_title.items(): if "4399" in t: hwnd = t.split("|")[3] name = t.split("|")[2] print("account number:" + name + "Handle:" + 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()#lock #try: print("Run successfully") #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("In operation")'.format(Znum)) exec('p{}.start()'.format(Znum)) else: conT[Znum]=1 exec('tx{}.set("not running")'.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()
\
After successful identification, we hook up the running hook
If successful, the successful operation will be displayed on the terminal
This time I encapsulate the data to be sent to the process in the onCreat method
Then dynamically assemble the process in onRunMain and start it
Then let the generated sub process to generate the daemon thread, and let the daemon thread control the game
Then the subprocess loop detects whether we have issued a stop command. If the thread detects that we have issued a stop command
Its own code is executed, and then the daemon thread generated by it is kill ed.
In this way, multithreading can be stopped at any time
The code also cleverly borrows the "characteristics" of the exec instruction: the output variables can only be visible in the method. Once the method is restarted, the variables will disappear
That is, if we just use P1 = JC Process (target = con, args = (D1, cont)) to generate a process
After the process ends, you need to use del p1 to remove the "corpse" of the process, and then recreate it
Set the Con method code so that it will produce its own daemon thread
def Con(hwnd,Znum,conT,l): #Set daemon thread time.sleep(1) exec('t{} = xc.Thread(target=RunMain,args=(hwnd,Znum))'.format(Znum)) #Depending on Znum (the id assigned to the game account), different threads are dynamically generated exec('t{}.setDaemon(True)'.format(Znum)) exec('t{}.start()'.format(Znum)) while True:#Start receiving whether we issued a stop command if conT[Znum] == 0: time.sleep(1) else: break print('process' + str(Znum) +': Exited')
Supplement the method executed by the child thread it produces (unavailable)
def RunMain(hwnd,Znum): RM=0#The number of runs, because the program cannot be output to the user after using multiple processes, so it has been discarded hdc=wg.GetWindowDC(int(hwnd)) #Get the hdc of the target page (flash) to get the color of the specified coordinates while True: while str(wg.GetPixel(hdc,919,280))!=str(10248996): #Check whether the game character is in the room interface (initially, the user needs to manually enter the game character into the room interface), Used to detect whether the game character has exited the copy and returned to the game room print("room") doClick(hwnd,5,5) time.sleep(1) if Chose_FB(hwnd,hdc) == 1: #Check which of the current two copies is open. In fact, this design is unreasonable. If there is no copy open, there will be a bug, But I only run this script when a copy is open, right-,- FB_MS(hwnd,hdc) #Start copy 1 Scheme else: FB_JD(hwnd,hdc) #Copy 2 Scheme RM = RM + 1
Of course, due to the topic and length, I will not supplement the process method of the copy, but this may lead to running errors
We can cut it down to
def RunMain(hwnd,Znum): white True: print("I'm running") time.sleep(1)
So when you check run,
The terminal will keep showing that I'm running
It won't be displayed until we cancel the running hook (the thread is kill ed)
Everyone familiar with the button wizard should have used a plug-in called desert
But let's talk about the script operation with Microsoft's official instructions without relying on the desert
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) # Minimum size 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='initialization', bg=('white'), font=('Microsoft YaHei ',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("not running")'.format(Znum)) exec('lb{} = tk.Label(wd,text="{}",bg=("#ffffff"), font=("Microsoft YaHei ",20))'.format(Znum,name)) #exec('lbn{} = tk.Label(wd,textvariable=txn{}, bg=("#ffffff"),font =" Microsoft YaHei ", 10") '. Format (znum, znum)) exec('cb{} = tk.Checkbutton(wd,textvariable=tx{}, bg=("#ffffff"), font=("Microsoft YaHei ",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("account number:" + name + "Handle:" + 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 #Operation class ------------------------------------------------------------------------------- def climb(hwnd,jl,fx): if fx==1: #right #Adaptation direction and prevention of invalidity wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None) wa.SendMessage(hwnd,wn.WM_KEYUP,68,None) #1.3 = 1 screen spacing wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None) time.sleep(jl*1.3) wa.SendMessage(hwnd,wn.WM_KEYUP,68,None) else: #Adaptation direction and prevention of invalidity wa.SendMessage(hwnd,wn.WM_KEYDOWN,65,None) wa.SendMessage(hwnd,wn.WM_KEYUP,65,None) #1.3 = 1 screen spacing 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) #Press big first wa.SendMessage(hwnd,wn.WM_KEYFIRST,69,None) #First press skill 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 big moves 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) #Game flow processing class------------------------------------------------------------------------------------- def Chose_FB(hwnd,hdc): doClick(hwnd,600,200) #open a menu time.sleep(1) doClick(hwnd,626,188) #Single copy time.sleep(1) while True: doClick(hwnd,5,5) if str(wg.GetPixel(hdc,244,237))==str(2041582): doClick(hwnd,289,243) #Dimensity FBn=1 break elif str(wg.GetPixel(hdc,337,278))==str(13298869): doClick(hwnd,292,299) #Skill pill FBn=2 break time.sleep(1) doClick(hwnd,726,501) #difficulty time.sleep(1) doClick(hwnd,504,563) #determine 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): #Round detection 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("Position 1") JD=18 break else: print("Position 2") climb(hwnd,0.5,0) JD=25 break wa.SendMessage(hwnd,wn.WM_KEYFIRST,69,None) #Trough only wa.SendMessage(hwnd,wn.WM_KEYFIRST,80,None) #First pass time.sleep(5) for i in range(2): while str(wg.GetPixel(hdc,497,169))!=str(5418993): #Round detection 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: #Round cycle cs = 0 while str(wg.GetPixel(hdc,497,169))!=str(5418993): #Round detection if cs>=20:#Timeout exit break else: doClick(hwnd,5,5) time.sleep(1) cs=cs+1 #sign out if cs==20: print("Exit copy") 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): #Round detection if cs>=20:#Timeout exit cg=1 cs=0 break else: doClick(hwnd,5,5) time.sleep(1) cs=cs+1 if cg==1: break else: doFire(hwnd,60) #Program flow module class---------------------------------------------------------------------------------------------- def RunMain(hwnd): RM=0 hdc=wg.GetWindowDC(hwnd) while True: while str(wg.GetPixel(hdc,919,280))!=str(10248996): #Room detection print("room") doClick(hwnd,5,5) time.sleep(1) if Chose_FB(hwnd,hdc) == 1: FB_MS(hwnd,hdc) else: FB_JD(hwnd,hdc) RM = RM + 1def Con(Data,conT): #Set daemon thread 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('process' + str(Znum) +': Exited') def onRunMan(Znum): if onRunMan2(Znum) == 1: conT[Znum]=0 exec('tx{}.set("In operation")'.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("not running")'.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()
I've distinguished the module code with -
We talked about window interface and program thread before
The focus is on the operation class
Method for generating mouse click command to specified game window
def doClick(hwnd,cx,cy): long_position = wa.MAKELONG(cx, cy) #Simulate the transfer of the mouse pointer to the specified coordinates wa.SendMessage(hwnd, wn.WM_LBUTTONDOWN, wn.MK_LBUTTON, long_position) #Simulate mouse press wa.SendMessage(hwnd, wn.WM_LBUTTONUP, wn.MK_LBUTTON, long_position) #Simulate mouse bounce
This method compresses the original complex code, so when we want to click the game interface, we can call this method to implement it, such as
Doclick (target window handle, x coordinate, y coordinate)
Does it have an internal flavor?
Look at other methods
def climb(hwnd,jl,fx): if fx==1: #right #Adaptation direction and prevention of invalidity wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None) wa.SendMessage(hwnd,wn.WM_KEYUP,68,None) #1.3 seconds = 1 screen spacing wa.SendMessage(hwnd,wn.WM_KEYDOWN,68,None) time.sleep(jl*1.3) wa.SendMessage(hwnd,wn.WM_KEYUP,68,None) else: #Adaptation direction and prevention of invalidity wa.SendMessage(hwnd,wn.WM_KEYDOWN,65,None) wa.SendMessage(hwnd,wn.WM_KEYUP,65,None) #1.3 = 1 screen spacing 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) #Press the big move first wa.SendMessage(hwnd,wn.WM_KEYFIRST,69,None) #First press skill wa.SendMessage(hwnd,wn.WM_KEYFIRST,97,None) wa.SendMessage(hwnd,wn.WM_KEYFIRST,98,None) #If there's a big move, wa.SendMessage(hwnd,wn.WM_KEYFIRST,97,None) #11 big moves wa.SendMessage(hwnd,wn.WM_KEYFIRST,100,None) wa.SendMessage(hwnd,wn.WM_KEYDOWN,32,None) #Space force storage time.sleep(ld * 0.04) #It takes about 0.04 seconds to store 1 force. There will be errors due to game delay and computer performance. It is generally acceptable, or it can be changed to identify the force bar (More accurate, but due to the impure color interference of the strength bar, the scheme will be shelved for the time being) wa.SendMessage(hwnd,wn.WM_KEYUP,32,None) #Release space
The methods here basically send a collection of keyboard operations
for instance
The climb method is used to control the crawling of characters in the game,
The doAngle method is used to adjust the angle at which the characters in the game fire shells
The method of doFire is to operate the game characters to launch attacks
To sum up the above methods, there are 3 commands for simulating keyboard keys
wa.SendMessage(Game window handle,wn.WM_KEYDOWN,Key code,None) wa.SendMessage(Game window handle,wn.WM_KEYUP,Key code,None) wa.SendMessage(Game window handle,wn.WM_KEYFIRST,Key code,None)
They are respectively sending the specified key to the game window, pressing the specified key to pop up the specified key and clicking the specified key to combine pressing and pop up
But it should be noted that
If you need to click a key repeatedly, do not click the code of the specified key
This will cause a bug, which is equivalent to pressing the key but not bouncing up, resulting in out of control
Like the doAngle method, you need to press and bounce to ensure that there are no bug s
Then go to the game
Because there was no need to extract, I didn't separate it separately
Color selection requires hdc (if you want to know hdc, you can go to Baidu hdc and hwnd)
hdc=wg.GetWindowDC(int(hwnd))
↑ use hwnd to obtain hdc
color = wg.GetPixel(hdc,x coordinate,y coordinate)
Finally, if your time is not very tight and you want to improve quickly, the most important thing is not afraid of hardship. I suggest you can contact Wei: 762459510. That's really good. Many people make rapid progress and need you to be not afraid of hardship! You can add it and have a look~
↑ get the color of the specified point
Careful partners can find
There is a call to doClick near each code that gets the color
That is to prevent the user from clicking other places after clicking the game interface, resulting in the loss of focus of the game window, so use doClick to forcibly activate the window
One thing to note here
Because the game officially allows the use of scripts, Microsoft's official instructions can be used
Otherwise, you can try to use desert plug-in or other plug-ins to send hardware level analog key information
The following explains how to call the desert plug-in
Desert plug-in download: click me to download
Note: the desert plug-in is 32-bit, so you must use 32-bit py when calling, otherwise an error will be reported
Download the DM DLL is placed in the same directory as the script
use
import win32com.client dm = win32com.client.Dispatch('dm.dmsoft') #Call desert plug-in print(dm.ver()) #Output version number
You can successfully call the desert plug-in and output the version number
Binding window
dm_ret = dm.BindWindow(hwnd,"gdi", "windows", "windows", 0)
Binding dictionary
dm.setDict(0, 'Dictionaries.txt')#Put the dictionary file in the same directory as the script DM useDict(0)
It can be said that after successfully registering the desert plug-in
Its use code is basically consistent with the use code in the manual it comes with
If you need it, you can read its own manual
But DM DLL is often reported as poison by defender... I can't use it if I want to
Although the desert identification system is very powerful, it is closed source payment after all, and it is forced to change to 32-bit python..
It's better to use less Finally, if your time is not very tight and you want to improve quickly, the most important thing is not afraid of hardship. I suggest you can contact Wei: 762459510. That's really good. Many people make rapid progress and need you to be not afraid of hardship! You can add it and have a look~