bcsfe 3.2.2__tar.gz → 3.3.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.2.2/src/bcsfe.egg-info → bcsfe-3.3.0}/PKG-INFO +1 -1
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/__init__.py +1 -1
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/__init__.py +2 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/dialog_creator.py +15 -6
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/main.py +35 -3
- bcsfe-3.3.0/src/bcsfe/cli/recent_saves.py +141 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/save_management.py +39 -8
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/cat.py +3 -1
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/login_bonuses.py +6 -5
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/talent_orbs.py +31 -31
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/cat_shrine.py +3 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/config.py +1 -1
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/save.py +14 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/game_data_getter.py +19 -2
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/request.py +1 -1
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/save.properties +9 -2
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/server.properties +2 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gamototo.properties +3 -3
- {bcsfe-3.2.2 → bcsfe-3.3.0/src/bcsfe.egg-info}/PKG-INFO +1 -1
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/SOURCES.txt +1 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/tests/test_parse.py +3 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/LICENSE +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/MANIFEST.in +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/README.md +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/pyproject.toml +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/setup.cfg +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/setup.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/__main__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/color.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/aku_realm.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/basic_items.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/cat_editor.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/clear_tutorial.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/enemy_editor.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/event_tickets.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/fixes.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/map.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/max_all.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/rare_ticket_trade.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/storage.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/feature_handler.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/file_dialog.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/server_cli.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/country_code.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/crypto.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/battle_items.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/cleared_slots.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/enemy.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/slots.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/beacon_base.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/drop_chara.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/gambling.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/gatya.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/gatya_item.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/item_pack.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/matatabi.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/medals.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/mission.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/my_sale.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/nyanko_club.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/officer_pass.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/playtime.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/powerup.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/scheme_items.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/special_skill.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/stamp.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/unlock_popups.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/upgrade.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/user_rank_rewards.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/base_materials.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/catamins.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/gamatoto.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/ototo.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/localizable.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/aku.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/challenge.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/chapters.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/dojo.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/enigma.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/event.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/ex_stage.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/gauntlets.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/item_reward_stage.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/legend_quest.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/map_names.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/map_option.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/map_reset.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/outbreaks.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/story.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/timed_score.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/tower.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/uncanny.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/zero_legends.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game_version.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/adb_handler.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/bc_csv.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/command.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/data.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/git_handler.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/json_file.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/path.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/root_handler.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/thread_helper.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/waydroid.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/yaml.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/locale_handler.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/log.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/max_value_helper.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/__init__.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/client_info.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/event_data.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/headers.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/managed_item.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/server_handler.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/updater.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/theme_handler.py +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/config.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/files.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/input.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/locale.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/main.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/theme.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/updater.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/bannable_items.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/cats.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/enemy.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/fixes.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gambling.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gatya.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gold_pass.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/items.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/map.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/medals.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/missions.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/playtime.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/scheme_items.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/special_skills.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/talent_orbs.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/treasures.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/user_rank.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/config.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/files.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/input.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/locale.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/main.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/save.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/server.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/theme.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/updater.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/bannable_items.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/cats.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/enemy.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/fixes.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gambling.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gamototo.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gatya.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gold_pass.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/items.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/map.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/medals.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/missions.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/playtime.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/scheme_items.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/special_skills.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/talent_orbs.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/treasures.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/user_rank.properties +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/metadata.json +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/max_values.json +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/themes/default.json +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/themes/discord.json +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/py.typed +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/dependency_links.txt +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/entry_points.txt +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/requires.txt +0 -0
- {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/top_level.txt +0 -0
|
@@ -73,16 +73,25 @@ class IntInput:
|
|
|
73
73
|
default: int | None = None,
|
|
74
74
|
signed: bool = True,
|
|
75
75
|
bit_count: int = 32,
|
|
76
|
+
ensure_max: bool = False,
|
|
76
77
|
):
|
|
77
78
|
self.signed = signed
|
|
78
79
|
self.bit_count = bit_count
|
|
79
|
-
self.max = self.get_max_value(max, signed, bit_count)
|
|
80
|
+
self.max = self.get_max_value(max, signed, bit_count, ensure_max)
|
|
80
81
|
self.min = min
|
|
81
82
|
self.default = default
|
|
82
83
|
|
|
83
84
|
@staticmethod
|
|
84
|
-
def get_max_value(
|
|
85
|
-
|
|
85
|
+
def get_max_value(
|
|
86
|
+
max: int | None,
|
|
87
|
+
signed: bool = True,
|
|
88
|
+
bit_count: int = 32,
|
|
89
|
+
ensure_max: bool = False,
|
|
90
|
+
) -> int:
|
|
91
|
+
disable_maxes = (
|
|
92
|
+
core.core_data.config.get_bool(core.ConfigKey.DISABLE_MAXES)
|
|
93
|
+
and not ensure_max
|
|
94
|
+
)
|
|
86
95
|
if signed:
|
|
87
96
|
bit_count -= 1
|
|
88
97
|
max_int = (2**bit_count) - 1
|
|
@@ -273,9 +282,9 @@ class ChoiceInput:
|
|
|
273
282
|
start_index=self.start_index,
|
|
274
283
|
localize_elements=self.localize_options,
|
|
275
284
|
).display_locale(self.remove_alias)
|
|
276
|
-
return IntInput(
|
|
277
|
-
self.
|
|
278
|
-
)
|
|
285
|
+
return IntInput(
|
|
286
|
+
self.get_max_value(), self.get_min_value(), ensure_max=True
|
|
287
|
+
).get_input_locale(self.dialog, self.perameters)
|
|
279
288
|
|
|
280
289
|
def get_input_while(self) -> int | None:
|
|
281
290
|
if len(self.strings) == 0:
|
|
@@ -40,6 +40,26 @@ class Main:
|
|
|
40
40
|
if stop:
|
|
41
41
|
break
|
|
42
42
|
|
|
43
|
+
def version_check(self, v1: str, v2: str) -> bool:
|
|
44
|
+
v1_p = v1.split(".")
|
|
45
|
+
v2_p = v2.split(".")
|
|
46
|
+
|
|
47
|
+
for p1, p2 in zip(v1_p, v2_p):
|
|
48
|
+
if p1.isdigit():
|
|
49
|
+
p1 = int(p1)
|
|
50
|
+
else:
|
|
51
|
+
continue
|
|
52
|
+
if p2.isdigit():
|
|
53
|
+
p2 = int(p2)
|
|
54
|
+
else:
|
|
55
|
+
continue
|
|
56
|
+
if p1 > p2:
|
|
57
|
+
return True
|
|
58
|
+
if p1 < p2:
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
return len(v1_p) > len(v2_p)
|
|
62
|
+
|
|
43
63
|
def check_update(self):
|
|
44
64
|
"""Check for updates."""
|
|
45
65
|
|
|
@@ -64,16 +84,19 @@ class Main:
|
|
|
64
84
|
local_no_beta = local_version.split("b")[0]
|
|
65
85
|
latest_no_beta = latest_version.split("b")[0]
|
|
66
86
|
|
|
67
|
-
if latest_no_beta
|
|
87
|
+
if self.version_check(latest_no_beta, local_no_beta):
|
|
68
88
|
update_needed = True
|
|
69
|
-
elif latest_no_beta
|
|
89
|
+
elif self.version_check(local_no_beta, latest_no_beta):
|
|
70
90
|
update_needed = False
|
|
71
91
|
else:
|
|
72
92
|
if latest_version == local_version:
|
|
73
93
|
update_needed = False
|
|
74
94
|
else:
|
|
75
95
|
if is_local_beta and is_latest_beta:
|
|
76
|
-
update_needed =
|
|
96
|
+
update_needed = self.version_check(
|
|
97
|
+
latest_version.replace("b", "."),
|
|
98
|
+
local_version.replace("b", "."),
|
|
99
|
+
)
|
|
77
100
|
elif is_local_beta:
|
|
78
101
|
update_needed = True
|
|
79
102
|
else:
|
|
@@ -168,6 +191,15 @@ class Main:
|
|
|
168
191
|
return stop
|
|
169
192
|
self.save_file = save_file
|
|
170
193
|
|
|
194
|
+
color.ColoredText.localize(
|
|
195
|
+
"current_save",
|
|
196
|
+
inquiry_code=save_file.inquiry_code[:4]
|
|
197
|
+
+ "***"
|
|
198
|
+
+ save_file.inquiry_code[-2:],
|
|
199
|
+
gv=save_file.game_version,
|
|
200
|
+
cc=save_file.cc,
|
|
201
|
+
)
|
|
202
|
+
|
|
171
203
|
self.feature_handler()
|
|
172
204
|
return False
|
|
173
205
|
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from bcsfe import core
|
|
5
|
+
import datetime
|
|
6
|
+
import json
|
|
7
|
+
from bcsfe.cli import color, dialog_creator
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RecentSave:
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
path: core.Path,
|
|
14
|
+
cc: core.CountryCode,
|
|
15
|
+
gv: core.GameVersion,
|
|
16
|
+
inquiry: str,
|
|
17
|
+
time: datetime.datetime,
|
|
18
|
+
name: core.Path,
|
|
19
|
+
):
|
|
20
|
+
self.path = path
|
|
21
|
+
self.cc = cc
|
|
22
|
+
self.gv = gv
|
|
23
|
+
self.inquiry = inquiry
|
|
24
|
+
self.time = time
|
|
25
|
+
self.name = name
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def from_dict(data: dict[str, Any]) -> RecentSave | None:
|
|
29
|
+
path = data.get("path")
|
|
30
|
+
cc = data.get("cc")
|
|
31
|
+
gv = data.get("gv")
|
|
32
|
+
inquiry = data.get("inquiry")
|
|
33
|
+
time_stamp = data.get("timestamp")
|
|
34
|
+
name = data.get("name")
|
|
35
|
+
if (
|
|
36
|
+
path is None
|
|
37
|
+
or cc is None
|
|
38
|
+
or gv is None
|
|
39
|
+
or inquiry is None
|
|
40
|
+
or time_stamp is None
|
|
41
|
+
or name is None
|
|
42
|
+
):
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
return RecentSave(
|
|
46
|
+
core.Path(path),
|
|
47
|
+
core.CountryCode(cc),
|
|
48
|
+
core.GameVersion.from_string(gv),
|
|
49
|
+
inquiry,
|
|
50
|
+
datetime.datetime.fromtimestamp(time_stamp),
|
|
51
|
+
core.Path(name),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def to_dict(self) -> dict[str, Any]:
|
|
55
|
+
return {
|
|
56
|
+
"path": self.path.to_str(),
|
|
57
|
+
"cc": self.cc.get_code(),
|
|
58
|
+
"gv": self.gv.to_string(),
|
|
59
|
+
"inquiry": self.inquiry,
|
|
60
|
+
"timestamp": self.time.timestamp(),
|
|
61
|
+
"name": self.name.to_str(),
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class RecentSaves:
|
|
66
|
+
def __init__(self, saves: list[RecentSave]):
|
|
67
|
+
self.saves = saves
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def from_json(data: list[dict[str, Any]]) -> RecentSaves:
|
|
71
|
+
res: list[RecentSave] = []
|
|
72
|
+
|
|
73
|
+
for item in data:
|
|
74
|
+
save = RecentSave.from_dict(item)
|
|
75
|
+
if save is not None:
|
|
76
|
+
res.append(save)
|
|
77
|
+
|
|
78
|
+
return RecentSaves(res)
|
|
79
|
+
|
|
80
|
+
def to_json(self) -> list[dict[str, Any]]:
|
|
81
|
+
return [save.to_dict() for save in self.saves][-10:] # only store 10
|
|
82
|
+
|
|
83
|
+
@staticmethod
|
|
84
|
+
def from_path(path: core.Path) -> RecentSaves | None:
|
|
85
|
+
json_data = json.loads(path.read().to_str())
|
|
86
|
+
|
|
87
|
+
return RecentSaves.from_json(json_data)
|
|
88
|
+
|
|
89
|
+
def to_path(self, path: core.Path):
|
|
90
|
+
data = json.dumps(self.to_json(), indent=4)
|
|
91
|
+
|
|
92
|
+
path.write(core.Data(data))
|
|
93
|
+
|
|
94
|
+
@staticmethod
|
|
95
|
+
def read_default() -> RecentSaves:
|
|
96
|
+
path = RecentSaves.get_path()
|
|
97
|
+
if path.exists():
|
|
98
|
+
return RecentSaves.from_path(path) or RecentSaves([])
|
|
99
|
+
return RecentSaves([])
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
def get_path() -> core.Path:
|
|
103
|
+
return core.Path.get_documents_folder().add("recent_saves.json")
|
|
104
|
+
|
|
105
|
+
def save_default(self):
|
|
106
|
+
path = RecentSaves.get_path()
|
|
107
|
+
self.to_path(path)
|
|
108
|
+
|
|
109
|
+
def select(self) -> RecentSave | None:
|
|
110
|
+
if not self.saves:
|
|
111
|
+
color.ColoredText.localize("no_recent_saves")
|
|
112
|
+
return None
|
|
113
|
+
items: list[str] = []
|
|
114
|
+
for save in self.saves:
|
|
115
|
+
items.append(
|
|
116
|
+
core.localize(
|
|
117
|
+
"recent_save",
|
|
118
|
+
path=save.path,
|
|
119
|
+
cc=save.cc,
|
|
120
|
+
gv=save.gv,
|
|
121
|
+
inquiry_code=save.inquiry,
|
|
122
|
+
year=save.time.year,
|
|
123
|
+
month=str(save.time.month).zfill(2),
|
|
124
|
+
day=str(save.time.day).zfill(2),
|
|
125
|
+
hour=str(save.time.hour).zfill(2),
|
|
126
|
+
minute=str(save.time.minute).zfill(2),
|
|
127
|
+
second=str(save.time.second).zfill(2),
|
|
128
|
+
name=save.name,
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
items.reverse()
|
|
132
|
+
|
|
133
|
+
resp = dialog_creator.ChoiceInput.from_reduced(
|
|
134
|
+
items, localize_options=False, dialog="select_recent"
|
|
135
|
+
).single_choice()
|
|
136
|
+
if resp is None:
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
resp = len(self.saves) - resp
|
|
140
|
+
|
|
141
|
+
return self.saves[resp]
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
import datetime
|
|
2
3
|
from bcsfe import core
|
|
3
4
|
import bcsfe
|
|
4
5
|
from bcsfe.core import io
|
|
5
|
-
from bcsfe.cli import main, color, dialog_creator, server_cli
|
|
6
|
+
from bcsfe.cli import main, color, dialog_creator, server_cli, recent_saves
|
|
6
7
|
from bcsfe.core.country_code import CountryCode
|
|
7
8
|
from bcsfe.core.io.config import ConfigKey
|
|
8
9
|
|
|
@@ -350,7 +351,7 @@ class SaveManagement:
|
|
|
350
351
|
)
|
|
351
352
|
if file is None:
|
|
352
353
|
return (None, True)
|
|
353
|
-
return (file, False)
|
|
354
|
+
return (file[0], False)
|
|
354
355
|
|
|
355
356
|
options = [
|
|
356
357
|
"download_save",
|
|
@@ -358,6 +359,7 @@ class SaveManagement:
|
|
|
358
359
|
"load_from_documents",
|
|
359
360
|
"adb_pull_save",
|
|
360
361
|
"load_save_data_json",
|
|
362
|
+
# "load_recent_saves",
|
|
361
363
|
# "create_new_save",
|
|
362
364
|
]
|
|
363
365
|
if starting_options:
|
|
@@ -463,6 +465,14 @@ class SaveManagement:
|
|
|
463
465
|
save_path, cc = data
|
|
464
466
|
else:
|
|
465
467
|
save_path = None
|
|
468
|
+
# elif choice == 5:
|
|
469
|
+
# recent_save = recent_saves.RecentSaves.read_default().select()
|
|
470
|
+
# if recent_save is None:
|
|
471
|
+
# save_path = None
|
|
472
|
+
# else:
|
|
473
|
+
# save_path = recent_save.path
|
|
474
|
+
# cc = recent_save.cc
|
|
475
|
+
|
|
466
476
|
# elif choice == 5:
|
|
467
477
|
# color.ColoredText.localize("create_new_save_warning")
|
|
468
478
|
# cc = core.CountryCode.select()
|
|
@@ -494,10 +504,30 @@ class SaveManagement:
|
|
|
494
504
|
if save_path is None or not save_path.exists():
|
|
495
505
|
return None, False
|
|
496
506
|
|
|
507
|
+
save = SaveManagement.load_save_file_path(
|
|
508
|
+
save_path, cc, used_storage, package_name
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
if save is None:
|
|
512
|
+
return (None, False)
|
|
513
|
+
|
|
514
|
+
save, backup_path = save
|
|
515
|
+
|
|
516
|
+
if choice != 5:
|
|
517
|
+
recent_s = recent_saves.RecentSaves.read_default()
|
|
518
|
+
recent_s.saves.append(
|
|
519
|
+
recent_saves.RecentSave(
|
|
520
|
+
backup_path,
|
|
521
|
+
save.cc,
|
|
522
|
+
save.game_version,
|
|
523
|
+
save.inquiry_code,
|
|
524
|
+
datetime.datetime.now(),
|
|
525
|
+
save_path,
|
|
526
|
+
)
|
|
527
|
+
)
|
|
528
|
+
recent_s.save_default()
|
|
497
529
|
return (
|
|
498
|
-
|
|
499
|
-
save_path, cc, used_storage, package_name
|
|
500
|
-
),
|
|
530
|
+
save,
|
|
501
531
|
False,
|
|
502
532
|
)
|
|
503
533
|
|
|
@@ -507,7 +537,7 @@ class SaveManagement:
|
|
|
507
537
|
cc: CountryCode | None,
|
|
508
538
|
used_storage: bool,
|
|
509
539
|
package_name: str | None = None,
|
|
510
|
-
) -> core.SaveFile | None:
|
|
540
|
+
) -> tuple[core.SaveFile, core.Path] | None:
|
|
511
541
|
color.ColoredText.localize("save_file_found", path=save_path)
|
|
512
542
|
|
|
513
543
|
data = save_path.read()
|
|
@@ -546,10 +576,11 @@ class SaveManagement:
|
|
|
546
576
|
return None
|
|
547
577
|
|
|
548
578
|
save_file.save_path = save_path
|
|
549
|
-
save_file.
|
|
579
|
+
backup_path = save_file.get_default_path()
|
|
580
|
+
save_file.save_path.copy_thread(backup_path)
|
|
550
581
|
save_file.used_storage = used_storage
|
|
551
582
|
|
|
552
|
-
return save_file
|
|
583
|
+
return save_file, backup_path
|
|
553
584
|
|
|
554
585
|
@staticmethod
|
|
555
586
|
def select_package_name(package_names: list[str]) -> str | None:
|
|
@@ -1208,6 +1208,8 @@ class Cats:
|
|
|
1208
1208
|
for _ in range(total_cats):
|
|
1209
1209
|
cat_id = stream.read_int()
|
|
1210
1210
|
if cat_id < 0 or cat_id >= len(self.cats):
|
|
1211
|
+
cat = Cat.init(cat_id)
|
|
1212
|
+
cat.read_talents(stream)
|
|
1211
1213
|
continue
|
|
1212
1214
|
self.cats[cat_id].read_talents(stream)
|
|
1213
1215
|
|
|
@@ -1217,7 +1219,7 @@ class Cats:
|
|
|
1217
1219
|
total_talents += 1 if cat.talents is not None else 0
|
|
1218
1220
|
stream.write_int(total_talents)
|
|
1219
1221
|
for cat in self.cats:
|
|
1220
|
-
if
|
|
1222
|
+
if cat.talents is None:
|
|
1221
1223
|
continue
|
|
1222
1224
|
stream.write_int(cat.id)
|
|
1223
1225
|
cat.write_talents(stream)
|
|
@@ -133,11 +133,12 @@ class LoginBonus:
|
|
|
133
133
|
return LoginBonus(logins=logins)
|
|
134
134
|
|
|
135
135
|
def write(self, stream: core.Data, gv: core.GameVersion):
|
|
136
|
-
if gv < 80000
|
|
137
|
-
self.old_logins.write(stream)
|
|
138
|
-
elif gv >= 80000
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
if gv < 80000:
|
|
137
|
+
(self.old_logins or LoginSets([])).write(stream)
|
|
138
|
+
elif gv >= 80000:
|
|
139
|
+
logins = self.logins or {}
|
|
140
|
+
stream.write_int(len(logins))
|
|
141
|
+
for id, login in logins.items():
|
|
141
142
|
stream.write_int(id)
|
|
142
143
|
login.write(stream)
|
|
143
144
|
|
|
@@ -451,30 +451,30 @@ def color_from_grade(grade_id: int) -> str:
|
|
|
451
451
|
|
|
452
452
|
|
|
453
453
|
def color_from_effect(effect_id: int):
|
|
454
|
-
if effect_id == 0:
|
|
455
|
-
|
|
456
|
-
elif effect_id == 1:
|
|
457
|
-
|
|
458
|
-
elif effect_id == 2:
|
|
459
|
-
|
|
460
|
-
elif effect_id == 3:
|
|
461
|
-
|
|
462
|
-
elif effect_id == 4:
|
|
463
|
-
|
|
464
|
-
elif effect_id == 5:
|
|
465
|
-
|
|
466
|
-
elif effect_id == 6:
|
|
467
|
-
|
|
468
|
-
elif effect_id == 7:
|
|
469
|
-
|
|
470
|
-
elif effect_id == 8:
|
|
471
|
-
|
|
472
|
-
elif effect_id == 9:
|
|
473
|
-
|
|
474
|
-
elif effect_id == 10:
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
return
|
|
454
|
+
# if effect_id == 0:
|
|
455
|
+
# return color.ColorHex.RED
|
|
456
|
+
# elif effect_id == 1:
|
|
457
|
+
# return color.ColorHex.GREEN
|
|
458
|
+
# elif effect_id == 2:
|
|
459
|
+
# return color.ColorHex.DARK_GREY
|
|
460
|
+
# elif effect_id == 3:
|
|
461
|
+
# return color.ColorHex.LIGHT_GREY
|
|
462
|
+
# elif effect_id == 4:
|
|
463
|
+
# return color.ColorHex.YELLOW
|
|
464
|
+
# elif effect_id == 5:
|
|
465
|
+
# return color.ColorHex.BLUE
|
|
466
|
+
# elif effect_id == 6:
|
|
467
|
+
# return color.ColorHex.MAGENTA
|
|
468
|
+
# elif effect_id == 7:
|
|
469
|
+
# return color.ColorHex.DARK_GREEN
|
|
470
|
+
# elif effect_id == 8:
|
|
471
|
+
# return color.ColorHex.WHITE
|
|
472
|
+
# elif effect_id == 9:
|
|
473
|
+
# return color.ColorHex.DARK_MAGENTA
|
|
474
|
+
# elif effect_id == 10:
|
|
475
|
+
# return color.ColorHex.ORANGE
|
|
476
|
+
|
|
477
|
+
return "@t"
|
|
478
478
|
|
|
479
479
|
|
|
480
480
|
class SaveOrbs:
|
|
@@ -556,23 +556,23 @@ class SaveOrbs:
|
|
|
556
556
|
all_effects = self.orb_info_list.get_all_effects()
|
|
557
557
|
all_effects.sort()
|
|
558
558
|
all_effects_str = [
|
|
559
|
-
effect.lower().replace("%@", "").replace(":", "").strip() + f" ({i})"
|
|
559
|
+
effect.lower().replace("%@", "").replace(":", "").strip() + f" <@s>({i})</>"
|
|
560
560
|
for (i, effect) in enumerate(all_effects)
|
|
561
561
|
]
|
|
562
562
|
all_effect_ids = [i for i in range(len(all_effects))]
|
|
563
563
|
|
|
564
|
-
all_grades_str = "".join(
|
|
565
|
-
f"<{color_from_grade(self.orb_info_list.get_all_grades().index(grade))}>{grade}
|
|
564
|
+
all_grades_str = ",".join(
|
|
565
|
+
f"<{color_from_grade(self.orb_info_list.get_all_grades().index(grade))}>{grade}</>"
|
|
566
566
|
for grade in all_grades
|
|
567
567
|
)
|
|
568
568
|
|
|
569
|
-
all_attributes_str = "".join(
|
|
570
|
-
f"<{color_from_enemy_type(self.orb_info_list.get_all_attributes().index(attribute))}>{attribute}
|
|
569
|
+
all_attributes_str = ",".join(
|
|
570
|
+
f"<{color_from_enemy_type(self.orb_info_list.get_all_attributes().index(attribute))}>{attribute}</>"
|
|
571
571
|
for attribute in all_attributes
|
|
572
572
|
)
|
|
573
573
|
|
|
574
|
-
all_effects_str = "".join(
|
|
575
|
-
f"<{color_from_effect(self.orb_info_list.get_all_effects().index(effect))}>{effect_str}
|
|
574
|
+
all_effects_str = ", ".join(
|
|
575
|
+
f"<{color_from_effect(self.orb_info_list.get_all_effects().index(effect))}>{effect_str}</>"
|
|
576
576
|
for effect_str, effect in zip(all_effects_str, all_effects)
|
|
577
577
|
)
|
|
578
578
|
|
|
@@ -1234,6 +1234,10 @@ class SaveFile:
|
|
|
1234
1234
|
val = self.data.read_byte()
|
|
1235
1235
|
self.uil11.append(val)
|
|
1236
1236
|
|
|
1237
|
+
if self.game_version >= 150300:
|
|
1238
|
+
self.ui24 = self.data.read_int()
|
|
1239
|
+
self.ub38 = self.data.read_bool()
|
|
1240
|
+
|
|
1237
1241
|
self.ub36 = self.data.read_bool()
|
|
1238
1242
|
|
|
1239
1243
|
length = self.data.read_byte()
|
|
@@ -2206,6 +2210,10 @@ class SaveFile:
|
|
|
2206
2210
|
for val in self.uil11:
|
|
2207
2211
|
self.data.write_byte(val)
|
|
2208
2212
|
|
|
2213
|
+
if self.game_version >= 150300:
|
|
2214
|
+
self.data.write_int(self.ui24)
|
|
2215
|
+
self.data.write_bool(self.ub38)
|
|
2216
|
+
|
|
2209
2217
|
self.data.write_bool(self.ub36)
|
|
2210
2218
|
|
|
2211
2219
|
self.data.write_byte(len(self.treasure_chests))
|
|
@@ -2574,6 +2582,8 @@ class SaveFile:
|
|
|
2574
2582
|
"ui23": self.ui23,
|
|
2575
2583
|
"uil13": self.uil13,
|
|
2576
2584
|
"ub37": self.ub37,
|
|
2585
|
+
"ub38": self.ub38,
|
|
2586
|
+
"ui24": self.ui24,
|
|
2577
2587
|
"remaining_data": base64.b64encode(self.remaining_data).decode("utf-8"),
|
|
2578
2588
|
}
|
|
2579
2589
|
return data
|
|
@@ -2960,6 +2970,8 @@ class SaveFile:
|
|
|
2960
2970
|
save_file.ui23 = data.get("ui23", 0)
|
|
2961
2971
|
save_file.uil13 = data.get("uil13", [])
|
|
2962
2972
|
save_file.ub37 = data.get("ub37", False)
|
|
2973
|
+
save_file.ub38 = data.get("ub38", False)
|
|
2974
|
+
save_file.ui24 = data.get("ui24", 0)
|
|
2963
2975
|
|
|
2964
2976
|
save_file.remaining_data = base64.b64decode(data.get("remaining_data", ""))
|
|
2965
2977
|
|
|
@@ -3011,6 +3023,7 @@ class SaveFile:
|
|
|
3011
3023
|
self.ub35 = False
|
|
3012
3024
|
self.ub36 = False
|
|
3013
3025
|
self.ub37 = False
|
|
3026
|
+
self.ub38 = False
|
|
3014
3027
|
|
|
3015
3028
|
self.mute_bgm = False
|
|
3016
3029
|
self.mute_se = False
|
|
@@ -3050,6 +3063,7 @@ class SaveFile:
|
|
|
3050
3063
|
self.ui21 = 0
|
|
3051
3064
|
self.ui22 = 0
|
|
3052
3065
|
self.ui23 = 0
|
|
3066
|
+
self.ui24 = 0
|
|
3053
3067
|
|
|
3054
3068
|
self.catfood = 0
|
|
3055
3069
|
self.current_energy = 0
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
from io import BytesIO
|
|
3
3
|
from typing import Any, Callable
|
|
4
4
|
|
|
5
|
-
from bcsfe.cli import color
|
|
5
|
+
from bcsfe.cli import color, dialog_creator
|
|
6
6
|
|
|
7
7
|
import tarfile
|
|
8
8
|
|
|
@@ -82,9 +82,26 @@ class GameDataGetter:
|
|
|
82
82
|
return cc_version_keys[-1], cc_versions[cc_version_keys[-1]]
|
|
83
83
|
return gv_string, cc_versions[gv_string]
|
|
84
84
|
|
|
85
|
-
def get_metadata(self) -> dict[str, Any] | None:
|
|
85
|
+
def get_metadata(self, show_alt: bool = True) -> dict[str, Any] | None:
|
|
86
86
|
response = core.RequestHandler(self.repo_url).get()
|
|
87
87
|
if response is None:
|
|
88
|
+
if (
|
|
89
|
+
self.repo_url
|
|
90
|
+
== core.core_data.config.get_default(core.ConfigKey.GAME_DATA_REPO)
|
|
91
|
+
and show_alt
|
|
92
|
+
):
|
|
93
|
+
alt = "https://gitlab.com/fieryhenry/bcdata/-/raw/main/metadata.json"
|
|
94
|
+
res = dialog_creator.YesNoInput().get_input_once(
|
|
95
|
+
"use_alternative_repo",
|
|
96
|
+
{
|
|
97
|
+
"repo": "https://gitlab.com/fieryhenry/bcdata/-/raw/main/metadata.json"
|
|
98
|
+
},
|
|
99
|
+
)
|
|
100
|
+
if res:
|
|
101
|
+
core.core_data.config.set(core.ConfigKey.GAME_DATA_REPO, alt)
|
|
102
|
+
self.repo_url = alt
|
|
103
|
+
return self.get_metadata(show_alt=False)
|
|
104
|
+
|
|
88
105
|
return None
|
|
89
106
|
try:
|
|
90
107
|
data = response.json()
|
|
@@ -88,7 +88,7 @@ class RequestHandler:
|
|
|
88
88
|
stream=stream,
|
|
89
89
|
files=None if self.form is None else self.form.into_files(),
|
|
90
90
|
)
|
|
91
|
-
except requests.exceptions.ConnectionError:
|
|
91
|
+
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
|
|
92
92
|
return None
|
|
93
93
|
|
|
94
94
|
def post(self, no_timeout: bool = False) -> requests.Response | None:
|
|
@@ -80,8 +80,8 @@ game_version_set=<@su>Succesfully set game version to <@s>{version}</>
|
|
|
80
80
|
convert_region=Convert country code (e.g en -\> jp)
|
|
81
81
|
convert_version=Convert game version (e.g 12.2.1 -\> 12.2.0)
|
|
82
82
|
|
|
83
|
-
cc_warning=<@w>Warning: This may cause issues with your save file. Bugs and crashes are expected! If reporting a bug, please ensure to mention you have used this feature.</>\nCurrent country code: <@t>{current}</>
|
|
84
|
-
gv_warning=<@w>Warning: This may cause issues with your save file. Bugs and crashes are expected! If reporting a bug, plesae ensure to mention you have used this feature.</>\nCurrent game version: <@t>{current}</>
|
|
83
|
+
cc_warning=<@w>Warning: This may cause issues with your save file. Bugs and crashes are expected! If reporting a bug, please ensure to mention you have used this feature. You should enter the cat base / upgrade menu after running this feature so the game makes the necessary changes to your save file.</>\nCurrent country code: <@t>{current}</>
|
|
84
|
+
gv_warning=<@w>Warning: This may cause issues with your save file. Bugs and crashes are expected! If reporting a bug, plesae ensure to mention you have used this feature. You should enter the cat base / upgrade menu after running this feature so the game makes the necessary changes to your save file.</>\nCurrent game version: <@t>{current}</>
|
|
85
85
|
|
|
86
86
|
create_new_save_success=<@su>Succesfully created new save file</>
|
|
87
87
|
create_new_save=Create new save file
|
|
@@ -107,3 +107,10 @@ root_rerun_fail=<@e>Failed to rerun game. Error: <@s>{error}</></>
|
|
|
107
107
|
|
|
108
108
|
root_push=Use root to push save directly to the game
|
|
109
109
|
root_push_rerun=Use root to push save directly to the game (and rerun the game)
|
|
110
|
+
|
|
111
|
+
select_recent=Select recent save:
|
|
112
|
+
recent_save=<@s><@q>{inquiry_code}</> <@t>{cc}</>-<@t>{gv}</> @ <@t>{year}</>-<@t>{month}</>-<@t>{day}</> <@t>{hour}</>:<@t>{minute}</>:<@t>{second}</> - original path: <@q>{name}</></>
|
|
113
|
+
|
|
114
|
+
load_recent_saves=Load from recent saves and backups
|
|
115
|
+
no_recent_saves=<@w>No recent saves</>
|
|
116
|
+
current_save=\nCurrent Save: <@t>{cc}</>-<@t>{gv}</> Inquiry: <@t>{inquiry_code}</>
|
|
@@ -54,3 +54,5 @@ validating_game_repo=Validating game data repo...
|
|
|
54
54
|
invalid_response=<@e>Invalid response code: <@s>{response_code}</>. Expected <@s>200</></>
|
|
55
55
|
no_internet_or_connection_error=<@e>Failed to connect to game data repo</>
|
|
56
56
|
invalid_url=<@e>Invalid URL</>
|
|
57
|
+
|
|
58
|
+
use_alternative_repo=<@e>Failed to fetch game data repo, this may be an issue with your internet connection or the repo is blocked on your network.</> Would you like to swap to <@t>{repo}</t> as an alternative game data repo? ({{y/n}}):
|
|
@@ -44,11 +44,11 @@ cannon_level=Cannon Level
|
|
|
44
44
|
|
|
45
45
|
cannon_success=<@su>Succesfully edited ototo cannons</>
|
|
46
46
|
|
|
47
|
-
cat_shrine=Cat Shrine
|
|
48
|
-
shrine_level=Shrine Level
|
|
47
|
+
cat_shrine=Edit Cat Shrine
|
|
48
|
+
shrine_level=Edit Shrine Level
|
|
49
49
|
shrine_xp=Shrine XP
|
|
50
50
|
current_shrine_xp_level=<@t>Current XP: <@q>{xp}</> (Level: <@q>{level}</>)</>
|
|
51
|
-
cat_shrine_choice_dialog=
|
|
51
|
+
cat_shrine_choice_dialog=What do you want to do?:
|
|
52
52
|
shrine_level_dialog=Enter cat shrine level (max: <@q>{max_level}</>):
|
|
53
53
|
shrine_xp_dialog=Enter cat shrine XP (max: <@q>{max_xp}</>):
|
|
54
54
|
cat_shrine_edited=<@su>Succesfully edited cat shrine</>
|