Example #1
0
    def _process_pvp_list(self, data):
        try:
            pvp_data = data['api_data']['api_list']
            pvp.pvp.update_pvp_list(pvp_data)
        except KeyError:
            Log.log_debug("No pvp data found in API response.")

        return None
Example #2
0
    def _process_expedition_start(self, data):
        try:
            complete_time = data['api_data']['api_complatetime']
            return complete_time
        except KeyError:
            Log.log_debug("No expedition sent data")

        return None
Example #3
0
 def _process_battle_deck(self, data):
     try:
         deck_data = data['api_data']['api_ship_data']
         shp.ships.update_local_ships(deck_data)
         for fleet in flt.fleets.combat_fleets:
             fleet.update_ship_data()
     except KeyError:
         Log.log_debug("No CF battle data found in API response.")
Example #4
0
 def _load_quest_data(self):
     Log.log_debug("Loading Quest data.")
     quest_data = JsonData.load_json('data|quests|quests.json')
     for quest_name in quest_data:
         quest = Quest(quest_name, quest_data[quest_name])
         self.quest_library[quest_name] = quest
         self.quest_library[quest.quest_id] = quest
         self.quest_id_to_name[quest_data[quest_name]['id']] = quest_name
Example #5
0
    def _process_get_data(self, data):
        try:
            get_data_ship = data['api_data']['api_mst_ship']
            shp.ships.update_ship_library(get_data_ship)
            JsonData.dump_json(get_data_ship, 'data|temp|get_data_ship.json')
        except KeyError:
            Log.log_debug("No getData found in API response.")

        return None
Example #6
0
    def _process_expedition_list(self, data):
        try:
            exp.expedition.available_expeditions = (
                data['api_data']['api_list_items'])
            exp.expedition.populate_available_expeditions_per_world()
        except KeyError:
            Log.log_debug("No expedition list data found in API response.")

        return None
Example #7
0
 def _click_quest_idx(self, idx):
     Log.log_debug(f"Clicking quest at position {idx}.")
     quest_list_region = Region(kca_u.kca.game_x + 230,
                                kca_u.kca.game_y + 173 + (idx * 102), 830,
                                30)
     quest_list_region.click()
     api.api.update_from_api(
         {KCSAPIEnum.QUEST_LIST, KCSAPIEnum.QUEST_TURN_IN}, need_all=False)
     kca_u.kca.sleep(1)
Example #8
0
 def update_local_ships(self, data):
     # from this api call, api_id = local_api_id, and api_ship_id = api_id
     Log.log_debug("Updating ship data from API.")
     self.local_ships = []
     self.local_ships_by_local_id = {}
     for ship in data:
         ship_instance = ship_instance = self.get_ship_from_api_id(
             ship['api_ship_id'], ship)
         self.local_ships.append(ship_instance)
         self.local_ships_by_local_id[ship['api_id']] = ship_instance
Example #9
0
    def get_and_save_wgtf_data(cls):
        """Wrapper method for retrieving and storing WCTF data.
        """
        Log.log_debug("Attempting to get WCTF data.")

        suffixes = cls._get_suffix_data()
        name_db = cls._get_ship_name_data(suffixes)

        Log.log_debug("Successfully downloaded WCTF data.")
        JsonData.dump_json(name_db, 'data|temp|wctf.json')
Example #10
0
    def require_fleetswitch(self, context):
        preset_id = self._get_next_preset_id(context)
        if preset_id is None:
            return False

        if preset_id in self.presets:
            if self.presets[preset_id] == flt.fleets.fleets[1].ship_ids:
                Log.log_debug("Preset Fleet is already loaded.")
                return False
        Log.log_msg(f"Need to switch to Fleet Preset {preset_id}.")
        return True
Example #11
0
 def _switch_ship(self, ship):
     if kca_u.kca.click_existing(
             'lower_right',
             'shipswitcher|shiplist_shipswitch_button.png',
             cached=True):
         kca_u.kca.r['top'].hover()
         kca_u.kca.wait('right', 'shipswitcher|shiplist_button.png')
         return True
     else:
         Log.log_debug("Could not switch to selected ship.")
     return False
Example #12
0
 def select(self):
     Log.log_debug(f"Selecting fleet {self.fleet_id}.")
     kca_u.kca.click_existing('top_submenu',
                              f'fleet|fleet_{self.fleet_id}.png')
     while not kca_u.kca.exists('top_submenu',
                                f'fleet|fleet_{self.fleet_id}_active.png',
                                FLEET_NUMBER_ICON):
         kca_u.kca.click_existing('top_submenu',
                                  f'fleet|fleet_{self.fleet_id}.png',
                                  FLEET_NUMBER_ICON)
     kca_u.kca.sleep()
