示例#1
0
 def copyItem(self, i_from='', i_to=''):
     if self.check(i_from):
         self.set(i_to, self.get(i_from))
         return True
     else:
         logger.error('不存在名为%s的数据') % i_from
         return False
 def _parseGetStageDrop(self, ver: bytes):
     ver = int.from_bytes(ver, 'little')
     try:
         return getattr(self, f"_getStageDrop_Ver{ver}")
     except AttributeError:
         logger.error(f"解析中断:未知的关卡掉落解析器版本:Ver{ver}")
         raise AttributeError(f"Unknown Parser Version:{ver}")
示例#3
0
 def import_from_data(self, datain):
     if type(datain) == dict:
         self._imp_data_dict(datain)
     elif type(datain) == list:
         self._imp_data_list(datain)
     else:
         logger.error('数据非list/dict形!')
示例#4
0
 def seek(self, name):
     if name == '_root':
         self.read = self.cfg
         self.__u = []
         return True
     elif name == '..':
         u = self.__u
         if u.__len__() == 0:
             self.read = self.cfg
             logger.error("当前目录已达到_root!")
             return False
         else:
             self.read = self.cfg
             u.pop(-1)
             for i in u:
                 self.read = getattr(self.read, i)
             self.__u = u
             return True
     elif name in self.read.folder:
         self.__u.append(name)
         self.read = getattr(self.read, name)
         return True
     else:
         logger.error('当前分支下不存在名为"%s"的分支' % name)
         return False
示例#5
0
 def addRawItem(self, raw_name, quantity):
     for field in self.__allKnownFields__:
         realName = field.get(raw_name, None)
         if realName is not None:
             return self._direct_add(realName, quantity)
     logger.error(f"0:不存在名为'{raw_name}'的物品")
     return self
示例#6
0
def recognizeOperation(image, map_dict=None) -> Tuple[str, str]:
    if not map_dict:
        map_dict = getMapCost()
    opidtext = fix_known_data(load_data()[1].recognize2(
        image, subset='0123456789abcdefghijklmnopqrstuvwxyz-')[0])

    where_ = map_dict.where(opidtext)
    if where_:
        return opidtext, where_
    # 无法识别,尝试使用tesseract
    logger.warning("无法识别地图信息" + opidtext)
    debug_ret = []
    import pytesseract
    for index in range(10):
        ret = pytesseract.image_to_string(image, lang="eng") \
            .replace("\n", "").replace("\x0c", "")
        where_ = map_dict.where(ret)
        debug_ret.append(ret)
        if where_:
            logger.debug("识别信息:%s" % str(debug_ret))
            return ret, where_

    logger.error("在10次识别后依旧无法识别出当前关卡信息。")
    logger.debug("识别信息:%s" % str(debug_ret))
    return "", ""
示例#7
0
    def _detect_image(self, dobj, image, sub_area=None):
        # {"type": type_,
        #  "image": imagePath,
        #  "threshold": threshold,
        #  "area": list(locationarea) if locationarea else None,
        #  "diff": diff}
        #  read with x,y,w,h dump x1,x2,y1,y2
        if sub_area is None:
            if dobj["area"] is not None:
                x, y, w, h = dobj["area"]
                img = image[y:y + h, x:x + w]
            else:
                img = image
        else:
            img = image
            if (sub_area[0] > dobj["area"][0] and sub_area[1] > dobj["area"][1]) or \
                    (sub_area[2] < dobj["area"][2] and sub_area[3] < dobj["area"][3]):
                return 'I', dobj["diff"], 0, True

        try:
            result = np.max(
                self.__gameTemp__.matchDifference(img, self.__gameTemp__.getTemplate(dobj["image"])[0], method=2))
        except ValueError:
            logger.error(f"Image load failed:{dobj['image']}")
            result = 0
        except cv2.error:
            logger.error(f"Image compare failed:{dobj['image']}")
            result = 0
        return 'I', dobj["diff"], 0 if result > dobj["threshold"] else 1, False
示例#8
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
示例#9
0
 def getStageInfo(self, stageName: str):
     if stageName is None:
         return [None]
     for name, data in self.maps.items():
         if stageName in [i for i, v in data['stages']]:
             return name, data
     logger.error(f"未知关卡名称'{stageName}',请检查!")
