Exemplo n.º 1
0
def recognizeEndItems(ark, stageCode, quantity=True):
    drop_list = getDropList(stageCode)
    for i in getActivityOpen()[1]:
        drop_list.add((i, getItemTag()['items'][i].get('name', "未知物品:" + i)))
    # drop_list = list(drop_list)
    # return drop_list
    screen = ark.getScreenShot(470, 520, 800, 160)
    drop_reco = []
    for item, name in drop_list:
        try:
            rep, where = ark.gameTemp.matchDifference(
                screen,
                cv2.resize(
                    ark.gameTemp.getTemplate("lootitem\\" + item + ".png")[0],
                    itemReco.STAGE_DROP)[29:29 + 46, 34:34 + 68],
                method=1)
        except cv2.error as cverr:
            logger.warning(
                f"处理掉落物'{name}'失败:(code={cverr.code}){cverr.err} in function '{cverr.func}'"
            )
            continue
        y, x, num = -1, -1, -1
        if rep >= 0.9:
            y, x = int(where[0]), int(where[1])
            x += 26
            y += 63
            if quantity:
                imgraw = Image.fromarray(screen[y:y + 27, x:x + 53])
                numimg = imgops.crop_blackedge2(imgraw, 120)
                if numimg is None or numimg.size < (5, 5):
                    numimg = imgops.clear_background(imgraw, threshold=180)
                # cv2.imshow("d",np.asarray(numimg)); cv2.waitKey(0)
                img = imgops.clear_background(numimg, threshold=120)
                # cv2.imshow("i", np.asarray(img)); cv2.waitKey(0)
                reco = ark.reconizerN.recognize2(img, subset="0123456789万")
                try:
                    num = int(reco[0]) if reco != '' else 0
                except:
                    num = 0
            else:
                num = -1
        err = rep > 0.9 and num <= 0
        if err:
            logger.warning(f"识别到物品\"{name}\"数量出现异常,已置零,该物品将不计入统计中")
        # drop_reco.append([name, rep > 0.9, rep, [x, y], num])
        drop_reco.append({
            "name": name,
            "have": rep > 0.9,
            "_acq": rep,
            "_pos": (x, y),
            "quantity": num,
            "error": err
        })
    return drop_reco
Exemplo n.º 2
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
Exemplo n.º 3
0
 def addItemFromRawDict(self, dumpdict: dict):
     if dumpdict.get('type') in ['FURN', 'CHAR', 'NONE', 'ET_STAGE']:
         logger.warning(
             f"cannot add type:{dumpdict.get('type')} into ItemStack")
         return self
     try:
         return self.addItem(
             getItemTag()['items'].get(dumpdict.get('id'))['name'],
             int(dumpdict.get('count')))
     except:
         logger.warning(
             f"cannot add [T:{dumpdict.get('type')} I:{dumpdict.get('id')}] into ItemStack"
         )
     return self