Example #13
0
 def _cycle_between_nodes(self, sortie_map):
     Log.log_debug("Between nodes.")
     while True:
         if kca_u.kca.exists('kc', 'combat|compass.png'):
             Log.log_msg("Spinning compass.")
             kca_u.kca.click_existing('kc', 'combat|compass.png', cached=True)
             kca_u.kca.r['top'].hover()
         elif (
                 kca_u.kca.exists(
                     'formation_line_ahead',
                     'fleet|formation_line_ahead.png')
                 or kca_u.kca.exists(
                     'formation_combined_fleet_1',
                     'fleet|formation_combined_fleet_1.png')):
             Log.log_msg(f"Combat at node {self.current_node}.")
             self._resolve_formation_prompt()
             api.api.update_from_api(self.COMBAT_APIS, need_all=False)
             return True
         elif self.current_node.selection_node:
             kca_u.kca.sleep()
             Log.log_msg(f"Node select node.")
             next_node = cfg.config.combat.node_selects.get(
                 self.current_node.name, None)
             if not next_node:
                 raise ValueError("Node select not defined.")
             else:
                 Log.log_msg(f"Selecting node {next_node.value}")
                 self.map_data.nodes[next_node.value].select()
                 api_result = api.api.update_from_api(
                     {KCSAPIEnum.SORTIE_NEXT}, need_all=False, timeout=4)
                 if KCSAPIEnum.SORTIE_NEXT.name in api_result:
                     self._find_next_node(
                         api_result[KCSAPIEnum.SORTIE_NEXT.name][0])
         elif kca_u.kca.exists('lower_right_corner', 'global|next_alt.png'):
             # resource node end
             return False
         else:
             Log.log_debug(self.current_node)
             Log.log_debug(self.current_node.selection_node)
             Log.log_debug("Wait for combat API.")
             api_result = api.api.update_from_api(
                 self.COMBAT_APIS, need_all=False, timeout=1)
             if KCSAPIEnum.SORTIE_NEXT.name in api_result:
                 self._find_next_node(
                     api_result[KCSAPIEnum.SORTIE_NEXT.name][0])
             elif KCSAPIEnum.PORT.name in api_result:
                 Log.log_debug("Sortie ended not immediately after battle.")
                 return False
             elif len(api_result) > 0:
                 kca_u.kca.r['top'].hover()
                 Log.log_msg(f"Action at Node {self.current_node}")
                 return True
         kca_u.kca.sleep(1)
Example #14
0
    def _process_sortie_maps(self, data):
        try:
            available_maps = data['api_data']['api_map_info']
            com.combat.update_combat_map_list(available_maps)
        except KeyError:
            Log.log_debug("No available combat map data in API response.")

        try:
            lbas_data = data['api_data']['api_air_base']
            lbas.lbas.update_lbas_groups(lbas_data)
        except KeyError:
            Log.log_debug("No available lbas data in API response.")
Example #15
0
    def _process_sortie_start(self, data):
        try:
            select_nodes = (
                data['api_data']['api_select_route']['api_select_cells'])
            com.combat.select_nodes = select_nodes
        except KeyError:
            Log.log_debug("No select node data found in API response.")

        try:
            next_node = data['api_data']['api_no']
            return next_node
        except KeyError:
            Log.log_debug("No next node data found in API response.")
Example #16
0
 def process_battle_result(self, data):
     Log.log_debug("Processing battle results.")
     if 'api_first_clear' in data:
         cleared = data['api_first_clear'] == 1
         if cleared:
             Log.log_debug("Map has been cleared.")
             self.map_cleared = True
     if 'api_get_ship' in data:
         dropped_ship_id = data['api_get_ship']['api_ship_id']
         ship = shp.ships.get_ship_from_api_id(dropped_ship_id)
         self.rescued_ships.append(ship)
         Log.log_success(f"Rescued {ship.name} (#{ship.sortno}).")
         sts.stats.combat.ships_rescued += 1
Example #17
0
File: rsc.py Project: ly2314/kcauto
 def update_resource_stats(self, data):
     Log.log_debug("Updating resource data from API.")
     for rsc in data:
         if rsc['api_id'] == 1:
             self.fuel = rsc['api_value']
         if rsc['api_id'] == 2:
             self.ammo = rsc['api_value']
         if rsc['api_id'] == 3:
             self.steel = rsc['api_value']
         if rsc['api_id'] == 4:
             self.bauxite = rsc['api_value']
         if rsc['api_id'] == 6:
             self.bucket = rsc['api_value']
