#!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = '刘兆辉' import os import sys import re base_path = os.getcwd() sys.path.append(base_path) from util.logger import Log log = Log() class Command: def __init__(self): self.result = None # self.result_list = [] @staticmethod def execute_cmd(command): """ 用于在cmd窗口执行命令 不返回结果 :param command:命令 :return: 不返回 """ # 这个方式,执行cmd命令后,不会往下执行 os.system('start ' + command)
import os import time import faiss import numpy as np import json import re from flask import Flask, request, send_from_directory from util.date import time_to_date from util.error import * from util.http import check_param, update_param from util.logger import Log app = Flask(__name__) logger = Log('app', 'index/') config = {} with open('config.json') as f: config = json.load(f) logger.info('======== system config ========') for key, value in config.items(): logger.info(key, ":", value) logger.info('system start time: ', time_to_date(time.time())) index = faiss.IndexFlatIP(config['dim']) index = faiss.IndexIDMap(index) logger.info('is trained:', index.is_trained) logger.info('======== system config ========') re_date = '^([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))$'
def update_pvp_list(self, data): Log.log_debug("Updating PvP data from API.") self.available_pvp = [] for index, pvp in enumerate(data): if pvp['api_state'] == 0: self.available_pvp.append(index)
def _update_regions(self): """Method that generates or updates all pre-defined regions accordingly based on the game's current x and y position. """ Log.log_debug("Updating regions.") x = self.game_x y = self.game_y w = GAME_W h = GAME_H hw = w / 2 hh = h / 2 # general regions self._create_or_shift_region('kc', x, y, w, h) self._create_or_shift_region('left', x, y, hw, h) self._create_or_shift_region('right', x + hw, y, hw, h) self._create_or_shift_region('upper', x, y, w, hh) self._create_or_shift_region('lower', x, y + hh, w, hh) self._create_or_shift_region('upper_left', x, y, hw, hh) self._create_or_shift_region('upper_right', x + hw, y, hw, hh) self._create_or_shift_region('lower_left', x, y + hh, hw, hh) self._create_or_shift_region('lower_right', x + hw, y + hh, hw, hh) self._create_or_shift_region( 'lower_right_corner', x + 1100, y + 620, 100, 100) self._create_or_shift_region('center', x + 225, y + 180, 750, 360) self._create_or_shift_region('top', x + 400, y + 12, 800, 30) self._create_or_shift_region('shipgirl', x + 700, y + 130, 400, 420) self._create_or_shift_region( 'combat_click', x + 700, y + 680, 200, 30) # function-specific regions self._create_or_shift_region( 'expedition_flag', x + 750, y + 20, 70, 50) self._create_or_shift_region('top_menu', x + 185, y + 50, 800, 50) self._create_or_shift_region( 'top_menu_quest', x + 790, y + 50, 105, 45) self._create_or_shift_region('home_menu', x + 45, y + 130, 500, 490) self._create_or_shift_region('side_menu', x, y + 190, 145, 400) self._create_or_shift_region( 'top_submenu', x + 145, y + 145, 1055, 70) self._create_or_shift_region( 'quest_status', x + 1065, y + 165, 95, 500) self._create_or_shift_region( 'check_damage_combat', x + 470, y + 215, 50, 475) self._create_or_shift_region('lbas', x + 500, y + 5, 200, 45) self._create_or_shift_region( 'lbas_mode_switch', x + 1135, y + 200, 55, 80) self._create_or_shift_region('7th_next', x + 386, y + 400, 27, 27) # combat-related regions self._create_or_shift_region( 'formation_line_ahead', x + 596, y + 256, 250, 44) self._create_or_shift_region( 'formation_double_line', x + 791, y + 256, 250, 44) self._create_or_shift_region( 'formation_diamond', x + 989, y + 256, 150, 44) self._create_or_shift_region( 'formation_echelon', x + 596, y + 495, 252, 44) self._create_or_shift_region( 'formation_line_abreast', x + 791, y + 495, 253, 44) self._create_or_shift_region( 'formation_vanguard', x + 989, y + 495, 150, 44) self._create_or_shift_region( 'formation_combined_fleet_1', x + 640, y + 240, 215, 45) self._create_or_shift_region( 'formation_combined_fleet_2', x + 890, y + 240, 215, 45) self._create_or_shift_region( 'formation_combined_fleet_3', x + 640, y + 445, 215, 45) self._create_or_shift_region( 'formation_combined_fleet_4', x + 890, y + 445, 215, 45)
def __init__(self): Log.log_debug("Kca module initialized.")
def _find_next_node(self, edge): next_node = self._get_next_node_from_edge(edge) Log.log_msg(f"Going to Node {next_node}") self.current_node = next_node self.nodes_run.append(next_node)
def find_kancolle(self): """Method that finds the Kancolle game on-screen and determine the UI being used as well as the position of the game. On first startup the method will look for all UIs until one is found; on subsequent runs it will first look for the last found UI. Generates or modifies pre-defined regions accordingly. Raises: FindFailed: could not find the game on-screen. """ Log.log_msg("Finding kancolle.") ref_r = None attempt = 0 screen = Region() # look for last-seen UI, if set if self.last_ui: try: ref_r = self.find( screen, f'global|kc_ref_point_{self.last_ui}.png', EXACT) except FindFailed: self.last_ui = None Log.log_debug("Last known UI not found.") # if last-seen UI was not found, or if kcauto is in first start while not ref_r: try: ref_r = self.find(screen, 'global|kc_ref_point_1.png', EXACT) self.last_ui = 1 Log.log_debug("Using UI 1 or 2") break except FindFailed: Log.log_debug("Not using UI 1 or 2") try: ref_r = self.find(screen, 'global|kc_ref_point_2.png', EXACT) self.last_ui = 2 Log.log_debug("Using UI 3") break except FindFailed: Log.log_debug("Not using UI 3") try: ref_r = self.find(screen, 'global|kc_ref_point_3.png', EXACT) self.last_ui = 3 Log.log_debug("Using UI 4 or 5") break except FindFailed: Log.log_debug("Not using UI 4 or 5") attempt += 1 sleep(1) if attempt > 3: Log.log_error("Could not find Kancolle reference point.") raise FindFailed() new_game_x = ref_r.x - 144 new_game_y = ref_r.y Log.log_debug(f"Game X:{new_game_x}, Y:{new_game_y}") # define click callback as needed if not arg.args.parsed_args.no_click_track: ImageMatch.click_callback = clt.click_tracker.track_click # define click and hover method overrides as needed if (cfg.config.general.interaction_mode is InteractionModeEnum.CHROME_DRIVER): ImageMatch.override_click_method = self._override_click_method ImageMatch.override_hover_method = self._override_hover_method if new_game_x != self.game_x or new_game_y != self.game_y: if not self.game_x or self.game_y: Log.log_success("Game found. Initializing regions.") else: Log.log_msg("Game has moved. Shifting regions.") self.game_x = new_game_x self.game_y = new_game_y self._update_regions() return True
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
def _resolve_continue_sortie_prompt(self): Log.log_debug("Resolve continue sortie prompt.") continue_sortie = True retreat_limit = cfg.config.combat.retreat_limit if self.current_node in cfg.config.combat.push_nodes: Log.log_msg(f"{self.current_node} is specified as a push node.") return True for fleet in flt.fleets.combat_fleets: if fleet.weakest_state >= retreat_limit: Log.log_warn(f"Fleet {fleet.fleet_id} has ships with " f"{retreat_limit.display_name} damage or above.") continue_sortie = False elif fleet.visual_health['heavy'] > 0: Log.log_warn( f"Fleet {fleet.fleet_id} has a critically damaged ship " "not calculated from the API.") continue_sortie = False if (NodeEnum(self.current_node.name) in cfg.config.combat.retreat_points): Log.log_debug("Retreat specified in config.") continue_sortie = False if (NodeEnum(len(self.combat_nodes_run)) in cfg.config.combat.retreat_points): Log.log_debug("Retreat specified combat # in config.") continue_sortie = False if continue_sortie: Log.log_msg("Continuing sortie.") kca_u.kca.click_existing('kc', 'combat|combat_continue.png', cached=True) else: Log.log_msg("Retreating from sortie.") kca_u.kca.click_existing('kc', 'combat|combat_retreat.png', cached=True) kca_u.kca.r['lbas'].hover() return continue_sortie
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
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("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)
def _handle_combat(self, sortie_map): kca_u.kca.r['top'].hover() result = api.api.update_from_api({KCSAPIEnum.SORTIE_START}) self._find_next_node(result[KCSAPIEnum.SORTIE_START.name][0]) lbas.lbas.assign_lbas(self.map_data) conducting_sortie = True while conducting_sortie: at_combat_node = self._cycle_between_nodes(sortie_map) if at_combat_node: self.combat_nodes_run.append(self.current_node) if self.current_node.boss_node or self.boss_api: self.boss_api = False Log.log_msg("Dismissing boss dialogue.") kca_u.kca.sleep(3) kca_u.kca.r['center'].click() kca_u.kca.sleep() kca_u.kca.r['center'].click() kca_u.kca.r['lbas'].hover() while not kca_u.kca.exists('lower_right_corner', 'global|next.png'): if kca_u.kca.exists('kc', 'global|combat_nb_fight.png'): Log.log_debug("Night battle prompt.") if self._resolve_night_battle_prompt(): api.api.update_from_api(self.COMBAT_APIS, need_all=False) kca_u.kca.r['lbas'].hover() api.api.update_from_api(self.RESULT_APIS, need_all=False) Log.log_debug("Battle animations complete.") sts.stats.combat.nodes_fought += 1 for fleet in flt.fleets.combat_fleets: kca_u.kca.wait('lower_right_corner', 'global|next.png') kca_u.kca.r['center'].click() kca_u.kca.r['lbas'].hover() kca_u.kca.wait('kc', 'combat|mvp_marker.png') kca_u.kca.sleep() fleet.visual_health_check( kca_u.kca.r['check_damage_combat']) Log.log_msg(fleet) Log.log_msg(fleet.detailed_fleet_status) while not (kca_u.kca.exists('left', 'nav|home_menu_sortie.png') or kca_u.kca.exists( 'lower_right', 'combat|combat_flagship_dmg.png') or kca_u.kca.exists('lower', 'combat|fcf_retreat_ship.png') or kca_u.kca.exists('kc', 'combat|combat_retreat.png')): Log.log_debug("Check for Port API.") api_result = api.api.update_from_api({KCSAPIEnum.PORT}, need_all=False, timeout=3) if KCSAPIEnum.PORT.name in api_result: kca_u.kca.wait('left', 'nav|home_menu_sortie.png') Log.log_debug("Sortie ended after battle.") conducting_sortie = False return else: kca_u.kca.r['combat_click'].click() if flt.fleets.combined_fleet: if kca_u.kca.exists('lower', 'combat|fcf_retreat_ship.png'): Log.log_debug("FCF prompt.") # self._resolve_fcf_prompt() if kca_u.kca.exists('kc', 'combat|combat_retreat.png'): Log.log_debug("Continue sortie prompt.") if self._resolve_continue_sortie_prompt(): api.api.update_from_api({KCSAPIEnum.SORTIE_SHIPDECK}) else: kca_u.kca.wait('left', 'nav|home_menu_sortie.png') elif kca_u.kca.exists('lower_right', 'combat|combat_flagship_dmg.png'): Log.log_debug("Flagship heavily damaged.") self._click_until_port() elif kca_u.kca.exists('lower_right_corner', 'global|next_alt.png'): Log.log_debug("Sortie completed on resource node.") self._click_until_port() if kca_u.kca.exists('left', 'nav|home_menu_sortie.png'): api.api.update_from_api({KCSAPIEnum.PORT}, need_all=False, timeout=2) Log.log_debug("Sortie ended after resource or flagship end.") conducting_sortie = False
def _check_map_clear(self): if self.map_cleared: if cfg.config.combat.clear_stop: Log.log_debug("Map has been cleared!") self.enabled = False
def should_and_able_to_sortie(self): if not self.enabled or not self.time_to_sortie: return False if cfg.config.combat.port_check: if shp.ships.current_ship_count == shp.ships.max_ship_count: Log.log_msg("Port is full.") self.set_next_sortie_time(15) return False if cfg.config.combat.sortie_map.world == 'E': if shp.ships.current_ship_count >= shp.ships.max_ship_count - 5: Log.log_warn("Port is too full for event map.") self.set_next_sortie_time(15) return False if cfg.config.combat.check_fatigue: for fleet in flt.fleets.combat_fleets: if fleet.highest_fatigue > FatigueStateEnum.NO_FATIGUE: Log.log_warn("Combat fleet is fatigued.") self.set_next_sortie_time(49 - fleet.lowest_morale) return False for fleet in flt.fleets.combat_fleets: if fleet.under_repair: Log.log_warn("Combat fleet is under repair.") self.set_next_sortie_time(rep.repair.soonest_complete_time) return False if fleet.needs_repair: Log.log_warn("Combat fleet needs repair.") if rep.repair.docks_are_available: self.set_next_sortie_time() else: self.set_next_sortie_time(rep.repair.soonest_complete_time) return False if fleet.needs_resupply: Log.log_warn("Combat fleet needs resupply.") return False return True