Exemplo n.º 4
0
def recognizeEndItemsWithTag(ark, stageCode_or_dropList, quantity=True):
    def removeClosePos(gps: list):
        if len(gps) <= 1:
            return gps
        gps.sort()
        final = [gps[0]]
        prev_x = gps[0][0]
        for _x, _y in gps:
            if -7 < prev_x - _x < 7:
                continue
            prev_x = _x
            final.append((
                _x,
                _y,
            ))
        return final

    if isinstance(stageCode_or_dropList, str):
        drop_list = getDropList(stageCode_or_dropList)
    else:
        drop_list = stageCode_or_dropList
    for i in getActivityOpen()[1]:
        drop_list.add((i, getItemTag()['items'][i].get('name', "未知物品:" + i)))
    screen = ark.getScreenShot(470, 520, 800, 160)
    drop_reco = []
    for item, name in drop_list:
        dumped = False
        try:
            gps = ark.gameTemp.matchDifference(
                screen,
                cv2.resize(
                    ark.gameTemp.getTemplate("lootitem\\" + item + ".png")[0],
                    itemReco.STAGE_DROP)[29:29 + 46, 34:34 + 68],
                threshold=0.9)
        except cv2.error as cverr:
            try:
                gps = ark.gameTemp.matchDifference(
                    screen,
                    ark.gameTemp.getTemplate("lootitem\\dumped\\" + item +
                                             ".png")[0][29:29 + 46,
                                                        34:34 + 68],
                    threshold=0.9)
                dumped = True
            except (cv2.error, TypeError):
                logger.warning(
                    f"处理掉落物'{name}<{item}>'失败:(code={cverr.code}){cverr.err} in function '{cverr.func}'"
                )
                continue
        gps = removeClosePos(gps)
        for x, y in gps:
            if dumped:
                y = 28
            # 检测所有位置的掉落信息,分别根据不同位置判断不同掉落属性dropType
            num = -1
            x += 26
            y += 63
            if quantity:
                imgraw = Image.fromarray(screen[y:y + 27, x:x + 53])
                # cv2.imshow('r', np.array(imgraw))
                # cv2.waitKey(0)
                numimg = imgops.crop_blackedge2(imgraw, 150)
                # cv2.imshow('n', np.array(numimg))
                # cv2.waitKey(0)
                if numimg is None or numimg.size < (5, 5):
                    numimg = imgops.clear_background(imgraw, threshold=180)
                img = imgops.clear_background(numimg, threshold=120)
                # cv2.imshow('g', np.array(img))
                # cv2.waitKey(0)
                reco = ark.reconizerN.recognize2(img, subset="0123456789万")
                # print(reco)
                try:
                    num = int(reco[0]) if reco != '' else 0
                except:
                    num = 0
            else:
                num = -1
            err = num <= 0
            if err:
                logger.warning(f"识别到物品\"{name}\"数量出现异常({num}),已置零,该物品将不计入统计中")
            else:
                drop_reco.append({
                    "name": name,
                    "have": True,
                    "_acq": 0.9,
                    "type": recognizeEndItemDropType(screen, x),
                    "_pos": (x, y),
                    "quantity": num,
                    "error": err
                })
    return drop_reco
