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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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("--------------------------------------------------------------------")
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()
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()