Teach you to write page tour automation Python script, color selection, desert recognition and background click

Posted by PHPrev on Fri, 24 Dec 2021 06:57:07 +0100

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~

Topics: Python Programming Pycharm Back-end Programmer