From 9353ae170719a39ee91ebc79ee9c6360255e5378 Mon Sep 17 00:00:00 2001 From: LmeSzinc Date: Wed, 3 Jun 2020 04:36:05 +0800 Subject: [PATCH 1/3] Optimize: Disable commission_time_limit by default - Faster ui click --- config/template.ini | 2 +- module/base/timer.py | 2 +- module/config/argparser.py | 2 +- module/config/argparser_en.py | 2 +- module/config/config.py | 5 ++++- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/config/template.ini b/config/template.ini index 902af17c0..0d17427cd 100644 --- a/config/template.ini +++ b/config/template.ini @@ -65,7 +65,7 @@ enable_coin_reward = yes enable_mission_reward = yes enable_commission_reward = yes enable_tactical_reward = yes -commission_time_limit = 23:30 +commission_time_limit = 0 duration_shorter_than_2 = 11 duration_longer_than_6 = -11 expire_shorter_than_2 = 11 diff --git a/module/base/timer.py b/module/base/timer.py index ce3b6e2aa..d0a8a4da9 100644 --- a/module/base/timer.py +++ b/module/base/timer.py @@ -91,7 +91,7 @@ class Timer: self.limit = limit self.count = count self._current = 0 - self._reach_count = 0 + self._reach_count = count def start(self): if not self.started(): diff --git a/module/config/argparser.py b/module/config/argparser.py index 433dd3d09..ac85524f0 100644 --- a/module/config/argparser.py +++ b/module/config/argparser.py @@ -229,7 +229,7 @@ def main(ini_name=''): reward_commission = reward_parser.add_argument_group('委托设置', '') reward_commission.add_argument('--启用委托收获', default=default('--启用委托收获'), choices=['是', '否']) - reward_commission.add_argument('--委托时间限制', default=default('--委托时间限制'), help='忽略完成时间超过限制的委托, 格式: 23:30') + reward_commission.add_argument('--委托时间限制', default=default('--委托时间限制'), help='忽略完成时间超过限制的委托, 格式: 23:30, 不需要就填0') priority1 = reward_commission.add_argument_group('委托耗时优先级', '') priority1.add_argument('--委托耗时小于2h', default=default('--委托耗时小于2h'), help='') diff --git a/module/config/argparser_en.py b/module/config/argparser_en.py index bbaa56b13..ad53be009 100644 --- a/module/config/argparser_en.py +++ b/module/config/argparser_en.py @@ -227,7 +227,7 @@ def main(ini_name=''): reward_commission = reward_parser.add_argument_group('Commission settings', '') reward_commission.add_argument('--enable_commission_reward', default=default('--enable_commission_reward'), choices=['yes', 'no']) - reward_commission.add_argument('--commission_time_limit', default=default('--commission_time_limit'), help='Ignore orders whose completion time exceeds the limit, Format: 23:30') + reward_commission.add_argument('--commission_time_limit', default=default('--commission_time_limit'), help='Ignore orders whose completion time exceeds the limit, Format: 23:30. Fill in 0 if it is not needed') priority1 = reward_commission.add_argument_group('Commission priority by time duration', '') priority1.add_argument('--duration_shorter_than_2', default=default('--duration_shorter_than_2'), help='') diff --git a/module/config/config.py b/module/config/config.py index 1a4745407..e4efe1db3 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -462,7 +462,10 @@ class AzurLaneConfig: self.REWARD_INTERVAL = int(option['reward_interval']) for attr in ['enable_reward', 'enable_oil_reward', 'enable_coin_reward', 'enable_mission_reward', 'enable_commission_reward', 'enable_tactical_reward']: self.__setattr__(attr.upper(), to_bool(option[attr])) - self.COMMISSION_TIME_LIMIT = future_time(option['commission_time_limit']) + if not option['commission_time_limit'].isdigit(): + self.COMMISSION_TIME_LIMIT = future_time(option['commission_time_limit']) + else: + self.COMMISSION_TIME_LIMIT = 0 for attr in self.COMMISSION_PRIORITY.keys(): self.COMMISSION_PRIORITY[attr] = int(option[attr]) self.TACTICAL_NIGHT_RANGE = future_time_range(option['tactical_night_range']) From 30e11c6caf363a6727efc07b25131723f7e479cb Mon Sep 17 00:00:00 2001 From: LmeSzinc Date: Wed, 3 Jun 2020 05:06:51 +0800 Subject: [PATCH 2/3] Fix: Re-check all timeout timer - Fix tactical class get stuck when skill level reach to max. --- module/base/timer.py | 3 +++ module/equipment/equipment.py | 5 ----- module/exercise/combat.py | 3 +-- module/handler/info_handler.py | 3 +-- module/handler/login.py | 2 +- module/reward/reward.py | 3 +-- module/reward/tactical_class.py | 15 +++++++++++---- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/module/base/timer.py b/module/base/timer.py index d0a8a4da9..f9fc6f31d 100644 --- a/module/base/timer.py +++ b/module/base/timer.py @@ -96,6 +96,9 @@ class Timer: def start(self): if not self.started(): self._current = time.time() + self._reach_count = 0 + + return self def started(self): return bool(self._current) diff --git a/module/equipment/equipment.py b/module/equipment/equipment.py index 9d2c6b1cb..d23e55158 100644 --- a/module/equipment/equipment.py +++ b/module/equipment/equipment.py @@ -27,11 +27,6 @@ class Equipment(InfoHandler): self.device.screenshot() if SWIPE_CHECK.match(self.device.image): - if swipe_timer.reached(): - import time - from PIL import Image - self.device.image.save(f'{int(time.time() * 1000)}.png') - Image.fromarray(SWIPE_CHECK.image).save(f'{int(time.time() * 1000)}.png') continue if self.appear(check_button, offset=(30, 30)) and not SWIPE_CHECK.match(self.device.image): diff --git a/module/exercise/combat.py b/module/exercise/combat.py index 2c711a137..cf9a38454 100644 --- a/module/exercise/combat.py +++ b/module/exercise/combat.py @@ -32,8 +32,7 @@ class ExerciseCombat(HpDaemon, OpponentChoose, ExerciseEquipment): bool: True if wins. False if quit. """ logger.info('Combat execute') - self.low_hp_confirm_timer = Timer(self.config.LOW_HP_CONFIRM_WAIT, count=2) - self.low_hp_confirm_timer.start() + self.low_hp_confirm_timer = Timer(self.config.LOW_HP_CONFIRM_WAIT, count=2).start() show_hp_timer = Timer(5) success = True end = False diff --git a/module/handler/info_handler.py b/module/handler/info_handler.py index e05a24e22..ba84a3e91 100644 --- a/module/handler/info_handler.py +++ b/module/handler/info_handler.py @@ -110,8 +110,7 @@ class InfoHandler(ModuleBase): def ensure_no_story(self, skip_first_screenshot=True): logger.info('Ensure no story') - story_timer = Timer(5, count=4) - story_timer.start() + story_timer = Timer(5, count=10).start() while 1: if skip_first_screenshot: skip_first_screenshot = False diff --git a/module/handler/login.py b/module/handler/login.py index 077bc3746..3877ce269 100644 --- a/module/handler/login.py +++ b/module/handler/login.py @@ -9,7 +9,7 @@ class LoginHandler(Combat): def handle_app_login(self): logger.hr('App login') - confirm_timer = Timer(1.5, count=4) + confirm_timer = Timer(1.5, count=4).start() while 1: self.device.screenshot() diff --git a/module/reward/reward.py b/module/reward/reward.py index 05b44e4b2..112a3edb6 100644 --- a/module/reward/reward.py +++ b/module/reward/reward.py @@ -52,9 +52,8 @@ class Reward(RewardCommission, RewardTacticalClass): logger.hr('Reward receive') reward = False - exit_timer = Timer(1, count=3) + exit_timer = Timer(1, count=3).start() click_timer = Timer(1) - exit_timer.start() btn = [] if self.config.ENABLE_REWARD: btn.append(REWARD_3) diff --git a/module/reward/tactical_class.py b/module/reward/tactical_class.py index 4f19024ab..17164b74e 100644 --- a/module/reward/tactical_class.py +++ b/module/reward/tactical_class.py @@ -148,8 +148,6 @@ class BookGroup: class RewardTacticalClass(UI, InfoHandler): - tactical_animation_timer = Timer(2, count=3) - def _tactical_animation_running(self): """ Returns: @@ -208,6 +206,8 @@ class RewardTacticalClass(UI, InfoHandler): return False logger.hr('Tactical class receive') + tactical_class_timout = Timer(10, count=10).start() + tactical_animation_timer = Timer(2, count=3).start() while 1: if skip_first_screenshot: skip_first_screenshot = False @@ -215,11 +215,14 @@ class RewardTacticalClass(UI, InfoHandler): self.device.screenshot() if self.appear_then_click(REWARD_2, interval=1): + tactical_class_timout.reset() continue if self.handle_popup_confirm(): + tactical_class_timout.reset() continue if self.handle_urgent_commission(save_get_items=False): # Only one button in the middle, when skill reach max level. + tactical_class_timout.reset() continue if self.appear(TACTICAL_CLASS_CANCEL, offset=(30, 30), interval=2) \ and self.appear(TACTICAL_CLASS_START, offset=(30, 30)): @@ -228,17 +231,21 @@ class RewardTacticalClass(UI, InfoHandler): self._tactical_books_choose() self.device.click(TACTICAL_CLASS_START) self.interval_reset(TACTICAL_CLASS_CANCEL) + tactical_class_timout.reset() continue # End if self.appear(TACTICAL_CHECK, offset=(20, 20)): self.ui_current = page_tactical if not self._tactical_animation_running(): - if self.tactical_animation_timer.reached(): + if tactical_animation_timer.reached(): logger.info('Tactical reward end.') break else: - self.tactical_animation_timer.reset() + tactical_animation_timer.reset() + if tactical_class_timout.reached(): + logger.info('Tactical reward timeout.') + break self.ui_goto(page_reward, skip_first_screenshot=True) return True From 126309bf848de46831bedb18a98973e548ee8ce4 Mon Sep 17 00:00:00 2001 From: LmeSzinc Date: Wed, 3 Jun 2020 12:49:18 +0800 Subject: [PATCH 3/3] Add: dev_tools item statistics and doc - add basic item templates --- dev_tools/item_stastistics.py | 241 ++++++++++++++++++ dev_tools/item_template/主炮部件T1.png | Bin 0 -> 3249 bytes dev_tools/item_template/主炮部件T2.png | Bin 0 -> 3532 bytes dev_tools/item_template/主炮部件T3.png | Bin 0 -> 3491 bytes dev_tools/item_template/物资.png | Bin 0 -> 2665 bytes dev_tools/item_template/科技箱T1.png | Bin 0 -> 3769 bytes dev_tools/item_template/科技箱T2.png | Bin 0 -> 3648 bytes dev_tools/item_template/科技箱T3.png | Bin 0 -> 3656 bytes dev_tools/item_template/科技箱T4.png | Bin 0 -> 3783 bytes dev_tools/item_template/舰载机部件T1.png | Bin 0 -> 3091 bytes dev_tools/item_template/舰载机部件T2.png | Bin 0 -> 3321 bytes dev_tools/item_template/舰载机部件T3.png | Bin 0 -> 3259 bytes dev_tools/item_template/通用部件T1.png | Bin 0 -> 3364 bytes dev_tools/item_template/通用部件T2.png | Bin 0 -> 3620 bytes dev_tools/item_template/通用部件T3.png | Bin 0 -> 3605 bytes dev_tools/item_template/防空炮部件T1.png | Bin 0 -> 3229 bytes dev_tools/item_template/防空炮部件T2.png | Bin 0 -> 3507 bytes dev_tools/item_template/防空炮部件T3.png | Bin 0 -> 3445 bytes dev_tools/item_template/鱼雷部件T1.png | Bin 0 -> 3324 bytes dev_tools/item_template/鱼雷部件T2.png | Bin 0 -> 3430 bytes dev_tools/item_template/鱼雷部件T3.png | Bin 0 -> 3557 bytes doc/item_statistics_en.md | 141 ++++++++++ 22 files changed, 382 insertions(+) create mode 100644 dev_tools/item_stastistics.py create mode 100644 dev_tools/item_template/主炮部件T1.png create mode 100644 dev_tools/item_template/主炮部件T2.png create mode 100644 dev_tools/item_template/主炮部件T3.png create mode 100644 dev_tools/item_template/物资.png create mode 100644 dev_tools/item_template/科技箱T1.png create mode 100644 dev_tools/item_template/科技箱T2.png create mode 100644 dev_tools/item_template/科技箱T3.png create mode 100644 dev_tools/item_template/科技箱T4.png create mode 100644 dev_tools/item_template/舰载机部件T1.png create mode 100644 dev_tools/item_template/舰载机部件T2.png create mode 100644 dev_tools/item_template/舰载机部件T3.png create mode 100644 dev_tools/item_template/通用部件T1.png create mode 100644 dev_tools/item_template/通用部件T2.png create mode 100644 dev_tools/item_template/通用部件T3.png create mode 100644 dev_tools/item_template/防空炮部件T1.png create mode 100644 dev_tools/item_template/防空炮部件T2.png create mode 100644 dev_tools/item_template/防空炮部件T3.png create mode 100644 dev_tools/item_template/鱼雷部件T1.png create mode 100644 dev_tools/item_template/鱼雷部件T2.png create mode 100644 dev_tools/item_template/鱼雷部件T3.png create mode 100644 doc/item_statistics_en.md diff --git a/dev_tools/item_stastistics.py b/dev_tools/item_stastistics.py new file mode 100644 index 000000000..55523271e --- /dev/null +++ b/dev_tools/item_stastistics.py @@ -0,0 +1,241 @@ +import os + +# os.chdir('../') +import module.config.server as server + +server.server = 'cn' # Don't need to edit, it's used to avoid error. +print(os.getcwd()) + +import numpy as np +from PIL import Image +import cv2 +import time +from module.combat.assets import GET_ITEMS_1, GET_ITEMS_2 +from module.handler.assets import INFO_BAR_1 +from module.base.button import ButtonGrid, Button +from module.base.ocr import Ocr +from module.logger import logger + + +""" +Set your folder here +Examples: xxx/campaign_7_2 +""" +IMAGE_FOLDER = '' +STATUS_ITEMS_INTERVAL = 10 +TEMPLATE_THRESHOLD = 0.9 + +BATTLE_STATUS_FOLDER = f'{IMAGE_FOLDER}/status' +GET_ITEMS_FOLDER = f'{IMAGE_FOLDER}/get_items' +TEMPLATE_FOLDER = f'{IMAGE_FOLDER}/item_template' +for f_ in [TEMPLATE_FOLDER]: + if not os.path.exists(f_): + os.mkdir(f_) +BATTLE_STATUS_TIMESTAMP = np.array([int(f.split('.')[0]) for f in os.listdir(BATTLE_STATUS_FOLDER)]) +ITEM_GRIDS_1_ODD = ButtonGrid(origin=(336, 298), delta=(128, 0), button_shape=(96, 96), grid_shape=(5, 1)) +ITEM_GRIDS_1_EVEN = ButtonGrid(origin=(400, 298), delta=(128, 0), button_shape=(96, 96), grid_shape=(4, 1)) +ITEM_GRIDS_2 = ButtonGrid(origin=(336, 227), delta=(128, 142), button_shape=(96, 96), grid_shape=(5, 2)) +ENEMY_GENRE_BUTTON = Button(area=(782, 285, 961, 319), color=(), button=(), name='ENEMY_GENRE') + + +class AmountOcr(Ocr): + def ocr(self, image): + start_time = time.time() + + image_list = [self.pre_process(i) for i in image] + result_list = self.cnocr.ocr_for_single_lines(image_list) + result_list = [self.after_process(result) for result in result_list] + + if len(self.buttons) == 1: + result_list = result_list[0] + logger.attr(name='%s %ss' % (self.name, str(round(time.time() - start_time, 3)).ljust(5, '0')), + text=str(result_list)) + + return result_list + + def after_process(self, raw): + """ + Returns: + int: + """ + raw = super().after_process(raw) + if not raw: + result = 0 + else: + result = int(raw) + + return result + + +AMOUNT_OCR = AmountOcr([], back=(-200, -200, -200), lang='digit', name='Amount_ocr') +ENEMY_GENRE_OCR = Ocr(ENEMY_GENRE_BUTTON, lang='cnocr', use_binary=False, back=(127, 127, 127)) + + +class ImageError(Exception): + pass + + +class ItemTemplate: + def __init__(self, image): + self.image = np.array(image) + + def match(self, image): + res = cv2.matchTemplate(self.image, np.array(image), cv2.TM_CCOEFF_NORMED) + _, similarity, _, _ = cv2.minMaxLoc(res) + return similarity > TEMPLATE_THRESHOLD + + def save(self, name): + image = Image.fromarray(self.image) + image.save(f'{TEMPLATE_FOLDER}/{name}.png') + + +class ItemTemplateGroup: + def __init__(self): + self.templates = {} + for file in os.listdir(TEMPLATE_FOLDER): + name = file[:-4] + image = Image.open(f'{TEMPLATE_FOLDER}/{file}').convert('RGB') + self.templates[name] = ItemTemplate(image) + + def match(self, item): + for name, template in self.templates.items(): + if template.match(item.image): + return name + + template = ItemTemplate(item.get_template()) + name = [int(n) for n in self.templates.keys() if n.isdigit()] + if len(name): + name = str(max(name) + 1) + else: + name = str(len(self.templates.keys()) + 1) + + logger.info(f'New item template: {name}') + self.templates[name] = template + template.save(name) + return name + + +template_group = ItemTemplateGroup() + + +class Item: + def __init__(self, image): + self.image = image + self.is_valid = np.mean(np.array(image.convert('L')) > 127) > 0.1 + self.name = 'Default_item' + self.amount = 1 + if self.is_valid: + self.name = template_group.match(self) + if not self.name.startswith('_') and '_' in self.name: + self.name = '_'.join(self.name.split('_')[:-1]) + + def __str__(self): + return f'{self.name}_x{self.amount}' + + @property + def has_amount(self): + return 'T' in self.name or self.name == '物资' + + def get_template(self): + # return self.image.crop((5, 5, 90, 68)) + return self.image.crop((40, 21, 89, 70)) + + def get_amount(self): + return self.image.crop((60, 75, 91, 88)) + + +class Items: + def __init__(self, timestamp): + self.timestamp = timestamp + self.get_items = Image.open(f'{GET_ITEMS_FOLDER}/{timestamp}.png').convert('RGB') + + # Enemy genre + interval = np.abs(BATTLE_STATUS_TIMESTAMP - timestamp) + if np.min(interval) > STATUS_ITEMS_INTERVAL * 1000: + raise ImageError(f'Timestamp: {timestamp}, battle_status image not found.') + self.status_timestamp = BATTLE_STATUS_TIMESTAMP[np.argmin(interval)] + self.enemy = 'Default_enemy' + + # get_item image properties + if INFO_BAR_1.appear_on(self.get_items): + raise ImageError(f'Timestamp: {timestamp}, Info bar') + if GET_ITEMS_1.appear_on(self.get_items): + self.row = 1 + self.is_odd = self.get_is_odd(self.get_items) + self.grids = ITEM_GRIDS_1_ODD if self.is_odd else ITEM_GRIDS_1_EVEN + elif GET_ITEMS_2.appear_on(self.get_items): + self.row = 2 + self.is_odd = True + self.grids = ITEM_GRIDS_2 + else: + raise ImageError(f'Timestamp: {timestamp}, Image is not a get_items image.') + + # Crop items + self.items = [] + for button in self.grids.buttons(): + item = Item(self.get_items.crop(button.area)) + if item.is_valid: + self.items.append(item) + + @staticmethod + def get_is_odd(image): + image = image.crop((628, 294, 651, 396)) + return np.mean(np.array(image.convert('L')) > 127) > 0.1 + + def predict(self): + self.battle_status = Image.open(f'{BATTLE_STATUS_FOLDER}/{self.status_timestamp}.png').convert('RGB') + self.enemy = ENEMY_GENRE_OCR.ocr(self.battle_status) + enemy = self.enemy + # Delete wrong OCR result + for letter in '-一个―~(': + enemy = enemy.replace(letter, '') + self.enemy = enemy + + amount_items = [item for item in self.items if item.has_amount] + amount = AMOUNT_OCR.ocr([item.get_amount() for item in amount_items]) + for a, i in zip(amount, amount_items): + i.amount = a + + def get_data(self): + return [[self.timestamp, self.status_timestamp, self.enemy, item.name, item.amount] for item in self.items] + + +""" +These code is for testing +Set your image name here +Examples: 159022xxxxxxx (int) +""" +# ts = 1590227624035 +# items = Items(ts) +# for item in items.items: +# print(item.amount, item.name) + +""" +These code is for template extracting +""" +# from tqdm import tqdm +# for ts in tqdm([int(f.split('.')[0]) for f in os.listdir(GET_ITEMS_FOLDER)]): +# try: +# items = Items(ts) +# except Exception: +# logger.warning(f'Error image: {ts}') +# continue + +""" +These code is for final statistic +Set your csv file name here +Examples: c64.csv +""" +# csv_file = 'c64.csv' +# import csv +# from tqdm import tqdm +# with open(csv_file, 'a', newline='') as file: +# writer = csv.writer(file) +# for ts in tqdm([int(f.split('.')[0]) for f in os.listdir(GET_ITEMS_FOLDER)]): +# try: +# items = Items(ts) +# items.predict() +# writer.writerows(items.get_data()) +# except Exception: +# logger.warning(f'Error image: {ts}') +# continue diff --git a/dev_tools/item_template/主炮部件T1.png b/dev_tools/item_template/主炮部件T1.png new file mode 100644 index 0000000000000000000000000000000000000000..4f8e706d6cc8b81998e1325d30be79b54b74559a GIT binary patch literal 3249 zcmV;i3{LZjP)bZ zkgT!~i)2`{+6NOY#4vu?%Z$NcI-sC7*iZ%wdccA%a6=tXKir4v>6ww_y}4{5#Hgpb z&Ue1^vyLtl?{WYP06>N567zq~ZV*6a0RS=xg7J8~{mu5y?oJqn-CNyy!B{j z2mmu%Ykl88D{BFQ+&%(GG(U9y(PHvYNC397x~1x#rG#B1@V4?YE;Uu%bBPBsy$`jrOm zgz}l63J?>XNX%0*Z#!zfs?PWvq^+zeO>{Zx-0G~Ztqxxd^E|I#qzMg^w`SqaicDKS*bJ|$jo9hawJ zS@%#1DTN%5$I4UP+ui%?_nBF1-RM2F%Y;0~R)cctbAlXCrzioP6@R|V%TpMQF<}t4 zZ?rq@&fvwMC<;^{qNyW`DWKYjM9kd8ru)5cTBN99%{%^wV9l+fEC6(GcayaQ6^74; z&YhWSnrF$FCJUMdsoU1rZt6M^#B<^sv${x}S=F4^OCj@d4uQ_C&gSnnM+c)k&uhn; zVd$)GjVHN>^IA`=?${=P&&}q|&e?dJd@#nuS7N@y{b&8baG*TpU-X;gbpGozN)pk+ zna49y&$8mw5_OO|U!nONn;+$-G)k$B&o+oCd!5b3`Aj7^D-ICgip3PWvwcHM1pquB z%p?dPu9!>C$GLv1l~Qt1swL$szvh^zIL@QX5hrn{-Pw7x6J3s?C~8ia^>OD(O)hYr zCuT*?rxQk<)B!;xz!maw&LyV@seY}C_XU>>peT#`zrNr5sAr5p#Sq|D_*?xWqEZ+8Yi4raYllI%b2*TFT3 zGW|vah%QIn+g)SK;lUwhYu_aF&PF1M)9HBv3jkn@DUS0jOO46%u_@kLCy$88qu!0) z?xS7hDK1$Bic3~XS+)(?*-IT=iFzOPQk@Q-4x9x~!E&d$6xBRDFWXemZ?x8WJRTQi zVT^GP<)U;S7@Vdl5hZKMU^v+Pe6zLI%3f!&7tbD(zst#^=yDXr(dfl!_B}t3GB65L)bCV0@prb?*03sO=Jk8)zVGX|y8pCa zm}2wu%_xevGys@Uye|N>l2*aR_FuNQzuvxo?|zabr#x7av~`DACx{E*efu2*l&8Yw zFwb-62h9#hd+3PI67Oy{8kCvnU)4nmrR@Omr zJUKw_$pR5+t>de4@1tJ0JfXcpL#azGwca(6QeviIZPaDE_2pJ_J!u*NEY{UmztX7C zN?OT{#Il{UU}MJ#dE((8ABJJ5U+eV;>+N5*lk15wM!(TTQJ7;h?e+!8BQ6bziK$MA zFmW*fE;)*$R?^B|X0BEOECCB54*>c<_B-v)#&0&vu^GG=gqOnBTFd!R!z50}HuPc|*vhUS{lMGF8P zamo6Pj<3bNdp&)m`_KB(a^x#tl58rpWy=*WNRI%R(xm@RA)t@+;Kd+4NWc63yTNb( z0kxzYRl%jGZlrKJ*M=(m{g=PbvTX1Bz0*!M@n!PJ7{euZZ+Cllddxf+4rUK=HGr8H zEW=i_eF$Y)Hu!Pim`u~uSrCBl`?C%t7wi38^2Yi`KF;@_?vGxK^0zr=FHCS@Apuxx z^&3rsT1hKOlJp=we0AtHG=NCZLenU=f7LFI3-U;LDj(ksZ zHa^){U0dDwY-2TE<%*?{{zc!NG&&gVKiMzd7p64k*bIlmQ+FdS`R+$|*YBcAfUo19XWsWm0$OYCEF9*yVu+M zelN>1^4y>STVHIQpMGH>U@hAd04UxSTyeY-Z+^BJUJQrNhpzi@Ixk2mYqzaHL_3dm z^jm!@8M-!kFdQ@lM3DhO;Tm8g|%RYQwBix zpA5iiyqerdwANZ{O!^jKPb?AH((0qSVX6&OIqe_?xMZ%_U-Dg2ZY3?H)NnY|ueEC# z!sT%N-n#T;`k%CZcTOcK0efP}BW5!GK;Up_t)>|NBQVr6fTFsQot1pxhR#V z3RAeE<9q&W#Wuzm80D$W&w5eR(QkG7uk;Vk{s5r0)*_;!C_3#sGT@S@(8#1K-+lgy;hR=t)k5kLmnXgWs%1@G{m9#+6Zw~DViIk7r6k0Ys$D}CXTPfcR#)xuf!y1=h4pY<6Ts6 z13w~Co?5-S+Wu9$m9)6z(ZNU`X;kbh6$Fu#(poDQVNd2S&;qDvI+>ZY(d}F9AP9!f zhx%*F#_U>hE6x z@I9X^wxz|)lAd%<$IR~TTbKQbjVAMAYW7EA03q%B>9#r(x=VHiW{#q${mXXtGTYhR z=|Ag-VHmH(zVFvlp(bSOTgvQALco@`Fa~uv|5jeXj)sUNh%ivFe=1X zZjEI{O9 zkP$6M@wJ%CdgS5&Ig>eY%p3;chbLT<RcfV!Wo`^Li+~Rbnkz`oIrk@o6-b9AQyo}*}B(e`)ehj#{jcsO$$1 z{&}k~MW@|OuDAD|?CpHBV@eaR#PQX5R@-nXoNJWbd|aNHD*yZ?g)B_5y4Ff=B>iXo z?Z0hjSr!CA6h*%BeXqW*oC4(9o`ush=h;M zt)r_^=Vqq{F=Mjne`W-^T)5zN)I|M!e;1G>i?WDU;_j`kKGHk8J87E6YjN*R&sV;y jo9@Dh$vt9jcF6p{j)*6BiSKV<00000NkvXXu0mjfpG8`| literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/主炮部件T2.png b/dev_tools/item_template/主炮部件T2.png new file mode 100644 index 0000000000000000000000000000000000000000..a5571782aef9ca51e13398d55bbb8e67bb97b551 GIT binary patch literal 3532 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 R2Oa literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/物资.png b/dev_tools/item_template/物资.png new file mode 100644 index 0000000000000000000000000000000000000000..2c3caa4ed0f4e2490da760259ed36e60c492dd4f GIT binary patch literal 2665 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 literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/科技箱T2.png b/dev_tools/item_template/科技箱T2.png new file mode 100644 index 0000000000000000000000000000000000000000..e681c1ff925621fc92a06125bf95d36cdfc5ae78 GIT binary patch literal 3648 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 Smfn5<0000C?4i0_Ki23C8whog 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 literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/舰载机部件T1.png b/dev_tools/item_template/舰载机部件T1.png new file mode 100644 index 0000000000000000000000000000000000000000..164c7cd84719d7d1af0e9b1f449e5ceacd354767 GIT binary patch literal 3091 zcmV+u4D9oXP)=+?-8d#WKrA_4};5CDkC z7!w4+>A8CT13+Zxdb{7IlXaKr%wRoAt#ufNyZ3hYzTHzw6-9yA8l<{GhGYr*2moY> zECE0e1Z3&-;(NfLeYuYTz<@Dej5YqIO_+aTIO9cG5YgbuAi11GQ8b-RiKrgLA@G0@ z!9uh08hRTLYh$WbPvFPmmUGJiH~{eO)q%%AmkNO5OYzRvI{+|$KX*7fb0dQF6V-72 zylqk}00V|lp;&1Qzyb%T7;1xQSmOZ3g4Q~@oDfl(rjv9M^n*Bx8z|6N$H84823l$Z zfF1xMv^ur=H54*_TDEPBMOjcu@r8Ie9EvZ*@#|wh!HQihG~~73HpT@2fF1!6P&GF- z_&f;1S=U_PRd1}Li*w+d1zKy-7o*#wJGbsoK~l=vSdCpA0z}VNg|g8cLjdS?DMDa? zfX!HN3eak6?5MSl!f0@95XbTK<+LaYuz-k-kXZxBYYx%*1hhP~2drYIWwOTPr%YC8 z`P1W{X0K+aVHITo0NY#J+gsaUVfM?+$(e}iVQVs)V1bR3x^BIOn=S(9I0%T1sz5H} z_}NrvdOn+Ton^k)b2@qA)d~r_4?{~!I7(lBBEd|*uB5YIhSvx*Hc^Xa7q=`L$cJvl~}+K7$S77 z$$+evOK>)Db7Uu(%9XLk^)UbjjH5&?Rk#)=Ns?Sk(vwuam-RR+a_(^9f|+%3{1YZ~ zg!yl%q^D1wPM%MwB=gbK15J;n(OP86#`WAjO(kiq2UiBWcXy*GnmiwCtpQfu-buUj z5YcJ8whsE3(Ne`bu~XE{I1gCK~a zC`po{EE>;(YS9ejLK0CN$D^&0d?)3JY~yzQgMQF>qRR{9iFBkzUqoU}L}4WQ!gbP1 zE#JxPBrBE$_9J9SRwIL*ySq^sxh2-oSuGU;f+ez!Cji9aLy`WP4sQ;LNagA{J&vL% zJQsomj@($|emz9@kc^Wzf(50Nd@oZ-!!Qia21QZmQmchRL`0;L$P!tzz4cXmF?N4C z=q^ThYj!h69`HgHav_Ib4xj$(sXUR#>G5{B?Ex_l$lW+Vz@S&hJvX=LW1i>PNtQ2j zDk%_wdn@_^07kb)$(2Ee|4+6$1pq)qc_OK#-MhORgN-apvn+Lh>h3i@j@;|178f$4 z3S1QwjJwgL9$Xs?Z;o7~Y0{f2W&*2nR145LaqzR8EXj8=xsvRBvy)s+CNIW%nHy_r zWDQT&aK?L+7n8#$hXCLb_&OG}a~L8*#LXLn6{n>|D^olRW?aT;<{7;DH<&)F3i@IF^dH94Bdx3b9(9efwD5LK=Y9v?VU z0svTJd{R)U-hM{@jB}1!Yp^i7J=*(rPis9rnzp+bGGKv-I&qvM2McMMPF_sZQq|iy z_gfjEK&|z`KMsfp`v{B!0a&U91l@43LYOf|zRQr|#$aPG7^JUKw+{kq03pL3XPh$* z*7yqm0Mt^=j%L~Gtd8BBaW^aWflAtcv=0_UUyvoT-MK#r$gTMdC|$^f99$plezTh- zN%kglXnb+Dqep{A1ZA2fC@JoI z{nh%T{{G>%|6j5X8Qboc(Qd@G53l%f_s0{|bZU~9oe1g&-UCQGg)ckbR%xjKGz z9G#ECwU8{aov(MI^O4K>YoiJwMq8uN?a}1LMD%fcYXl7UAMUG#Ds&-V$oOKMTuK}) z4m^96>7@=tpcc|wttwE#$5X1Z{uC;u4Az3-_2K;X{D&WZP)douKtx8CvMe)XIPxYX zEkX2gdNctrWI-vV@xaGAE(D)K?vbyW#9rqM#uX84hP)M?Q08007Zi^Lq;#Plrp{;3n9{9)BV5iYpvr8 zaeO`&eNk6hYd`?d^Eo8LiZ5(cr%#osyAA7Yq`q2>GtQCAg$&Py$S`}89sKh^zLl;B z>rLj4=W9WIf&~E9h__wNZkLYR7@*bRH=8?m6uQ{Fu{pds96vk!`EUDLtK{-Vaw%!M zcC;2zH;eBNU_CFzhyIF96HU=BRFNf)`>Hg#WG@S?$#Bt2~Jm?3!&%Mdo zbsvVUSkO#^EkIPg`iuono%L$U4Vma%6rYP{|DGKj9?WLx;Ob~J+zi$t|Dp9J^Zzwl6cI}Xe{tJ-Iiv`&sI_!WCT9bn%Vu%dy5Rp?%E_u1-7hCKWrUxsP5^W-OVAzu=LD! z*Zv$oBmrn8T0sLE)PP=NQlN@xs=?+G z_S6x0{Fjf?G?n+Zd^v%Fu5WGw(h4A`YV!*0QnNi7w4w&KYQutPxcU$^EM4K)c$n*z zDHJD`NwR-`KTT6vOx(ML5AXm0FAbo`6BMCpS16)l0UFIpwrT=c8xlYe1gf4lx{Pb8 zB+k{q3rH!0dk@h~C7^uz9ahU|;4)8fg;f|(tLU%BAvLDx9c+&He7%UuxFQt+Qlb7E z4KusdD^3b)Eft+DmM?zvE7@R(0H6aPKp+$=GzvgXAu2Czv9sxpR@^k;TGuhQSo;@1 zFHN8@c{VAX6A=JqJ`rdA+8wImJNi_|fK%`y5t-hkWUE3GErA4^sA`Rhur)*l0!G0o zNqd~WE0*u3DM1pTI4OSk7Qw}NbZe?6{1tTE?3Y-meAfXw4Ry`#Y^`#0QbBNli@zjY z=C5;qE>K`sGxB#*xEJFXkqFUiq5-eq>j`6|dXdIT074z(1h|2WT=R#9Hmy)PH+eB$ zEaq930Z0srQ&+qzoJd5&u10_av9pPs=FyT5qPwlV8=a^%6!eY62Q=ZO^j4dR3Ry)G ztIfFPNx_~Kc|I*q3;S+?mDODor!sk-_dgj@d7#uC0wjrG#990N$cy+O;N@Ke=nB?_ z*O9Z1hSt8x1+5rjr-^r}7F&S*r6^s=E(KV;&PkfCLGYT~|LPkF@D~CIsYy*m$>;9n zRClRWoraW#(q3r*xPbSq@bDhzUc+w@mEnyT>VO@oa#ahKTvQYqW9BcXMkf-)Y$tEu zS7K_AAo9LQ z4WR&I7WuqC*mZ#J5Qx4?0E)Br>49IB)y(ZA8QB4JNBau!I>uWO)4-|-BLES3`_p9c z=16?Go{Nf$S99J-Ad;HIuY}a2y^(!ybqBgrl~Dk4Ja<1Y5Io=;Tb=5oI~5$?f!Eq= zUGuc&Qh}Es#;+G5=Uzf|O_ieNc|Q5CAJd*8nV3WZ9(?r(N?U8o^HQXY3PPMKUmSXo zrYLlP3*cgdu(dZom@fXOEdqRqbVAl72LNJEip64Dt-H>@2q?v++r9nIzpyL1RhfO1 z*^?rFIWYu)!o70}%04 zlpww?rKNM@r$0XUtKSp_^5bH(yED8yWS0QaE)4Mxz|oV!&c>#{lYBD71puNWmn^R< zn6f8JlDt7EY5*$6zecEFN$HBy!k!fI5h^V}FHPhE2qNMI7z}n0;8p_Q;9n1@$!-$w zAMOs)Ue@pLEM^n??0~njv(d!zjILM-gF z19NYrb$Uszw8s_{wK7@}3Zy0zz}vI379PH??S#VDzkaxM&c1i7g$i1+iR;&{i_=0x zMth^IzauLte*aJ2mzM#BCIM|tUrwVw(b0?olqNNl2R&3J<;runvpaxdablrZ*;eq7 zH4)9{n&W&m5Gw=KQ3vT;}$dDIm}Qgi1Ehpgy3*mB1r-2_C^$M6SGj zZwG^6@57z+W>zjH<%>z>GS%|>dAS8ZL?nm=kyUx{?+5e6tZj*?q&F4anJa#pz{}Om za<#Z#{;$%@Q%f>tRB^62`qrP=DxrILh(D3C(FL`2t+@DUK7KZKuB6h8ArAl)0AwjL z|7j|&q^eyMqIwlT`zM2vjm~R+IONL3Q%I5^DFp3fh0*JY??1}3Drq! zeZn_J=g0H>c-HS{j1e8vXUl!@)LLEFt`w1cvFHzWcK7zp?M#mI;arK8jkNVY$*2cM=GONja%0zutf zLEXMummLX$0JCj|gPrMYIzBpp*!0)GF&_?~phkQ9W;>C9*-IN4iTi8ttDT*}aK4zj zV6smKT5dH|a^VpmXK-aXyf-S2 z^L%zFFAnkX00L!27sn;86bA=0p1nmNy4pFnEK8BH|4D!U{ukrfymT%<_Sr2^6F~oV zzt>CO9#5OHdTj~~K#Bi2+qW7ScmDnnGTC&lAO`~6$|?%xh&`4)iwupjSP z*9gI;5?T*kCt}j%uk+~HrIdIN069P+JGJ#$e&Z0Q6@1eO1p@?tf}EFMe>occ*3uqk{m!i`7}`9?JzRZ_y``(VO+@nC$_fBki?H<}tlj8|ze`#6`*%k7 zb|-&aeEa0ko-8HJl6#Lt86OD7#^>77b=@GSO5rqE)dsA{ZgFBsq-jzeH5C{j3J7%% zxDv-=5Mnr%CQUFxwdvwMzU7T0!Be47wK9wQ#Q+%ahV| zeR?x7#z>HgEkJ;@%dhW`mP;8wn=IbE#SN2uHZr#o4Z;8`(c7%s)$5RKw>#HE)lpT~ z;JT|^KeFB&s!{=7L<(yX$v*4}gb=Jmi{HQh&_j-XIGj8k14ur5XgR}sjfT=o{ zS7Q81Cv$_X4MEaEQ!lB$AQW9$=EnsBs08y-D98vo${BtG2f z-F*N>-PLfwcHR9B06NzzLpM3+>t^GyUo16D|?dh67%f}jbDb%?Bq++;Mc1%*H(PD+%_V@ZvAoqf&h}Rz&0V++UV!iHS+&CHk=+6U)oC_{Q16J z7PHx5aWY{x$nJlmw=-@Vak9?!aU)YxL?i`QfWrR*iZY((n&~C{00000NkvXXu0mjf DJGMa- literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/舰载机部件T3.png b/dev_tools/item_template/舰载机部件T3.png new file mode 100644 index 0000000000000000000000000000000000000000..c7289f3d78506dff74c3d040fd9440ebaf89ed57 GIT binary patch literal 3259 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 literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/通用部件T1.png b/dev_tools/item_template/通用部件T1.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaffa6fe614636e9f8b300d3e78ddd60bd3d5c9 GIT binary patch literal 3364 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 literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/通用部件T3.png b/dev_tools/item_template/通用部件T3.png new file mode 100644 index 0000000000000000000000000000000000000000..d06813f3dbd2fa35071e28b99e0ce3a70a0a1805 GIT binary patch literal 3605 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 b6qfj33Q*qL!{W)<00000NkvXXu0mjfZtCHE literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/防空炮部件T1.png b/dev_tools/item_template/防空炮部件T1.png new file mode 100644 index 0000000000000000000000000000000000000000..4ac5ca9a779da0356ee2f9872b2449956b3389da GIT binary patch literal 3229 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 P00000NkvXXu0mjfZUScr literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/防空炮部件T2.png b/dev_tools/item_template/防空炮部件T2.png new file mode 100644 index 0000000000000000000000000000000000000000..a26ecd6c9d4572cd525f9a239cc874d93b1ba183 GIT binary patch literal 3507 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 literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/防空炮部件T3.png b/dev_tools/item_template/防空炮部件T3.png new file mode 100644 index 0000000000000000000000000000000000000000..06590e0f6e14912e07466692fe946ce4674776c4 GIT binary patch literal 3445 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 XbysuQRRoVo00000NkvXXu0mjfJi&kT literal 0 HcmV?d00001 diff --git a/dev_tools/item_template/鱼雷部件T1.png b/dev_tools/item_template/鱼雷部件T1.png new file mode 100644 index 0000000000000000000000000000000000000000..6fbc6be7ea3c5a016756ccb7ddcb131d84b7ead3 GIT binary patch literal 3324 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 + campaign_7_2 + get_items + 158323xxxxxxx.png + 158323xxxxxxx.png + 158323xxxxxxx.png + get_mission + get_ship + mystery + status + campaign_10_4_HARD + get_items + get_mission + get_ship + status + d3 + get_items + get_mission + get_ship + status +``` + +Screenshot are named after millesecond timestamp. + +## Prepare a new environment + +- Prepare another virtual environment, accoring to `requirements.txt`. But use the GPU version of `mxnet`. + + I am using GTX1080Ti, and I installed `mxnet-cu80==1.4.1`, `CUDA8.0`, `cuDNN`. Google `mxnet gpu install`, and see how to do in details. You may intall other version of CUDA, and mxnet for that CUDA, because you are using another graphic card. + +- Look for the cnocr in your virtual environment. Replace site-packages\cnocr\cn_ocr.py line 89 + +``` +mod = mx.mod.Module(symbol=sym, context=mx.cpu(), data_names=data_names, label_names=None) +``` + +​ to be: + +``` +mod = mx.mod.Module(symbol=sym, context=mx.gpu(), data_names=data_names, label_names=None) +``` + +​ Now cnocr will run on GPU. + +​ You can skip these anyway, and use the same environment as alas, but the OCR will run really slow. + +- Install tqdm, a package to show progressbar. + +``` +pip install tqdm +``` + +## Extract item_template + +Copy folder `dev_tools\item_template` to the map folder such as `\campaign_7_2`. + +Change the folder in line 24 + +These template are named in chinese, rename them in English. + +>**How to a name template image** +> +>You should use their full name, such as "138.6mm单装炮Mle1929T3", instead of short name or nickname, such as "DD_gun". +> +>If you have same item with different image, use names like `torpedo_part.png`, `torpedo_part_2.png`, they will a classified as torpedo_part + +Uncomment the part for item extract in dev_tools/item_statistics.py, and run, you will have some new item templates. Here's an example log: + +``` + 1%| | 107/12668 [00:05<10:24, 20.10it/s]2020-06-03 10:39:42.609 | INFO | New item template: 50 + 1%| | 158/12668 [00:07<10:42, 19.47it/s]2020-06-03 10:39:45.098 | INFO | New item template: 51 + 2%|▏ | 207/12668 [00:10<10:33, 19.66it/s]2020-06-03 10:39:47.772 | INFO | New item template: 52 + 2%|▏ | 215/12668 [00:10<11:20, 18.29it/s]2020-06-03 10:39:48.304 | INFO | New item template: 53 +100%|██████████| 12668/12668 [10:33<00:00, 19.99it/s] +``` + +Rename those new templates. + +If you find some items haven't been extracted, try use line 140, instead of 141. + +## Final statistic + +Uncomment the part for final statistic, configure the csv file you wang to save. + +The ocr model may not works fine in EN. + +Here's an example log: + +``` +2020-06-03 12:23:55.355 | INFO | [ENEMY_GENRE 0.007s] 中型侦查舰队 +2020-06-03 12:23:55.363 | INFO | [Amount_ocr 0.009s] [1, 1, 22] +100%|█████████▉| 14916/14919 [20:32<00:00, 13.20it/s]2020-06-03 12:23:55.442 | INFO | [ENEMY_GENRE 0.007s] 大型航空舰队 +2020-06-03 12:23:55.455 | INFO | [Amount_ocr 0.013s] [1, 1, 1, 17] +2020-06-03 12:23:55.539 | INFO | [ENEMY_GENRE 0.007s] 敌方旗舰 +2020-06-03 12:23:55.549 | INFO | [Amount_ocr 0.010s] [1, 2, 1, 63] +100%|█████████▉| 14918/14919 [20:33<00:00, 12.35it/s]2020-06-03 12:23:55.623 | INFO | [ENEMY_GENRE 0.007s] 精英舰队 +2020-06-03 12:23:55.633 | INFO | [Amount_ocr 0.010s] [1, 1, 1, 17] +100%|██████████| 14919/14919 [20:33<00:00, 12.10it/s] +``` + +Now you got a csv file, formated to be: + +``` +, , , , +``` + +like this: + +``` +1590271317900,1590271315841,中型主力舰队,主炮部件T3,1 +1590271317900,1590271315841,中型主力舰队,物资,23 +1590271359374,1590271357251,小型侦查舰队,通用部件T1,1 +1590271359374,1590271357251,小型侦查舰队,鱼雷部件T2,1 +1590271359374,1590271357251,小型侦查舰队,物资,13 +1590271415308,1590271413207,敌方旗舰,彗星,1 +1590271415308,1590271413207,敌方旗舰,通用部件T3,1 +1590271415308,1590271413207,敌方旗舰,科技箱T1,1 +1590271415308,1590271413207,敌方旗舰,物资,42 +1590271415308,1590271413207,敌方旗舰,_比萨研发物资,1 +1590271415308,1590271413207,敌方旗舰,_鸢尾之印,1 +``` + +You can open it in Excel or load it into database. + +## Improvement + +These code is running on single thread, you can try adding multiprocess to speed up. I didn't do that because it's still acceptable (20it/s without ocr, 12it/s with ocr) \ No newline at end of file