예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
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
예제 #4
0
    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()
예제 #5
0
 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
예제 #6
0
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
예제 #7
0
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)
예제 #8
0
 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}")
예제 #9
0
 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}的创建!")