예제 #1
0
    def goumaitili(self, times, var={}, limit_today=False):  # 购买体力
        # 稳定性保证
        # 2020-07-31 TheAutumnOfRice: 检查完毕

        mv = movevar(var)
        if "cur" in var:
            self.log.write_log(
                "info",
                f"断点恢复:已经购买了{var['cur']}次体力,即将购买剩余{times - var['cur']}次。")
        else:
            var.setdefault("cur", 0)
        self.lock_home()
        while var["cur"] < times:
            if self.lock_img(img="img/ui/ok_btn_1.bmp",
                             at=(488, 346, 692, 394),
                             elseclick=MAIN_BTN["tili_plus"],
                             elsedelay=2,
                             retry=3):
                # 这里限制了一天只能够购买多少次体力
                try:
                    if limit_today:
                        tili_time = self.ocr_center(530,
                                                    313,
                                                    583,
                                                    338,
                                                    size=1.2).split('/')
                        tili_time = int(tili_time[1]) - int(tili_time[0])
                        if tili_time >= times:
                            return False
                except:
                    self.log.write_log("warning",
                                       f"{self.account}在购买体力时识别次数失败。")

            state = self.lock_img(MAIN_BTN["tili_ok"],
                                  elseclick=MAIN_BTN["tili_plus"],
                                  elsedelay=2,
                                  retry=3)
            if not state:
                self.log.write_log("warning", "体力达到上限,中断体力购买")
                break

            self.lock_no_img(MAIN_BTN["tili_ok"],
                             elseclick=MAIN_BTN["tili_ok"],
                             elsedelay=2)
            self.start_shuatu()
            state = self.lock_img(MAIN_BTN["tili_ok2"], retry=3)
            # 宝石不够时的判断(已写
            if self.is_exists(SHOP_BTN["goumaibaoshi"]):
                self.log.write_log("warning", f"{self.account}已经没有宝石买体力了。")
                self.lock_home()
                return False
            var["cur"] += 1
            mv.save()
            self.start_shuatu()
            self.lock_no_img(MAIN_BTN["tili_ok2"],
                             elseclick=MAIN_BTN["tili_ok2"],
                             elsedelay=1)
        del var["cur"]

        mv.save()
예제 #2
0
    def chushihua2(self, var={}):
        """
        另一个初始化的思路:全部体力投入1-1刷经验之后,等级拉上来了不需要装备都能秒关
        """
        def getab():
            data = self.AR.get("tuitu_status", UDD["tuitu_status"])
            a = 1
            b = 1
            if data['max'] is not None:
                a, b = self.parse_tu_str(data['max'])
                if a >= 3:
                    self.log.write_log("info", "该账号已经成功初始化。")
            return a, b

        self.start_shuatu()
        a, b = getab()
        if a >= 3:
            return
        mv = movevar(var)
        self.lock_home()
        if not mv.flag("set"):
            self.setting()
            mv.setflag("set")
        if not mv.flag("liwu"):
            self.__getattribute__("shouqu")()
            mv.setflag("liwu")
        if not mv.flag("renwu"):
            self.__getattribute__("shouqurenwu")()
            mv.setflag("renwu")
        if not mv.flag("exp"):
            self.__getattribute__("buyExp")()
            mv.setflag("exp")
        if not mv.flag("jingyan"):
            self.shuajingyan_super(0, 0)
            mv.setflag("jingyan")
        if not mv.flag("shengji"):
            self.auto_upgrade(0, True, False)
            mv.setflag("shengji")
        if a == 1 and b < 8:
            self.tuitu(0,
                       "1-8",
                       buy_tili=3,
                       auto_upgrade=1,
                       use_ub=1,
                       clear_tili=False,
                       var=var)
            a, b = getab()
        if a == 1 and b == 8:
            self.auto_upgrade(0, True, False)
        if a < 3:
            self.tuitu(0,
                       "3-1",
                       buy_tili=3,
                       auto_upgrade=1,
                       use_ub=1,
                       clear_tili=False,
                       var=var)
        self.clear_tili_info(var)
        mv.clearflags()
예제 #3
0
 def shuatuNN(self, tu_dict: list, use_ocr=False, var={}):
     """
     刷指定N图
     tu_dict: 其实应该叫tu_list,来不及改了
     ["A-B-Times",...,]
     :return:
     """
     # 进入冒险
     L = ShuatuToTuple(tu_dict)
     if use_ocr or force_as_ocr_as_possible:
         # L: List[Tuple[A,B,T]]
         new_L = []
         for l in L:
             A, B, T = l
             new_L += [f"{A}-{B}-{T}"]
         self.shuatu_daily_ocr(new_L, 0, False, "do", "do", "skip", "exit", False, "zhanli", False, var)
         return
     # 按照 A-B的顺序排序:A为主要依据,B为次要依据。
     self.enter_normal()
     self.switch = 0
     cur_map = self.check_normal_id()
     mv = movevar(var)
     if "curNN" in var:
         cur = var["curNN"]
         A, B, Times = L[cur]
         self.log.write_log("info", f"断点恢复:上次刷到了{A}-{B},继续执行。")
     else:
         cur = 0
         var["curNN"] = 0
     for cur in range(cur, len(L)):
         var["curNN"] = cur
         mv.save()
         A, B, Times = L[cur]
         if A not in NORMAL_COORD:
             pcr_log(self.account).write_log("error", f"坐标库中没有图号{A}-{B}的信息!跳过此图。")
             continue
         while cur_map != A:
             self.select_normal_id(A)
             cur_map = A
         now_dict = NORMAL_COORD[A]
         if B in now_dict["left"]:
             if A != 1:
                 self.Drag_Left()
             xy = now_dict["left"][B]
             self.shuatuzuobiao(*xy, Times)
         elif B in now_dict["right"]:
             if A != 1:
                 self.Drag_Right()
             xy = now_dict["right"][B]
             self.shuatuzuobiao(*xy, Times)
         else:
             pcr_log(self.account).write_log("error", f"坐标库中没有图号{A}-{B}的信息!跳过此图。")
             continue
     del var["curNN"]
     mv.save()
     self.lock_home()
