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.
Files changed (184) hide show
  1. {bcsfe-3.2.2/src/bcsfe.egg-info → bcsfe-3.3.0}/PKG-INFO +1 -1
  2. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/__init__.py +1 -1
  3. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/__init__.py +2 -0
  4. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/dialog_creator.py +15 -6
  5. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/main.py +35 -3
  6. bcsfe-3.3.0/src/bcsfe/cli/recent_saves.py +141 -0
  7. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/save_management.py +39 -8
  8. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/cat.py +3 -1
  9. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/login_bonuses.py +6 -5
  10. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/talent_orbs.py +31 -31
  11. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/cat_shrine.py +3 -0
  12. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/config.py +1 -1
  13. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/save.py +14 -0
  14. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/game_data_getter.py +19 -2
  15. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/request.py +1 -1
  16. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/save.properties +9 -2
  17. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/server.properties +2 -0
  18. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gamototo.properties +3 -3
  19. {bcsfe-3.2.2 → bcsfe-3.3.0/src/bcsfe.egg-info}/PKG-INFO +1 -1
  20. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/SOURCES.txt +1 -0
  21. {bcsfe-3.2.2 → bcsfe-3.3.0}/tests/test_parse.py +3 -0
  22. {bcsfe-3.2.2 → bcsfe-3.3.0}/LICENSE +0 -0
  23. {bcsfe-3.2.2 → bcsfe-3.3.0}/MANIFEST.in +0 -0
  24. {bcsfe-3.2.2 → bcsfe-3.3.0}/README.md +0 -0
  25. {bcsfe-3.2.2 → bcsfe-3.3.0}/pyproject.toml +0 -0
  26. {bcsfe-3.2.2 → bcsfe-3.3.0}/setup.cfg +0 -0
  27. {bcsfe-3.2.2 → bcsfe-3.3.0}/setup.py +0 -0
  28. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/__main__.py +0 -0
  29. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/color.py +0 -0
  30. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/__init__.py +0 -0
  31. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/aku_realm.py +0 -0
  32. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/basic_items.py +0 -0
  33. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/cat_editor.py +0 -0
  34. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/clear_tutorial.py +0 -0
  35. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/enemy_editor.py +0 -0
  36. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/event_tickets.py +0 -0
  37. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/fixes.py +0 -0
  38. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/map.py +0 -0
  39. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/max_all.py +0 -0
  40. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/rare_ticket_trade.py +0 -0
  41. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/edits/storage.py +0 -0
  42. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/feature_handler.py +0 -0
  43. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/file_dialog.py +0 -0
  44. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/cli/server_cli.py +0 -0
  45. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/__init__.py +0 -0
  46. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/country_code.py +0 -0
  47. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/crypto.py +0 -0
  48. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/__init__.py +0 -0
  49. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/__init__.py +0 -0
  50. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/battle_items.py +0 -0
  51. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/cleared_slots.py +0 -0
  52. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/enemy.py +0 -0
  53. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/battle/slots.py +0 -0
  54. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/__init__.py +0 -0
  55. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/beacon_base.py +0 -0
  56. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/drop_chara.py +0 -0
  57. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/gambling.py +0 -0
  58. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/gatya.py +0 -0
  59. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/gatya_item.py +0 -0
  60. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/item_pack.py +0 -0
  61. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/matatabi.py +0 -0
  62. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/medals.py +0 -0
  63. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/mission.py +0 -0
  64. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/my_sale.py +0 -0
  65. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/nyanko_club.py +0 -0
  66. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/officer_pass.py +0 -0
  67. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/playtime.py +0 -0
  68. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/powerup.py +0 -0
  69. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/scheme_items.py +0 -0
  70. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/special_skill.py +0 -0
  71. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/stamp.py +0 -0
  72. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/unlock_popups.py +0 -0
  73. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/upgrade.py +0 -0
  74. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/catbase/user_rank_rewards.py +0 -0
  75. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/__init__.py +0 -0
  76. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/base_materials.py +0 -0
  77. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/catamins.py +0 -0
  78. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/gamatoto.py +0 -0
  79. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/gamoto/ototo.py +0 -0
  80. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/localizable.py +0 -0
  81. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/__init__.py +0 -0
  82. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/aku.py +0 -0
  83. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/challenge.py +0 -0
  84. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/chapters.py +0 -0
  85. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/dojo.py +0 -0
  86. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/enigma.py +0 -0
  87. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/event.py +0 -0
  88. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/ex_stage.py +0 -0
  89. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/gauntlets.py +0 -0
  90. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/item_reward_stage.py +0 -0
  91. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/legend_quest.py +0 -0
  92. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/map_names.py +0 -0
  93. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/map_option.py +0 -0
  94. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/map_reset.py +0 -0
  95. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/outbreaks.py +0 -0
  96. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/story.py +0 -0
  97. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/timed_score.py +0 -0
  98. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/tower.py +0 -0
  99. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/uncanny.py +0 -0
  100. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game/map/zero_legends.py +0 -0
  101. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/game_version.py +0 -0
  102. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/__init__.py +0 -0
  103. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/adb_handler.py +0 -0
  104. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/bc_csv.py +0 -0
  105. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/command.py +0 -0
  106. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/data.py +0 -0
  107. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/git_handler.py +0 -0
  108. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/json_file.py +0 -0
  109. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/path.py +0 -0
  110. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/root_handler.py +0 -0
  111. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/thread_helper.py +0 -0
  112. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/waydroid.py +0 -0
  113. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/io/yaml.py +0 -0
  114. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/locale_handler.py +0 -0
  115. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/log.py +0 -0
  116. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/max_value_helper.py +0 -0
  117. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/__init__.py +0 -0
  118. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/client_info.py +0 -0
  119. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/event_data.py +0 -0
  120. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/headers.py +0 -0
  121. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/managed_item.py +0 -0
  122. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/server_handler.py +0 -0
  123. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/server/updater.py +0 -0
  124. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/core/theme_handler.py +0 -0
  125. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/config.properties +0 -0
  126. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/files.properties +0 -0
  127. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/input.properties +0 -0
  128. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/locale.properties +0 -0
  129. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/main.properties +0 -0
  130. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/theme.properties +0 -0
  131. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/core/updater.properties +0 -0
  132. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/bannable_items.properties +0 -0
  133. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/cats.properties +0 -0
  134. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/enemy.properties +0 -0
  135. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/fixes.properties +0 -0
  136. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gambling.properties +0 -0
  137. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gatya.properties +0 -0
  138. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/gold_pass.properties +0 -0
  139. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/items.properties +0 -0
  140. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/map.properties +0 -0
  141. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/medals.properties +0 -0
  142. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/missions.properties +0 -0
  143. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/playtime.properties +0 -0
  144. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/scheme_items.properties +0 -0
  145. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/special_skills.properties +0 -0
  146. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/talent_orbs.properties +0 -0
  147. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/treasures.properties +0 -0
  148. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/en/edits/user_rank.properties +0 -0
  149. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/config.properties +0 -0
  150. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/files.properties +0 -0
  151. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/input.properties +0 -0
  152. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/locale.properties +0 -0
  153. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/main.properties +0 -0
  154. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/save.properties +0 -0
  155. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/server.properties +0 -0
  156. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/theme.properties +0 -0
  157. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/core/updater.properties +0 -0
  158. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/bannable_items.properties +0 -0
  159. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/cats.properties +0 -0
  160. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/enemy.properties +0 -0
  161. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/fixes.properties +0 -0
  162. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gambling.properties +0 -0
  163. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gamototo.properties +0 -0
  164. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gatya.properties +0 -0
  165. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/gold_pass.properties +0 -0
  166. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/items.properties +0 -0
  167. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/map.properties +0 -0
  168. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/medals.properties +0 -0
  169. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/missions.properties +0 -0
  170. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/playtime.properties +0 -0
  171. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/scheme_items.properties +0 -0
  172. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/special_skills.properties +0 -0
  173. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/talent_orbs.properties +0 -0
  174. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/treasures.properties +0 -0
  175. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/edits/user_rank.properties +0 -0
  176. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/locales/vi/metadata.json +0 -0
  177. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/max_values.json +0 -0
  178. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/themes/default.json +0 -0
  179. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/files/themes/discord.json +0 -0
  180. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe/py.typed +0 -0
  181. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/dependency_links.txt +0 -0
  182. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/entry_points.txt +0 -0
  183. {bcsfe-3.2.2 → bcsfe-3.3.0}/src/bcsfe.egg-info/requires.txt +0 -0
  184. {bcsfe-3.2.2 → bcsfe-3.3.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.2.2
3
+ Version: 3.3.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
@@ -1,4 +1,4 @@
1
- __version__ = "3.2.2"
1
+ __version__ = "3.3.0"
2
2
 
3
3
  from bcsfe import core, cli
4
4
 
@@ -7,6 +7,7 @@ from bcsfe.cli import (
7
7
  save_management,
8
8
  server_cli,
9
9
  edits,
10
+ recent_saves,
10
11
  )
11
12
 
12
13
  __all__ = [
@@ -18,4 +19,5 @@ __all__ = [
18
19
  "save_management",
19
20
  "server_cli",
20
21
  "edits",
22
+ "recent_saves",
21
23
  ]
@@ -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(max: int | None, signed: bool = True, bit_count: int = 32) -> int:
85
- disable_maxes = core.core_data.config.get_bool(core.ConfigKey.DISABLE_MAXES)
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(self.get_max_value(), self.get_min_value()).get_input_locale(
277
- self.dialog, self.perameters
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 > local_no_beta:
87
+ if self.version_check(latest_no_beta, local_no_beta):
68
88
  update_needed = True
69
- elif latest_no_beta < local_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 = latest_version > local_version
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
- SaveManagement.load_save_file_path(
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.save_path.copy_thread(save_file.get_default_path())
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 not cat.talents:
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 and self.old_logins is not None:
137
- self.old_logins.write(stream)
138
- elif gv >= 80000 and self.logins is not None:
139
- stream.write_int(len(self.logins))
140
- for id, login in self.logins.items():
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
- 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 color.ColorHex.BLACK
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
 
@@ -109,6 +109,9 @@ class CatShrine:
109
109
 
110
110
  if choice == 2:
111
111
  shrine.shrine_gone = False
112
+
113
+ shrine.stamp_1 = 0.0
114
+ shrine.stamp_2 = 0.0
112
115
  color.ColoredText.localize("cat_shrine_edited")
113
116
  return
114
117
  elif choice == 3:
@@ -232,7 +232,7 @@ class Config:
232
232
  "game_data_repo_dialog", {}
233
233
  )
234
234
  if value is None:
235
- return
235
+ value = self.get_default(ConfigKey.GAME_DATA_REPO)
236
236
  color.ColoredText.localize("validating_game_repo")
237
237
  try:
238
238
  resp = core.RequestHandler(value).get()
@@ -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=Do you want to edit the cat shrine <@t>level</> or the cat shrine <@t>XP</>?:
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</>