Exemplo n.º 5
0
class ItemStack(dict):
    __itemType__ = ItemType()
    __roguList__ = getRogueLikeItemNameDict()
    __itemList__ = getItemNameDict()
    __charList__ = getCharNameDict()
    __skinList__ = getSkinNameDict()
    __furnList__ = getFurniItemNameDict()
    __allKnownFields__ = [
        __itemList__, __furnList__, __charList__, __skinList__, __roguList__
    ]
    __itemtag__ = getItemTag()["items"]

    def __init__(self, *val, **kwargs):
        # ItemStack({"扭转醇":1})
        # ItemStack(扭转醇=1,...)
        # ItemStack("扭转醇:1","固源岩:1")
        if len(val) == 0:
            super(ItemStack, self).__init__()
        elif isinstance(val[0], dict):
            super(ItemStack, self).__init__(val[0])
        elif isinstance(val[0], str):
            _MT = {}
            for value in val:
                try:
                    k, v = value.replace('=', ':').split(":")
                    _MT.update({k: float(v)})
                except ValueError:
                    logger.error(
                        f"Unresolved string:{value},expect \'NAME:NUM\' or \'NAME=NUM\'"
                    )
            super(ItemStack, self).__init__(_MT)
        self.addItemFromDict(kwargs)
        self._check_value()

    def raiser(self, other, operation):
        raise TypeError(
            f"'{operation}' not supported between instances of '{self.__class__.__name__}'"
            f" and '{other.__class__.__name__}'")

    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)

    def _direct_add(self, name, quantity):
        self.update({name: self.get(name, 0) + quantity})
        if self.get(name) == 0:
            self.pop(name)
        return self

    def addItems(self, droplist=None):
        if droplist is not None:
            for _ in droplist:
                self.addItem(_["name"], _["quantity"])
        return self

    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

    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

    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

    def addItemFromRawDictList(self, dumplist: list):
        for val in dumplist:
            self.addItemFromRawDict(val)
        return self

    def addItemFromRawDict(self, dumpdict: dict):
        if dumpdict.get('type') in ['FURN', 'CHAR', 'NONE', 'ET_STAGE']:
            logger.warning(
                f"cannot add type:{dumpdict.get('type')} into ItemStack")
            return self
        try:
            return self.addItem(
                getItemTag()['items'].get(dumpdict.get('id'))['name'],
                int(dumpdict.get('count')))
        except:
            logger.warning(
                f"cannot add [T:{dumpdict.get('type')} I:{dumpdict.get('id')}] into ItemStack"
            )
        return self

    def addItemFromDict(self, dictobj):
        for k, v in dictobj.items():
            self.autoAddItem(k, v)
        return self

    def addItemFromCharCost(self, cost):
        self.addItem(self.__itemtag__[cost["id"]]['name'], cost['count'])
        return self

    # def addItemFromDropReco(self,reco_list):

    def addItemFromList_NameQuantity(self, li: list):
        for name, quantity in li:
            self.addItem(name, quantity)
        return self

    def registItem(self, drop_list, value=1):
        if isinstance(drop_list, (list, set)):
            for _id, name in drop_list:
                self.addItem(name, value)
        elif isinstance(drop_list, str):
            self.addItem(drop_list, value)
        return self

    def delItem(self, k):
        if self.get(k, None) is not None:
            return self.pop(k)
        return None

    def __contains__(self, item):
        if isinstance(item, (dict, list)):
            for _ in item:
                if _ not in self:
                    return False
            return True
        if isinstance(item, str):
            if self.get(item, None) is not None:
                return True
            return False

    def formatItems(self, format_='%item%(%quantity%) ', skip_zero=True):
        format_ = format_.replace('%item%',
                                  '{item}').replace('%quantity%', '{quantity}')
        opt_ = ''
        for item, quantity in self.items():
            if quantity == 0 and skip_zero:
                continue
            opt_ += format_.format(item=item, quantity=quantity)
        return opt_

    def format_rich(self):
        _ = []
        for k_name, v_quantity in self.items():
            _.append(f"[yellow1]{k_name}[/]([blue]{v_quantity}[/])")
        return "Items{" + ' '.join(_) + '}'

    def __add__(self, other):
        if isinstance(other, ItemStack):
            that = self.copy()
            for k, v in other.items():
                that.update({k: that.get(k, 0) + v})
            return ItemStack(that)
        elif isinstance(other, DropItemStack):
            that = self.copy()
            for k, v in other.items():
                for name, quantity in v:
                    that.update({name: that.get(name, 0) + quantity})
            return ItemStack(that)
        raise ValueError('other expected a ItemStack-Type')

    def __sub__(self, other):
        if isinstance(other, ItemStack):
            that = self.copy()
            for k, v in other.items():
                if self.get(k, None) is None:
                    continue
                val = self.get(k) - v
                if val > 0:
                    that.setdefault(k, val)
                else:
                    that.pop(k)
            return ItemStack(that)
        raise ValueError('other expected a ItemStack-Type')

    # def __eq__(self, other):
    #     print('__eq__ function is proceeded!')
    #
    # def __ne__(self, other):
    #     print('__nq__ function is proceeded!')

    def __gt__(self, other):
        # self > other called
        if not isinstance(other, (dict, int)):
            self.raiser(other, ">")
        for k, v in self.items():
            if v <= other.get(k, 0):
                return False
        return True

    def __ge__(self, other):
        # self >= other called
        if not isinstance(other, (dict, int)):
            self.raiser(other, ">=")
        for k, v in self.items():
            if v < other.get(k, 0):
                return False
        return True

    def __lt__(self, other):
        # self < other called
        if not isinstance(other, (dict, int)):
            self.raiser(other, "<")
        for k, v in self.items():
            if v >= other.get(k, 0):
                return False
        return True

    def __le__(self, other):
        # self <= other called
        if not isinstance(other, (dict, int)):
            self.raiser(other, "<=")
        for k, v in self.items():
            if v > other.get(k, 0):
                return False
        return True

    def __str__(self):
        if self:
            return super(ItemStack,
                         self).__str__().replace('\'', '').replace(' ', '')
        else:
            return '{无掉落物}'