예제 #4
0
    def goumaimana(self, times, mode=1, var={}, limit_today=False):
        # mode 1: 购买times次10连
        # mode 0:购买times次1连

        self.lock_home()
        self.lock_img(MAIN_BTN["mana_title"], elseclick=MAIN_BTN["mana_plus"])

        # 这里限制了一天只能购买mana多少次,通过OCR判断
        try:
            if limit_today:
                time.sleep(0.5)
                self.lock_img(MAIN_BTN["mana_title"],
                              elseclick=MAIN_BTN["mana_plus"])
                mana_time = self.ocr_center(422, 451, 480, 471,
                                            size=2.0).split('/')
                mana_time = int(mana_time[0])
                if mana_time >= times:
                    self.lock_home()
                    return False
        except:
            pass

        def BuyOne():
            self.lock_img(MAIN_BTN["mana_ok"], elseclick=MAIN_BTN["mana_one"])
            self.lock_no_img(MAIN_BTN["mana_ok"],
                             elseclick=MAIN_BTN["mana_ok"])
            time.sleep(2)

        def BuyTen():
            self.lock_img(MAIN_BTN["mana_ok"], elseclick=MAIN_BTN["mana_ten"])
            self.lock_no_img(MAIN_BTN["mana_ok"],
                             elseclick=MAIN_BTN["mana_ok"])
            time.sleep(16)

        if self.is_exists(MAIN_BTN["mana_blank"]):
            BuyOne()
        mv = movevar(var)
        if "cur" in var:
            self.log.write_log(
                "info",
                f"断点恢复:已经购买了{var['cur']}次玛娜,即将购买剩余{times - var['cur']}次。")
        else:
            var.setdefault("cur", 0)
        while var["cur"] < times:
            if mode == 1:
                BuyTen()
            else:
                BuyOne()
            var["cur"] += 1
            mv.save()
        del var["cur"]
        mv.save()
        self.lock_home()
예제 #5
0
    def goumaimana(self, times, mode=1, var={}, limit_today=False):
        # mode 1: 购买times次10连
        # mode 0:购买times次1连

        self.lock_home()
        self.lock_img(MAIN_BTN["mana_title"], elseclick=MAIN_BTN["mana_plus"])

        # 这里限制了一天只能购买mana多少次,通过OCR判断
        try:
            if limit_today:
                time.sleep(0.5)
                self.lock_img(MAIN_BTN["mana_title"],
                              elseclick=MAIN_BTN["mana_plus"])
                at = (733, 389, 783, 405)
                mana_left, mana_right = self.ocr_A_B(*at)
                mana_time = mana_left // 10
                if mana_time >= times:
                    self.lock_home()
                    return False
        except:
            pass

        def BuyOne():
            self.lock_img(MAIN_BTN["mana_ok"], elseclick=MAIN_BTN["mana_one"])
            self.lock_no_img(MAIN_BTN["mana_ok"],
                             elseclick=MAIN_BTN["mana_ok"])
            time.sleep(2)

        def BuyTen():
            self.lock_img(MAIN_BTN["mana_ok"], elseclick=MAIN_BTN["mana_ten"])
            self.lock_no_img(MAIN_BTN["mana_ok"],
                             elseclick=MAIN_BTN["mana_ok"])
            time.sleep(16)

        if self.is_exists(MAIN_BTN["mana_blank"]):
            BuyOne()
        mv = movevar(var)
        if "cur" in var:
            self.log.write_log(
                "info",
                f"断点恢复:已经购买了{var['cur']}次玛娜,即将购买剩余{times - var['cur']}次。")
        else:
            var.setdefault("cur", 0)
        while var["cur"] < times:
            if mode == 1:
                BuyTen()
            else:
                BuyOne()
            var["cur"] += 1
            mv.save()
        del var["cur"]
        mv.save()
        self.lock_home()
예제 #6
0
 def shuatuNN(self, tu_dict: list, var={}):
     """
     刷指定N图
     tu_dict: 其实应该叫tu_list,来不及改了
     ["A-B-Times",...,]
     :return:
     """
     # 进入冒险
     L = ShuatuToTuple(tu_dict)
     # 按照 A-B的顺序排序:A为主要依据,B为次要依据。
     self.enter_normal()
     self.switch = 0
     cur_map = self.check_normal_id()
     mv = movevar(var)
     if "curNN" in var:
         cur = var["curNN"]
         A, B, Times = L[cur]
         self.log.write_log("info", f"断点恢复:上次刷到了{A}-{B},继续执行。")
     else:
         cur = 0
         var["curNN"] = 0
     for cur in range(cur, len(L)):
         var["curNN"] = cur
         mv.save()
         A, B, Times = L[cur]
         if A not in NORMAL_COORD:
             pcr_log(self.account).write_log("error",
                                             f"坐标库中没有图号{A}-{B}的信息!跳过此图。")
             continue
         while cur_map != A:
             self.select_normal_id(A)
             cur_map = A
         now_dict = NORMAL_COORD[A]
         if B in now_dict["left"]:
             if A != 1:
                 self.Drag_Left()
             xy = now_dict["left"][B]
             self.shuatuzuobiao(*xy, Times)
         elif B in now_dict["right"]:
             if A != 1:
                 self.Drag_Right()
             xy = now_dict["right"][B]
             self.shuatuzuobiao(*xy, Times)
         else:
             pcr_log(self.account).write_log("error",
                                             f"坐标库中没有图号{A}-{B}的信息!跳过此图。")
             continue
     del var["curNN"]
     mv.save()
     self.lock_home()
예제 #7
0
 def shuatuHH(self, tu_dict: list, use_ocr: bool = False, var={}):
     """
     刷指定H图
     :param tu_dict: 刷图列表
     tu_dict: 其实应该叫tu_list,来不及改了
     ["A-B-Times",...,]
     :return:
     """
     L = ShuatuToTuple(tu_dict)
     if use_ocr or force_as_ocr_as_possible:
         # L: List[Tuple[A,B,T]]
         new_L = []
         for l in L:
             A, B, T = l
             new_L += [f"H{A}-{B}-{T}"]
         self.shuatu_daily_ocr(new_L, 0, False, "do", "do", "skip", "exit", False, "zhanli", False, var)
         return
     self.enter_hard()
     self.switch = 0
     cur_map = self.check_hard_id(self.last_screen)
     mv = movevar(var)
     if "curHH" in var:
         cur = var["curHH"]
         A, B, Times = L[cur]
         self.log.write_log("info", f"断点恢复:上次刷到了H{A}-{B},继续执行。")
     else:
         cur = 0
         var["curHH"] = 0
     for cur in range(cur, len(L)):
         var["curHH"] = cur
         mv.save()
         A, B, Times = L[cur]
         if A not in HARD_COORD:
             pcr_log(self.account).write_log("error", f"坐标库中没有图号H{A}-{B}的信息!跳过此图。")
             continue
         while cur_map != A:
             self.select_hard_id(A)
             cur_map = A
         now_dict = HARD_COORD[A]
         if B in now_dict:
             xy = now_dict[B]
             self.shuatuzuobiao(*xy, Times)
         else:
             pcr_log(self.account).write_log("error", f"坐标库中没有图号H{A}-{B}的信息!跳过此图。")
             continue
     del var["curHH"]
     mv.save()
     self.lock_home()