Example #18
0
 def __init__(self):
     self.start_time = datetime.now()
     self.loop_count = 0
     self.combat = CombatStats(self.start_time)
     self.expedition = ExpeditionStats(self.start_time)
     self.pvp = PvPStats(self.start_time)
     self.ship_switcher = ShipSwitcherStats(self.start_time)
     self.resupply = ResupplyStats(self.start_time)
     self.repair = RepairStats(self.start_time)
     self.quest = QuestStats(self.start_time)
     self.recovery = RecoveryStats(self.start_time)
     self.rsc = ResourceStats(self.start_time)
     Log.log_debug("Stats module initialized.")
Example #19
0
    def load_json(cls, path):
        """Method for deserializing a json file.

        Args:
            path (str): kcauto-style path to json file.

        Returns:
            object: deserialized object.
        """
        json_path = cls.create_path(path)
        Log.log_debug(f"Loading data from '{json_path}'.")
        with open(json_path, encoding='utf-8') as json_file:
            data = json.load(json_file)
        return data
Example #20
0
    def hook_chrome(self, host="localhost", port=9222):
        """Method that initializes the necessary hooks to Chrome using
        PyChromeDevTools. The visual hook connects to the tab that actually
        contains the Kancolle HTML5 canvas, while the api hook connects to the
        tab that interacts with the Kancolle backend. The former is used for
        detecting refreshes and when using the Chrome driver interaction mode,
        while the latter is used for reading all API interactions.

        Args:
            host (str, optional): Chrome dev protocol server address. Defaults
                to "localhost".
            port (int, optional): Chrome dev protocol server port. Defaults to
                9222.

        Raises:
            Exception: could not find Kancolle tabs in Chrome.
        """
        Log.log_msg("Hooking into Chrome.")
        self.visual_hook = PyChromeDevTools.ChromeInterface(host=host,
                                                            port=port)
        self.api_hook = PyChromeDevTools.ChromeInterface(host=host, port=port)

        visual_tab = None
        visual_tab_id = None
        api_tab = None
        api_tab_id = None
        for n, tab in enumerate(self.visual_hook.tabs):
            if tab['url'] == VISUAL_URL:
                visual_tab = n
                visual_tab_id = tab['id']
            if API_URL in tab['url']:
                api_tab = n
                api_tab_id = tab['id']

        if visual_tab_id is None or api_tab_id is None:
            Log.log_error(
                "No Kantai Collection tab found in Chrome. Shutting down "
                "kcauto.")
            raise Exception(
                "No running Kantai Collection tab found in Chrome.")

        self.visual_hook.connect_targetID(visual_tab_id)
        Log.log_debug(
            f"Connected to visual tab ({visual_tab}:{visual_tab_id})")
        self.visual_hook.Page.enable()

        self.api_hook.connect_targetID(api_tab_id)
        self.api_hook.Network.enable()
        Log.log_debug(f"Connected to API tab ({api_tab}:{api_tab_id})")
        Log.log_success("Connected to Chrome")
Example #21
0
    def _resolve_night_battle_prompt(self):
        Log.log_debug("Resolve night battle prompt.")
        night_battle = False

        if self.current_node.name in cfg.config.combat.node_night_battles:
            Log.log_debug("NB specified in config")
            night_battle = cfg.config.combat.node_night_battles[
                self.current_node.name]
        elif (
                len(self.combat_nodes_run)
                in cfg.config.combat.node_night_battles):
            Log.log_debug("NB specified combat # in config")
            night_battle = cfg.config.combat.node_night_battles[
                len(self.combat_nodes_run)]
        elif self.current_node.boss_node:
            Log.log_debug("Node is boss node")
            night_battle = True

        if night_battle:
            Log.log_msg("Entering night battle.")
            kca_u.kca.click_existing(
                'kc', 'global|combat_nb_fight.png', cached=True)
        else:
            Log.log_msg("Declining night battle.")
            kca_u.kca.click_existing(
                'kc', 'global|combat_nb_retreat.png', cached=True)
        kca_u.kca.r['lbas'].hover()

        return night_battle