示例#10
0
 def clickEpNearist(self, mapId: int):
     targMap = mapId
     targStage = None
     currMap = None
     currStage = None
     for stage, include in ArkMap_MainStage.items():
         if mapId in include:
             targStage = int(stage[-1])
         if self.__ark.gameTemp.dingwei(
                 f"main\\epstage\\{stage}.png",
                 self.__ark.getScreenShot(121, 208, 86, 47)):
             currStage = int(stage[-1])
             for inc in include:
                 if self.__ark.gameTemp.dingwei(
                         f"main\\epstage\\{inc}.png",
                         self.__ark.getScreenShot(871, 383, 149, 68)):
                     currMap = inc
     logger.debug(f"[{targStage}-{targMap} {currStage}-{currMap}]")
     if not (targMap and targStage and currMap and currStage):
         logger.error(
             f"未找到地图![{targStage}-{targMap} {currStage}-{currMap}]")
         raise KeyError(f"未找到地图")
     if currStage == targStage:
         self.__ark.clicker.mouse_click(
             945 - 312 * min(3, max(currMap - targMap, 0)), 367, t=1.3)
         return -1
     dist = targStage - currStage
     clk = (64, 133) if dist < 0 else (65, 517)
     for rg in range(abs(dist)):
         self.__ark.clicker.mouse_click(*clk, t=0.7)
     logger.debug(f"{clk},{dist}")
     return self.clickEpNearist(mapId)
示例#11
0
    def fromActivityMapMainToActivityMap(self, targMap: str, targStage: str):
        logger.debug(f"Activity MapMain To Map:{targMap} for {targStage}")
        if targMap in ACTIVITY_MAP:
            # TODO:适配所有的活动地图
            time.sleep(1.5)
            if targMap == 'CB':
                return self.activityMapAdapter((1098, 438), 'CB-', (1061, 613),
                                               'CB-EX-', 2, 2, 0, targStage,
                                               targMap)
            if targMap == 'MB':
                return self.activityMapAdapter((1140, 162), 'MB-', (1140, 295),
                                               'MB-EX-', 2, 2, 1, targStage,
                                               targMap)
            if targMap == 'WR':
                return self.activityMapAdapter((1157, 598), 'WR-', (1030, 630),
                                               'WR-EX-', 1.7, 1.7, 1.7,
                                               targStage, targMap)
            if targMap == 'OD':
                return self.activityMapAdapter((205, 317), 'OD-', (205, 397),
                                               'OD-EX-', 2, 2, 1.5, targStage,
                                               targMap)
            if targMap == 'DM':
                return self.activityMapAdapter((789, 523), 'DM-', (870, 640),
                                               'DM-EX-', 1.3, 1.5, 1.5,
                                               targStage, targMap)

            logger.error(f"当前地图'{targMap}'尚未适配进入模式,请在ArkMap中进行适配后再次运行")
            return False
        return True
示例#12
0
 def addChild(self, name=None, data=None):
     if name:
         if not hasattr(self, name):
             setattr(self, name, configTree(name))
             self.folder.append(name)
             return True
         elif getattr(self, name) == None:
             setattr(self, name, configTree(name))
             self.folder.append(name)
             return True
         elif name in self.folder:
             logger.error("子分支名称重复了")
             return False
         else:
             logger.error('禁止使用子数组名称命名')
             return False
     elif data:
         if hasattr(data, '_root'):
             if data._root not in self.folder:
                 self.folder.append(data._root)
                 setattr(self, data._root, data)
                 return True
             else:
                 logger.error("子分支名称重复了")
                 return False
         else:
             logger.error('分支数据错误')
             self.wrong = data
             return False
     else:
         logger.error('?ErrSomewhere...')
         return False
示例#13
0
 def listall(self):
     try:
         logger.common('[item]' + str(self.item)[1:-1:])
         print('[folder]' + str(self.folder)[1:-1:])
         return True
     except:
         logger.error("不存在参数!")
         return False
示例#14
0
 def check(self, data):
     if data == '' or data is None:
         logger.error('数据不能为空!')
         return False
     if data in self._keylist or data in self._vallist:
         logger.error('禁止存在相同数据!')
         return False
     return True