예제 #8
0
    def chushihua(self, var={}):
        """
        初始化:从1-3到3-1。
        目前不能实现1-1~1-2,因为TheAutumnOfRice买不到这么早的初始号
        """

        def getab():
            data = self.AR.get("tuitu_status", UDD["tuitu_status"])
            a = 1
            b = 1
            if data['max'] is not None:
                a, b = self.parse_tu_str(data['max'])
                if a >= 3:
                    self.log.write_log("info", "该账号已经成功初始化。")
            return a, b

        self.start_shuatu()
        a, b = getab()
        if a >= 3:
            return
        mv = movevar(var)
        if not mv.flag("set"):
            self.lock_home()
            self.setting()
            mv.setflag("set")
        if a == 1 and b < 8:
            print("1")
            self.tuitu(0, "1-8", buy_tili=3, clear_tili=False, var=var)
            a, b = getab()
        if a == 1 and b == 8:
            self.auto_upgrade(buy_tili=3, var=var)
        if a == 1 or (a == 2 and b < 5):
            print("2")
            self.tuitu(0, "2-5", buy_tili=3, clear_tili=False, var=var)
            a, b = getab()
        if a == 2 and b == 5:
            self.auto_upgrade(buy_tili=3, var=var)
        if a == 1 or (a == 2 and b < 11):
            print("3")
            self.tuitu(0, "2-11", buy_tili=3, clear_tili=False, var=var)
            a, b = getab()
        if a == 2 and b == 11:
            self.auto_upgrade(buy_tili=3, var=var)
        if a < 3:
            print("4")
            self.tuitu(0, "3-1", buy_tili=3, clear_tili=False, var=var)
        self.clear_tili_info(var)
        mv.clearflags()
예제 #9
0
 def shuatuHH(self, tu_dict: list, var={}):
     """
     刷指定H图
     :param tu_dict: 刷图列表
     tu_dict: 其实应该叫tu_list,来不及改了
     ["A-B-Times",...,]
     :return:
     """
     L = ShuatuToTuple(tu_dict)
     self.enter_hard()
     self.switch = 0
     cur_map = self.check_hard_id(self.last_screen)
     mv = movevar(var)
     if "curHH" in var:
         cur = var["curHH"]
         A, B, Times = L[cur]
         self.log.write_log("info", f"断点恢复:上次刷到了H{A}-{B},继续执行。")
     else:
         cur = 0
         var["curHH"] = 0
     for cur in range(cur, len(L)):
         var["curHH"] = cur
         mv.save()
         A, B, Times = L[cur]
         if A not in HARD_COORD:
             pcr_log(self.account).write_log("error",
                                             f"坐标库中没有图号H{A}-{B}的信息!跳过此图。")
             continue
         while cur_map != A:
             self.select_hard_id(A)
             cur_map = A
         now_dict = HARD_COORD[A]
         if B in now_dict:
             xy = now_dict[B]
             self.shuatuzuobiao(*xy, Times)
         else:
             pcr_log(self.account).write_log("error",
                                             f"坐标库中没有图号H{A}-{B}的信息!跳过此图。")
             continue
     del var["curHH"]
     mv.save()
     self.lock_home()
def TaskList(self: "Automator", var: Optional[dict] = None):
    """
    这个任务可以让你仿佛回到masterV1年代
    你在这里可以按照顺序写下很多task,从而就不需要写task文件了
    你还可以在这里写一些复杂的判断逻辑,比如检测扫荡券不够则购买扫荡券等。
    甚至还可以判断self.account,来手动实现switch功能。
    非常方便
    :param self: Automator本体,必须要有,通过self.XXX进行脚本控制。
    :param var: 中断恢复字典,利用movevar可以存取相关信息
    return: None 啥都不返回
    """
    mv = movevar(var)
    if mv.notflag("step_1"):
        self.buyExp()  # 购买经验
        mv.setflag("step_1")
    if mv.notflag("step_2"):
        self.goumaimana(1, 1, var=var)  # 购买10次mana
        mv.setflag("step_2")
    if mv.notflag("step_3"):
        # And So On...
        mv.setflag("step_3")
    # ...
    mv.clearflags()
예제 #11
0
    def jueseshibie(self, var: Optional[dict] = None):
        mv = movevar(var)

        def get_stars(screen=None):
            from core.constant import PCRelement as p
            five_stars = {
                1: p(170, 337),
                2: p(209, 337),
                3: p(243, 335),
                4: p(281, 336),
                5: p(320, 335),
            }
            return int(self.count_stars(five_stars, screen))

        def get_level(screen=None):
            at = (259, 416, 291, 433)
            return make_it_as_number_as_possible(self.ocr_center(*at, screen))

        def get_haogan(screen=None):
            at = (271, 390, 291, 405)
            return make_it_as_number_as_possible(self.ocr_center(*at, screen))

        def get_zhanli(screen=None):
            at = (830, 261, 894, 275)
            return make_it_as_number_as_possible(self.ocr_center(*at, screen))

        def get_name(screen=None):
            data = self._load_data_cache()
            at = (483, 119, 760, 141)
            ori_out = self.ocr_center(*at, screen)
            while True:
                if make_it_as_zhuangbei_as_possible(ori_out) in getattr(
                        data, "EQU_ID") or "?" in ori_out.replace("?", "?"):
                    # 是装备!
                    self.click(782, 76, post_delay=0.5)
                    screen = self.getscreen()
                    ori_out = self.ocr_center(*at, screen)
                else:
                    break

            out = make_it_as_juese_as_possible(ori_out)
            out = self._check_img_in_list_or_dir(out, (482, 114, 750, 261),
                                                 "ocrfix/juese", "C_ID",
                                                 screen)
            return out

        def get_rank(screen=None):
            if screen is None:
                screen = self.getscreen()
            out = self.check_dict_id(RANKS_DICT, screen, diff_threshold=0.001)
            for _ in range(3):
                if out is None:
                    self.click(525, 71, post_delay=1)
                    out = self.check_dict_id(RANKS_DICT,
                                             screen,
                                             diff_threshold=0.001)
            if out is None:
                self.log.write_log("warning", "获取Rank失败!")
                return None
            return int(out)

        def get_six_clothes(screen=None):
            if screen is None:
                screen = self.getscreen()
            Six_Points = [
                (101, 111),
                (336, 112),
                (65, 198),
                (371, 199),
                (101, 284),
                (336, 286),
            ]
            sc = cv2.cvtColor(screen, cv2.COLOR_RGB2HSV)
            value = sc[:, :, 1]
            out = []  # 从左到右,从上到下
            for p in Six_Points:
                w, h = 60, 30
                pic = UIMatcher.img_cut(value,
                                        (p[0], p[1], p[0] + w, p[1] + h))
                if debug:
                    print(pic.max())
                if pic.max() > 150:
                    out += [True]
                else:
                    out += [False]
            if debug:
                print(out)
            return out

        def _next():
            sc = self.getscreen()
            name_at = (40, 393, 104, 441)
            self.click(929, 269)
            for _ in range(10):
                m = self.wait_for_change(screen=sc,
                                         at=name_at,
                                         delay=1,
                                         threshold=0.84,
                                         max_retry=1)
                if self.is_exists(JUESE_BTN["fhqhdj_ok"],
                                  screen=self.last_screen):
                    self.click_btn(JUESE_BTN["fhqhdj_ok"])
                    time.sleep(0.5)
                    sc = self.getscreen()
                elif m:
                    break
                if self.upgrade_kkr(sc):
                    break
            else:
                raise Exception("原因不明的wait_for_change错误!")

        def _enter():
            getattr(self, "enter_upgrade")()

        def Click_CaiNeng(screen=None):
            at = (549, 155, 858, 352)
            if screen is None:
                screen = self.getscreen()
            old = UIMatcher.img_cut(screen, at)
            while True:
                self.click(782, 76, post_delay=0.5)
                screen = self.getscreen()
                new = UIMatcher.img_cut(screen, at)
                if self.img_equal(old, new) > 0.98:
                    continue
                break

        def Click_Zhuangbei(screen=None):
            at = (549, 155, 858, 352)
            if screen is None:
                screen = self.getscreen()
            old = UIMatcher.img_cut(screen, at)
            while True:
                self.click(525, 71, post_delay=0.5)
                screen = self.getscreen()
                new = UIMatcher.img_cut(screen, at)
                if self.img_equal(old, new) > 0.98:
                    continue
                break

        def output_dict(d):
            path = os.path.join("outputs", "juese_info")
            if not os.path.isdir(path):
                os.makedirs(path)
            sd = sorted(d)
            with open(os.path.join(path, self.account + ".txt"),
                      "w",
                      encoding="utf-8") as f:
                f.write("\t".join([
                    "名称", "星级", "Rank", "等级", "左上", "右上", "左中", "右中", "左下",
                    "右下", "好感", "更新时间"
                ]) + "\n")
                for k in sd:
                    v = d[k]
                    f.write("\t".join([
                        str(s) for s in [
                            k, v["star"], v["rank"], v["dengji"], *v["zb"],
                            v["haogan"],
                            get_time_str(v["last_update"])
                        ]
                    ]) + "\n")

        self.lock_home()
        _enter()
        mv.regflag("count", 0)
        Click_CaiNeng()
        FIRST_NAME = get_name()
        Click_Zhuangbei()
        for _ in range(var["count"]):
            _next()
        while True:
            sc = self.getscreen()
            data = self.AR.get("juese_info", UDD["juese_info"])
            # Main Info
            D = {}
            D["haogan"] = get_haogan(sc)
            D["dengji"] = get_level(sc)
            D["rank"] = get_rank(sc)
            D["zb"] = get_six_clothes(sc)
            Click_CaiNeng(sc)
            sc = self.last_screen
            NAME = get_name(sc)
            if NAME == FIRST_NAME and var["count"] != 0:
                break
            D["star"] = get_stars(sc)
            D["last_update"] = time.time()
            if NAME not in data:
                data[NAME] = {}
            data[NAME].update(D)
            self.AR.set("juese_info", data)
            var["count"] += 1
            mv.save()
            Click_Zhuangbei(sc)
            _next()
        mv.clearflags()
        output_dict(self.AR.get("juese_info", UDD["juese_info"]))
        self.lock_home()