Example #22
0
    def initialize_config(self):
        update = False
        config_json = self._load_cfg_json()
        initial_load = True
        new_update_time = os.path.getmtime(self.cfg_path)

        if self.general:
            initial_load = False
            if config_json != self.general._config:
                Log.log_msg("Changes detected from previous config load.")
            else:
                Log.log_debug("No change from previous config load.")
                self.last_cfg_update_time = new_update_time
                return False

        try:
            new_general = ConfigGeneral(config_json)
            new_expedition = ConfigExpedition(config_json)
            new_pvp = ConfigPvP(config_json)
            new_combat = ConfigCombat(config_json)
            new_event_reset = ConfigEventReset(config_json)
            new_ship_switcher = ConfigShipSwitcher(config_json)
            new_passive_repair = ConfigPassiveRepair(config_json)
            new_quest = ConfigQuest(config_json)
            new_scheduler = ConfigScheduler(config_json)
            update = True
        except Exception as e:
            Log.log_error(e)

        if update:
            Log.log_success("Config successfully loaded.")
            if not initial_load:
                Log.log_success("Hot-reloading config in 3...")
                sleep(1)
                Log.log_success("2...")
                sleep(1)
                Log.log_success("1...")
                sleep(1)
            self.general = new_general
            self.expedition = new_expedition
            self.pvp = new_pvp
            self.combat = new_combat
            self.event_reset = new_event_reset
            self.ship_switcher = new_ship_switcher
            self.passive_repair = new_passive_repair
            self.quest = new_quest
            self.scheduler = new_scheduler
            self.last_cfg_update_time = new_update_time
            return True
Example #23
0
 def _reset_next_pvp_time(self):
     """Method to reset the next PvP time. Called when the next PvP time
     needs to be reset in subsequent times.
     """
     jst_time = KCTime.convert_to_jst(datetime.now())
     if 5 <= jst_time.hour < 15:
         temp_time = jst_time.replace(hour=15, minute=randint(5, 15))
     elif 15 <= jst_time.hour < 24:
         temp_time = jst_time + timedelta(days=1)
         temp_time = temp_time.replace(hour=5, minute=randint(5, 15))
     else:
         temp_time = jst_time.replace(hour=5, minute=randint(5, 15))
     self.next_pvp_time = KCTime.convert_from_jst(temp_time)
     Log.log_debug(
         f"Next PvP at {KCTime.datetime_to_str(self.next_pvp_time)}.")
Example #24
0
 def update_repair_data(self, data):
     Log.log_debug("Updating Repair data from API.")
     self.docks_count = 0
     self.docks_available_count = 0
     self.complete_times = []
     self.ships_under_repair = []
     for dock_data in data:
         if dock_data['api_state'] > -1:
             self.docks_count += 1
         if dock_data['api_state'] == 0:
             self.docks_available_count += 1
         if dock_data['api_state'] == 1:
             self.complete_times.append(
                 KCTime.convert_epoch(dock_data['api_complete_time']))
             self.ships_under_repair.append(dock_data['api_ship_id'])
Example #25
0
    def _toggle_quests(self, context):
        Log.log_debug(
            f"Checking for quests to activate with {context} context.")
        # quests should only be activated at this point
        relevant_quests = self._filter_quest_by_context(context)
        quest_types = sorted(
            list(self._get_types_from_quests(relevant_quests)),
            key=lambda quest_type: self.QUEST_TYPE_WEIGHTS[quest_type])

        for quest_type in quest_types:
            Log.log_debug(f"Navigating to {quest_type} quests tab.")
            kca_u.kca.click_existing('left',
                                     f'quest|filter_tab_{quest_type}.png')
            api.api.update_from_api({KCSAPIEnum.QUEST_LIST})
            kca_u.kca.wait('left', f'quest|filter_tab_{quest_type}_active.png',
                           NEAR_EXACT)

            page_processed = False
            while not page_processed:
                for idx, quest in enumerate(self.visible_quests):
                    if quest == -1:
                        page_processed = True
                        break

                    if quest['api_no'] not in self.quest_library:
                        continue

                    quest_i = self.quest_library[quest['api_no']]
                    if quest['api_state'] == 1 and quest_i in relevant_quests:
                        Log.log_msg(f"Activating quest {quest_i.name}.")
                        self._track_quest(quest_i)
                        self._click_quest_idx(idx)
                        sts.stats.quest.quests_activated += 1
                        continue
                    if (quest['api_state'] == 2
                            and quest_i not in relevant_quests):
                        Log.log_msg(f"Deactivating quest {quest_i.name}.")
                        self._click_quest_idx(idx)
                        self._untrack_quest(quest_i)
                        sts.stats.quest.quests_deactivated += 1
                        continue
                page_processed = True

            if self.cur_page < self.tot_page:
                kca_u.kca.click_existing('lower_right',
                                         'global|page_next.png',
                                         pad=PAGE_NAV)
                api.api.update_from_api({KCSAPIEnum.QUEST_LIST})
