import time
import pyautogui as pg
from PIL import Image
import random
import datetime
import threading
import os
import keyboard as kb
AutoPalyFlag = True
# 設定 圖示 box
box_settings = (1890, 870, 1920, 900)
# 發起投降 按鈕 box
box_surrender = (700, 820, 840, 860)
# 確認投降 按鈕 box
box_confirm = (720, 460, 940, 520)
# 空白區域
box_empty_area = (700, 0, 800, 10)
# 再玩一次
box_play_again = (530, 830, 780, 880)
# 商店5個怪的box
champ_box = [
(480, 930, 670, 1070),
(680, 930, 870, 1070),
(880, 930, 1070, 1070),
(1080, 930, 1270, 1070),
(1290, 930, 1480, 1070),
]
pg.FAILSAFE = False
log_path = 'log\\%s.log'%time.strftime('%Y_%m_%d_%H_%M_%S')
log_file = open(log_path, 'w', encoding='utf8')
def slow_click(p, button='PRIMARY', move_time = 0.2, down_time = 0.2, up_time = 0.2):
pg.moveTo(p[0], p[1], duration=move_time)
pg.mouseDown(p[0], p[1], button=button, duration = down_time)
pg.mouseUp(p[0], p[1], button=button, duration = up_time)
return True
def slow_key_press(key, down_time = 0.2):
kb.press(key)
time.sleep(down_time)
kb.release(key)
return True
def record_and_print_log(log):
global log_file
print(log)
log_file.write(log)
log_file.write('\n')
return True
def get_time_fmt_str(t = None):
if not t:
t = time.localtime()
return time.strftime("%Y/%m/%d %H:%M:%S", t)
def stray():
# 在棋盤小范圍內隨機游蕩,防止滑鼠指標擋住關卡圖片導致檢測不到3-2關卡
x = random.randint(500, 1200)
y = random.randint(250, 650)
slow_click((x,y), button='right', move_time=0.5)
return True
# 買一個怪
def buy_single_champ(index):
global champ_box
if index > 4:
index = 4
if index < 0:
index = 0
box = champ_box[index]
center = get_box_center(box)
slow_click(center, move_time=0.3)
return True
# 重繪商店
def refresh_shop():
kb.press_and_release('d')
return True
def show_emoji():
kb.press_and_release('t')
return True
# 提升等級
def upgrade_champ():
kb.press_and_release('f')
return True
def get_lol_hwnd():
title = 'League of Legends'
w = pg.getWindowsWithTitle(title)
hwnd = False
for i in w:
if i.title == title:
hwnd = i
break
return hwnd
def get_box_center(box):
x = int((box[2] - box[0]) / 2) + box[0]
y = int((box[3] - box[1]) / 2) + box[1]
return (x, y)
def move_to_empty_area(lol_hwnd):
global box_empty_area
# 客戶端已經最小化,不移動滑鼠
if lol_hwnd.size < (1024, 768):
return
center = convert_lol_to_destop_point(get_box_center(box_empty_area), lol_hwnd)
pg.moveTo(center[0], center[1], duration = 0.1)
return True
# 將LOL客戶端相對坐標根據LOL客戶端位置轉換為實際桌面的絕對坐標
def convert_lol_to_destop_point(p, lol_hwnd):
x = lol_hwnd.topleft[0] + p[0]
y = lol_hwnd.topleft[1] + p[1]
return (x, y)
def surrender():
global box_settings, box_surrender, box_confirm
# center = get_box_center(box_settings)
# 點擊設定
# slow_click(center, move_time=0.5)
slow_key_press('esc')
center = get_box_center(box_surrender)
# 發起投降
slow_click(center, move_time=0.5)
center = get_box_center(box_confirm)
# 確定離開
slow_click(center, move_time=0.5)
return True
# 賣掉候選臺前三個怪,和棋盤上自動上的怪
def sell_monsters():
slot1 = (443, 758)
slot2 = (576, 758)
slot3 = (696, 758)
slot4 = (975, 672)
pg.moveTo(slot1)
slow_key_press('e')
time.sleep(1)
pg.moveTo(slot2)
slow_key_press('e')
time.sleep(1)
pg.moveTo(slot3)
slow_key_press('e')
time.sleep(1)
pg.moveTo(slot4)
slow_key_press('e')
game_inactive_count = 0
# 切換到游戲
def make_game_active(game_hwnd):
global game_inactive_count
while not game_hwnd.isActive:
game_hwnd.activate()
pg.press('enter')
time.sleep(2)
game_inactive_count = 0
# 讓游戲處于活動狀態
def check_game_active(game_hwnd):
global game_inactive_count
if not game_hwnd.isActive:
game_inactive_count += 1
else :
game_inactive_count = 0
# 等待3 * 5秒,游戲還未切換回來,就主動切換回來
if game_inactive_count > 3:
make_game_active(game_hwnd)
# 開始匹配
def click_find_match(lol_hwnd):
pic_find_match = Image.open(r'scs\find_match.jpg')
p = pg.locateCenterOnScreen(pic_find_match, confidence=0.9)
if p:
slow_click(p)
move_to_empty_area(lol_hwnd)
else:
return False
if not pg.locateCenterOnScreen(pic_find_match, confidence=0.9):
return True
return False
# 等待太久,重新匹配
def stop_and_start_a_new_match(lol_hwnd):
pic = Image.open(r'scs\stop.png')
p = pg.locateCenterOnScreen(pic, confidence=0.9)
if p:
slow_click(p)
move_to_empty_area(lol_hwnd)
else:
record_and_print_log('找不到停止按鈕!')
return False
time.sleep(1)
return click_find_match(lol_hwnd)
# 等待并接受對局
def accept_match(lol_hwnd):
# 5分鐘未進入游戲,直接重新匹配
timeout = 5 * 60
start_time = time.time()
pic_accept = Image.open(r'scs\accept.jpg')
while time.time() - start_time < timeout * 10:
while time.time() - start_time < timeout:
p = pg.locateCenterOnScreen(pic_accept, confidence = 0.93)
if p:
slow_click(p)
move_to_empty_area(lol_hwnd)
# 客戶端已最小化,正在啟動游戲
if lol_hwnd.size < (1024, 768):
return True
time.sleep(1)
# 等待太久,重新匹配
if not stop_and_start_a_new_match(lol_hwnd):
return False
record_and_print_log("10次超時未找到對局!")
return False
# 尋找對局 -> 佇列中 -> 接受 -> 開始加載
# 尋找對局 -> 佇列中 -> 接受 -> 有人拒絕 -> 佇列中
def pg_find_match(lol_hwnd):
click_find_match(lol_hwnd)
return accept_match(lol_hwnd)
def pg_wait_loading(lol_hwnd):
pic = Image.open(r'scs\1_1.jpg')
while True:
# pyautogui 模塊檢測關卡
box = pg.locateOnScreen(pic, confidence=0.9)
if box:
return True
time.sleep(2)
return True
WaitStageFlag = True
def change_wait_flag_callback():
global WaitStageFlag
record_and_print_log("17分鐘未檢測到3-2回合,直接進行下一步操作")
WaitStageFlag = False
return True
# 空城速八
def pg_quick_wait_quit():
global game_inactive_count
print("Start wait quit button")
pic = Image.open(r'scs\quit.png')
client_title = 'League of Legends (TM) Client'
game_hwnd = pg.getWindowsWithTitle(client_title)[0]
while True:
# 讓游戲處于活動狀態
check_game_active(game_hwnd)
# 游戲被切換出去了,此時不操作滑鼠鍵盤
if game_inactive_count > 0:
time.sleep(5)
continue
box = pg.locateOnScreen(pic, confidence=0.95)
if box:
slow_click(pg.center(box))
break
case = random.randint(1,100)
# %50 概率游蕩
if case <= 50:
stray()
case = random.randint(1,100)
# %50 概率發表情
if case <= 50:
show_emoji()
# case = random.randint(1,100)
# # %5 概率升級
# if case >= 85 and case < 90:
# upgrade_champ()
sell_monsters()
return True
# 亂拿等死
def pg_slow_wait_quit():
global game_inactive_count
print("Start wait quit button")
pic = Image.open(r'scs\quit.png')
client_title = 'League of Legends (TM) Client'
game_hwnd = pg.getWindowsWithTitle(client_title)[0]
while True:
# 讓游戲處于活動狀態
check_game_active(game_hwnd)
# 游戲被切換出去了,此時不操作滑鼠鍵盤
if game_inactive_count > 0:
time.sleep(5)
continue
box = pg.locateOnScreen(pic, confidence=0.95)
if box:
slow_click(pg.center(box))
break
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %40 概率游蕩
if case <= 40:
stray()
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %25 概率買1個英雄
if case >= 25 and case < 50:
buy_single_champ(random.randint(0, 4))
# case = random.randint(1,100)
# %0 概率重繪商店
# if case == 0:
# refresh_shop()
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %30 概率發表情
if case <= 30:
show_emoji()
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %5 概率升級
if case >= 85 and case < 90:
upgrade_champ()
time.sleep(1)
return True
# 速度投降
def pg_wait_stage_3_2():
global WaitStageFlag, game_inactive_count
pic = Image.open(r'scs\3_2.jpg')
WaitStageFlag = True
# 啟動一個Timer,17分鐘未檢測到3-2回合,直接進行下一步
t = threading.Timer(17 * 60, change_wait_flag_callback)
t.start()
client_title = 'League of Legends (TM) Client'
game_hwnd = pg.getWindowsWithTitle(client_title)[0]
while WaitStageFlag:
# 讓游戲處于活動狀態
check_game_active(game_hwnd)
# 游戲被切換出去了,此時不操作滑鼠鍵盤
if game_inactive_count > 0:
time.sleep(5)
continue
# pyautogui 模塊檢測關卡
box = pg.locateOnScreen(pic, confidence=0.9)
if box:
# 檢測到3-2,停止Timer
t.cancel()
return True
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %40 概率游蕩
if case <= 40:
stray()
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %25 概率買1個英雄
if case >= 25 and case < 50:
buy_single_champ(random.randint(0, 4))
# case = random.randint(1,100)
# %0 概率重繪商店
# if case == 0:
# refresh_shop()
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %30 概率發表情
if case <= 30:
show_emoji()
if game_inactive_count > 0:
time.sleep(5)
continue
case = random.randint(1,100)
# %5 概率升級
if case >= 85 and case < 90:
upgrade_champ()
time.sleep(1)
return True
def close_award_interface(lol_hwnd):
ok_box = (lol_hwnd.centerx - 100, lol_hwnd.bottom - 60, 200, 40)
c = pg.center(ok_box)
slow_click(c)
move_to_empty_area(lol_hwnd)
return True
def pg_wait_surrender_finish(lol_hwnd):
client_title = 'League of Legends (TM) Client'
times = 0
while True:
time.sleep(1)
times += 1
if pg.getWindowsWithTitle(client_title) == []:
break
if times % 10 == 0:
print("pg_wait_surrender_finish %d sec, still wait client over!"%times)
# 檢測結算界面是否打開
while True:
pic = Image.open(r'scs\end.jpg')
box = pg.locateOnScreen(pic, confidence = 0.9)
if box:
break
record_and_print_log("Not Found end.jpg!")
# 結算界面已打開,但被獎勵界面遮擋
if lol_hwnd.size == (1600, 900):
record_and_print_log("try to close_award_interface!")
close_award_interface(lol_hwnd)
time.sleep(3)
return True
def pg_play_again(lol_hwnd):
global box_play_again, box_empty_area
center = convert_lol_to_destop_point(get_box_center(box_play_again), lol_hwnd)
pg.click(center[0], center[1], duration = 0.3) # 點擊再玩一次
move_to_empty_area(lol_hwnd)
time.sleep(1)
pic = Image.open(r'scs\end.jpg')
pic_find_match = Image.open(r'scs\find_match.jpg')
box = pg.locateOnScreen(pic_find_match, confidence=0.9)
while not box:
if pg.locateOnScreen(pic, confidence = 0.9) != []:
pg.click(center[0], center[1], duration = 0.3) # 點擊再玩一次
move_to_empty_area(lol_hwnd)
else:
# 獎勵界面遮擋
close_award_interface(lol_hwnd)
time.sleep(1)
box = pg.locateOnScreen(pic_find_match, confidence=0.9)
return True
def pg_stop_play():
global AutoPalyFlag
AutoPalyFlag = False
return True
# 手動結束腳本命令,按Ctrl+Alt+q即可設定停止運行標志
kb.add_hotkey('ctrl+alt+q', pg_stop_play)
def pg_main():
global AutoPalyFlag, log_file
w = get_lol_hwnd()
if not w:
print("游戲未啟動,請啟動游戲后再運行腳本!")
return False
play_times = 0
start_time = time.localtime()
game_time_list = []
# record_and_print_log("[%s] pg_find_match"%get_time_fmt_str())
# pg_find_match(w)
# record_and_print_log("[%s] pg_wait_loading"%get_time_fmt_str())
# pg_wait_loading(w)
# record_and_print_log("[%s] pg_quick_wait_quit"%get_time_fmt_str())
# pg_quick_wait_quit()
# record_and_print_log("[%s] pg_wait_surrender_finish"%get_time_fmt_str())
# pg_wait_surrender_finish(w)
# play_times += 1
# record_and_print_log("[%s] pg_play_again"%get_time_fmt_str())
# pg_play_again(w)
while AutoPalyFlag:
# 游戲開始時間
game_start = time.time()
record_and_print_log("[%s] pg_find_match"%get_time_fmt_str())
pg_find_match(w)
record_and_print_log("[%s] pg_wait_loading"%get_time_fmt_str())
pg_wait_loading(w)
case = random.randint(1, 3)
# case = 1
if case == 1:
record_and_print_log("[%s] pg_wait_stage_3_2"%get_time_fmt_str())
pg_wait_stage_3_2()
record_and_print_log("[%s] surrender"%get_time_fmt_str())
surrender()
record_and_print_log("[%s] pg_wait_surrender_finish"%get_time_fmt_str())
elif case == 2:
record_and_print_log("[%s] pg_quick_wait_quit"%get_time_fmt_str())
pg_quick_wait_quit()
elif case == 3:
record_and_print_log("[%s] pg_slow_wait_quit"%get_time_fmt_str())
pg_slow_wait_quit()
pg_wait_surrender_finish(w)
play_times += 1
record_and_print_log("[%s] pg_play_again"%get_time_fmt_str())
# 游戲結束時間
game_end = time.time()
game_time = int(game_end - game_start)
game_time_list.append(game_time)
if not AutoPalyFlag:
break
pg_play_again(w)
# 統計每局時間,寫入到檔案
for i in range(len(game_time_list)):
seconds = game_time_list[i] % 60
minutes = int(game_time_list[i] / 60)
info = "第%d局用時[%d]分[%d]秒"%(i + 1, minutes, seconds)
record_and_print_log(info)
# 輸出統計資訊
end_time = time.localtime()
record_and_print_log("[%s] 開始掛機"%get_time_fmt_str(start_time))
record_and_print_log("[%s] 結束掛機"%get_time_fmt_str(end_time))
diff_time_sec = time.mktime(end_time) - time.mktime(start_time)
t_s = int(diff_time_sec) % 60
diff_time_sec /= 60
# 總共所用分鐘數
total_minutes = diff_time_sec
t_m = int(diff_time_sec) % 60
diff_time_sec /= 60
t_h = int(diff_time_sec)
average_minutes = total_minutes / play_times
t_ave_m = int(average_minutes)
t_ave_s = int((average_minutes - t_ave_m) * 60)
record_and_print_log("共掛機[%d]小時[%d]分鐘[%d]秒,掛機[%d]局,平均[%d]分鐘[%d]秒一局"%(t_h, t_m, t_s, play_times, t_ave_m, t_ave_s))
log_file.close()
return True
if __name__ == '__main__':
pg_main()
os.system("pause")
測驗程式:win10下打包好的最新程式和截圖資源檔案:某度網盤 提取碼:lek7
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/274405.html
標籤:python
上一篇:Java進階知識——反射
下一篇:使用request下載圖片