예제 #12
0
    def kucunshibie(self,
                    scan_zb=True,
                    scan_sp=True,
                    var: Optional[dict] = None):
        mv = movevar(var)
        self.lock_home()
        title_at = (613, 85, 909, 112)
        self.lock_img(ZHUCAIDAN_BTN["bangzhu"], elseclick=[(871, 513)])  # 锁定帮助
        # 去道具
        self.lock_no_img(ZHUCAIDAN_BTN["daoju"], elseclick=[(536, 159)])
        self.lock_img(ZHUCAIDAN_BTN["daojuyilan"],
                      elseclick=[(536, 159)])  # 锁定道具一览

        LAST_PAGE = False

        def get_equ_at(r, c):
            EQU_X = [97, 203, 315, 421, 535]
            EQU_Y = [126, 228, 336]
            if LAST_PAGE:
                EQU_Y = [198, 305, 412]
            return EQU_X[c], EQU_Y[r]

        DIR = ""
        LAST_SCREEN = None

        def dao_ju_kuang(screen=None):
            at = (616, 78, 924, 227)  # 道具框
            djk = screen if screen is not None else self.getscreen()
            djk = UIMatcher.img_cut(djk, at)
            return djk

        def check_last_screen():
            # 防止同一屏幕重复出现
            nonlocal LAST_SCREEN
            if LAST_SCREEN is None:
                LAST_SCREEN = dao_ju_kuang(self.last_screen)
                return True
            else:
                NOW_SCREEN = dao_ju_kuang(self.last_screen)
                if self.img_equal(NOW_SCREEN, LAST_SCREEN) > 0.98:
                    return False
                else:
                    LAST_SCREEN = NOW_SCREEN
                    return True

        def output_dict(d):
            path = os.path.join("outputs", DIR)
            if not os.path.isdir(path):
                os.makedirs(path)
            sd = sorted(d)
            with open(os.path.join(path, self.account + ".txt"),
                      "w",
                      encoding="utf-8") as f:
                f.write("%s\t%s\t%s\t%s\n" % ("名称", "数量", "更新时间", "备注"))
                for k in sd:
                    f.write("%s\t%s\t%s\t%s\n" %
                            (k, d[k][0], get_time_str(d[k][1]), d[k][2]))

        def output_warning_pic(title, value):
            path = os.path.join("outputs", DIR, "warning", self.account)
            if not os.path.isdir(path):
                os.makedirs(path)
            target = os.path.join(path, title + ".bmp")
            djk = dao_ju_kuang()
            cv2.imwrite(target, djk)
            self.log.write_log("warning",
                               f"在识别{title}时读到了不可识别的{value},图片已保存至{target}")

        def getrecord():
            kucun = self.AR.get(DIR, {})
            return kucun

        def addrecord(d, nam, val, bz=""):
            d[nam] = (val, time.time(), bz)

        def saverecord(d):
            self.AR.set(DIR, d)

        def get_number_by_sale():
            sc = self.getscreen()
            if self.is_exists(ZHUCAIDAN_BTN["sale_short"], screen=sc):
                self.click_btn(ZHUCAIDAN_BTN["sale_short"],
                               until_appear=ZHUCAIDAN_BTN["chushouqueren"])
            elif self.is_exists(ZHUCAIDAN_BTN["sale_long"], screen=sc):
                self.click(ZHUCAIDAN_BTN["sale_long"],
                           until_appear=ZHUCAIDAN_BTN["chushouqueren"])
            else:
                return None
            sc = self.last_screen
            for _ in range(6):
                self.click(1, 1)
            at = (492, 266, 566, 286)
            out = self.ocr_center(*at, screen_shot=sc)
            new_out = make_it_as_number_as_possible(out)
            try:
                the_int = int(new_out)
                return the_int
            except:
                return None

        def dragdown():
            obj = self.d.touch.down(55, 445)
            time.sleep(0.5)
            obj.move(55, 130)
            time.sleep(0.8)
            sc = self.getscreen()
            r1c0 = UIMatcher.img_cut(sc, at=(56, 354, 140, 441))
            r1c0.std()
            flag = False
            if r1c0.std() < 15:
                # 拖到底了
                flag = True
            obj.up(55, 130)
            time.sleep(1)
            return flag

        if scan_zb and mv.notflag("zb_scanned"):
            # 扫描装备
            DIR = "zhuangbei_kucun"
            rec = getrecord()
            self.lock_img(ZHUCAIDAN_BTN["sortico"],
                          elseclick=ZHUCAIDAN_BTN["zhuangbei"])
            mv.regflag("zb_r", 0)  # 行数
            mv.regflag("zb_c", 0)  # 列数
            mv.regflag("zb_p", 0)  # 页数
            LAST_PAGE = mv.flag("zb_last_page")
            for _ in range(var["zb_p"]):
                dragdown()  # 回到上次页数
            while True:
                while var["zb_r"] < 3:
                    count = 0
                    while var["zb_c"] < 5:
                        if count >= 25 or (count >= 5 and not fast_screencut
                                           ) or (count >= 10
                                                 and mv.flag("zb_last_page")):
                            self.log.write_log("warning", "不反映了,可能结束了。")
                            var["zb_c"] = 999
                            var["zb_r"] = 999
                            break
                        x, y = get_equ_at(var["zb_r"], var["zb_c"])
                        self.click(x,
                                   y,
                                   post_delay=0.5 * (count == 0) + 0.1 + 5 *
                                   (count % 10 == 9))
                        sc = self.getscreen()
                        if not check_last_screen():
                            count += 1
                            continue
                        title = self.ocr_center(*title_at, screen_shot=sc)
                        if title == -1:
                            count += 1
                            continue
                        title = make_it_as_zhuangbei_as_possible(title)
                        title = self._check_img_in_list_or_dir(
                            title, (616, 76, 884, 194), "ocrfix/zb", "EQU_ID",
                            sc)
                        out, original_out = self.get_daoju_number(sc, True)
                        comment = ""
                        if out is None:
                            out = get_number_by_sale()
                        if out is None:
                            # 没救了
                            out = original_out
                            output_warning_pic(title, out)
                            comment = "存疑"
                        addrecord(rec, title, out, comment)
                        saverecord(rec)
                        var["zb_c"] += 1
                        mv.save()
                    if var["zb_c"] == 999:
                        break
                    var["zb_c"] = 0
                    var["zb_r"] += 1
                    mv.save()
                if var["zb_r"] == 999:
                    mv.setflag("zb_scanned")
                    break
                flag = dragdown()

                if flag:
                    if mv.notflag("zb_last_page"):
                        mv.setflag("zb_last_page")
                        LAST_PAGE = True
                    else:
                        mv.setflag("zb_scanned")
                        break
                time.sleep(1)
                LAST_SCREEN = dao_ju_kuang()
                var["zb_r"] = 0
                var["zb_p"] += 1
                mv.save()
            # Output
            output_dict(rec)
        mv.clearflags()
        self.lock_home()
