From a78f482d655aaf99791fc62edb14a1448368db95 Mon Sep 17 00:00:00 2001 From: qwerdvd <105906879+qwerdvd@users.noreply.github.com> Date: Fri, 11 Aug 2023 02:01:57 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E5=AE=8C=E6=88=90=20Excel=20?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E5=92=8C=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arknightsuid_resource/__init__.py | 39 +- .../arknightsuid_resource/cachedata.py | 61 +++ .../arknightsuid_resource/constants.py | 513 ++++++++++++++++++ ArknightsUID/arknightsuid_start/__init__.py | 21 +- ArknightsUID/utils/file.py | 27 + .../utils/resource/download_all_resource.py | 2 +- .../utils/resource/download_from_cos.py | 9 +- ArknightsUID/utils/resource/resource_map.json | 194 +++++++ 8 files changed, 834 insertions(+), 32 deletions(-) create mode 100644 ArknightsUID/arknightsuid_resource/cachedata.py create mode 100644 ArknightsUID/arknightsuid_resource/constants.py create mode 100644 ArknightsUID/utils/file.py create mode 100644 ArknightsUID/utils/resource/resource_map.json diff --git a/ArknightsUID/arknightsuid_resource/__init__.py b/ArknightsUID/arknightsuid_resource/__init__.py index c25b6a3..255ed4f 100644 --- a/ArknightsUID/arknightsuid_resource/__init__.py +++ b/ArknightsUID/arknightsuid_resource/__init__.py @@ -1,20 +1,31 @@ -# from gsuid_core.bot import Bot -# from gsuid_core.logger import logger -# from gsuid_core.models import Event -# from gsuid_core.sv import SV +from pathlib import Path -# from ..utils.resource.download_all_resource import download_all_resource +from gsuid_core.bot import Bot +from gsuid_core.data_store import get_res_path +from gsuid_core.logger import logger +from gsuid_core.models import Event +from gsuid_core.sv import SV -# sv_download_config = SV('下载资源', pm=2) +from ..utils.resource.download_all_resource import download_all_resource +from .cachedata import CacheData +from .constants import Excel + +sv_download_config = SV('下载资源', pm=2) -# @sv_download_config.on_fullmatch(('下载全部资源')) -# async def send_download_resource_msg(bot: Bot, ev: Event): -# await bot.send('正在开始下载~可能需要较久的时间!') -# im = await download_all_resource() -# await bot.send(im) +@sv_download_config.on_fullmatch(('下载全部资源')) +async def send_download_resource_msg(bot: Bot, ev: Event): + await bot.send('正在开始下载~可能需要较久的时间!') + im = await download_all_resource() + await bot.send(im) -# async def startup(): -# logger.info('[资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等') -# logger.info(f'[资源文件下载] {await download_all_resource()}') +async def startup(): + logger.info('[资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等') + await download_all_resource() + logger.info('[资源文件下载] 检查完毕, 正在加载 gamedata') + + for file_path in Path(get_res_path(['ArknightsUID', 'resource', 'gamedata'])).rglob('*.json'): + CacheData.readFile(file_path) + + Excel.preload_table() diff --git a/ArknightsUID/arknightsuid_resource/cachedata.py b/ArknightsUID/arknightsuid_resource/cachedata.py new file mode 100644 index 0000000..ead4cd2 --- /dev/null +++ b/ArknightsUID/arknightsuid_resource/cachedata.py @@ -0,0 +1,61 @@ +import json +from functools import cache +from pathlib import Path +from time import time +from typing import Any, ClassVar + +from loguru import logger + +from ..utils.file import read_json + + +class StoreData: + data: dict[Any, Any] + modification_time: float + + def __init__(self, data: dict[Any, Any], modification_time: float) -> None: + self.data = data + self.modification_time = modification_time + + +class CacheData: + cached_data: ClassVar[dict[str, StoreData]] = {} + + @classmethod + @cache + def get_cache(cls, local_path: Path) -> dict[Any, Any]: + data_name = local_path.stem + if data_name in cls.cached_data: + current_modification_time = local_path.stat().st_mtime + if current_modification_time == cls.cached_data[data_name].modification_time: + logger.debug(f'hit cached: {data_name}') + return cls.cached_data[data_name].data + return cls.set_cache(local_path, data_name) + + @classmethod + def set_cache(cls, local_path: Path | None, data_name: str, memory_data: dict | None = None) -> dict[Any, Any]: + data = read_json(local_path) if local_path else memory_data + if data is None: + raise FileNotFoundError + modification_time = local_path.stat().st_mtime if local_path else time() + cls.cached_data[data_name] = StoreData(data, modification_time) + logger.debug(f'cached: {data_name}') + return cls.cached_data[data_name].data + + @classmethod + def readFile(cls, local_path: Path) -> dict[Any, Any]: + try: + if isinstance(local_path, str): + local_path = Path(local_path) + logger.debug(f'loading: {local_path.stem}') + return cls.get_cache(local_path) + except json.decoder.JSONDecodeError as e: + logger.error(f'Could not load file "{local_path}".') + raise FileNotFoundError from e + + @classmethod + def readExcel(cls, table_name: str) -> dict[Any, Any]: + logger.debug(f'loading: {table_name}.json') + if table_name not in cls.cached_data: + return {} + return cls.cached_data[table_name].data diff --git a/ArknightsUID/arknightsuid_resource/constants.py b/ArknightsUID/arknightsuid_resource/constants.py new file mode 100644 index 0000000..486275a --- /dev/null +++ b/ArknightsUID/arknightsuid_resource/constants.py @@ -0,0 +1,513 @@ +import inspect + +from ..utils.models.gamedata.ActivityTable import ActivityTable +from ..utils.models.gamedata.AudioData import AudioData +from ..utils.models.gamedata.BattleEquipTable import BattleEquipTable +from ..utils.models.gamedata.BuildingData import BuildingData +from ..utils.models.gamedata.CampaignTable import CampaignTable +from ..utils.models.gamedata.ChapterTable import ChapterTable +from ..utils.models.gamedata.CharacterTable import CharacterTable +from ..utils.models.gamedata.CharMetaTable import CharMetaTable +from ..utils.models.gamedata.CharmTable import CharmTable +from ..utils.models.gamedata.CharPatchTable import CharPatchTable +from ..utils.models.gamedata.CharwordTable import CharwordTable +from ..utils.models.gamedata.CheckinTable import CheckinTable +from ..utils.models.gamedata.ClimbTowerTable import ClimbTowerTable +from ..utils.models.gamedata.ClueData import ClueData +from ..utils.models.gamedata.CrisisTable import CrisisTable +from ..utils.models.gamedata.DisplayMetaTable import DisplayMetaTable +from ..utils.models.gamedata.EnemyHandbookTable import EnemyHandbookTable +from ..utils.models.gamedata.FavorTable import FavorTable +from ..utils.models.gamedata.GachaTable import GachaTable +from ..utils.models.gamedata.GamedataConst import GamedataConst +from ..utils.models.gamedata.HandbookInfoTable import HandbookInfoTable +from ..utils.models.gamedata.HandbookTable import HandbookTable +from ..utils.models.gamedata.HandbookTeamTable import HandbookTeamTable +from ..utils.models.gamedata.ItemTable import ItemTable +from ..utils.models.gamedata.MedalTable import MedalTable +from ..utils.models.gamedata.MissionTable import MissionTable +from ..utils.models.gamedata.OpenServerTable import OpenServerTable +from ..utils.models.gamedata.PlayerAvatarTable import PlayerAvatarTable +from ..utils.models.gamedata.RangeTable import RangeTable +from ..utils.models.gamedata.ReplicateTable import ReplicateTable +from ..utils.models.gamedata.RetroTable import RetroTable +from ..utils.models.gamedata.RoguelikeTable import RoguelikeTable +from ..utils.models.gamedata.RoguelikeTopicTable import RoguelikeTopicTable +from ..utils.models.gamedata.SandboxTable import SandboxTable +from ..utils.models.gamedata.ShopClientTable import ShopClientTable +from ..utils.models.gamedata.SkillTable import SkillTable +from ..utils.models.gamedata.SkinTable import SkinTable +from ..utils.models.gamedata.StageTable import StageTable +from ..utils.models.gamedata.StoryReviewMetaTable import StoryReviewMetaTable +from ..utils.models.gamedata.StoryReviewTable import StoryReviewTable +from ..utils.models.gamedata.StoryTable import StoryTable +from ..utils.models.gamedata.TechBuffTable import TechBuffTable +from ..utils.models.gamedata.TipTable import TipTable +from ..utils.models.gamedata.TokenTable import TokenTable +from ..utils.models.gamedata.UniequipData import UniequipData +from ..utils.models.gamedata.UniequipTable import UniEquipTable +from ..utils.models.gamedata.ZoneTable import ZoneTable +from .cachedata import CacheData + + +class ExcelTableManager: + activity_table_: ActivityTable | None = None + audio_data_: AudioData | None = None + battle_equip_table_: BattleEquipTable | None = None + building_data_: BuildingData | None = None + campaign_table_: CampaignTable | None = None + chapter_table_: ChapterTable | None = None + character_table_: CharacterTable | None = None + char_meta_table_: CharMetaTable | None = None + charm_table_: CharmTable | None = None + char_patch_table_: CharPatchTable | None = None + charword_table_: CharwordTable | None = None + checkin_table_: CheckinTable | None = None + climb_tower_table_: ClimbTowerTable | None = None + clue_data_: ClueData | None = None + crisis_table_: CrisisTable | None = None + display_meta_table_: DisplayMetaTable | None = None + enemy_handbook_table_: EnemyHandbookTable | None = None + favor_table_: FavorTable | None = None + gacha_table_: GachaTable | None = None + gamedata_const_: GamedataConst | None = None + handbook_info_table_: HandbookInfoTable | None = None + handbook_table_: HandbookTable | None = None + handbook_team_table_: HandbookTeamTable | None = None + item_table_: ItemTable | None = None + medal_table_: MedalTable | None = None + mission_table_: MissionTable | None = None + open_server_table_: OpenServerTable | None = None + player_avatar_table_: PlayerAvatarTable | None = None + range_table_: RangeTable | None = None + replicate_table_: ReplicateTable | None = None + retro_table_: RetroTable | None = None + roguelike_table_: RoguelikeTable | None = None + roguelike_topic_table_: RoguelikeTopicTable | None = None + sandbox_table_: SandboxTable | None = None + shop_client_table_: ShopClientTable | None = None + skill_table_: SkillTable | None = None + skin_table_: SkinTable | None = None + stage_table_: StageTable | None = None + story_review_meta_table_: StoryReviewMetaTable | None = None + story_review_table_: StoryReviewTable | None = None + story_table_: StoryTable | None = None + tech_buff_table_: TechBuffTable | None = None + tip_table_: TipTable | None = None + token_table_: TokenTable | None = None + uniequip_data_: UniequipData | None = None + uniequip_table_: UniEquipTable | None = None + zone_table_: ZoneTable | None = None + + @property + def ACTIVITY_TABLE(self) -> ActivityTable: + if not self.activity_table_: + if hasattr(ActivityTable, 'model_validate'): + self.activity_table_ = ActivityTable.model_validate(CacheData.readExcel('activity_table')) # type: ignore + else: + self.activity_table_ = ActivityTable.parse_obj(CacheData.readExcel('activity_table')) + return self.activity_table_ + + @property + def AUDIO_DATA(self) -> AudioData: + if not self.audio_data_: + if hasattr(AudioData, 'model_validate'): + self.audio_data_ = AudioData.model_validate(CacheData.readExcel('audio_data')) # type: ignore + else: + self.audio_data_ = AudioData.parse_obj(CacheData.readExcel('audio_data')) + return self.audio_data_ + + @property + def BATTLE_EQUIP_TABLE(self) -> BattleEquipTable: + if not self.battle_equip_table_: + self.battle_equip_table_ = BattleEquipTable(CacheData.readExcel('battle_equip_table')) + return self.battle_equip_table_ + + @property + def BUILDING_DATA(self) -> BuildingData: + if not self.building_data_: + if hasattr(BuildingData, 'model_validate'): + self.building_data_ = BuildingData.model_validate(CacheData.readExcel('building_data')) # type: ignore + else: + self.building_data_ = BuildingData.parse_obj(CacheData.readExcel('building_data')) + return self.building_data_ + + @property + def CAMPAIGN_TABLE(self) -> CampaignTable: + if not self.campaign_table_: + if hasattr(CampaignTable, 'model_validate'): + self.campaign_table_ = CampaignTable.model_validate(CacheData.readExcel('campaign_table')) # type: ignore + else: + self.campaign_table_ = CampaignTable.parse_obj(CacheData.readExcel('campaign_table')) + return self.campaign_table_ + + @property + def CHAPTER_TABLE(self) -> ChapterTable: + if not self.chapter_table_: + self.chapter_table_ = ChapterTable(CacheData.readExcel('chapter_table')) + return self.chapter_table_ + + @property + def CHARATER_TABLE(self) -> CharacterTable: + if not self.character_table_: + if hasattr(CharacterTable, 'model_validate'): + self.character_table_ = CharacterTable.model_validate(CacheData.readExcel('character_table')) # type: ignore + else: + self.character_table_ = CharacterTable(CacheData.readExcel('character_table')) + return self.character_table_ + + @property + def CHAR_META_TABLE(self) -> CharMetaTable: + if not self.char_meta_table_: + if hasattr(CharMetaTable, 'model_validate'): + self.char_meta_table_ = CharMetaTable.model_validate(CacheData.readExcel('char_meta_table')) # type: ignore + else: + self.char_meta_table_ = CharMetaTable.parse_obj(CacheData.readExcel('char_meta_table')) + return self.char_meta_table_ + + @property + def CHARM_TABLE(self) -> CharmTable: + if not self.charm_table_: + if hasattr(CharmTable, 'model_validate'): + self.charm_table_ = CharmTable.model_validate(CacheData.readExcel('charm_table')) # type: ignore + else: + self.charm_table_ = CharmTable.parse_obj(CacheData.readExcel('charm_table')) + return self.charm_table_ + + @property + def CHAR_PATH_TABLE(self) -> CharPatchTable: + if not self.char_patch_table_: + if hasattr(CharPatchTable, 'model_validate'): + self.char_patch_table_ = CharPatchTable.model_validate(CacheData.readExcel('char_patch_table')) # type: ignore + else: + self.char_patch_table_ = CharPatchTable.parse_obj(CacheData.readExcel('char_patch_table')) + return self.char_patch_table_ + + @property + def CHARWORD_TABLE(self) -> CharwordTable: + if not self.charword_table_: + if hasattr(CharwordTable, 'model_validate'): + self.charword_table_ = CharwordTable.model_validate(CacheData.readExcel('charword_table')) # type: ignore + else: + self.charword_table_ = CharwordTable.parse_obj(CacheData.readExcel('charword_table')) + return self.charword_table_ + + @property + def CHECKIN_TABLE(self) -> CheckinTable: + if not self.checkin_table_: + if hasattr(CheckinTable, 'model_validate'): + self.checkin_table_ = CheckinTable.model_validate(CacheData.readExcel('checkin_table')) # type: ignore + else: + self.checkin_table_ = CheckinTable.parse_obj(CacheData.readExcel('checkin_table')) + return self.checkin_table_ + + @property + def CLIMB_TOWER_TABLE(self) -> ClimbTowerTable: + if not self.climb_tower_table_: + if hasattr(ClimbTowerTable, 'model_validate'): + self.climb_tower_table_ = ClimbTowerTable.model_validate(CacheData.readExcel('climb_tower_table')) # type: ignore + else: + self.climb_tower_table_ = ClimbTowerTable.parse_obj(CacheData.readExcel('climb_tower_table')) + return self.climb_tower_table_ + + @property + def CLUE_DATA(self) -> ClueData: + if not self.clue_data_: + if hasattr(ClueData, 'model_validate'): + self.clue_data_ = ClueData.model_validate(CacheData.readExcel('clue_data')) # type: ignore + else: + self.clue_data_ = ClueData.parse_obj(CacheData.readExcel('clue_data')) + return self.clue_data_ + + @property + def CRISIS_TABLE(self) -> CrisisTable: + if not self.crisis_table_: + if hasattr(CrisisTable, 'model_validate'): + self.crisis_table_ = CrisisTable.model_validate(CacheData.readExcel('crisis_table')) # type: ignore + else: + self.crisis_table_ = CrisisTable.parse_obj(CacheData.readExcel('crisis_table')) + return self.crisis_table_ + + @property + def DISPLAY_META_TABLE(self) -> DisplayMetaTable: + if not self.display_meta_table_: + if hasattr(DisplayMetaTable, 'model_validate'): + self.display_meta_table_ = DisplayMetaTable.model_validate(CacheData.readExcel('display_meta_table')) # type: ignore + else: + self.display_meta_table_ = DisplayMetaTable.parse_obj(CacheData.readExcel('display_meta_table')) + return self.display_meta_table_ + + @property + def ENEMY_HANDBOOK_TABLE(self) -> EnemyHandbookTable: + if not self.enemy_handbook_table_: + if hasattr(EnemyHandbookTable, 'model_validate'): + self.enemy_handbook_table_ = EnemyHandbookTable.model_validate(CacheData.readExcel('enemy_handbook_table')) # type: ignore + else: + self.enemy_handbook_table_ = EnemyHandbookTable.parse_obj(CacheData.readExcel('enemy_handbook_table')) + return self.enemy_handbook_table_ + + @property + def FAVOR_TABLE(self) -> FavorTable: + if not self.favor_table_: + if hasattr(FavorTable, 'model_validate'): + self.favor_table_ = FavorTable.model_validate(CacheData.readExcel('favor_table')) # type: ignore + else: + self.favor_table_ = FavorTable.parse_obj(CacheData.readExcel('favor_table')) + return self.favor_table_ + + @property + def GACHA_TABLE(self) -> GachaTable: + if not self.gacha_table_: + if hasattr(GachaTable, 'model_validate'): + self.gacha_table_ = GachaTable.model_validate(CacheData.readExcel('gacha_table')) # type: ignore + else: + self.gacha_table_ = GachaTable.parse_obj(CacheData.readExcel('gacha_table')) + return self.gacha_table_ + + @property + def GAMEDATA_CONST(self) -> GamedataConst: + if not self.gamedata_const_: + if hasattr(GamedataConst, 'model_validate'): + self.gamedata_const_ = GamedataConst.model_validate(CacheData.readExcel('gamedata_const')) # type: ignore + else: + self.gamedata_const_ = GamedataConst.parse_obj(CacheData.readExcel('gamedata_const')) + return self.gamedata_const_ + + @property + def HANDBOOK_INFO_TABLE(self) -> HandbookInfoTable: + if not self.handbook_info_table_: + if hasattr(HandbookInfoTable, 'model_validate'): + self.handbook_info_table_ = HandbookInfoTable.model_validate(CacheData.readExcel('handbook_info_table')) # type: ignore + else: + self.handbook_info_table_ = HandbookInfoTable.parse_obj(CacheData.readExcel('handbook_info_table')) + return self.handbook_info_table_ + + @property + def HANDBOOK_TABLE(self) -> HandbookTable: + if not self.handbook_table_: + if hasattr(HandbookTable, 'model_validate'): + self.handbook_table_ = HandbookTable.model_validate(CacheData.readExcel('handbook_table')) # type: ignore + else: + self.handbook_table_ = HandbookTable.parse_obj(CacheData.readExcel('handbook_table')) + return self.handbook_table_ + + @property + def HANDBOOK_TEAM_TABLE(self) -> HandbookTeamTable: + if not self.handbook_team_table_: + if hasattr(HandbookTeamTable, 'model_validate'): + self.handbook_team_table_ = HandbookTeamTable.model_validate(CacheData.readExcel('handbook_team_table')) # type: ignore + else: + self.handbook_team_table_ = HandbookTeamTable.parse_obj(CacheData.readExcel('handbook_team_table')) + return self.handbook_team_table_ + + @property + def ITEM_TABLE(self) -> ItemTable: + if not self.item_table_: + if hasattr(ItemTable, 'model_validate'): + self.item_table_ = ItemTable.model_validate(CacheData.readExcel('item_table')) # type: ignore + else: + self.item_table_ = ItemTable.parse_obj(CacheData.readExcel('item_table')) + return self.item_table_ + + @property + def MEDAL_TABLE(self) -> MedalTable: + if not self.medal_table_: + if hasattr(MedalTable, 'model_validate'): + self.medal_table_ = MedalTable.model_validate(CacheData.readExcel('medal_table')) # type: ignore + else: + self.medal_table_ = MedalTable.parse_obj(CacheData.readExcel('medal_table')) + return self.medal_table_ + + @property + def MISSION_TABLE(self) -> MissionTable: + if not self.mission_table_: + if hasattr(MissionTable, 'model_validate'): + self.mission_table_ = MissionTable.model_validate(CacheData.readExcel('mission_table')) # type: ignore + else: + self.mission_table_ = MissionTable.parse_obj(CacheData.readExcel('mission_table')) + return self.mission_table_ + + @property + def OPEN_SERVER_TABLE(self) -> OpenServerTable: + if not self.open_server_table_: + if hasattr(OpenServerTable, 'model_validate'): + self.open_server_table_ = OpenServerTable.model_validate(CacheData.readExcel('open_server_table')) # type: ignore + else: + self.open_server_table_ = OpenServerTable.parse_obj(CacheData.readExcel('open_server_table')) + return self.open_server_table_ + + @property + def PLAYER_AVATAR_TABLE(self) -> PlayerAvatarTable: + if not self.player_avatar_table_: + if hasattr(PlayerAvatarTable, 'model_validate'): + self.player_avatar_table_ = PlayerAvatarTable.model_validate(CacheData.readExcel('player_avatar_table')) # type: ignore + else: + self.player_avatar_table_ = PlayerAvatarTable.parse_obj(CacheData.readExcel('player_avatar_table')) + return self.player_avatar_table_ + + @property + def RANGE_TABLE(self) -> RangeTable: + if not self.range_table_: + if hasattr(RangeTable, 'model_validate'): + self.range_table_ = RangeTable.model_validate(CacheData.readExcel('range_table')) # type: ignore + else: + self.range_table_ = RangeTable.parse_obj(CacheData.readExcel('range_table')) + return self.range_table_ + + @property + def REPLICATE_TABLE(self) -> ReplicateTable: + if not self.replicate_table_: + if hasattr(ReplicateTable, 'model_validate'): + self.replicate_table_ = ReplicateTable.model_validate(CacheData.readExcel('replicate_table')) # type: ignore + else: + self.replicate_table_ = ReplicateTable.parse_obj(CacheData.readExcel('replicate_table')) + return self.replicate_table_ + + @property + def RETRO_TABLE(self) -> RetroTable: + if not self.retro_table_: + if hasattr(RetroTable, 'model_validate'): + self.retro_table_ = RetroTable.model_validate(CacheData.readExcel('retro_table')) # type: ignore + else: + self.retro_table_ = RetroTable.parse_obj(CacheData.readExcel('retro_table')) + return self.retro_table_ + + @property + def ROGUELIKE_TABLE(self) -> RoguelikeTable: + if not self.roguelike_table_: + if hasattr(RoguelikeTable, 'model_validate'): + self.roguelike_table_ = RoguelikeTable.model_validate(CacheData.readExcel('roguelike_table')) # type: ignore + else: + self.roguelike_table_ = RoguelikeTable.parse_obj(CacheData.readExcel('roguelike_table')) + return self.roguelike_table_ + + @property + def ROGUELIKE_TOPIC_TABLE(self) -> RoguelikeTopicTable: + if not self.roguelike_topic_table_: + if hasattr(RoguelikeTopicTable, 'model_validate'): + self.roguelike_topic_table_ = RoguelikeTopicTable.model_validate(CacheData.readExcel('roguelike_topic_table')) # type: ignore + else: + self.roguelike_topic_table_ = RoguelikeTopicTable.parse_obj(CacheData.readExcel('roguelike_topic_table')) + return self.roguelike_topic_table_ + + @property + def SANDBOX_TABLE(self) -> SandboxTable: + if not self.sandbox_table_: + if hasattr(SandboxTable, 'model_validate'): + self.sandbox_table_ = SandboxTable.model_validate(CacheData.readExcel('sandbox_table')) # type: ignore + else: + self.sandbox_table_ = SandboxTable.parse_obj(CacheData.readExcel('sandbox_table')) + return self.sandbox_table_ + + @property + def SHOP_CLIENT_TABLE(self) -> ShopClientTable: + if not self.shop_client_table_: + if hasattr(ShopClientTable, 'model_validate'): + self.shop_client_table_ = ShopClientTable.model_validate(CacheData.readExcel('shop_client_table')) # type: ignore + else: + self.shop_client_table_ = ShopClientTable.parse_obj(CacheData.readExcel('shop_client_table')) + return self.shop_client_table_ + + @property + def SKILL_TABLE(self) -> SkillTable: + if not self.skill_table_: + self.skill_table_ = SkillTable(CacheData.readExcel('skill_table')) + return self.skill_table_ + + @property + def SKIN_TABLE(self) -> SkinTable: + if not self.skin_table_: + if hasattr(SkinTable, 'model_validate'): + self.skin_table_ = SkinTable.model_validate(CacheData.readExcel('skin_table')) # type: ignore + else: + self.skin_table_ = SkinTable.parse_obj(CacheData.readExcel('skin_table')) + return self.skin_table_ + + @property + def STAGE_TABLE(self) -> StageTable: + if not self.stage_table_: + if hasattr(StageTable, 'model_validate'): + self.stage_table_ = StageTable.model_validate(CacheData.readExcel('stage_table')) # type: ignore + else: + self.stage_table_ = StageTable.parse_obj(CacheData.readExcel('stage_table')) + return self.stage_table_ + + @property + def STORY_REVIEW_META_TABLE(self) -> StoryReviewMetaTable: + if not self.story_review_meta_table_: + if hasattr(StoryReviewMetaTable, 'model_validate'): + self.story_review_meta_table_ = StoryReviewMetaTable.model_validate(CacheData.readExcel('story_review_meta_table')) # type: ignore + else: + self.story_review_meta_table_ = StoryReviewMetaTable.parse_obj(CacheData.readExcel('story_review_meta_table')) + return self.story_review_meta_table_ + + @property + def STORY_REVIEW_TABLE(self) -> StoryReviewTable: + if not self.story_review_table_: + self.story_review_table_ = StoryReviewTable(CacheData.readExcel('story_review_table')) + return self.story_review_table_ + + @property + def STORY_TABLE(self) -> StoryTable: + if not self.story_table_: + self.story_table_ = StoryTable(CacheData.readExcel('story_table')) + return self.story_table_ + + @property + def TECH_BUFF_TABLE(self) -> TechBuffTable: + if not self.tech_buff_table_: + if hasattr(TechBuffTable, 'model_validate'): + self.tech_buff_table_ = TechBuffTable.model_validate(CacheData.readExcel('tech_buff_table')) # type: ignore + else: + self.tech_buff_table_ = TechBuffTable.parse_obj(CacheData.readExcel('tech_buff_table')) + return self.tech_buff_table_ + + @property + def TIP_TABLE(self) -> TipTable: + if not self.tip_table_: + if hasattr(TipTable, 'model_validate'): + self.tip_table_ = TipTable.model_validate(CacheData.readExcel('tip_table')) # type: ignore + else: + self.tip_table_ = TipTable.parse_obj(CacheData.readExcel('tip_table')) + return self.tip_table_ + + @property + def TOKEN_TABLE(self) -> TokenTable: + if not self.token_table_: + self.token_table_ = TokenTable(CacheData.readExcel('token_table')) + return self.token_table_ + + @property + def UNIEQUIP_DATA(self) -> UniequipData: + if not self.uniequip_data_: + if hasattr(UniequipData, 'model_validate'): + self.uniequip_data_ = UniequipData.model_validate(CacheData.readExcel('uniequip_data')) # type: ignore + else: + self.uniequip_data_ = UniequipData.parse_obj(CacheData.readExcel('uniequip_data')) + return self.uniequip_data_ + + @property + def UNIEQUIP_TABLE(self) -> UniEquipTable: + if not self.uniequip_table_: + if hasattr(UniEquipTable, 'model_validate'): + self.uniequip_table_ = UniEquipTable.model_validate(CacheData.readExcel('uniequip_table')) # type: ignore + else: + self.uniequip_table_ = UniEquipTable.parse_obj(CacheData.readExcel('uniequip_table')) + return self.uniequip_table_ + + @property + def ZONE_TABLE(self) -> ZoneTable: + if not self.zone_table_: + if hasattr(ZoneTable, 'model_validate'): + self.zone_table_ = ZoneTable.model_validate(CacheData.readExcel('zone_table')) # type: ignore + else: + self.zone_table_ = ZoneTable.parse_obj(CacheData.readExcel('zone_table')) + return self.zone_table_ + + def preload_table(self) -> None: + for name, method in inspect.getmembers(self, predicate=inspect.ismethod): + if callable(method) and not name.startswith('__') and name != 'preload_table': + method() + + +Excel = ExcelTableManager() diff --git a/ArknightsUID/arknightsuid_start/__init__.py b/ArknightsUID/arknightsuid_start/__init__.py index f697d10..701ffb8 100644 --- a/ArknightsUID/arknightsuid_start/__init__.py +++ b/ArknightsUID/arknightsuid_start/__init__.py @@ -1,13 +1,16 @@ +import asyncio +import threading + +from loguru import logger + +from ..arknightsuid_resource import startup -# from ..arknightsuid_resource import startup +async def all_start(): + try: + await startup() + except Exception as e: + logger.exception(e) -# async def all_start(): -# try: -# await startup() -# except Exception as e: -# logger.exception(e) - - -# threading.Thread(target=lambda: asyncio.run(all_start()), daemon=True).start() +threading.Thread(target=lambda: asyncio.run(all_start()), daemon=True).start() diff --git a/ArknightsUID/utils/file.py b/ArknightsUID/utils/file.py new file mode 100644 index 0000000..5e22743 --- /dev/null +++ b/ArknightsUID/utils/file.py @@ -0,0 +1,27 @@ +import json +from pathlib import Path + +from loguru import logger + + +def read_json(file_path: Path, **kwargs) -> dict: + """ + Read a JSON file and return its contents as a dictionary. + """ + try: + with Path.open(file_path, encoding='UTF-8', **kwargs) as file: + return json.load(file) + except (FileNotFoundError, json.JSONDecodeError) as e: + logger.error(f'Error reading JSON file: {e}') + return {} + + +def write_json(data: dict, file_path: Path) -> None: + """ + Write a dictionary to a JSON file. + """ + try: + with Path.open(file_path, mode='w', encoding='UTF-8') as file: + json.dump(data, file, sort_keys=False, indent=4, ensure_ascii=False) + except FileNotFoundError as e: + logger.error(f'Error writing JSON file: {e}') diff --git a/ArknightsUID/utils/resource/download_all_resource.py b/ArknightsUID/utils/resource/download_all_resource.py index a51357f..c7f549b 100644 --- a/ArknightsUID/utils/resource/download_all_resource.py +++ b/ArknightsUID/utils/resource/download_all_resource.py @@ -8,4 +8,4 @@ async def download_all_resource(): ret = [str(x) for x in ret if x] if ret: return '\n'.join(ret) - return 'sr全部资源下载完成!' + return 'arknights全部资源下载完成!' diff --git a/ArknightsUID/utils/resource/download_from_cos.py b/ArknightsUID/utils/resource/download_from_cos.py index 927bd19..395e447 100644 --- a/ArknightsUID/utils/resource/download_from_cos.py +++ b/ArknightsUID/utils/resource/download_from_cos.py @@ -32,14 +32,7 @@ async def download_all_file_from_cos(): for res_type in ['resource']: logger.info('[cos]开始下载资源文件...') resource_type_list = [ - 'character', - 'character_portrait', - 'character_preview', - 'consumable', - 'element', - 'light_cone', - 'relic', - 'skill', + 'gamedata', ] for resource_type in resource_type_list: file_dict = resource_map[res_type][resource_type] diff --git a/ArknightsUID/utils/resource/resource_map.json b/ArknightsUID/utils/resource/resource_map.json new file mode 100644 index 0000000..0e86c34 --- /dev/null +++ b/ArknightsUID/utils/resource/resource_map.json @@ -0,0 +1,194 @@ +{ + "resource": { + "gamedata": { + "activity_table.json": { + "size": 5595508, + "url": "http://182.43.43.40:8765/UploadPic/54809ad17f7f6a9a4af15f32eb2d49bd.json" + }, + "audio_data.json": { + "size": 3919762, + "url": "http://182.43.43.40:8765/UploadPic/cb205e653bc616e05e40944ec09ad6bb.json" + }, + "battle_equip_table.json": { + "size": 2938199, + "url": "http://182.43.43.40:8765/UploadPic/f22b5ad6c7ab5fb80320956083688055.json" + }, + "building_data.json": { + "size": 3539111, + "url": "http://182.43.43.40:8765/UploadPic/1d8ad3249825d02f55c03c6b657f0314.json" + }, + "campaign_table.json": { + "size": 364334, + "url": "http://182.43.43.40:8765/UploadPic/fa5ffb9d8984fb21468ee68ca9f77129.json" + }, + "chapter_table.json": { + "size": 971, + "url": "http://182.43.43.40:8765/UploadPic/37811c39da5a5982909814c1ff30bd5f.json" + }, + "character_table.json": { + "size": 10271949, + "url": "http://182.43.43.40:8765/UploadPic/9d6ddccd93eaeaa16d72f17364a4148f.json" + }, + "charm_table.json": { + "size": 112839, + "url": "http://182.43.43.40:8765/UploadPic/874f366c4b380b6ca7d3490156ed271c.json" + }, + "charword_table.json": { + "size": 7996766, + "url": "http://182.43.43.40:8765/UploadPic/e4a897073ba6484182317ce0969ec91d.json" + }, + "char_meta_table.json": { + "size": 68518, + "url": "http://182.43.43.40:8765/UploadPic/67664817336a8331018b02b3f6d54461.json" + }, + "char_patch_table.json": { + "size": 32184, + "url": "http://182.43.43.40:8765/UploadPic/9e1c18366b2a683e62ce45a046736bfc.json" + }, + "checkin_table.json": { + "size": 128629, + "url": "http://182.43.43.40:8765/UploadPic/66c5b9adff70e540de47ba9727634bd1.json" + }, + "climb_tower_table.json": { + "size": 215485, + "url": "http://182.43.43.40:8765/UploadPic/667d5191839d498745ebc964937c55fa.json" + }, + "clue_data.json": { + "size": 9157, + "url": "http://182.43.43.40:8765/UploadPic/1a4bc40c48a8ab09f1e17bd52c40694f.json" + }, + "crisis_table.json": { + "size": 26075, + "url": "http://182.43.43.40:8765/UploadPic/e0ae91a98b61c08815e7cee46d6db028.json" + }, + "display_meta_table.json": { + "size": 42176, + "url": "http://182.43.43.40:8765/UploadPic/2f404165c4f0aa8f078bff786eddb3a5.json" + }, + "enemy_handbook_table.json": { + "size": 946626, + "url": "http://182.43.43.40:8765/UploadPic/fc8e60949be7cf3e0b09a0530c17dc39.json" + }, + "favor_table.json": { + "size": 39045, + "url": "http://182.43.43.40:8765/UploadPic/a2aad37d3f67ffae35ce18aaba24898a.json" + }, + "gacha_table.json": { + "size": 229854, + "url": "http://182.43.43.40:8765/UploadPic/5c9145383fde2b02b7d2759688b4153e.json" + }, + "gamedata_const.json": { + "size": 48534, + "url": "http://182.43.43.40:8765/UploadPic/196f1730a9946ebbd4091c409a6be715.json" + }, + "handbook_info_table.json": { + "size": 3683089, + "url": "http://182.43.43.40:8765/UploadPic/d4c0f5b0d2246a099b5ae04b1d1f642d.json" + }, + "handbook_table.json": { + "size": 17270, + "url": "http://182.43.43.40:8765/UploadPic/5212c2720ab7afde6685cfdc8b580b9a.json" + }, + "handbook_team_table.json": { + "size": 11170, + "url": "http://182.43.43.40:8765/UploadPic/eb15c058fb2607fd149146b47b0657a3.json" + }, + "item_table.json": { + "size": 977369, + "url": "http://182.43.43.40:8765/UploadPic/2dea005233b875c20538a3c4f97b8ee5.json" + }, + "medal_table.json": { + "size": 898088, + "url": "http://182.43.43.40:8765/UploadPic/af9b11fbf7a1aea655ad67b7280a3a83.json" + }, + "mission_table.json": { + "size": 605772, + "url": "http://182.43.43.40:8765/UploadPic/56c25cd7e4d3a066db26147ec813ae91.json" + }, + "open_server_table.json": { + "size": 140679, + "url": "http://182.43.43.40:8765/UploadPic/409ed506ad8384719284aa1bdd4f0922.json" + }, + "player_avatar_table.json": { + "size": 9277, + "url": "http://182.43.43.40:8765/UploadPic/ed23f950d5771278aee506281dc0df5d.json" + }, + "range_table.json": { + "size": 57566, + "url": "http://182.43.43.40:8765/UploadPic/3a1f57189cc3b6098621b1ea0c3143e5.json" + }, + "replicate_table.json": { + "size": 84595, + "url": "http://182.43.43.40:8765/UploadPic/e4c9765508d0b37ffb5f50e58eeeb4d9.json" + }, + "retro_table.json": { + "size": 2782991, + "url": "http://182.43.43.40:8765/UploadPic/eba859c9e2598487bd38db26260f3a8d.json" + }, + "roguelike_table.json": { + "size": 493073, + "url": "http://182.43.43.40:8765/UploadPic/f6d59f951312558c0129b7841746574c.json" + }, + "roguelike_topic_table.json": { + "size": 5664453, + "url": "http://182.43.43.40:8765/UploadPic/3b5a2ac195e1aec964a9143f738bc334.json" + }, + "sandbox_table.json": { + "size": 792331, + "url": "http://182.43.43.40:8765/UploadPic/044c47ec055ee1fc6596d09c9229357b.json" + }, + "shop_client_table.json": { + "size": 710007, + "url": "http://182.43.43.40:8765/UploadPic/1bed49da245e48cfbc283a2f4fbf0d3b.json" + }, + "skill_table.json": { + "size": 7542154, + "url": "http://182.43.43.40:8765/UploadPic/f485f536c4bf581f01e5ecb1c56024d3.json" + }, + "skin_table.json": { + "size": 2144536, + "url": "http://182.43.43.40:8765/UploadPic/3b3d9786abc9456f30e14ca919d93316.json" + }, + "stage_table.json": { + "size": 12521439, + "url": "http://182.43.43.40:8765/UploadPic/d4b1621315770e54688c6f9b99ac333f.json" + }, + "story_review_meta_table.json": { + "size": 442837, + "url": "http://182.43.43.40:8765/UploadPic/467a1bfb27b9b105827330aa75ad1f25.json" + }, + "story_review_table.json": { + "size": 1339685, + "url": "http://182.43.43.40:8765/UploadPic/8e0228675c85d525511fcce51a4217e9.json" + }, + "story_table.json": { + "size": 1037661, + "url": "http://182.43.43.40:8765/UploadPic/ea363389eabc508c4b28ce62b00e4aef.json" + }, + "tech_buff_table.json": { + "size": 12110, + "url": "http://182.43.43.40:8765/UploadPic/e5d63aced0994d95ce6e27e13f88c84c.json" + }, + "tip_table.json": { + "size": 19659, + "url": "http://182.43.43.40:8765/UploadPic/1bc4eaf9db02b3d2abbd5581033e1f67.json" + }, + "token_table.json": { + "size": 15033, + "url": "http://182.43.43.40:8765/UploadPic/99aa92331d9b9fe28be10dbe4338e9e3.json" + }, + "uniequip_data.json": { + "size": 11460, + "url": "http://182.43.43.40:8765/UploadPic/1d89fb12977515ccb0887b391a781928.json" + }, + "uniequip_table.json": { + "size": 1694592, + "url": "http://182.43.43.40:8765/UploadPic/aa52b93a77fd427c2f40e576d976ee3e.json" + }, + "zone_table.json": { + "size": 205286, + "url": "http://182.43.43.40:8765/UploadPic/3545aed264f3fdb412712d943e4c608f.json" + } + } + } +}