def _autoDetect(self, name: str, overwrite=False): assert name in self.root["maps"], f"不存在地图{name}" root_stage = self.maps[name]["root"] assert root_stage != '', f"地图{name}中无数据!请先设置地图根节点" apd_stage = [] basex, basey = 0, 0 # rect_stage = [os.path.basename(i)[:-4] for i, v in rect] rect = self.getMapStageInfo(name) rect_stage = [os.path.basename(i)[:-4] for i, v in rect] logger.debug(rect_stage) for stage, where in self.maps[name]["stages"]: if stage in rect_stage: apd_stage = [stage, where] basex, basey = rect[rect_stage.index(stage)][1] logger.debug(f"寻找到已知根节点{apd_stage}位于{basex},{basey},退出循环") break assert apd_stage != [], f"在地图中未寻找到已知节点!" dx, dy = apd_stage[1] dx -= basex dy -= basey _exist_stage = [i for i, v in self.maps[name]["stages"]] for stage, where in rect: real_stage = os.path.basename(stage)[:-4] if (real_stage != apd_stage[0] and real_stage not in _exist_stage) or overwrite: self._addStageInMap(name, real_stage, int(dx + where[0]), int(dy + where[1])) logger.notice( f"add {real_stage} in {name} at {dx + where[0]},{dy + where[1]}" ) return True
def getSkillUpgradeCost(self, skillID=0, level_from=1, level_to=7, show=False): from ArkType.ItemStack import ItemStack skillID -= 1 if len(self["skills"]) < skillID: logger.error(f"该角色无第{skillID}技能 最大技能:{len(self['skills'])}") return ItemStack() ret = ItemStack() for level in range(level_from, level_to): try: if level <= 6: for item in self["allSkillLvlup"][level - 1]['lvlUpCost']: ret.addItemFromCharCost(item) elif 6 < level <= 9: for item in self["skills"][skillID]["levelUpCostCond"][ level - 7]["levelUpCost"]: ret.addItemFromCharCost(item) except Exception as e: logger.error( f"CHAR={self['name']},SKILL={skillID},LVL={level},ERR={str(e)}" ) if show: logger.notice( f"{self['name']}{skillID}技能 {level_from}->{level_to} " f"消耗{ret.formatItems('%item%(%quantity%) ')}") return ret
def UpgradeDropFromVer1_ToVer2(ark, stage, force=False): drp = getStageTag().getStage(stage).getDropInfo().getDropList() li = list(i[1] for i in drp) se = set(i[1] for i in drp) if len(li) != len(se): logger.warning('Unable to upgrade the level with different drop overlaps from Ver.1 to Ver.2!') if not force: return False drop_info = ark.dropLinker.getStageDrop(stage) drp_wname = {} for drop_type, game_id in drp: drop_name = getItemTag()['items'].get(game_id)['name'] drop_id = ark.dropLinker.get(drop_name) drp_wname.update({drop_name: [drop_name, drop_id, drop_type]}) for index in range(len(drop_info)): cur_drop: DropInfo = drop_info[index] if cur_drop.getVersion() != 1: continue if cur_drop.isEmpty(): logger.warning(f"Find Empty Attack at Index:{index} in Stage:{stage},Set to None.") drop_info[index] = None continue new_drop = DropItemStack() ERR_G = [None, None, None] for type_, drp_li in cur_drop.dropList.items(): for drp_name, drop_q in drp_li: new_drop.addItem(drp_name, drop_q, drp_wname.get(drp_name, ERR_G)[2] or 253) drop_info[index] = DropInfo(2, stage, cur_drop.attackTime, new_drop) # Write file Structure:([version \x02][len(droplist)<1>][[itemid<2>][quantity<2>][type<1>]]..[atk_time<3>][time<4>]) # save raw file to backup os.rename(f"{DROPFOLDER_PATH}{stage}.drp", f"{DROPFOLDER_PATH}{stage}.drp.U12.{randomstr()}") ttl_upg = 0 with open(f"{DROPFOLDER_PATH}{stage}.drp", 'wb') as fd: for dropstack in drop_info: if dropstack is None: continue fd.write(b'\x02') all_items = dropstack.dropList.getAllItems() fd.write(len(all_items).to_bytes(1, 'little')) for name, quantity, type_ in all_items: fd.write(ark.dropLinker.get(name).to_bytes(2, 'little')) fd.write(quantity.to_bytes(2, 'little')) fd.write((type_ + 1).to_bytes(1, 'little')) cost_time = dropstack.atk_in_t or 0 try: fd.write(int(cost_time * 100).to_bytes(3, 'little')) except OverflowError: logger.warning(f"cannot convert cost_time({cost_time}) into byte!") fd.write(b'\xff\xff\xff') fd.write(dropstack.attackTime.to_bytes(4, 'little')) ttl_upg += 1 logger.notice(f"Upgrade Finished![STAGE {stage},{ttl_upg}TUI]") return drop_info
def update(self, filter_freq=200, filter_stages=[], url_stats='result/matrix?show_closed_zone=true', url_rules='formula', path_stats=MATRIX_FILE_DIR + '/data/matrix.json', path_rules=MATRIX_FILE_DIR + '/data/formula.json', force=True): """ To update parameters when probabilities change or new items added. Args: url_stats: string. url to the dropping rate stats data. url_rules: string. url to the composing rules data. path_stats: string. local path to the dropping rate stats data. path_rules: string. local path to the composing rules data. """ if os.path.isfile(f"{MATRIX_FILE_DIR}/data/matrix.json") and force: mtime = os.path.getmtime(f"{MATRIX_FILE_DIR}/data/matrix.json") logger.debug(f"planner MTime is {int(mtime)},creating backup folder") if not os.path.exists(f"{MATRIX_FILE_DIR}/data/b_{int(mtime)}/"): os.mkdir(f"{MATRIX_FILE_DIR}/data/b_{int(mtime)}/") for _ in os.listdir(f"{MATRIX_FILE_DIR}/data/"): if _ != ".gitkeep" and os.path.isfile(f"{MATRIX_FILE_DIR}/data/{_}"): shutil.move(f"{MATRIX_FILE_DIR}/data/{_}", f"{MATRIX_FILE_DIR}/data/b_{int(mtime)}/{_}") logger.debug("file backup successful") logger.notice(f'Start to update Planning data {time.asctime(time.localtime(time.time()))}.') if not force: # if not force to update, try loading data from file. try: material_probs, self.convertion_rules = load_data(path_stats, path_rules) except: # loading failed, try loading from server. force = True if force: # load from server. try: logger.common('Requesting data from web resources (i.e., penguin-stats.io)...') material_probs, self.convertion_rules = request_data(penguin_url + url_stats, penguin_url + url_rules, path_stats, path_rules) logger.common('done.') except: logger.error("Request data error.") return if filter_freq: filtered_probs = [] for drop in material_probs['matrix']: if drop['times'] >= filter_freq and drop['stageId'] not in filter_stages: filtered_probs.append(drop) material_probs['matrix'] = filtered_probs if self._pre_processing(material_probs, forceupdate=force) != -1: self._set_lp_parameters()
def addLocate_Auto(self, name, imagePath, image, area=None, threshold=0.95, diff=5): assert self.checkMapExist(name), '地图不存在!' assert self.__gameTemp__.has(imagePath), '图片不存在!' template = self.__gameTemp__.getTemplate(imagePath)[0] max_thres, where = self.__gameTemp__.matchDifference(image, template, method=1) logger.debug("在(%d,%d)匹配到%s的最佳阈值%s" % (where[0], where[1], imagePath, max_thres)) if max_thres < threshold: logger.error("未找到最为匹配的源,请尝降低变最高阈值") return False y, x = int(where[0]), int(where[1]) h, w, depth = template.shape area = [x - 2, y - 2, w + 4, h + 4] if area is None else area self.getMap(name).get("detector") \ .addDetector(type_='I', imagePath=imagePath, threshold=max_thres - 0.07, locationarea=area, diff=diff) logger.notice( "成功在%s中添加关键图像%s[area=[%d,%d,%d,%d],threshold=%.2f]" % (name, imagePath, x, y, w, h, max_thres - 0.07)) return True
def appender(parent): root_time = time.time() last_cover = time.time() next_duration = 6 * 60 # TODO:满体力检测 while parent.running: time.sleep(next_duration - 0.01) parent.intellect += 1 cover_time = time.time() - last_cover if cover_time > 6 * 60 + 0.5: # 电脑睡眠唤醒后时间跨度 logger.notice("检测到程序终止跨度:%d" % int(cover_time)) int_add = 0 while cover_time >= 6 * 60: cover_time -= 6 * 60 parent.intellect += 1 int_add += 1 logger.notice("期间恢复%d理智" % int_add) last_cover = time.time() - cover_time - 0.01 next_duration = 6 * 60 - cover_time else: last_cover = time.time() next_duration = 6 * 60
def updateItemData(): import requests from bs4 import BeautifulSoup as soup k = requests.get("http://prts.wiki/w/%E9%81%93%E5%85%B7%E4%B8%80%E8%A7%88") r = soup(k.content, "html.parser") item_dump = [] for data in list(r.find_all(class_="smwdata")): item_dump.append([data.get("data-name"), data.get("data-rarity"), data.get("data-file"), data.get("data-id")]) with open(".\\ArknightsGameData\\zh_CN\\gamedata\\excel\\item_table.json", "r", encoding="utf-8") as f: item = json.load(f) item_from_json = item["items"] item_names = {item_from_json.get(i)["name"]: item_from_json.get(i)["iconId"] for i in item_from_json.keys()} # for name, _, __, ___ in item_dump: # try: # item_names.remove(name) # except ValueError: # print(name) # print(item_names) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE' } patch_item_name_data = { "合约赏金(旧)": "CRISIS_SHOP_COIN", "晶体电子单元": "MTL_SL_OEU", "寻访数据契约(遗愿焰火)": "LMTGS_COIN_601", "寻访数据契约(勿忘我)": "LMTGS_COIN_903", "寻访数据契约(地生五金)": "LMTGS_COIN_1401", "寻访数据契约(月隐晦明)": "LMTGS_COIN_1601", "α类新年寻访凭证(2020)": "2020recruitment10_1", "β类新年寻访凭证(2020)": "2020recruitment10_2", "γ类新年寻访凭证(2020)": "2020recruitment10_3", "α类新年寻访凭证(2021)": "2021recruitment10_1", "β类新年寻访凭证(2021)": "2021recruitment10_2", "γ类新年寻访凭证(2021)": "2021recruitment10_3", } _ = os.path _PARENT = _.realpath(_.join(_.dirname(__file__), '..')) unknown_item = [] err_k = [] for name, rarity, url, sortid in item_dump: # http://prts.wiki/images/thumb/2/23/%E9%81%93%E5%85%B7_%E5%B8%A6%E6%A1%86_%E6%97%A0%E5%90%8D%E7%9A%84%E8%AF%86%E5%88%AB%E7%89%8C.png/100px-%E9%81%93%E5%85%B7_%E5%B8%A6%E6%A1%86_%E6%97%A0%E5%90%8D%E7%9A%84%E8%AF%86%E5%88%AB%E7%89%8C.png # http://prts.wiki/images/2/23/%E9%81%93%E5%85%B7_%E5%B8%A6%E6%A1%86_%E6%97%A0%E5%90%8D%E7%9A%84%E8%AF%86%E5%88%AB%E7%89%8C.png # if image in current path,break try: id_ = item_names.get(name) if id_ is None: id_ = patch_item_name_data.get(name) if id_ is None: id_ = name unknown_item.append(id_) logger.warning("[ItemIconUpdater]无效的材料转换名称:" + name) if os.path.exists(f"{_PARENT}\\imgReco\\img\\lootitem\\{id_}.png"): continue url_new = url.replace("/thumb", "")[::-1].split("/", 1)[1][::-1] rep = requests.get(url_new, headers=headers) if rep.status_code == 200: logger.notice(f"[ItemIconUpdater]完成图标更新: {id_}") with open(f"{_PARENT}\\imgReco\\img\\lootitem\\{id_}.png", "wb") as f: f.write(rep.content) except: logger.error("出现错误:" + str([name, rarity, url, sortid])) err_k.append([name, rarity, url, sortid]) print(unknown_item) print(err_k)
def _setBaseStage(self, name: str, stage: str): assert name in self.root["maps"] self.maps[name]["root"] = stage self.maps[name]["stages"].append([stage, (0, 0)]) logger.notice(f"设定{name}原点关卡为{stage}")
def _createMap(self, name: str = "EP0"): assert name not in self.root["maps"] assert name != 'root' self.root["maps"].append(name) self.maps.update({name: self._map_template(name)}) logger.notice(f"完成{name}的创建!")