def CustomTask(self: "Automator", a: int = 10, b: str = "字符串类型变量b的默认值", var: Optional[dict] = None):
    """
    这是一个样例任务
    :param self: Automator本体,必须要有,通过self.XXX进行脚本控制。
    :param a: 测试用变量
    :param b: 测试用变量
    :param var: 中断恢复字典,利用movevar可以存取相关信息
    return: None 啥都不返回
    """
    print("这是一个样例程序。")
    print("--------------------------------------------------------------------")
    print("在__valid__中定义了a,b两个变量,它们已经被成功传入了。")
    print("a: ", a)
    print("b: ", b)
    print("--------------------------------------------------------------------")
    print("一个完整的脚本必须以self.lock_home()开头。")
    print("这条语句将会让PCR回到主界面。")
    self.lock_home()
    print("--------------------------------------------------------------------")
    print("利用movevar可以保存一些变量,记录程序运行的状态。")
    print("先定义一个Handle")
    mv = movevar(var)
    print("setflag命令可以做一个标记。")
    print("使用mv.flag和mv.notflag命令可以判断一个标记是否被标记过")
    if mv.notflag("flag1"):
        print("做了一些事情。")
        mv.setflag("flag1")
        print("setflag将会把标记写入rec文件,如果程序中断,再次进入该脚本时,")
        print("程序会自动将之前的标记从文件中读入,传给var参数。")
        print("如果已经执行过setflag,则notflag将会返回False")
        print("这一段文字将不会被输出第二次。")
    if mv.notflag("flag2"):
        print("又做了一些事情。")
        mv.setflag("flag2")
    print("反复使用notflag - setflag可以很方便地让脚本按顺序执行一系列指令,")
    print("且已经执行过的指令不会执行第二次。")
    mv.clearflags()
    print("一定记住最后需要执行clearflags,不然之前做的标记将会一直伴随脚本执行后续的任务,")
    print("如果后续任务中也存在相关的flag指令,则会受到此任务的影响,可能会跳过一些任务。")
    print("--------------------------------------------------------------------")
    print("当然也可以手动存储一些命令。")
    var["times"] = 0
    print("调用save命令可以手动将其存入rec文件。")
    mv.save()
    print("使用regflag命令将该变量注册为flag,")
    print("则此后调用clearflags时,就会自动将该变量从字典中删去。")
    print("也可以不注册,手动使用 del var[...] 后mv.save也行。")
    mv.regflag("times")
    mv.clearflags()
    print("--------------------------------------------------------------------")
    print("movevar所保存的变量将会在该task全部执行完成后自我销毁。")
    print("使用AutomatorRecorder可以长久保存一些变量。")
    print("self.AR可以调出这个对象。")
    print("AR.get(key,default) 将会调取静态存储中key的值,若key不存在,返回default。")
    print("在constant.py的USER_DEFAULT_DICT中有一些在其它task中被使用的key,下以此举例。")
    from core.constant import USER_DEFAULT_DICT as UDD
    print("获取一些时间状态。")
    status = self.AR.get("time_status", UDD["time_status"])
    print("输出上次捐赠的时间。")
    from datetime import datetime
    if status["juanzeng"] == 0:
        print("还未捐赠。")
    else:
        print("上次捐赠时间:", datetime.fromtimestamp(status["juanzeng"]).strftime("%Y-%m-%d %H:%M:%S"))
    print("使用AR.set可以将某值保存在静态存储区域中。")
    print("比如希望增加一条刷图记录:已经刷了H1-1了。")
    status = self.AR.get("daily_status", UDD["daily_status"])
    print("记录1-1刷了3次。")
    status["hard"]["1-1"] = 3
    print("保存到文件。")
    self.AR.set("daily_status", status)
    print("--------------------------------------------------------------------")
    print("以下为一些基础指令:")
    print("click指令:点击(x,y),在那之前延迟pre_delay秒,在那之后延迟post_delay秒。")
    self.click(1, 1, pre_delay=2, post_delay=2)
    print("可以使用PCRElement的格式(推荐)进行传参。")
    print("在constant中已经出现了很多例子了,可以参考。")
    from core.constant import PCRelement as p
    left_up_point = p(1, 1)
    print("用constant的方式实现click:")
    self.click(left_up_point, pre_delay=2, post_delay=2)
    print()
    print("is_exists指令:判断某个图片是否存在。")
    print("使用screencut截图小工具可以轻松获得某一个图片的PCRelemnt格式。")
    print("在constant.py中也有大量已经存在的元素。")
    print("如演示:判断礼物图标是否存在:")
    liwu = p(908, 432, img="img/home/liwu.bmp", at=(891, 417, 927, 448))
    if self.is_exists(liwu):
        print("liwu图标存在!")
    else:
        print("未找到liwu图标!")
    print()
    print("lock_img指令:循环直到img出现。")
    print("以下代码会不断循环检测直到liwu出现,并且每隔8秒点击left_up_point。")
    self.lock_img(liwu, elseclick=left_up_point, elsedelay=8)
    print("lock_no_img同理,只不过为循环直到img消失。")
    print()
    print("click_btn指令:按下某一个元素。")
    print("以下代码节选自self.enter_zhuxian,进入主线地图。")
    from core.constant import MAIN_BTN, MAOXIAN_BTN
    print("如果设置了until_appear,则会等待其出现,在那之前不断尝试按下按钮。")
    print("以下命令表示按下主页下方冒险按钮,直到主线的三个人头图片出现。")
    self.click_btn(MAIN_BTN["maoxian"], until_appear=MAIN_BTN["zhuxian"])
    # 进入地图
    print("如果还设置了wait_self_before,则在不断点击按钮之前还会先检测本身是否已经出现,防止误操作。")
    self.click_btn(MAIN_BTN["zhuxian"], wait_self_before=True, until_appear=MAOXIAN_BTN["ditu"])
    print("如果没有设置until_appear,则为按下按钮等待自己消失。")
    print("更多细节请见click_btn的doc。")
    print()
    print("--------------------------------------------------------------------")
    print("如果需要记录log,可以使用以下指令:")
    self.log.write_log('info', 'This is info.')
    self.log.write_log('warning', 'This is WARNING')
    self.log.write_log('error', 'ERROR!')
    print("--------------------------------------------------------------------")
    print("在执行完全部任务后,别忘了回到主页。")
    self.lock_home()
    print("以及记得清除flag。")
    mv.clearflags()
    print("--------------------------------------------------------------------")