示例#15
0
 def addItem(self, name, quantity, check=True):
     if not check:
         return self._direct_add(name, quantity)
     for field in self.__allKnownFields__:
         if name in field.values():
             return self._direct_add(name, quantity)
     logger.error(f"0:不存在名为'{name}'的物品")
     return self
示例#16
0
    def fromMaptoMapMain(self, mapName: str = None):
        if mapName is None:
            # 自动定位当前位置
            loc = self.__ark.getLocation(self.__ark.getScreenShot(),
                                         self.RECO,
                                         addon=True)
            logger.debug(f"获得当前定位于{loc}")
            if len(loc) == 0:
                if not self.toMain():
                    logger.error('无法定位当前位置且无法返回主界面!请检查!')
                    # raise ValueError("cannot locate current location")
                    return False
                else:
                    self.__ark.clicker.mouse_click(923, 201, t=1.7)
                    return True
            if loc[0] == 'map_atk':
                # 在攻击界面 但是不知道在哪个关卡的攻击界面
                # 因此还需要返回后再次进行识别
                self.__ark.clicker.mouse_click(86, 42, t=1)
                loc = self.__ark.getLocation(self.__ark.getScreenShot(),
                                             self.RECO,
                                             addon=True)
                logger.debug("在攻击界面中,返回后执行识别:" + str(loc))
            if not loc:
                if not self.toMain():
                    logger.error("请切换至任一地图、主界面或地图主界面再试一次!")
                    return None
                else:
                    self.__ark.clicker.mouse_click(923, 201, t=1.7)
                    return True
            if loc[0] == 'map_main':
                return True
            if loc[0] == 'main':
                self.__ark.clicker.mouse_click(923, 201, t=1.7)
                return True
            if loc[0] in ['map_ep', 'map_mat', 'map_exterm']:
                if 'map_exterm.inmap' in loc:
                    self.__ark.clicker.mouse_click(86, 42, t=1.5)
                self.__ark.clicker.mouse_click(86, 42, t=1)
                self.__ark.clicker.mouse_click(80, 658, t=1)
                return True
            if loc[0] in ArkMap_ACTIVITY:
                self.__ark.clicker.mouse_click(86, 42, t=1)
                self.__ark.clicker.mouse_click(86, 42, t=1)
                self.__ark.clicker.mouse_click(80, 658, t=1)
                return True
        else:
            # TODO: 存在mapName 进行位置检测
            # 否则需要有开始行动标志的界面介入
            if mapName in ACTIVITY_MAP:
                # 需要额外返回上一级的特殊地图
                self.__ark.clicker.mouse_click(86, 42, t=1.6)

            self.__ark.clicker.mouse_click(86, 42, t=1)
            self.__ark.clicker.mouse_click(86, 42, t=1)
            self.__ark.clicker.mouse_click(80, 658, t=1)
            return True
示例#17
0
 def _detect_condition(self, result, condition, suc, show):
     _cond = self._replace_condition_value(condition, result, suc, show)
     if _cond == '':
         return True
     try:
         return bool(eval(_cond))
     except Exception as e:
         logger.error(f"Detect ERROR!(cond='{_cond}'):{e}")
         return None
示例#18
0
 def _readfromdict(self, dictin):
     if isinstance(dictin, dict):
         for key in dictin.keys():
             value = dictin.get(key)
             if self.check(key) and self.check(value):
                 self._keylist.append(key)
                 self._vallist.append(value)
     else:
         logger.error('输入非dict类型')
示例#19
0
 def autoAddItem(self, name, quantity):
     for field in self.__allKnownFields__:
         if name in field.values():
             return self._direct_add(name, quantity)
     for field in self.__allKnownFields__:
         realName = field.get(name, None)
         if realName is not None:
             return self._direct_add(realName, quantity)
     logger.error(f"-1:不存在名为'{name}'的物品")
     return self
示例#20
0
 def delPoint(self, name: str, index: int = None, x: int = None, y: int = None):
     if self.config.get(name) is None:
         logger.error("不存在明文%s的数据集!")
         return False
     if index is not None:
         return self.config.get(name).pop(index)
     else:
         for _ in self.config.get(name):
             if _[0] == x and _[1] == y:
                 self.config.get(name).remove(_)
                 return _
