bcsfe 3.3.0__tar.gz → 3.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bcsfe-3.3.0/src/bcsfe.egg-info → bcsfe-3.4.0}/PKG-INFO +6 -4
- {bcsfe-3.3.0 → bcsfe-3.4.0}/README.md +5 -3
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/__init__.py +1 -1
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/__main__.py +16 -2
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/cat_editor.py +6 -4
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/storage.py +31 -2
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/feature_handler.py +36 -40
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/main.py +2 -4
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/recent_saves.py +5 -2
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/save_management.py +13 -8
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/server_cli.py +7 -1
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/__init__.py +20 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/gatya.py +1 -1
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/config.py +1 -1
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/git_handler.py +2 -4
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/path.py +47 -7
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/root_handler.py +1 -1
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/save.py +10 -3
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/locale_handler.py +1 -1
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/log.py +11 -18
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/game_data_getter.py +6 -5
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/server_handler.py +8 -6
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/theme_handler.py +3 -11
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/save.properties +4 -3
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/cats.properties +2 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/special_skills.properties +1 -1
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/config.properties +95 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/files.properties +9 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/input.properties +31 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/locale.properties +33 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/main.properties +111 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/save.properties +117 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/server.properties +58 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/theme.properties +24 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/core/updater.properties +19 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/bannable_items.properties +30 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/cats.properties +160 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/enemy.properties +17 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/fixes.properties +13 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/gambling.properties +3 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/gamototo.properties +56 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/gatya.properties +8 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/gold_pass.properties +6 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/items.properties +64 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/map.properties +178 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/medals.properties +8 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/missions.properties +7 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/playtime.properties +7 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/scheme_items.properties +6 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/special_skills.properties +10 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/talent_orbs.properties +26 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/treasures.properties +24 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/edits/user_rank.properties +9 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/tw/metadata.json +4 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/config.properties +95 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/vi/core/files.properties +1 -1
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/input.properties +33 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/locale.properties +118 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/main.properties +75 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/save.properties +84 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/server.properties +31 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/theme.properties +24 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/core/updater.properties +20 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/bannable_items.properties +31 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/cats.properties +154 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/enemy.properties +18 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/fixes.properties +13 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/vi/edits/gambling.properties +4 -3
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/gamototo.properties +56 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/gatya.properties +9 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/gold_pass.properties +7 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/items.properties +65 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/map.properties +177 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/medals.properties +9 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/missions.properties +8 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/playtime.properties +8 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/vi/edits/scheme_items.properties +1 -1
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/vi/edits/special_skills.properties +3 -3
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/talent_orbs.properties +24 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/treasures.properties +25 -0
- bcsfe-3.4.0/src/bcsfe/files/locales/vi/edits/user_rank.properties +10 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0/src/bcsfe.egg-info}/PKG-INFO +6 -4
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe.egg-info/SOURCES.txt +28 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/tests/test_parse.py +0 -3
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/config.properties +0 -97
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/input.properties +0 -32
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/locale.properties +0 -33
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/main.properties +0 -113
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/save.properties +0 -107
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/server.properties +0 -51
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/theme.properties +0 -25
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/core/updater.properties +0 -20
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/bannable_items.properties +0 -31
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/cats.properties +0 -166
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/enemy.properties +0 -18
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/fixes.properties +0 -14
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/gamototo.properties +0 -55
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/gatya.properties +0 -9
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/gold_pass.properties +0 -7
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/items.properties +0 -56
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/map.properties +0 -158
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/medals.properties +0 -9
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/missions.properties +0 -8
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/playtime.properties +0 -8
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/talent_orbs.properties +0 -25
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/treasures.properties +0 -25
- bcsfe-3.3.0/src/bcsfe/files/locales/vi/edits/user_rank.properties +0 -10
- {bcsfe-3.3.0 → bcsfe-3.4.0}/LICENSE +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/MANIFEST.in +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/pyproject.toml +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/setup.cfg +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/setup.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/color.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/dialog_creator.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/aku_realm.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/basic_items.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/clear_tutorial.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/enemy_editor.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/event_tickets.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/fixes.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/map.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/max_all.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/edits/rare_ticket_trade.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/cli/file_dialog.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/country_code.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/crypto.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/battle/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/battle/battle_items.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/battle/cleared_slots.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/battle/enemy.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/battle/slots.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/beacon_base.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/cat.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/drop_chara.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/gambling.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/gatya_item.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/item_pack.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/login_bonuses.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/matatabi.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/medals.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/mission.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/my_sale.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/nyanko_club.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/officer_pass.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/playtime.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/powerup.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/scheme_items.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/special_skill.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/stamp.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/talent_orbs.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/unlock_popups.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/upgrade.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/catbase/user_rank_rewards.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/gamoto/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/gamoto/base_materials.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/gamoto/cat_shrine.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/gamoto/catamins.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/gamoto/gamatoto.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/gamoto/ototo.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/localizable.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/aku.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/challenge.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/chapters.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/dojo.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/enigma.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/event.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/ex_stage.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/gauntlets.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/item_reward_stage.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/legend_quest.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/map_names.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/map_option.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/map_reset.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/outbreaks.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/story.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/timed_score.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/tower.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/uncanny.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game/map/zero_legends.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/game_version.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/adb_handler.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/bc_csv.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/command.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/data.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/json_file.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/thread_helper.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/waydroid.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/io/yaml.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/max_value_helper.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/__init__.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/client_info.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/event_data.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/headers.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/managed_item.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/request.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/core/server/updater.py +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/config.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/files.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/input.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/locale.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/main.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/server.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/theme.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/core/updater.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/bannable_items.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/enemy.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/fixes.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/gambling.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/gamototo.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/gatya.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/gold_pass.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/items.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/map.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/medals.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/missions.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/playtime.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/scheme_items.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/talent_orbs.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/treasures.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/en/edits/user_rank.properties +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/locales/vi/metadata.json +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/max_values.json +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/themes/default.json +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/files/themes/discord.json +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe/py.typed +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe.egg-info/dependency_links.txt +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe.egg-info/entry_points.txt +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe.egg-info/requires.txt +0 -0
- {bcsfe-3.3.0 → bcsfe-3.4.0}/src/bcsfe.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bcsfe
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.0
|
|
4
4
|
Summary: A save file editor for The Battle Cats
|
|
5
5
|
Author: fieryhenry
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -56,6 +56,8 @@ test/develop new features
|
|
|
56
56
|
|
|
57
57
|
- HungJoesifer for Vietnamese localization
|
|
58
58
|
|
|
59
|
+
- LinYuAn for Traditional Chinese localization
|
|
60
|
+
|
|
59
61
|
### Themes
|
|
60
62
|
|
|
61
63
|
- HungJoesifer for the `discord` inspired theme
|
|
@@ -330,7 +332,7 @@ Once you have installed and ran the editor, you can now begin to edit your save
|
|
|
330
332
|
|
|
331
333
|
1. In `The Battle Cats` enter the `Change Account / Device` menu in the `Settings` on the main menu.
|
|
332
334
|
|
|
333
|
-
2. Then enter the `
|
|
335
|
+
2. Then enter the `Change Device` -> `Retrieve Data from Old Device` menu.
|
|
334
336
|
|
|
335
337
|
3. Then click / tap `Save Data to Server`, this should give you a transfer code and a confirmation
|
|
336
338
|
code.
|
|
@@ -359,8 +361,8 @@ may also fail, if it does then try again.
|
|
|
359
361
|
11. Back in-game, tap the `Close Game` button, then tap `Cancel Data Transfer` (and also possibly
|
|
360
362
|
`Start Game From Beginning`)
|
|
361
363
|
|
|
362
|
-
12. Go back into the `Change Account / Device` menu and then go into the `Resume Data Transfer`
|
|
363
|
-
menu
|
|
364
|
+
12. Go back into the `Change Account / Device` menu and then go into the `Resume Data Transfer` ->
|
|
365
|
+
`Transfer Data to New Device` menu
|
|
364
366
|
|
|
365
367
|
13. Enter the new codes, and tap `Resume Transfer`
|
|
366
368
|
|
|
@@ -27,6 +27,8 @@ test/develop new features
|
|
|
27
27
|
|
|
28
28
|
- HungJoesifer for Vietnamese localization
|
|
29
29
|
|
|
30
|
+
- LinYuAn for Traditional Chinese localization
|
|
31
|
+
|
|
30
32
|
### Themes
|
|
31
33
|
|
|
32
34
|
- HungJoesifer for the `discord` inspired theme
|
|
@@ -301,7 +303,7 @@ Once you have installed and ran the editor, you can now begin to edit your save
|
|
|
301
303
|
|
|
302
304
|
1. In `The Battle Cats` enter the `Change Account / Device` menu in the `Settings` on the main menu.
|
|
303
305
|
|
|
304
|
-
2. Then enter the `
|
|
306
|
+
2. Then enter the `Change Device` -> `Retrieve Data from Old Device` menu.
|
|
305
307
|
|
|
306
308
|
3. Then click / tap `Save Data to Server`, this should give you a transfer code and a confirmation
|
|
307
309
|
code.
|
|
@@ -330,8 +332,8 @@ may also fail, if it does then try again.
|
|
|
330
332
|
11. Back in-game, tap the `Close Game` button, then tap `Cancel Data Transfer` (and also possibly
|
|
331
333
|
`Start Game From Beginning`)
|
|
332
334
|
|
|
333
|
-
12. Go back into the `Change Account / Device` menu and then go into the `Resume Data Transfer`
|
|
334
|
-
menu
|
|
335
|
+
12. Go back into the `Change Account / Device` menu and then go into the `Resume Data Transfer` ->
|
|
336
|
+
`Transfer Data to New Device` menu
|
|
335
337
|
|
|
336
338
|
13. Enter the new codes, and tap `Resume Transfer`
|
|
337
339
|
|
|
@@ -18,19 +18,27 @@ def main():
|
|
|
18
18
|
parser.add_argument(
|
|
19
19
|
"--input-path", "-i", type=str, help="input path to save file to edit"
|
|
20
20
|
)
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"--game-data-dir", "-g", type=str, help="path to store the game data to"
|
|
23
|
+
)
|
|
24
|
+
parser.add_argument(
|
|
25
|
+
"--transfer-backup-path",
|
|
26
|
+
type=str,
|
|
27
|
+
help="path to save the backup SAVE_DATA after transfering to",
|
|
28
|
+
)
|
|
21
29
|
parser.add_argument(
|
|
22
30
|
"--config-path",
|
|
23
31
|
"-c",
|
|
24
32
|
type=str,
|
|
25
33
|
default=None,
|
|
26
|
-
help="path to the config file. If unspecified defaults to
|
|
34
|
+
help=f"path to the config file. If unspecified defaults to {core.Config.get_config_path()}",
|
|
27
35
|
)
|
|
28
36
|
parser.add_argument(
|
|
29
37
|
"--log-path",
|
|
30
38
|
"-l",
|
|
31
39
|
type=str,
|
|
32
40
|
default=None,
|
|
33
|
-
help="path to the log file. If unspecified defaults to
|
|
41
|
+
help=f"path to the log file. If unspecified defaults to {core.Logger.get_log_path()}",
|
|
34
42
|
)
|
|
35
43
|
|
|
36
44
|
args = parser.parse_args()
|
|
@@ -44,6 +52,12 @@ def main():
|
|
|
44
52
|
if args.log_path is not None:
|
|
45
53
|
core.set_log_path(core.Path(args.log_path))
|
|
46
54
|
|
|
55
|
+
if args.transfer_backup_path is not None:
|
|
56
|
+
core.set_transfer_backup_path(core.Path(args.transfer_backup_path))
|
|
57
|
+
|
|
58
|
+
if args.game_data_dir is not None:
|
|
59
|
+
core.set_game_data_path(core.Path(args.game_data_dir))
|
|
60
|
+
|
|
47
61
|
core.core_data.init_data()
|
|
48
62
|
|
|
49
63
|
try:
|
|
@@ -413,8 +413,9 @@ class CatEditor:
|
|
|
413
413
|
if should_exit:
|
|
414
414
|
return
|
|
415
415
|
if upgrade is not None:
|
|
416
|
-
|
|
417
|
-
|
|
416
|
+
if upgrade.base != -1:
|
|
417
|
+
power_up.reset_upgrade()
|
|
418
|
+
power_up.upgrade_by(upgrade.base)
|
|
418
419
|
cat.set_upgrade(self.save_file, upgrade, True)
|
|
419
420
|
color.ColoredText.localize(
|
|
420
421
|
"selected_cat_upgraded",
|
|
@@ -435,8 +436,9 @@ class CatEditor:
|
|
|
435
436
|
success = True
|
|
436
437
|
for cat in cats:
|
|
437
438
|
power_up = core.PowerUpHelper(cat, self.save_file)
|
|
438
|
-
|
|
439
|
-
|
|
439
|
+
if upgrade.base != -1:
|
|
440
|
+
power_up.reset_upgrade()
|
|
441
|
+
power_up.upgrade_by(upgrade.base)
|
|
440
442
|
cat.set_upgrade(self.save_file, upgrade, True)
|
|
441
443
|
if success:
|
|
442
444
|
color.ColoredText.localize("upgrade_success")
|
|
@@ -128,6 +128,23 @@ def edit_loop(save_file: core.SaveFile) -> bool:
|
|
|
128
128
|
if editor is None:
|
|
129
129
|
return False
|
|
130
130
|
|
|
131
|
+
new_cats: list[core.Cat] = []
|
|
132
|
+
for cat in cats:
|
|
133
|
+
names = cat.get_names_cls(save_file)
|
|
134
|
+
if names is None or not names:
|
|
135
|
+
name = core.localize("unknown")
|
|
136
|
+
else:
|
|
137
|
+
name = names[0]
|
|
138
|
+
quantity, _ = dialog_creator.IntInput(default=1).get_input_locale(
|
|
139
|
+
"cat_quantity", {"name": name, "id": cat.id}
|
|
140
|
+
)
|
|
141
|
+
if quantity is None:
|
|
142
|
+
return False
|
|
143
|
+
for _ in range(quantity):
|
|
144
|
+
new_cats.append(cat)
|
|
145
|
+
|
|
146
|
+
cats = new_cats
|
|
147
|
+
|
|
131
148
|
space = get_storage_space(storage)
|
|
132
149
|
if len(cats) > len(storage):
|
|
133
150
|
color.ColoredText.localize(
|
|
@@ -164,6 +181,19 @@ def edit_loop(save_file: core.SaveFile) -> bool:
|
|
|
164
181
|
if options is None:
|
|
165
182
|
return False
|
|
166
183
|
|
|
184
|
+
items: list[core.StorageItem] = []
|
|
185
|
+
|
|
186
|
+
for id in options:
|
|
187
|
+
item = core.StorageItem.from_special_skill(id)
|
|
188
|
+
|
|
189
|
+
quantity, _ = dialog_creator.IntInput(default=1).get_input_locale(
|
|
190
|
+
"skill_quantity", {"name": skill_names[id]}
|
|
191
|
+
)
|
|
192
|
+
if quantity is None:
|
|
193
|
+
return False
|
|
194
|
+
for _ in range(quantity):
|
|
195
|
+
items.append(item)
|
|
196
|
+
|
|
167
197
|
space = get_storage_space(storage)
|
|
168
198
|
if len(options) > len(storage):
|
|
169
199
|
color.ColoredText.localize(
|
|
@@ -177,8 +207,7 @@ def edit_loop(save_file: core.SaveFile) -> bool:
|
|
|
177
207
|
return False
|
|
178
208
|
|
|
179
209
|
color.ColoredText.localize("added_special_skills")
|
|
180
|
-
for
|
|
181
|
-
item = core.StorageItem.from_special_skill(choice)
|
|
210
|
+
for item in items:
|
|
182
211
|
add_item(storage, item)
|
|
183
212
|
display_item(item, save_file)
|
|
184
213
|
|
|
@@ -8,7 +8,7 @@ class FeatureHandler:
|
|
|
8
8
|
def __init__(self, save_file: core.SaveFile):
|
|
9
9
|
self.save_file = save_file
|
|
10
10
|
|
|
11
|
-
def get_features(self):
|
|
11
|
+
def get_features(self) -> dict[str, Any]:
|
|
12
12
|
cat_features = {"cats": edits.cat_editor.CatEditor.edit_cats}
|
|
13
13
|
if core.core_data.config.get_bool(core.ConfigKey.SEPARATE_CAT_EDIT_OPTIONS):
|
|
14
14
|
cat_features = {
|
|
@@ -33,7 +33,9 @@ class FeatureHandler:
|
|
|
33
33
|
"save_save": save_management.SaveManagement.save_save,
|
|
34
34
|
"save_upload": save_management.SaveManagement.save_upload,
|
|
35
35
|
"save_save_file": save_management.SaveManagement.save_save_dialog,
|
|
36
|
-
|
|
36
|
+
core.localize(
|
|
37
|
+
"save_save_documents", path=core.SaveFile.get_save_path()
|
|
38
|
+
): save_management.SaveManagement.save_save_data_dir,
|
|
37
39
|
"waydroid_push": save_management.SaveManagement.waydroid_push,
|
|
38
40
|
"waydroid_push_rerun": save_management.SaveManagement.waydroid_push_rerun,
|
|
39
41
|
"adb_push": save_management.SaveManagement.adb_push,
|
|
@@ -142,8 +144,7 @@ class FeatureHandler:
|
|
|
142
144
|
}
|
|
143
145
|
return features
|
|
144
146
|
|
|
145
|
-
def get_feature(self,
|
|
146
|
-
feature_path = feature_name.split(".")
|
|
147
|
+
def get_feature(self, feature_path: list[str]):
|
|
147
148
|
feature_dict = self.get_features()
|
|
148
149
|
feature = feature_dict
|
|
149
150
|
for path in feature_path:
|
|
@@ -154,10 +155,10 @@ class FeatureHandler:
|
|
|
154
155
|
def search_features(
|
|
155
156
|
self,
|
|
156
157
|
name: str,
|
|
157
|
-
|
|
158
|
+
current_path: list[str],
|
|
158
159
|
features: dict[str, Any] | None = None,
|
|
159
|
-
found_features: dict[str, int] | None = None,
|
|
160
|
-
) -> dict[str, int]:
|
|
160
|
+
found_features: dict[tuple[str, ...], int] | None = None,
|
|
161
|
+
) -> dict[tuple[str, ...], int]:
|
|
161
162
|
name = name.lower()
|
|
162
163
|
if features is None:
|
|
163
164
|
features = self.get_features()
|
|
@@ -166,9 +167,8 @@ class FeatureHandler:
|
|
|
166
167
|
|
|
167
168
|
for feature_name_key, feature in features.items():
|
|
168
169
|
feature_name = core.core_data.local_manager.get_key(feature_name_key)
|
|
169
|
-
path = (
|
|
170
|
-
|
|
171
|
-
)
|
|
170
|
+
path = current_path.copy()
|
|
171
|
+
path.append(feature_name_key)
|
|
172
172
|
if isinstance(feature, dict):
|
|
173
173
|
found_features.update(
|
|
174
174
|
self.search_features(
|
|
@@ -180,34 +180,36 @@ class FeatureHandler:
|
|
|
180
180
|
)
|
|
181
181
|
for alias in core.LocalManager.get_all_aliases(feature_name):
|
|
182
182
|
if not name:
|
|
183
|
-
found_features[path] = 100
|
|
183
|
+
found_features[*path] = 100
|
|
184
184
|
break
|
|
185
185
|
alias = alias.lower()
|
|
186
186
|
|
|
187
187
|
name = name.replace(" ", "")
|
|
188
188
|
alias = alias.replace(" ", "")
|
|
189
189
|
if alias in name or name in alias:
|
|
190
|
-
found_features[path] = 100
|
|
190
|
+
found_features[*path] = 100
|
|
191
191
|
break
|
|
192
192
|
|
|
193
193
|
return found_features
|
|
194
194
|
|
|
195
|
-
def display_features(self, features: list[str]):
|
|
195
|
+
def display_features(self, features: list[list[str]]):
|
|
196
196
|
feature_names: list[str] = []
|
|
197
197
|
for feature_name in features:
|
|
198
|
-
feature_names.append(feature_name
|
|
198
|
+
feature_names.append(feature_name[-1])
|
|
199
199
|
print()
|
|
200
200
|
dialog_creator.ListOutput(feature_names, [], "features", {}).display_locale(
|
|
201
201
|
remove_alias=True
|
|
202
202
|
)
|
|
203
203
|
|
|
204
|
-
def select_features(
|
|
204
|
+
def select_features(
|
|
205
|
+
self, features: list[list[str]], current_path: list[str]
|
|
206
|
+
) -> list[list[str]]:
|
|
205
207
|
if features != list(self.get_features().keys()):
|
|
206
|
-
features.insert(0, "go_back")
|
|
208
|
+
features.insert(0, ["go_back"])
|
|
207
209
|
self.display_features(features)
|
|
208
210
|
print()
|
|
209
211
|
usr_input = color.ColoredInput().localize("select_features").strip()
|
|
210
|
-
selected_features: list[str] = []
|
|
212
|
+
selected_features: list[list[str]] = []
|
|
211
213
|
if usr_input.isdigit():
|
|
212
214
|
usr_input = int(usr_input)
|
|
213
215
|
if usr_input > len(features):
|
|
@@ -216,59 +218,53 @@ class FeatureHandler:
|
|
|
216
218
|
color.ColoredText.localize("invalid_input")
|
|
217
219
|
else:
|
|
218
220
|
feature_name_top = features[usr_input - 1]
|
|
219
|
-
if feature_name_top == "go_back":
|
|
220
|
-
return
|
|
221
|
+
if feature_name_top == ["go_back"]:
|
|
222
|
+
return [[k] for k in self.get_features().keys()]
|
|
221
223
|
feature = self.get_feature(feature_name_top)
|
|
222
224
|
if isinstance(feature, dict):
|
|
223
225
|
for feature_name in feature.keys(): # type: ignore
|
|
224
|
-
feature_path = (
|
|
225
|
-
|
|
226
|
-
if parent_path
|
|
227
|
-
else f"{feature_name_top}.{feature_name}"
|
|
228
|
-
)
|
|
226
|
+
feature_path: list[str] = current_path.copy()
|
|
227
|
+
feature_path.extend(feature_name_top + [feature_name])
|
|
229
228
|
selected_features.append(feature_path)
|
|
230
229
|
|
|
231
230
|
else:
|
|
232
|
-
feature_path = (
|
|
233
|
-
|
|
234
|
-
if parent_path
|
|
235
|
-
else feature_name_top
|
|
236
|
-
)
|
|
231
|
+
feature_path = current_path.copy()
|
|
232
|
+
feature_path.extend(feature_name_top)
|
|
237
233
|
selected_features.append(feature_path)
|
|
238
234
|
|
|
239
235
|
else:
|
|
240
|
-
feats = self.search_features(usr_input)
|
|
236
|
+
feats = self.search_features(usr_input, [])
|
|
241
237
|
if not feats:
|
|
242
238
|
color.ColoredText.localize("no_feature_with_name", name=usr_input)
|
|
243
239
|
kv_map = list(feats.items())
|
|
244
240
|
kv_map.sort(key=lambda v: v[1], reverse=True)
|
|
245
|
-
selected_features = [v[0] for v in kv_map]
|
|
241
|
+
selected_features = [list(v[0]) for v in kv_map]
|
|
246
242
|
|
|
247
243
|
return selected_features
|
|
248
244
|
|
|
249
245
|
def select_features_run(self):
|
|
250
|
-
|
|
251
|
-
features =
|
|
246
|
+
features_dict = self.get_features()
|
|
247
|
+
features: list[list[str]] = [[k] for k in features_dict.keys()]
|
|
252
248
|
self.save_file.to_file_thread(self.save_file.get_temp_path())
|
|
253
249
|
edits.clear_tutorial.clear_tutorial(self.save_file, False)
|
|
254
250
|
self.save_file.show_ban_message = False
|
|
255
251
|
|
|
256
252
|
while True:
|
|
257
|
-
features = self.select_features(features)
|
|
253
|
+
features = self.select_features(features, [])
|
|
258
254
|
|
|
259
|
-
new_features: list[str] = []
|
|
255
|
+
new_features: list[list[str]] = []
|
|
260
256
|
found_strs: list[str] = []
|
|
261
257
|
for feature_ in features:
|
|
262
|
-
if feature_
|
|
258
|
+
if feature_[-1] in found_strs:
|
|
263
259
|
continue
|
|
264
|
-
found_strs.append(feature_
|
|
260
|
+
found_strs.append(feature_[-1])
|
|
265
261
|
new_features.append(feature_)
|
|
266
262
|
|
|
267
263
|
features = new_features
|
|
268
264
|
feature = None
|
|
269
265
|
if len(features) == 1:
|
|
270
266
|
feature = features[0]
|
|
271
|
-
if len(features) == 2 and features[0] == "go_back":
|
|
267
|
+
if len(features) == 2 and features[0] == ["go_back"]:
|
|
272
268
|
feature = features[1]
|
|
273
269
|
|
|
274
270
|
if not feature:
|
|
@@ -283,8 +279,8 @@ class FeatureHandler:
|
|
|
283
279
|
|
|
284
280
|
self.save_file.to_file_thread(self.save_file.get_temp_path())
|
|
285
281
|
|
|
286
|
-
|
|
287
|
-
features =
|
|
282
|
+
features_dict = self.get_features()
|
|
283
|
+
features = [[k] for k in features_dict.keys()]
|
|
288
284
|
|
|
289
285
|
core.core_data.game_data_getter = None # reset game data getter so that if an old version is removed, it will download the new version
|
|
290
286
|
|
|
@@ -291,10 +291,8 @@ class Main:
|
|
|
291
291
|
return None
|
|
292
292
|
try:
|
|
293
293
|
json_data = core.JsonFile.from_data(path.read()).to_object()
|
|
294
|
-
except core.JSONDecodeError:
|
|
295
|
-
color.ColoredText.localize(
|
|
296
|
-
"load_json_fail", error=core.core_data.logger.get_traceback()
|
|
297
|
-
)
|
|
294
|
+
except (core.JSONDecodeError, UnicodeDecodeError):
|
|
295
|
+
color.ColoredText.localize("parse_json_fail")
|
|
298
296
|
return None
|
|
299
297
|
try:
|
|
300
298
|
save_file = core.SaveFile.from_dict(json_data)
|
|
@@ -89,7 +89,10 @@ class RecentSaves:
|
|
|
89
89
|
def to_path(self, path: core.Path):
|
|
90
90
|
data = json.dumps(self.to_json(), indent=4)
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
try:
|
|
93
|
+
path.write(core.Data(data))
|
|
94
|
+
except Exception as e:
|
|
95
|
+
print(e)
|
|
93
96
|
|
|
94
97
|
@staticmethod
|
|
95
98
|
def read_default() -> RecentSaves:
|
|
@@ -100,7 +103,7 @@ class RecentSaves:
|
|
|
100
103
|
|
|
101
104
|
@staticmethod
|
|
102
105
|
def get_path() -> core.Path:
|
|
103
|
-
return core.Path.
|
|
106
|
+
return core.Path.get_data_folder().add("recent_saves.json")
|
|
104
107
|
|
|
105
108
|
def save_default(self):
|
|
106
109
|
path = RecentSaves.get_path()
|
|
@@ -27,7 +27,11 @@ class SaveManagement:
|
|
|
27
27
|
if save_file.save_path is None:
|
|
28
28
|
return
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
try:
|
|
31
|
+
save_file.to_file(save_file.save_path)
|
|
32
|
+
except OSError as e:
|
|
33
|
+
print(e)
|
|
34
|
+
return
|
|
31
35
|
|
|
32
36
|
color.ColoredText.localize("save_success", path=save_file.save_path)
|
|
33
37
|
|
|
@@ -48,14 +52,14 @@ class SaveManagement:
|
|
|
48
52
|
color.ColoredText.localize("save_success", path=save_file.save_path)
|
|
49
53
|
|
|
50
54
|
@staticmethod
|
|
51
|
-
def
|
|
52
|
-
"""Save the save file to the
|
|
55
|
+
def save_save_data_dir(save_file: core.SaveFile):
|
|
56
|
+
"""Save the save file to the data folder.
|
|
53
57
|
|
|
54
58
|
Args:
|
|
55
59
|
save_file (core.SaveFile): The save file to save.
|
|
56
60
|
"""
|
|
57
61
|
SaveManagement.upload_items_checker(save_file)
|
|
58
|
-
save_file.save_path = core.SaveFile.
|
|
62
|
+
save_file.save_path = core.SaveFile.get_save_path()
|
|
59
63
|
save_file.to_file(save_file.save_path)
|
|
60
64
|
color.ColoredText.localize("save_success", path=save_file.save_path)
|
|
61
65
|
|
|
@@ -356,11 +360,9 @@ class SaveManagement:
|
|
|
356
360
|
options = [
|
|
357
361
|
"download_save",
|
|
358
362
|
"select_save_file",
|
|
359
|
-
"load_from_documents",
|
|
363
|
+
core.localize("load_from_documents", path=core.SaveFile.get_save_path()),
|
|
360
364
|
"adb_pull_save",
|
|
361
365
|
"load_save_data_json",
|
|
362
|
-
# "load_recent_saves",
|
|
363
|
-
# "create_new_save",
|
|
364
366
|
]
|
|
365
367
|
if starting_options:
|
|
366
368
|
options.append("edit_config")
|
|
@@ -577,7 +579,10 @@ class SaveManagement:
|
|
|
577
579
|
|
|
578
580
|
save_file.save_path = save_path
|
|
579
581
|
backup_path = save_file.get_default_path()
|
|
580
|
-
|
|
582
|
+
try:
|
|
583
|
+
save_file.save_path.copy_thread(backup_path)
|
|
584
|
+
except Exception as e:
|
|
585
|
+
print(e)
|
|
581
586
|
save_file.used_storage = used_storage
|
|
582
587
|
|
|
583
588
|
return save_file, backup_path
|
|
@@ -64,7 +64,13 @@ class ServerCLI:
|
|
|
64
64
|
if path is None:
|
|
65
65
|
return None
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
try:
|
|
68
|
+
save_file.to_file(path)
|
|
69
|
+
except OSError as e:
|
|
70
|
+
print(
|
|
71
|
+
f"failed to write save file to: {path} due to: {e}. Skipping writing the save file to disk"
|
|
72
|
+
)
|
|
73
|
+
input("press enter to continue anyway")
|
|
68
74
|
|
|
69
75
|
color.ColoredText.localize("save_downloaded", path=path.to_str())
|
|
70
76
|
|
|
@@ -299,6 +299,8 @@ class CoreData:
|
|
|
299
299
|
config_path = None
|
|
300
300
|
print_config_err = True
|
|
301
301
|
log_path = None
|
|
302
|
+
transfer_backup_path = None
|
|
303
|
+
game_data_path = None
|
|
302
304
|
|
|
303
305
|
|
|
304
306
|
def set_config_path(path: Path):
|
|
@@ -306,11 +308,29 @@ def set_config_path(path: Path):
|
|
|
306
308
|
config_path = path
|
|
307
309
|
|
|
308
310
|
|
|
311
|
+
def set_game_data_path(path: Path):
|
|
312
|
+
global game_data_path
|
|
313
|
+
game_data_path = path
|
|
314
|
+
|
|
315
|
+
|
|
309
316
|
def set_log_path(path: Path):
|
|
310
317
|
global log_path
|
|
311
318
|
log_path = path
|
|
312
319
|
|
|
313
320
|
|
|
321
|
+
def set_transfer_backup_path(path: Path):
|
|
322
|
+
global transfer_backup_path
|
|
323
|
+
transfer_backup_path = path
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def get_transfer_backup_path() -> Path | None:
|
|
327
|
+
return transfer_backup_path
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def get_game_data_path() -> Path | None:
|
|
331
|
+
return game_data_path
|
|
332
|
+
|
|
333
|
+
|
|
314
334
|
def update_external_content(_: Any = None):
|
|
315
335
|
"""Updates external content."""
|
|
316
336
|
|
|
@@ -48,7 +48,7 @@ class Config:
|
|
|
48
48
|
|
|
49
49
|
@staticmethod
|
|
50
50
|
def get_config_path() -> core.Path:
|
|
51
|
-
return core.Path.
|
|
51
|
+
return core.Path.get_config_folder().add("config.yaml")
|
|
52
52
|
|
|
53
53
|
def __getitem__(self, key: ConfigKey) -> Any:
|
|
54
54
|
return self.config[key]
|
|
@@ -52,9 +52,7 @@ class Repo:
|
|
|
52
52
|
except FileNotFoundError:
|
|
53
53
|
return None
|
|
54
54
|
|
|
55
|
-
def get_temp_file(
|
|
56
|
-
self, temp_folder: core.Path, file_path: core.Path
|
|
57
|
-
) -> core.Data:
|
|
55
|
+
def get_temp_file(self, temp_folder: core.Path, file_path: core.Path) -> core.Data:
|
|
58
56
|
path = temp_folder.add(file_path)
|
|
59
57
|
return path.read()
|
|
60
58
|
|
|
@@ -74,7 +72,7 @@ class Repo:
|
|
|
74
72
|
class GitHandler:
|
|
75
73
|
@staticmethod
|
|
76
74
|
def get_repo_folder() -> core.Path:
|
|
77
|
-
repo_folder = core.Path.
|
|
75
|
+
repo_folder = core.Path.get_data_folder().add("repos")
|
|
78
76
|
repo_folder.generate_dirs()
|
|
79
77
|
return repo_folder
|
|
80
78
|
|
|
@@ -74,12 +74,22 @@ class Path:
|
|
|
74
74
|
return self.path.replace("\\", "/")
|
|
75
75
|
|
|
76
76
|
@staticmethod
|
|
77
|
-
def
|
|
77
|
+
def get_data_folder(app_name: str = "bcsfe") -> Path:
|
|
78
78
|
os_name = os.name
|
|
79
79
|
if os_name == "nt":
|
|
80
80
|
path = Path.join(os.environ["USERPROFILE"], "Documents", app_name)
|
|
81
81
|
elif os_name == "posix":
|
|
82
|
-
|
|
82
|
+
data_home = os.environ.get("XDG_DATA_HOME")
|
|
83
|
+
if data_home is None:
|
|
84
|
+
path = Path.join(os.environ["HOME"], ".local", "share", app_name)
|
|
85
|
+
else:
|
|
86
|
+
path = Path.join(data_home, app_name)
|
|
87
|
+
|
|
88
|
+
# migrate old data
|
|
89
|
+
if path.is_empty():
|
|
90
|
+
orig = Path.join(os.environ["HOME"], "Documents", app_name)
|
|
91
|
+
orig.copy(path)
|
|
92
|
+
|
|
83
93
|
elif os_name == "mac":
|
|
84
94
|
path = Path.join(os.environ["HOME"], "Documents", app_name)
|
|
85
95
|
else:
|
|
@@ -87,6 +97,41 @@ class Path:
|
|
|
87
97
|
path.generate_dirs()
|
|
88
98
|
return path
|
|
89
99
|
|
|
100
|
+
@staticmethod
|
|
101
|
+
def get_config_folder(app_name: str = "bcsfe") -> Path:
|
|
102
|
+
os_name = os.name
|
|
103
|
+
if os_name != "posix":
|
|
104
|
+
return Path.get_data_folder()
|
|
105
|
+
|
|
106
|
+
data_home = os.environ.get("XDG_CONFIG_HOME")
|
|
107
|
+
if data_home is None:
|
|
108
|
+
path = Path.join(os.environ["HOME"], ".config", app_name)
|
|
109
|
+
else:
|
|
110
|
+
path = Path.join(data_home, app_name)
|
|
111
|
+
path.generate_dirs()
|
|
112
|
+
|
|
113
|
+
# migrate from old Documents location
|
|
114
|
+
if path.is_empty():
|
|
115
|
+
orig = Path.join(os.environ["HOME"], "Documents", app_name, "config.yaml")
|
|
116
|
+
if orig.exists():
|
|
117
|
+
orig.copy(path.join("config.yaml"))
|
|
118
|
+
return path
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def get_state_folder(app_name: str = "bcsfe") -> Path:
|
|
122
|
+
os_name = os.name
|
|
123
|
+
if os_name != "posix":
|
|
124
|
+
return Path.get_data_folder()
|
|
125
|
+
data_home = os.environ.get("XDG_STATE_HOME")
|
|
126
|
+
if data_home is None:
|
|
127
|
+
path = Path.join(os.environ["HOME"], ".local", "state", app_name)
|
|
128
|
+
else:
|
|
129
|
+
path = Path.join(data_home, app_name)
|
|
130
|
+
path.generate_dirs()
|
|
131
|
+
|
|
132
|
+
# no need to migrate log file really
|
|
133
|
+
return path
|
|
134
|
+
|
|
90
135
|
def is_empty(self) -> bool:
|
|
91
136
|
return self.path == ""
|
|
92
137
|
|
|
@@ -100,11 +145,6 @@ class Path:
|
|
|
100
145
|
print(e, self)
|
|
101
146
|
return self
|
|
102
147
|
|
|
103
|
-
def create(self) -> Path:
|
|
104
|
-
if not self.exists():
|
|
105
|
-
self.write(core.Data("test"))
|
|
106
|
-
return self
|
|
107
|
-
|
|
108
148
|
def exists(self) -> bool:
|
|
109
149
|
return os.path.exists(self.path)
|
|
110
150
|
|
|
@@ -78,7 +78,7 @@ class RootHandler:
|
|
|
78
78
|
self, local_path: core.Path | None = None
|
|
79
79
|
) -> tuple[core.Path | None, core.CommandResult]:
|
|
80
80
|
if local_path is None:
|
|
81
|
-
local_path = core.Path.
|
|
81
|
+
local_path = core.Path.get_data_folder().add("saves").add("SAVE_DATA")
|
|
82
82
|
local_path.parent().generate_dirs()
|
|
83
83
|
result = self.save_battlecats_save(local_path)
|
|
84
84
|
if not result.success:
|