예제 #14
0
    def jueseshibie(self, var: Optional[dict] = None):
        mv = movevar(var)
        self.check_ocr_running()
        S = self.get_zhuye().goto_juese()
        self.click(299, 23)  # 全部
        S = S.enter_first_juese()

        def output_dict(d):
            path = os.path.join("outputs", "juese_info")
            if not os.path.isdir(path):
                os.makedirs(path)
            sd = sorted(d)
            with open(os.path.join(path, self.account + ".txt"),
                      "w",
                      encoding="utf-8") as f:
                f.write("\t".join([
                    "名称", "星级", "Rank", "等级", "左上", "右上", "左中", "右中", "左下",
                    "右下", "好感", "更新时间"
                ]) + "\n")
                for k in sd:
                    v = d[k]
                    f.write("\t".join([
                        str(s) for s in [
                            k, v["star"], v["rank"], v["dengji"], *v["zb"],
                            v["haogan"],
                            get_time_str(v["last_update"])
                        ]
                    ]) + "\n")

        mv.regflag("count", 0)
        S = S.goto_kaihua()
        FIRST_NAME = S.get_name()
        S = S.goto_zhuangbei()

        for _ in range(var["count"]):
            S.next_char()

        while True:
            sc = self.getscreen()
            data = self.AR.get("juese_info", UDD["juese_info"])
            # Main Info
            D = {}
            D["haogan"] = S.get_haogan(sc)
            D["dengji"] = S.get_level(sc)
            D["rank"] = S.get_rank(sc)
            D["zb"] = S.get_six_clothes(sc)
            S = S.goto_kaihua()
            sc = self.getscreen()
            NAME = S.get_name(sc)
            if NAME == FIRST_NAME and var["count"] != 0:
                break
            D["star"] = S.get_stars(sc)
            D["last_update"] = time.time()
            if NAME not in data:
                data[NAME] = {}
            data[NAME].update(D)
            self.AR.set("juese_info", data)
            var["count"] += 1
            mv.save()
            S = S.goto_zhuangbei()
            S.next_char()
        mv.clearflags()
        output_dict(self.AR.get("juese_info", UDD["juese_info"]))
        self.lock_home()