示例#21
0
 def dingwei(self, name, image, threshold=None):
     template, tbd, default_th, tbd = self.getTemplate(name)
     if template.all() is None:
         logger.error("未找到名为%s的定位标志" % name)
         return []
     else:
         threshold = threshold or default_th
         return self.matchDifference(image,
                                     template,
                                     threshold,
                                     method=self.TEMPLATE)
示例#22
0
 def getStageDrop(self, stageId: str):
     if not os.path.isfile(f"{DROPFOLDER_PATH}{stageId}.drp"):
         return list()
     data = []
     with open(f"{DROPFOLDER_PATH}{stageId}.drp", 'rb') as f:
         while (_ver := f.read(1)) != b'':
             try:
                 data.append(self._parseGetStageDrop(_ver)(stageId, f))
             except AttributeError:
                 logger.error(f"got Unparsed data at {len(data) + 1},Version={_ver}. break")
                 break
示例#23
0
 def delPoint(self, name, index=None, x=None, y=None):
     assert self.checkMapExist(name)
     _detector = self.getMap(name).get("detector")
     if index is not None:
         _detector.delDetector_Index(index)
     elif x is not None and y is not None:
         _detector.delDetector_XY(x, y)
     else:
         logger.error("index and (x,y) can not be None at sametime")
         return False
     return True
示例#24
0
 def detect(self, image, condition, sub_area=None, type='L', show=False):
     result = []
     suc = {'I': 0, 'C': 0}
     for dobj in self:
         ret = self._auto_detect(dobj, image, sub_area=sub_area)
         if ret is None:
             logger.error("Wrong type of detector!%s" % dobj.get("type"))
             continue
         suc[ret[0]] += (1 if ret[2] < 0.2 else 0)
         result.append(ret)
     return result, self._detect_condition(result, condition, [suc['I'], suc['C']], show)
示例#25
0
 def getTemplate(self, name) -> [np.ndarray, str, float, bool]:
     try:
         v = getattr(self, name)
         if not v[3]:
             v[0] = self.loadImage(v[1])
             v[3] = True
         return v
     except (NameError, AttributeError):
         return [None, None, None, None]
     except ValueError:
         logger.error("图像" + name + "路径不存在")
         return [None, None, None, None]
示例#26
0
 def _check_value(self):
     for k, v in self.items():
         if isinstance(v, (int, float)):
             continue
         if isinstance(v, str):
             try:
                 self[k] = float(v)
             except:
                 logger.error(
                     f"cannot convert {v} to an float format. remove {k} instead"
                 )
                 self.pop(k)
示例#27
0
 def stageInSameMap(self, stage1, stage2, mapName=None):
     if mapName is not None:
         if stage2 in [name for name, pos in self.maps[mapName]["stages"]]:
             return True
         return False
     for mapName, data in self.maps.items():
         stagelist = [name for name, pos in data["stages"]]
         if stage1 in stagelist:
             if stage2 in stagelist:
                 return True
             return False
     logger.error(f"{stage1} not in the MapData")
     return False
示例#28
0
 def fromPlanner(planned_data, require_request=False):
     if not isinstance(planned_data, dict):
         logger.error(
             f"规划数据并非dict形式,请检查(获得了{planned_data.__class__.__name__})")
         return StageSet()
     stages = planned_data.get("stages", [])
     if not stages:
         logger.warning("规划数据关卡列表为空!")
         return StageSet()
     ret = StageSet()
     for stage in stages:
         ret.addStage(stage['stage'], int(float(stage['count']) + 0.9),
                      stage['items'], require_request)
     return ret
示例#29
0
 def getEvolveCost(self, now=1, target=2):
     from ArkType.ItemStack import ItemStack
     if target < now:
         logger.error(f"角色目标精英化阶段需要大于当前精英化阶段")
         return ItemStack()
     ret = ItemStack()
     for targ in range(now, target):
         _UM = targ + 1
         try:
             for item in self["phases"][_UM]["evolveCost"]:
                 ret.addItemFromCharCost(item)
         except Exception as e:
             logger.error(f"CHAR={self['name']},EVOLVE={_UM},ERR={str(e)}")
     return ret
示例#30
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()