Example #26
0
    def dump_json(cls, data, path, pretty=False):
        """Method for serializing an object into a json file.

        Args:
            data (object): object to serialize.
            path (str): kcauto-style path.
            pretty (bool, optional): flag for pretty-printing the dumped file.
                Defaults to False.
        """
        json_path = cls.create_path(path)
        Log.log_debug(f"Writing data to '{json_path}'.")
        with open(json_path, 'w', encoding='utf-8') as json_file:
            if not pretty:
                json.dump(data, json_file, ensure_ascii=False)
            else:
                json.dump(data, json_file, ensure_ascii=False, indent=2)
Example #27
0
 def manage_quests(self, context=None, fast_check=True):
     # dismiss Ooyodo
     kca_u.kca.r['center'].click()
     kca_u.kca.sleep(1)
     if context and context != self.last_checked_context:
         fast_check = False
         self.last_checked_context = context
     if not context and self.last_checked_context:
         context = self.last_checked_context
     if fast_check:
         if self._turn_in_quests(context):
             self._toggle_quests(context)
     else:
         self._turn_in_quests(context)
         self._toggle_quests(context)
     Log.log_debug(
         f"Tracked quests: {list(self.next_check_intervals.keys())}")
Example #28
0
    def predict_battle(self, data):
        print(data)
        Log.log_debug("Predicting battle from data.")
        if 'api_flavor_info' in data:
            print('boss node')
        # if 'api_midnight_flag' in data:
        #     print(f"nightbattle: {data['api_midnight_flag']}")

        new_hps = (
            list(data['api_f_nowhps'] + data['api_f_nowhps_combined'])
            if flt.fleets.combined_fleet
            else list(data['api_f_nowhps']))
        print('calculate hps')
        new_hps = self._calculate_hps(new_hps, data)
        print(new_hps)
        flt.fleets.combat_fleets[0].update_ship_hps(new_hps[0:6])
        Log.log_msg(flt.fleets.combat_fleets[0])
        if flt.fleets.combined_fleet:
            flt.fleets.combat_fleets[1].update_ship_hps(new_hps[6:12])
            Log.log_msg(flt.fleets.combat_fleets[1])
Example #29
0
 def _set_to_desired_state(self, start, stop):
     if start is stop:
         return
     Log.log_msg(f"Switching LBAS state from {start.display_name} to "
                 f"{stop.display_name}.")
     state_order = list(LBASStateEnum)
     idx = state_order.index(start)
     relative_order = state_order[idx:] + state_order[:idx]
     for idx, state in enumerate(relative_order):
         if state is stop:
             break
         Log.log_debug(f"Switching LBAS state from {state.display_name} to "
                       f"{relative_order[idx + 1].display_name}.")
         cur_name = state.name.lower()
         next_name = relative_order[idx + 1].name.lower()
         kca_u.kca.click_existing('upper_right',
                                  f'combat|lbas_group_mode_{cur_name}.png')
         kca_u.kca.r['top'].hover()
         kca_u.kca.wait('upper_right',
                        f'combat|lbas_group_mode_{next_name}.png')
         kca_u.kca.sleep(0.5)
     api.api.update_from_api({KCSAPIEnum.SORTIE_ASSIGN_LBAS})
Example #30
0
    def _resolve_formation_prompt(self):
        Log.log_debug("Resolving formation prompt.")
        formation = (
            FormationEnum.COMBINED_FLEET_4
            if flt.fleets.combined_fleet
            else FormationEnum.LINE_AHEAD)

        if self.current_node.name in cfg.config.combat.node_formations:
            Log.log_debug("Formation specified in config")
            formation = cfg.config.combat.node_formations[
                self.current_node.name]
        elif (
                len(self.combat_nodes_run) + 1
                in cfg.config.combat.node_formations):
            # formation resolution occurs before the combat_nodes_run list is
            # updated, so account for the 1-offset
            Log.log_debug("Formation specified combat # in config")
            formation = cfg.config.combat.node_formations[
                len(self.combat_nodes_run) + 1]
        elif self.current_node.sub_node:
            Log.log_debug("Node is sub node")
            formation = (
                FormationEnum.COMBINED_FLEET_1
                if flt.fleets.combined_fleet
                else FormationEnum.LINE_ABREAST)
        elif self.current_node.air_node:
            Log.log_debug("Node is air node")
            formation = (
                FormationEnum.COMBINED_FLEET_3
                if flt.fleets.combined_fleet
                else FormationEnum.DIAMOND)

        Log.log_msg(f"Selecting formation {formation.display_name}.")
        kca_u.kca.click_existing(
            f'formation_{formation.value}',
            f'fleet|formation_{formation.value}.png')
        kca_u.kca.r['lbas'].hover()
        return formation