예제 #15
0
    def shuatu_daily_ocr(self,
                         tu_order: list,
                         daily_tili=0,
                         xianding=False,
                         not_three_star_action="do",
                         zero_star_action="exit",
                         lose_action="skip",
                         can_not_enter_action="exit",
                         win_without_threestar_is_lose=True,
                         team_order="zhanli",
                         _use_daily=True,
                         var={}):
        """
        OCR 刷图!!超快!!
        :param tu_order: 刷图顺序表。
            tu_order为一个list,对每一个元素:
                "A-B-T"表示刷普通图A-B共T次
                "HA-B-T"表示刷困难图A-B共T次
            Example:
                tu_order=["3-4-10","H1-1-3"]
            注意:困难图如果刷超过3次,并不会自动购买次数。
            该刷图列表表示的刷图顺序为录入顺序。
        :param daily_tili: 每日买体力次数。
        :param xianding: 是否买空限定商店(如果出现的话)
        :param not_three_star_action: 遇到未满三星图如何操作
        :param zero_star_action: 遇到零星图如何操作
        :param lose_action: 推图失败如何操作
        :param can_not_enter_action: 无法进图时如何操作(不适用do)
            - action的种类
                "do" 手刷
                "exit" 终止刷图
                "skip" 跳过该图
        :param win_without_threestar_is_lose: 如果没有三星过关就算输
        :param team_order:
            使用队伍 "A-B" 形式,表示编组A选择B。
            若为 order指令:则按以下order排序后取前5.
                - "zhanli" 按战力排序
                - "dengji" 按等级排序
                - "xingshu" 按星数排序
            若为"none":不换人
        :param _use_daily: 开启后,统计体力使用次数以及每个图刷过的次数(兼容shuatuNN)
        """
        # 每日更新
        from core.utils import diffday
        mv = movevar(var)
        if _use_daily:
            ds = self.AR.get("daily_status", UDD["daily_status"])
        else:
            mv.regflag("normal", {})
            mv.regflag("hard", {})
            mv.regflag("buy_tili", 0)
            ds = var

        def record_ds(ds):
            if _use_daily:
                t1 = time.time()
                t2 = ds["last_time"]
                if diffday(t1, t2):
                    # 新的一天,清空刷图记录
                    self.log.write_log("info", "已经重置刷图记录。")
                    ds["normal"] = {}
                    ds["hard"] = {}
                    ds["buy_tili"] = 0
                ds["last_time"] = t1
                self.AR.set("daily_status", ds)
            else:
                mv.save()

        # 图号解析
        def parse_tu(ds):
            # 根据已经刷的图,制定接下来剩余要刷的图号
            def parse_str(s):
                mode = "N"
                if s[0] == "H":
                    mode = "H"
                    s = s[1:]
                lst = s.split("-")
                A, B, T = int(lst[0]), int(lst[1]), int(lst[2])
                return mode, A, B, T

            cur = []
            for i in tu_order:
                m, a, b, t = parse_str(i)
                target = ds["normal"] if m == "N" else ds["hard"]
                label = f"{a}-{b}"
                target.setdefault(label, 0)
                if target[label] < t:
                    cur += [(m, a, b, t - target[label])]
            new_cur = []
            # 分解任务:一次最多80扫荡
            for m, a, b, t in cur:
                tt = t
                while tt > 0:
                    if tt > 80:
                        ttt = 80
                    else:
                        ttt = tt
                    tt -= ttt
                    new_cur += [(m, a, b, ttt)]
            return new_cur

        # 关卡分析
        def GetXYTD(mode, nowA, nowB):
            if mode == "N":
                D = NORMAL_COORD[nowA]
                DR = D["right"]
                DL = D["left"]
                if nowB in DR:
                    return DR[nowB].x, DR[nowB].y, 1, "right"
                else:
                    return DL[nowB].x, DL[nowB].y, 1, "left"
            elif mode == "H":
                D = HARD_COORD[nowA]
                return D[nowB].x, D[nowB].y, 1, None

        record_ds(ds)
        cur = parse_tu(ds)
        ds.setdefault("buy_tili", 0)
        if len(cur) == 0:
            if _use_daily:
                self.log.write_log("info", "今天的刷图任务已经全部完成啦。")
            return
        if ds["buy_tili"] < daily_tili:
            self.start_shuatu()
        if not self.check_shuatu():
            return

        S = self.get_zhuye()
        S = S.goto_maoxian()
        last_a = -1
        last_m = None
        for ind, (m, a, b, t) in enumerate(cur):
            mode = "hard" if m == "H" else "normal"
            x, y, _, d = GetXYTD(m, a, b)
            # m: mode (H,N)
            # a,b: a-b
            # t: **剩余** 要刷几次
            # x,y:坐标
            # d:拖动状态
            # Enter
            if m != last_m or a != last_a:
                if m == "N":
                    S = S.goto_normal()
                    res = S.select_normal_id(a)
                else:
                    S = S.goto_hard()
                    res = S.select_hard_id(a)
                if not res:
                    if can_not_enter_action == "exit":
                        self.log.write_log("info", f"无法进入图{m}{a}-{b}!结束刷图。")
                        self.save_last_screen(f"CanNotEnter1_{self.account}.bmp")
                        self.lock_home()
                        return
                    elif can_not_enter_action == "skip":
                        self.log.write_log("info", f"无法进入图{m}{a}-{b}!跳过该图。")
                        continue

            if d == "left":
                S.Drag_Left()
            elif d == "right":
                S.Drag_Right()

            @PCRRetry(name="DOIT")
            def DOIT():
                nonlocal t
                if t == 0:
                    return "continue"
                M: FightInfoZhuXian = S.click_xy_and_open_fightinfo(x, y)
                if M is None:
                    if can_not_enter_action == "exit":
                        self.log.write_log("info", f"无法进入图{m}{a}-{b}!结束刷图。")
                        self.save_last_screen(f"CanNotEnter2_{self.account}.bmp")
                        self.lock_home()
                        return "return"
                    elif can_not_enter_action == "skip":
                        self.log.write_log("info", f"无法进入图{m}{a}-{b}!跳过该图。")
                        return "continue"
                S.clear_initFC()
                sc = self.getscreen()
                stars = M.get_upperright_stars(sc)
                if stars == 3:
                    # 可以扫荡
                    # 次数判断:对Hard图
                    max_cishu = t  # 目标:刷t次
                    if m == "H":
                        cishu = M.get_cishu(sc)
                        if cishu == 0:
                            # 不能扫荡,没有次数
                            ds["hard"][f"{a}-{b}"] = 3
                            record_ds(ds)
                            for _ in range(6):
                                self.click(1,1)
                            self.log.write_log("info", f"{m}{a}-{b}已经不能再刷更多了!")
                            return "continue"
                        max_cishu = min(cishu, max_cishu)
                    self._zdzb_info = ""  # 记录失败原因
                    # 扫荡券判断:最多还能扫荡几次
                    quan = M.get_saodangquan(sc)
                    if quan<max_cishu:
                        self._zdzb_info = "noquan"
                        if quan==0:
                            self.log.write_log("warning", "已经没有扫荡券了!终止刷图。")
                            self.lock_home()
                            return "return"
                        self.log.write_log("warning", f"扫荡券可能不足,只能支持刷{quan}次了。")
                        max_cishu=quan

                    # 体力判断:最多还能进行几次
                    left_tili = M.get_tili_left(sc)
                    one_tili = LoadPCRData().get_map_tili(mode, a, b)
                    max_cishu_tili = floor(left_tili / one_tili)
                    bought_tili = False
                    while max_cishu_tili < max_cishu:
                        # 体力不足:可以选择买体力倒是。
                        if ds["buy_tili"] < daily_tili:
                            # 可以!买体力!
                            for _ in range(6):
                                self.click(1, 1)
                            bought_tili = True
                            S.goto_buytili().OK().OK()
                            ds["buy_tili"] += 1
                            record_ds(ds)
                            self.log.write_log("info", f"体力不足,购买体力{ds['buy_tili']}/{daily_tili}")
                            left_tili += 120
                            max_cishu_tili = floor(left_tili / one_tili)
                        else:
                            # 已经……买不动了
                            if daily_tili > 0:
                                self.log.write_log("info", f"已经消耗完全部的买体力次数了。")
                            self._zdzb_info = "notili"
                            if max_cishu_tili == 0:
                                self.log.write_log("info", "已经一点体力都不剩了!终止刷图。")
                                self.stop_shuatu()
                                self.lock_home()
                                return "return"
                            else:
                                self.log.write_log("info", f"剩下的体力只够刷{max_cishu_tili}次了!")
                            break
                    if bought_tili:
                        # 买过体力之后要重新进图
                        S.click_xy_and_open_fightinfo(x, y)
                    max_cishu = min(max_cishu, max_cishu_tili)
                    # 扫荡
                    true_cishu = max_cishu
                    M.set_saodang_cishu(true_cishu, one_tili=one_tili, left_tili=left_tili,sc=self.last_screen)
                    SD = M.goto_saodang()  # 扫荡确认
                    SD = SD.OK()  # 扫荡结果
                    # 记录
                    ds[mode][f"{a}-{b}"] += true_cishu
                    record_ds(ds)
                    MsgList = SD.OK()  # 扫荡后的一系列MsgBox
                    while True:
                        out = MsgList.check()
                        if out is None:  # 无msgbox
                            break
                        if isinstance(out, MsgList.XianDingShangDianBox):
                            # 限定商店
                            if xianding:
                                shop = out.Go()
                                shop.buy_all()
                                shop.back()
                                break
                            else:
                                out.Cancel()
                        if isinstance(out,MsgList.TuanDuiZhanBox):
                            out.OK()
                        if isinstance(out,MsgList.LevelUpBox):
                            out.OK()
                            self.start_shuatu()  # 体力又有了!
                        if isinstance(out,MsgList.ChaoChuShangXianBox):
                            out.OK()
                    # 扫荡结束
                    # 保险起见
                    for _ in range(6):
                        self.click(1,1)
                    if true_cishu<t:
                        self.log.write_log("info", f"{m}{a}-{b}刷图剩余次数:{t - true_cishu}")
                        t -= true_cishu
                        raise ContinueNow("DOIT")
                    else:
                        self.log.write_log("info", f"{m}{a}-{b}刷图成功!")
                else:
                    # 特判
                    if stars==0:
                        if zero_star_action == "exit":
                            self.log.write_log("info",f"{m}{a}-{b}尚未通关,终止刷图!")
                            self.lock_home()
                            return "return"
                        elif zero_star_action == "skip":
                            self.log.write_log("info", f"{m}{a}-{b}尚未通关,跳过刷图!")
                            for _ in range(6):
                                self.click(1,1)
                            return "continue"
                    if stars<3:
                        if not_three_star_action == "exit":
                            self.log.write_log("info", f"{m}{a}-{b}尚未三星,终止刷图!")
                            self.lock_home()
                            return "return"
                        elif not_three_star_action == "skip":
                            self.log.write_log("info", f"{m}{a}-{b}尚未三星,跳过刷图!")
                            for _ in range(6):
                                self.click(1,1)
                            return "continue"
                    # 次数判断:对Hard图
                    if m == "H":
                        cishu = M.get_cishu(sc)
                        if cishu == 0:
                            # 不能扫荡,没有次数
                            ds["hard"][f"{a}-{b}"] = 3
                            record_ds(ds)
                            for _ in range(6):
                                self.click(1, 1)
                            self.log.write_log("info", f"{m}{a}-{b}已经不能再刷更多了!")
                            return "continue"
                    # 体力判断:至少得有一次体力,否则就买
                    left_tili = M.get_tili_left(sc)
                    one_tili = LoadPCRData().get_map_tili(mode, a, b)
                    bought_tili = False
                    if left_tili<one_tili:
                        # 体力不足:可以选择买体力倒是。
                        if ds["buy_tili"] < daily_tili:
                            # 可以!买体力!
                            for _ in range(6):
                                self.click(1, 1)
                            bought_tili = True
                            S.goto_buytili().OK().OK()
                            ds["buy_tili"] += 1
                            record_ds(ds)
                            self.log.write_log("info", f"体力不足,购买体力{ds['buy_tili']}/{daily_tili}")
                        else:
                            # 已经……买不动了
                            self.log.write_log("info", "已经一点体力都不剩了!终止刷图。")
                            self.stop_shuatu()
                            self.lock_home()
                            return "return"
                    if bought_tili:
                        # 买过体力之后要重新进图
                        S.click_xy_and_open_fightinfo(x, y)
                    # 体力次数都够了,进入挑战
                    TZ = M.goto_tiaozhan()
                    TZ.select_team(team_order)
                    F = TZ.goto_fight()
                    During = F.get_during()
                    F.set_auto(1, self.last_screen)
                    F.set_speed(1, self.last_screen)
                    state = {"flag": None}
                    last_time = time.time()
                    while True:
                        if time.time() - last_time > 300:
                            # TOO LONG
                            raise LockTimeoutError("战斗超时!")
                        out = During.check()
                        if out is None:
                            continue
                        if isinstance(out, During.LoveUpScene):
                            out.skip()
                        if isinstance(out, During.FightingLoseZhuXian):
                            state["flag"] = "lose"
                            out.goto_zhuxian(type(S))
                            break
                        if isinstance(out, During.FightingWinZhuXian):
                            state["flag"] = "win"
                            state["star"] = out.get_star()
                            state["next"] = out.get_after()
                            out.next()
                            break
                        if isinstance(out, During.FightingDialog):
                            out.skip()
                    if state["flag"] == "win":
                        # 记录
                        ds[mode][f"{a}-{b}"] += 1
                        record_ds(ds)
                    if state["flag"] == "win" and state["star"] < 3 and win_without_threestar_is_lose:
                        self.log.write_log("info", f"没有三星通关({state['star']}/3),算作失败!")
                        state["flag"] = "lose"
                    if state["flag"] == "lose":
                        if lose_action == "exit":
                            self.log.write_log("info", f"战败于{m}{a}-{b},结束刷图!")
                            self.lock_home()
                            return "return"
                        elif lose_action == "skip":
                            self.log.write_log("info", f"战败于{m}{a}-{b},跳过该图!")
                            return "continue"
                        else:
                            self.log.write_log("info", f"战败于{m}{a}-{b},重试该图!")
                            raise RetryNow("DOIT")
                    else:
                        # 战胜了!
                        self.log.write_log("info", f"战胜了{m}{a}-{b} ({state['star']}/3)!")
                        last_time = time.time()
                        next = state["next"]
                        while True:
                            if time.time() - last_time > 120:
                                raise LockTimeoutError("在结算页面超时!")
                            out = next.check()
                            if out is None:
                                break
                            if isinstance(out, next.XianDingShangDianBox):
                                # 限定商店
                                if xianding:
                                    shop = out.Go()
                                    shop.buy_all()
                                    shop.back()
                                    break
                                else:
                                    out.Cancel()
                            if isinstance(out, next.TuanDuiZhanBox):
                                out.OK()
                            if isinstance(out, next.LevelUpBox):
                                out.OK()
                                self.start_shuatu()  # 体力又有了!
                            if isinstance(out, next.ChaoChuShangXianBox):
                                out.OK()
                            if isinstance(out, next.AfterFightKKR):
                                out.skip()
                                # 再次进图
                                self.get_zhuye().goto_maoxian().goto_zhuxian()
                                break
                            if isinstance(out, next.FightingWinZhuXian2):
                                # 外出后可能还有Box,需要小心谨慎
                                out.next()
                        # 开init
                        S.set_initFC()

                        # 手刷结束
                        t -= 1
                    raise ContinueNow("DOIT")  # 把t次刷完

            cmd = DOIT()
            if cmd == "continue":
                continue
            elif cmd == "return":
                if not _use_daily:
                    mv.clearflags()
                return
        if not _use_daily:
            mv.clearflags()
        self.log.write_log("info", f"全部刷图任务已经完成。")
        self.lock_home()