Python脚本:完美国际开星盘

1 前言

垃圾策划还不出个自动开星盘的小助手脚本,自己动手,丰衣足食。
本脚本为使用python自动开星盘。

2 环境搭建

下载相关所需库:pip install pyautogui opencv-python pyscreeze Pillow numpy
其中,pyautogui用于模拟键鼠操作,OpenCV用于图像识别。

3 实操

思路:

脚本开始
根据装备星盘判断职业
循环判断每个星盘属性
是否符合要求?
记录坐标A
根据坐标A吞噬不合要求星盘
是否有星盘礼盒?
结束
包裹空位 > 0?
开星盘

完整代码:

import time
import pyautogui
import cv2
import pygetwindow as gw
import numpy as np
import logging


logging.basicConfig(
    level=logging.INFO,
    format='[%(asctime)s] - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('log.txt', encoding='utf-8'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)


def check_astrolabe(attribute='spell', times=1):
    # 使用 pytesseract 读取图片中的文本
    attackImg = cv2.imread(rf"res\{attribute}.png")
    shotImg = cv2.imread(rf"screenshot.png")
    match = cv2.matchTemplate(shotImg, attackImg, cv2.TM_CCOEFF_NORMED)
    threshold = 0.8  # 设置阈值
    matching_count = np.sum(match >= threshold)
    if matching_count >= times:
        logging.info(f"该星盘符合要求,{attribute}大于{times}条")
        return True
    else:
        logging.info(f"该星盘不符合要求,{attribute}小于{times}条")
        return False


def check_all_astrolabe(avg, attribute='spell', times=1):
    avg_dont_match = []
    for i in avg:
        window = gw.getWindowsWithTitle(f'{account}')[0]  # 替换为实际窗口标题
        window.activate()  # 激活窗口以确保它在前台
        window.restore()  # 如果窗口最小化,恢复窗口
        pyautogui.moveTo(i)
        time.sleep(1)
        pyautogui.screenshot(region=(window.left, window.top, window.width, window.height)).save("./screenshot.png")
        if not check_astrolabe(attribute, times):
            avg_dont_match.append(i)
    return avg_dont_match


def check_career(account):
    print(account)
    xy = get_xy(r"res/astrolabe-jo.png", account, 0.8)
    if len(xy) >0:
        return ['剑灵', 'res/astrolabe-jo.png']
    xy = get_xy(r"res/astrolabe-yx.png", account, 0.8)
    if len(xy) > 0:
        return ['月仙', 'res/astrolabe-yx.png']
    xy = get_xy(r"res/astrolabe-yj.png", account, 0.8)
    if len(xy) > 0:
        return ['妖精', 'res/astrolabe-yj.png']
    xy = get_xy(r"res/astrolabe-mm.png", account, 0.8)
    if len(xy) > 0:
        return ['羽灵', 'res/astrolabe-mm.png']
    xy = get_xy(r"res/astrolabe-mo.png", account, 0.8)
    if len(xy) > 0:
        return ['魅灵', 'res/astrolabe-mo.png']
    xy = get_xy(r"res/astrolabe-wx.png", account, 0.8)
    if len(xy) > 0:
        return ['武侠', 'res/astrolabe-wx.png']
    else:
        logger.error(f"缺少该职业星盘")
        return


def devour_astrolabe(avg, account):
    """
    :param avg: 待吞噬星盘的坐标。[tuple, tuple...]
    :param account:
    :return:
    """
    if len(avg) == 0:
        logger.info(f"{account}没有星盘需要吞噬")
        return
    devAvg = get_xy('res/Button-devour.png', account)
    if len(devAvg) == 0:
        giftBoxAvg = get_xy('res/Button-giftBox.png', account)
        if len(giftBoxAvg) == 0:
            pracAvg = get_xy('res/Button-practice.png', account)
            if len(pracAvg) == 0:
                logger.error(f"{account}找不到修行按钮")
                return
            auto_Click(pracAvg[0], lef='left')
            giftBoxAvg = get_xy('res/Button-giftBox.png', account)
        auto_Click(giftBoxAvg[0], lef='left')
        devAvg = get_xy('res/Button-devour.png', account)
    auto_Click(devAvg[0], lef='left')
    time.sleep(2)
    for i in avg:
        auto_Click(i, lef='left')
        pyautogui.press('y')
        time.sleep(0.5)
        pyautogui.press('y')
        keepAvg = get_xy(r"res/Button-keep.png", account)
        auto_Click(keepAvg[0], lef='left')
        time.sleep(0.5)
    astAvg = get_xy('res/ast-w.png', account)
    auto_Click(astAvg[0], lef='left')
    time.sleep(0.5)
    exitAvg = get_xy('res/ast-exit.png', account)
    auto_Click(exitAvg[0], lef='right')
    auto_Click(exitAvg[0], lef='left')
    return


def get_xy(img_model_path, account, threashold=0.8):
    """
    :param img_model_path:用来检测的图片
    :return:以元组形式返回检测到的区域中心的坐标
    """
    # 获取窗口大小位置
    window = gw.getWindowsWithTitle(f'{account}')[0]  # 替换为实际窗口标题
    window.activate()  # 激活窗口以确保它在前台
    window.restore()  # 如果窗口最小化,恢复窗口
    time.sleep(0.5)
    pyautogui.screenshot(region=(window.left, window.top, window.width, window.height)).save("./screenshot.png")  # 截图
    all_img = cv2.imread("./screenshot.png")  # 待读取图像
    origin_img = cv2.imread(f"{img_model_path}")  # 模板图像
    all_img = cv2.cvtColor(all_img, cv2.COLOR_BGR2GRAY)
    origin_img = cv2.cvtColor(origin_img, cv2.COLOR_BGR2GRAY)
    match = cv2.matchTemplate(all_img, origin_img, cv2.TM_CCOEFF_NORMED)  # 开始匹配

    threshold = threashold  # 设置阈值
    loc = np.where(match >= threshold)

    h, w = origin_img.shape[:2]
    matches = []
    for pt in zip(*loc[::-1]):  # *loc[::-1] 解压坐标
        top_left = pt
        bottom_right = (top_left[0] + w, top_left[1] + h)
        center = (int((top_left[0] + bottom_right[0]) / 2), int((top_left[1] + bottom_right[1]) / 2))
        avg = (center[0] + window.left, center[1] + window.top)
        # 检查新点与已有点之间的距离
        if not any(np.linalg.norm(np.array(avg) - np.array(m)) < 10 for m in matches):
            matches.append(avg)

    return matches


def auto_Click(var_avg, lef='left'):
    """
    输入一个元组,自动点击
    :param var_avg: 坐标元组
    :return: None
    """
    pyautogui.click(var_avg[0], var_avg[1], button=f'{lef}')
    time.sleep(0.5)


def main(account, attribute='spell', times=1):
    """
    循环:
    0.【根据装备星盘判断职业】
    1.循环判断每个星盘属性,不是双攻的记录坐标
    2.吞噬所有非双攻的
    3.无星盘礼盒→结束
    4.判断包裹空位>0
    5.开星盘,开当前页面空位个
    """
    if attribute not in ['spell', 'physical', 'health']:
        logger.info(f"{attribute}属性不在范围内")
        return
    career = check_career(account)  # [职业, 星盘模板路径]
    try:
        logger.info(f"{account}职业为{career[0]}, 资源路径为{career[1]}")
    except Exception as e:
        logger.error(f"{account}背包未打开,无星盘")
        return

    while True:
        pyautogui.moveTo(1,1)
        xy = get_xy(career[1], f"{account}", 0.6)
        # print(xy, len(xy))
        if len(xy) > 1:
            logger.info(f"有多余星盘{len(xy)-1}个,开始判断属性")
            avg_not_match = check_all_astrolabe(xy[1:], attribute, times)
            logger.info("开始吞噬星盘")
            devour_astrolabe(avg_not_match,account)
            logger.info("吞噬完毕,开始开星盘")
        avg_giftBox = get_xy(r"res\giftBox.png", account)
        giftBoxTimes = len(avg_giftBox)
        if giftBoxTimes == 0:
            logger.info(f"{account}无星盘礼盒,脚本结束")
            return
        spaceTimes = len(get_xy(r"res/table.png", account))
        if spaceTimes == 0:
            logger.info(f"{account}无包裹空位,脚本结束")
            return
        for i in range(spaceTimes):
            auto_Click(avg_giftBox[0], lef='right')


if __name__ == '__main__':
    account = "角色名"
    main(account, attribute='属性', times=条数)

目录结构:

├── res
│ ├── ast-exit.png
│ └── ast-w.png
│ └── astrolabe-jo.png
│ └── astrolabe-mm.png
│ └── astrolabe-mo.png
│ └── astrolabe-wx.png
│ └── astrolabe-yj.png
│ └── astrolabe-yx.png
│ └── Button-devour.png
│ └── Button-giftBox.png
│ └── Button-keep.png
│ └── Button-practice.png
│ └── giftBox.png
│ └── health.png
│ └── spell.png
│ └── physical.png
│ └── table.png
└── 星盘.py
找不到好用的图床,粗略放个图吧。在这里插入图片描述
以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值