ksaa 2025.7.7.0__py3-none-any.whl → 2025.7.13.0__py3-none-any.whl
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.
- kotonebot/backend/context/context.py +23 -10
- kotonebot/errors.py +5 -1
- kotonebot/kaa/common.py +2 -976
- kotonebot/kaa/config/__init__.py +62 -0
- kotonebot/kaa/config/const.py +255 -0
- kotonebot/kaa/config/migrations/__init__.py +28 -0
- kotonebot/kaa/config/migrations/_idol.py +106 -0
- kotonebot/kaa/config/migrations/_v1_to_v2.py +203 -0
- kotonebot/kaa/config/migrations/_v2_to_v3.py +126 -0
- kotonebot/kaa/config/migrations/_v3_to_v4.py +29 -0
- kotonebot/kaa/config/migrations/_v4_to_v5.py +26 -0
- kotonebot/kaa/config/migrations/_v5_to_v6.py +134 -0
- kotonebot/kaa/config/produce.py +255 -0
- kotonebot/kaa/config/schema.py +236 -0
- kotonebot/kaa/config/upgrade.py +63 -0
- kotonebot/kaa/game_ui/commu_event_buttons.py +3 -0
- kotonebot/kaa/game_ui/schedule.py +1 -1
- kotonebot/kaa/main/gr.py +821 -172
- kotonebot/kaa/main/kaa.py +23 -13
- kotonebot/kaa/metadata.py +45 -0
- kotonebot/kaa/resources/__pycache__/__init__.cpython-310.pyc +0 -0
- kotonebot/kaa/tasks/R.py +126 -126
- kotonebot/kaa/tasks/daily/acquire_activity_funds.py +1 -1
- kotonebot/kaa/tasks/daily/acquire_presents.py +1 -1
- kotonebot/kaa/tasks/daily/assignment.py +1 -1
- kotonebot/kaa/tasks/daily/capsule_toys.py +1 -1
- kotonebot/kaa/tasks/daily/club_reward.py +1 -1
- kotonebot/kaa/tasks/daily/contest.py +1 -1
- kotonebot/kaa/tasks/daily/mission_reward.py +1 -1
- kotonebot/kaa/tasks/daily/purchase.py +1 -1
- kotonebot/kaa/tasks/daily/upgrade_support_card.py +1 -1
- kotonebot/kaa/tasks/end_game.py +1 -1
- kotonebot/kaa/tasks/produce/cards.py +1 -1
- kotonebot/kaa/tasks/produce/common.py +3 -2
- kotonebot/kaa/tasks/produce/in_purodyuusu.py +9 -7
- kotonebot/kaa/tasks/produce/non_lesson_actions.py +3 -2
- kotonebot/kaa/tasks/produce/produce.py +27 -22
- kotonebot/kaa/tasks/start_game.py +1 -1
- {ksaa-2025.7.7.0.dist-info → ksaa-2025.7.13.0.dist-info}/METADATA +1 -1
- {ksaa-2025.7.7.0.dist-info → ksaa-2025.7.13.0.dist-info}/RECORD +170 -158
- /kotonebot/kaa/sprites/{2f4f3d81-2a8c-49d3-84a8-4d1205237ed4.png → 065de266-800e-4ebf-bab1-a37038e531d8.png} +0 -0
- /kotonebot/kaa/sprites/{177ee196-1013-487e-9944-64c4a9b803ef.png → 0951b840-439e-4289-991e-51b5b2df0bb2.png} +0 -0
- /kotonebot/kaa/sprites/{6d4337f4-e30c-44eb-bab9-220a46c0c96f.png → 09ca39cd-c964-4258-a860-6a327e31713c.png} +0 -0
- /kotonebot/kaa/sprites/{9e861b2e-f896-4738-b0d0-9b703395720d.png → 0b166ce2-85b0-4207-b4ee-e720462cf9ab.png} +0 -0
- /kotonebot/kaa/sprites/{1cd922b1-cd9c-4b60-b7e7-014c59217cb0.png → 0d10fa02-b8e7-405a-a463-83f472807a39.png} +0 -0
- /kotonebot/kaa/sprites/{c692a9b3-8a2a-42f1-8f63-ad8bd553272d.png → 0edc4c9d-9249-4bf0-86ad-c9fee3ee06f7.png} +0 -0
- /kotonebot/kaa/sprites/{f5917c99-185e-4bd9-b367-972c77accb44.png → 10d7c07d-9731-4b2a-bc92-bfb822616303.png} +0 -0
- /kotonebot/kaa/sprites/{59997849-5a5a-4589-a4ff-e91a789fc68d.png → 13ebdaaf-dee5-48be-963e-c2e6915b2b00.png} +0 -0
- /kotonebot/kaa/sprites/{b720a22b-a2f1-4686-969d-2a2edd8fb96b.png → 14e920fb-7410-4927-96e1-c40211069182.png} +0 -0
- /kotonebot/kaa/sprites/{489feedd-f44e-4714-ad24-b53630dfcf27.png → 17d9408b-b429-402c-9d06-f2a0b2b1abe2.png} +0 -0
- /kotonebot/kaa/sprites/{835a1f3e-5a06-4490-bc2e-c6d3d8edc1fd.png → 2228a02e-fec3-4bb7-ad29-d7ef0d7b7a90.png} +0 -0
- /kotonebot/kaa/sprites/{9d94c24c-5aab-4fb6-8fa7-902cebac134c.png → 28b29b73-758c-41ef-8829-4b93d7a6f424.png} +0 -0
- /kotonebot/kaa/sprites/{e64c9477-35f7-4f05-995f-f3f38bb7db66.png → 2b845193-37f8-4e17-9fd2-52765977b1fa.png} +0 -0
- /kotonebot/kaa/sprites/{21fe29c2-f49b-473f-8ac3-896b4d3c72f5.png → 31f239cb-58f7-4fe9-95e4-15572afa9855.png} +0 -0
- /kotonebot/kaa/sprites/{466524da-0d9e-424f-82eb-d6e6d3145bd3.png → 32fa7671-2413-400f-9bad-3fd7859840e4.png} +0 -0
- /kotonebot/kaa/sprites/{80c45554-0758-47eb-b9d7-d8c10f462ae5.png → 33dfe24e-9cc8-43c9-98a8-999e850b778a.png} +0 -0
- /kotonebot/kaa/sprites/{84c0f8bf-c670-47d4-8d5c-06de599f7c40.png → 34050b3d-1684-403d-95b1-8ad7ff2a85bb.png} +0 -0
- /kotonebot/kaa/sprites/{30ff50f2-7ab2-4a1d-88db-fd6deaba328e.png → 387b6503-d6c8-40ab-8cad-2a81021b6103.png} +0 -0
- /kotonebot/kaa/sprites/{1d714b45-6b20-40ba-8e0b-e7c106f0c8f3.png → 3995bbdb-4b0c-4327-b299-7d105a78e977.png} +0 -0
- /kotonebot/kaa/sprites/{4112f697-094b-4046-bfac-409f156784b0.png → 43648de0-a0dc-4d0b-b081-ddb4a6aae9c4.png} +0 -0
- /kotonebot/kaa/sprites/{899ad2c0-7b23-4b77-aed4-34ba4911672b.png → 44713a59-3d15-427a-af43-27efdc1b2b20.png} +0 -0
- /kotonebot/kaa/sprites/{4670fd78-3748-4df3-968b-25c8246da92b.png → 46189b9d-16fd-4385-9654-2a6fa95bc933.png} +0 -0
- /kotonebot/kaa/sprites/{f9e8cde8-fda0-4436-8072-6bc32c3c0b8e.png → 4660a922-bb9a-4543-b11a-d7b3be41e42e.png} +0 -0
- /kotonebot/kaa/sprites/{b2f31f86-b7ae-4eb1-8042-d14c5b226714.png → 476c4b40-a024-4253-bd57-b775b1559c44.png} +0 -0
- /kotonebot/kaa/sprites/{c639b2f6-35f2-4924-9e81-878637c176a6.png → 488c8e34-9a36-4335-8a69-c9288e3344d7.png} +0 -0
- /kotonebot/kaa/sprites/{f18c683d-1eb2-4279-a05c-c411683354df.png → 48a169b5-e3ad-41c8-9895-5fff217a24a3.png} +0 -0
- /kotonebot/kaa/sprites/{bfd495eb-7ec2-47d7-aff2-59c1a663be5d.png → 48d52db5-9d6f-4d6d-a8a9-56ec3e03cf2e.png} +0 -0
- /kotonebot/kaa/sprites/{d07f0d30-465e-4b4e-803f-a81aeabdd1e8.png → 4ca16d51-1b1c-4174-98df-dce028749eb0.png} +0 -0
- /kotonebot/kaa/sprites/{54f5e4d6-44f9-4249-bf80-aaaacf0a8d52.png → 4ee4dde9-378f-4ef3-b1f3-29bbb3d9e073.png} +0 -0
- /kotonebot/kaa/sprites/{025f1786-cd28-4a08-ad81-178d267dbb1a.png → 4f36ddbb-967e-41d5-9bdb-05bb8f906227.png} +0 -0
- /kotonebot/kaa/sprites/{b73fa422-bf9c-43aa-ad80-ae92286042e6.png → 51c39af7-efe6-4763-a85c-f1275e7cf4e8.png} +0 -0
- /kotonebot/kaa/sprites/{31dd40b0-1c07-4d6c-aabe-fd3e4895f4df.png → 524134df-5ade-4eb0-903f-dbae8d2a6e00.png} +0 -0
- /kotonebot/kaa/sprites/{d7d6ace9-35f1-4c71-b4c1-9de938b254f4.png → 582e8afb-81d9-433b-9297-2741f78224c0.png} +0 -0
- /kotonebot/kaa/sprites/{e6a16a1e-e821-45f0-bc64-f2e0dab7efd7.png → 59d453f1-a2df-4138-9e4e-277f6b636bde.png} +0 -0
- /kotonebot/kaa/sprites/{2ffd9c12-0520-4f9c-92b1-bfdef0681583.png → 5b382fe1-da9d-4644-b4e7-aa2759b36b9d.png} +0 -0
- /kotonebot/kaa/sprites/{97e33fa0-1442-418d-b393-3b916312c9e1.png → 5ca735d9-04b0-40a4-8eda-adbf9d0ded34.png} +0 -0
- /kotonebot/kaa/sprites/{af0f65a5-8d32-4211-86df-66b3fa609462.png → 5cda82c5-6026-4a4b-9447-30779ef07e51.png} +0 -0
- /kotonebot/kaa/sprites/{7315c6b9-6fda-4790-8e9a-c8c4220834e1.png → 5e00a181-041a-4456-8850-773f68de8573.png} +0 -0
- /kotonebot/kaa/sprites/{0089161a-0dac-41da-97af-b9200339a383.png → 6151e500-a626-44db-89d5-a7b15d99f9aa.png} +0 -0
- /kotonebot/kaa/sprites/{898325da-307d-4108-ab4c-25d9ae94ee24.png → 618b8738-c9ae-4def-951f-a3627b26a980.png} +0 -0
- /kotonebot/kaa/sprites/{a586f586-85e9-439e-ab3f-905d6cbe6746.png → 661760df-f790-47cb-8ddf-21b684a1096d.png} +0 -0
- /kotonebot/kaa/sprites/{5200fbda-653d-4b6f-84d8-15793cc53684.png → 69601752-7606-4af4-9252-097be36eec84.png} +0 -0
- /kotonebot/kaa/sprites/{2d0ed04f-777a-4a69-9a58-0be791260dca.png → 69d32f6c-e982-4418-94f9-5a625dc06584.png} +0 -0
- /kotonebot/kaa/sprites/{f2d614b3-d3bf-4340-b261-f4c385a59e4e.png → 6c2ba024-4e1e-4a07-9b58-277a1873c279.png} +0 -0
- /kotonebot/kaa/sprites/{c9e507d5-94dd-4ff3-b995-70c6cb360095.png → 6cc3d385-7c1a-4df2-92dd-0bc7f4931f2c.png} +0 -0
- /kotonebot/kaa/sprites/{b2743383-a3e4-43ff-82a3-3c7c6450fc50.png → 6d7d40e7-8f54-40b5-a900-784e2ced0df5.png} +0 -0
- /kotonebot/kaa/sprites/{06e7d3f6-1ab8-4714-8ab5-8af71dcbfa78.png → 721caff2-926b-4778-a20b-77c9fee8f45a.png} +0 -0
- /kotonebot/kaa/sprites/{dfb1d18d-b768-46c4-9d31-b654ba7a2b6d.png → 740c5975-00d7-42a7-ad95-cee0d59db3f0.png} +0 -0
- /kotonebot/kaa/sprites/{3de5ce1b-f72b-450a-a1de-5a841fbd507a.png → 75972e14-44b8-4ac7-9bfa-a0e0ed563b05.png} +0 -0
- /kotonebot/kaa/sprites/{2146a037-c3ad-4c33-834c-ddd7f3b7876c.png → 77a55e26-3901-4be0-9edb-a434c6e5e719.png} +0 -0
- /kotonebot/kaa/sprites/{0a3c0a4e-a979-401c-9bf3-a389e8a74e7b.png → 79d26ab2-499d-46a5-b15d-a0d0845fc535.png} +0 -0
- /kotonebot/kaa/sprites/{78c0f6b4-c09d-4b44-9b5e-35e1e40dd748.png → 7a72a3ad-666c-478e-a249-2ca7e35f84cb.png} +0 -0
- /kotonebot/kaa/sprites/{f9b38a5e-72cb-4b18-8817-18473effd41d.png → 7b58df80-77e7-4a81-84b5-3d7e61f4237e.png} +0 -0
- /kotonebot/kaa/sprites/{b974e1ac-1f24-4498-aa84-62cb5c0984e7.png → 80ca25c8-03b6-4ed8-bf0b-36f6ad71ffd4.png} +0 -0
- /kotonebot/kaa/sprites/{1cede0b7-5042-481c-b507-957dd98ec17a.png → 83d759a1-04fc-40d3-93d6-d31b4be70e5d.png} +0 -0
- /kotonebot/kaa/sprites/{20748b0c-889f-4706-857b-48fc921a88e3.png → 84b25f6f-aeb4-41b0-bb61-9e028ee1173f.png} +0 -0
- /kotonebot/kaa/sprites/{6490c5b2-2ed8-44d6-93b8-72d88434b49e.png → 88bcca49-4150-4820-8b47-049f7f1aa604.png} +0 -0
- /kotonebot/kaa/sprites/{5367d7ad-5a27-42e4-a7d9-5bf27102f502.png → 88cb2321-ac35-4fe6-a467-19ba5ef3af35.png} +0 -0
- /kotonebot/kaa/sprites/{e798ff2f-6f30-4536-923a-a65433817423.png → 897a1e29-c5e2-4c26-a348-6fd7d63c9f09.png} +0 -0
- /kotonebot/kaa/sprites/{cdc6e5e2-5b38-4471-b23f-17ec229268db.png → 8a8f4be3-9538-4ead-9002-009432dce534.png} +0 -0
- /kotonebot/kaa/sprites/{fc44214e-ef8a-4ea1-baec-35674ce0c4d6.png → 8acb588c-200f-4927-bb50-2f01c7fbf0f5.png} +0 -0
- /kotonebot/kaa/sprites/{0913f34e-1790-4afb-af31-9a5e94d54b05.png → 8d093e5a-3ce8-4e67-9e5d-7d91f2dd3b00.png} +0 -0
- /kotonebot/kaa/sprites/{3091351b-ab63-4688-8082-32545052d7a8.png → 8e0b582b-68d3-4a4f-93e1-dec23e8e6abf.png} +0 -0
- /kotonebot/kaa/sprites/{1762b8dc-abb8-402e-88b9-22111b054d27.png → 8f1413b8-fe01-4a37-9c10-0dcabf092367.png} +0 -0
- /kotonebot/kaa/sprites/{688d653e-7ee7-4d41-ac79-b4efd6c3cadd.png → 917cd398-166e-4abe-a769-6d74cfbb611e.png} +0 -0
- /kotonebot/kaa/sprites/{adf0eea7-a052-410b-b479-8c672ae38268.png → 92ac2224-ce9d-4ba0-aafc-c627ba97c163.png} +0 -0
- /kotonebot/kaa/sprites/{6f06519d-4f33-4418-b4cb-35a7356cc121.png → 9529c488-2256-4a3d-baed-4928c151b1b1.png} +0 -0
- /kotonebot/kaa/sprites/{18369504-36b1-4b10-93e6-878c2cae6c8f.png → 9579ad74-b049-4e27-a07c-12537c5ee051.png} +0 -0
- /kotonebot/kaa/sprites/{99b58811-42ff-415b-9229-f5c75cbe1a1a.png → 96044a90-a417-4042-a359-ddfd374afd0c.png} +0 -0
- /kotonebot/kaa/sprites/{0eb4e53c-f0af-4c86-870c-b1db087d53db.png → 96669532-4774-4c2e-bda0-ea94f3b1d41b.png} +0 -0
- /kotonebot/kaa/sprites/{c7e90767-3661-4e86-8c54-8e1d1e83d113.png → 985e8bd4-7658-4da1-beb3-c53220ec1c25.png} +0 -0
- /kotonebot/kaa/sprites/{1e398be7-49ac-4eb6-b828-b935f042037a.png → 995b71e0-ce5d-48b7-b1a1-35443a37c295.png} +0 -0
- /kotonebot/kaa/sprites/{467fe027-96ba-48b1-963b-75a5c41277c4.png → 9e5202cc-ef3c-433e-8cbb-afa5842f0a34.png} +0 -0
- /kotonebot/kaa/sprites/{6faf9942-994d-418a-ae42-25c5fcffa79e.png → 9fd3858a-c2a7-468d-b224-ca6386a08d1e.png} +0 -0
- /kotonebot/kaa/sprites/{2712893d-0219-43e1-8de7-c2761456719e.png → 9ff3e793-1c21-45c6-88b5-24543f300f81.png} +0 -0
- /kotonebot/kaa/sprites/{4abd8e80-83ef-4d1a-b143-e6ad0ac189ab.png → a49babfb-a958-4de0-b2c5-2c64ce8641fa.png} +0 -0
- /kotonebot/kaa/sprites/{126f5161-3567-4c76-8e91-371392e39a9c.png → a5b80b05-f6a2-407e-bf93-27b88bd982d1.png} +0 -0
- /kotonebot/kaa/sprites/{05d933de-6274-4d46-a81b-860de1981ebc.png → a622194f-000b-48d9-871f-89e2ba9a249d.png} +0 -0
- /kotonebot/kaa/sprites/{7dd1c478-719f-4432-891f-9543064fd1fc.png → a7b99e72-68c1-4b11-994f-a3238bee5fa3.png} +0 -0
- /kotonebot/kaa/sprites/{87a59b06-0ac7-4a35-93c4-3705bf9e774a.png → a9ec257b-d82f-4ebf-9b46-1af8836d5768.png} +0 -0
- /kotonebot/kaa/sprites/{08f93e03-18c9-42e3-9a2f-7d7954f585b0.png → abeb625a-74c1-45dc-a6c9-2a123dee1ab4.png} +0 -0
- /kotonebot/kaa/sprites/{2ed453f3-9c31-4c96-95dd-1a6aa68302f7.png → af04e2ac-bffa-4bfb-9580-c934e403d578.png} +0 -0
- /kotonebot/kaa/sprites/{f3e4e9ec-ddd6-42c4-9638-b93ff4e6b514.png → b04f4554-d6ea-4f99-822c-657ad1b9cd1e.png} +0 -0
- /kotonebot/kaa/sprites/{d5899bda-b311-469d-b4fb-963799ef1720.png → b06ebc30-305e-4f8a-8a3c-1d91aab4f9c0.png} +0 -0
- /kotonebot/kaa/sprites/{bbfb7670-2537-4a92-9a39-487d174f27a0.png → b07b112c-08c8-45ff-b980-105d263ff1c4.png} +0 -0
- /kotonebot/kaa/sprites/{4d3e267c-552c-4a65-840a-dc72a61c8db1.png → b1e6c930-f659-4ea8-a694-a4590160b438.png} +0 -0
- /kotonebot/kaa/sprites/{e6d0979a-cd27-4933-b528-7777be525ace.png → b34c399b-ea60-4de2-86ee-003d308594c2.png} +0 -0
- /kotonebot/kaa/sprites/{d43f214a-4db4-4222-941c-3d3216a0c0c3.png → b4db5745-d7d0-4afb-8962-9f71fc4188c8.png} +0 -0
- /kotonebot/kaa/sprites/{4eb9a3a1-da46-493b-a17d-5eb9ef53524c.png → ba45d490-da2e-4c2f-badf-7058f1802ad3.png} +0 -0
- /kotonebot/kaa/sprites/{3e9bdd08-3a74-40b3-8320-05ed4e8fe5d7.png → c03c6076-7935-42e7-a2e5-5f74015e92e2.png} +0 -0
- /kotonebot/kaa/sprites/{5cff1e6f-81ea-4d4a-88ba-209cf3bbb165.png → c0b5a0a7-0cb7-4d2c-8105-42b434437610.png} +0 -0
- /kotonebot/kaa/sprites/{23464a7b-dc7a-439c-86b7-04a5dd506412.png → c2a12970-cfff-4772-a4ec-127f4309f2b5.png} +0 -0
- /kotonebot/kaa/sprites/{c1336997-ea27-4d53-9c64-826ca7eca11f.png → c9f0ddc4-832c-42f0-b46d-a2b4326d1a1c.png} +0 -0
- /kotonebot/kaa/sprites/{3ddd0976-7c8b-4c67-bac7-a0cc1af3bfad.png → ca37b366-0a29-436c-8c22-78daf4148bfe.png} +0 -0
- /kotonebot/kaa/sprites/{c686d99a-248a-460b-a4fe-2fa5b8e9660b.png → cafb66c1-10d3-4612-80f9-f9e183d509c6.png} +0 -0
- /kotonebot/kaa/sprites/{8308964d-96d1-4b7e-b0fa-b20163311153.png → cf007582-08d0-4fc7-bc7c-113e211b226a.png} +0 -0
- /kotonebot/kaa/sprites/{308818b7-a252-45a6-868d-553c078b3752.png → cf33f626-5944-4dfe-bb46-2976c187f2a9.png} +0 -0
- /kotonebot/kaa/sprites/{f957edb2-3534-4d1d-a9be-70b478b2ff63.png → d1f662b1-7aa2-4ccc-a8bf-6e7a94ae2427.png} +0 -0
- /kotonebot/kaa/sprites/{6df0db09-9159-43b5-a6b9-43a2dfdafdab.png → d1fff69a-474d-416f-a53f-2a88a4d552c7.png} +0 -0
- /kotonebot/kaa/sprites/{e614c8e1-1d7b-4535-a8ba-cbf09fd5b163.png → d251bb28-4d34-4db9-85eb-554a56ac8184.png} +0 -0
- /kotonebot/kaa/sprites/{bcb990e6-58ae-460d-859a-812b4121e716.png → d2fe6a19-df40-43f9-8e75-2376e9987290.png} +0 -0
- /kotonebot/kaa/sprites/{2154ebd3-9c89-4355-b4f4-a5e18ecf728d.png → d7b786c8-7887-4870-a719-f703945cc6f1.png} +0 -0
- /kotonebot/kaa/sprites/{6f638005-aa18-4804-a5fe-269de4d1ad9e.png → d9ac597e-8d6d-4ab3-b865-e68a83563d25.png} +0 -0
- /kotonebot/kaa/sprites/{54d71b39-a3f2-4f20-a294-b6b5ef9c56f3.png → db041968-9811-494c-ae2c-1b31d4e1773c.png} +0 -0
- /kotonebot/kaa/sprites/{119f04e2-3871-46a8-9d5c-808c641f7aae.png → db2fb64d-3e2d-4cd4-ac3a-a993e9784697.png} +0 -0
- /kotonebot/kaa/sprites/{10713c56-e462-4543-8a51-02f220ed6943.png → dd268b19-354f-4e39-a4b4-0578719a40e1.png} +0 -0
- /kotonebot/kaa/sprites/{7c40ea85-87f6-4531-a25a-896dd70b49d1.png → deca8ee5-616a-4652-8a37-dab4f34951b6.png} +0 -0
- /kotonebot/kaa/sprites/{acd1a611-f93d-4d32-8070-dc325b42eeb9.png → e214cd8e-b79f-42e5-959a-64f745f35896.png} +0 -0
- /kotonebot/kaa/sprites/{dd431a8a-3ffa-43d6-96c6-4e84aa946b72.png → e2d11737-e1e2-4056-bd85-7d242c9c3023.png} +0 -0
- /kotonebot/kaa/sprites/{4e040068-e2ae-4348-80a2-f113c2426d46.png → e6e33419-ee43-48d1-98c6-a64f07b9e9e9.png} +0 -0
- /kotonebot/kaa/sprites/{e007420c-b92b-414c-96a3-d556e3c25cb2.png → e7fb4631-aad6-4fad-934c-72396737a98a.png} +0 -0
- /kotonebot/kaa/sprites/{bad07ebd-c8e7-4721-ab74-a38fa30e0401.png → eb56ba19-433e-4bab-9e47-7a2702c83954.png} +0 -0
- /kotonebot/kaa/sprites/{fffa0118-dd3a-4d01-8c4e-d43182778391.png → ebef3530-94ab-4ba7-b43e-5b3249286d51.png} +0 -0
- /kotonebot/kaa/sprites/{5d5db2d4-2648-40fe-bd17-05aea9afbc7d.png → edcb7ca8-9e3f-4232-b6c9-b7189a62d2ec.png} +0 -0
- /kotonebot/kaa/sprites/{acd01a53-c689-4ffd-ae45-744a37c70197.png → ee7c3730-b678-4ffe-a7e5-5637016ce5b4.png} +0 -0
- /kotonebot/kaa/sprites/{e87f0760-4bc9-4d7f-91e2-5452ba0fcd9d.png → f270ddb2-fabc-4dd6-818a-c818a44893ed.png} +0 -0
- /kotonebot/kaa/sprites/{f26d4e09-2511-48e4-9c69-ba413ddf65e1.png → f2b784ee-eeca-4633-9083-4cb996c26f66.png} +0 -0
- /kotonebot/kaa/sprites/{76f43a30-b76d-4648-91b6-49f2786e668d.png → f621f114-11c3-4957-a86c-cb474721d660.png} +0 -0
- /kotonebot/kaa/sprites/{5587551f-011c-4f94-86e8-7e81d08c4be2.png → f85c9e53-870d-46e4-9963-c5245d0c5628.png} +0 -0
- /kotonebot/kaa/sprites/{5efa51e6-5cb7-4843-9397-8d71c6175fcf.png → f88ee970-84ea-46b2-99e0-d3fe1cde908e.png} +0 -0
- /kotonebot/kaa/sprites/{51eac702-ca23-4aba-b75a-cdb03a93a117.png → fa8ee7e4-ee13-497e-856b-e210f6b1f114.png} +0 -0
- /kotonebot/kaa/sprites/{6a45398a-4240-4fb7-8926-fa1254125bbf.png → fb00d537-d921-4a5f-9bc7-8aac1b68a71d.png} +0 -0
- /kotonebot/kaa/sprites/{2d4001e6-137e-40b2-94b0-ba3ae9e397e4.png → fc23b108-7717-4b16-9e91-aacd5ddcc2ce.png} +0 -0
- /kotonebot/kaa/sprites/{d108794a-60b8-4637-bced-84f46140eaac.png → fd3b7b22-7011-4267-8365-64a4933073a4.png} +0 -0
- /kotonebot/kaa/sprites/{774ca489-09c2-414e-b27b-f32d3bf6894d.png → fd7ce00d-d45c-468b-a918-f5ded551a17d.png} +0 -0
- /kotonebot/kaa/sprites/{e93a983d-b869-45e4-8a5c-cd1c9d511b11.png → ffd7676f-6b57-42d2-9631-bc758d2e0a31.png} +0 -0
- {ksaa-2025.7.7.0.dist-info → ksaa-2025.7.13.0.dist-info}/WHEEL +0 -0
- {ksaa-2025.7.7.0.dist-info → ksaa-2025.7.13.0.dist-info}/entry_points.txt +0 -0
- {ksaa-2025.7.7.0.dist-info → ksaa-2025.7.13.0.dist-info}/licenses/LICENSE +0 -0
- {ksaa-2025.7.7.0.dist-info → ksaa-2025.7.13.0.dist-info}/top_level.txt +0 -0
kotonebot/kaa/main/gr.py
CHANGED
|
@@ -16,17 +16,19 @@ import gradio as gr
|
|
|
16
16
|
|
|
17
17
|
from kotonebot.kaa.main import Kaa
|
|
18
18
|
from kotonebot.kaa.db import IdolCard
|
|
19
|
+
from kotonebot.backend.context.context import vars
|
|
20
|
+
from kotonebot.errors import ContextNotInitializedError
|
|
21
|
+
from kotonebot.client.host import Mumu12Host, LeidianHost
|
|
19
22
|
from kotonebot.config.manager import load_config, save_config
|
|
20
23
|
from kotonebot.config.base_config import UserConfig, BackendConfig
|
|
21
24
|
from kotonebot.backend.context import task_registry, ContextStackVars
|
|
22
|
-
from kotonebot.
|
|
23
|
-
from kotonebot.client.host import Mumu12Host, LeidianHost
|
|
24
|
-
from kotonebot.kaa.common import (
|
|
25
|
+
from kotonebot.kaa.config import (
|
|
25
26
|
BaseConfig, APShopItems, CapsuleToysConfig, ClubRewardConfig, PurchaseConfig, ActivityFundsConfig,
|
|
26
27
|
PresentsConfig, AssignmentConfig, ContestConfig, ProduceConfig,
|
|
27
28
|
MissionRewardConfig, DailyMoneyShopItems, ProduceAction,
|
|
28
29
|
RecommendCardDetectionMode, TraceConfig, StartGameConfig, EndGameConfig, UpgradeSupportCardConfig, MiscConfig,
|
|
29
30
|
)
|
|
31
|
+
from kotonebot.kaa.config.produce import ProduceSolution, ProduceSolutionManager, ProduceData
|
|
30
32
|
|
|
31
33
|
logger = logging.getLogger(__name__)
|
|
32
34
|
GradioInput = gr.Textbox | gr.Number | gr.Checkbox | gr.Dropdown | gr.Radio | gr.Slider | gr.Tabs | gr.Tab
|
|
@@ -52,14 +54,7 @@ ConfigKey = Literal[
|
|
|
52
54
|
'select_which_contestant',
|
|
53
55
|
|
|
54
56
|
# produce
|
|
55
|
-
'produce_enabled', '
|
|
56
|
-
'produce_count', 'produce_idols',
|
|
57
|
-
'memory_sets', 'auto_set_memory',
|
|
58
|
-
'auto_set_support', 'use_pt_boost',
|
|
59
|
-
'use_note_boost', 'follow_producer',
|
|
60
|
-
'self_study_lesson', 'prefer_lesson_ap',
|
|
61
|
-
'actions_order', 'recommend_card_detection_mode',
|
|
62
|
-
'use_ap_drink', 'skip_commu',
|
|
57
|
+
'produce_enabled', 'selected_solution_id', 'produce_count',
|
|
63
58
|
'mission_reward_enabled',
|
|
64
59
|
|
|
65
60
|
# club reward
|
|
@@ -186,6 +181,15 @@ def _save_bug_report(
|
|
|
186
181
|
zipf.write(file_path, arcname)
|
|
187
182
|
yield f"### 打包 log 文件:{arcname}"
|
|
188
183
|
|
|
184
|
+
# 打包 conf 文件夹
|
|
185
|
+
if os.path.exists('conf'):
|
|
186
|
+
for root, dirs, files in os.walk('conf'):
|
|
187
|
+
for file in files:
|
|
188
|
+
file_path = os.path.join(root, file)
|
|
189
|
+
arcname = os.path.join('conf', os.path.relpath(file_path, 'conf'))
|
|
190
|
+
zipf.write(file_path, arcname)
|
|
191
|
+
yield f"### 打包配置文件:{arcname}"
|
|
192
|
+
|
|
189
193
|
# 写出版本号
|
|
190
194
|
zipf.writestr('version.txt', version)
|
|
191
195
|
|
|
@@ -387,14 +391,44 @@ class KotoneBotUI:
|
|
|
387
391
|
"""获取暂停按钮的状态和交互性"""
|
|
388
392
|
try:
|
|
389
393
|
text = "恢复" if vars.flow.is_paused else "暂停"
|
|
390
|
-
except
|
|
391
|
-
#
|
|
394
|
+
except ContextNotInitializedError:
|
|
395
|
+
# ContextNotInitializedError: Forwarded object vars called before initialization.
|
|
392
396
|
# TODO: vars.flow.is_paused 应该要可以在脚本正式启动前就能访问
|
|
393
397
|
text = '未启动'
|
|
394
398
|
# 如果正在停止过程中,禁用暂停按钮
|
|
395
399
|
interactive = not (self.is_stopping or self.is_single_task_stopping)
|
|
396
400
|
return gr.Button(value=text, interactive=interactive)
|
|
397
401
|
|
|
402
|
+
def reload_config(self) -> bool:
|
|
403
|
+
"""
|
|
404
|
+
重新加载配置并重新初始化相关组件
|
|
405
|
+
|
|
406
|
+
:return: 是否成功重新加载
|
|
407
|
+
"""
|
|
408
|
+
try:
|
|
409
|
+
# 重新加载配置文件
|
|
410
|
+
self._load_config()
|
|
411
|
+
|
|
412
|
+
# 重新设置 kaa 的配置
|
|
413
|
+
self._kaa.config_path = "config.json"
|
|
414
|
+
self._kaa.config_type = BaseConfig
|
|
415
|
+
|
|
416
|
+
# 重新初始化 kaa(这会重新创建设备和 Context)
|
|
417
|
+
self._setup_kaa()
|
|
418
|
+
|
|
419
|
+
# 重新加载 Context 中的配置数据
|
|
420
|
+
from kotonebot.backend.context.context import config
|
|
421
|
+
try:
|
|
422
|
+
config.load()
|
|
423
|
+
except ContextNotInitializedError:
|
|
424
|
+
pass
|
|
425
|
+
|
|
426
|
+
logger.info("配置已成功重新加载")
|
|
427
|
+
return True
|
|
428
|
+
except Exception as e:
|
|
429
|
+
logger.error(f"重新加载配置失败:{str(e)}")
|
|
430
|
+
return False
|
|
431
|
+
|
|
398
432
|
def save_settings2(self, return_values: list[ConfigBuilderReturnValue], *args) -> str:
|
|
399
433
|
options = BaseConfig()
|
|
400
434
|
# return_values: (set_func, { 'key': component })
|
|
@@ -406,45 +440,50 @@ class KotoneBotUI:
|
|
|
406
440
|
assert key in CONFIG_KEY_VALUE, f"未知的配置项:{key}"
|
|
407
441
|
key = cast(ConfigKey, key)
|
|
408
442
|
data[key] = value
|
|
409
|
-
|
|
443
|
+
|
|
410
444
|
# 先设置options
|
|
411
445
|
for (set_func, _) in return_values:
|
|
412
446
|
set_func(options, data)
|
|
413
|
-
|
|
447
|
+
|
|
414
448
|
# 验证规则1:截图方法验证
|
|
415
449
|
screenshot_method = self.current_config.backend.screenshot_impl
|
|
416
450
|
backend_type = self.current_config.backend.type
|
|
417
|
-
|
|
451
|
+
|
|
418
452
|
valid_screenshot_methods = {
|
|
419
453
|
'mumu12': ['adb', 'adb_raw', 'uiautomator2', 'nemu_ipc'],
|
|
420
454
|
'leidian': ['adb', 'adb_raw', 'uiautomator2'],
|
|
421
455
|
'custom': ['adb', 'adb_raw', 'uiautomator2'],
|
|
422
456
|
'dmm': ['remote_windows', 'windows']
|
|
423
457
|
}
|
|
424
|
-
|
|
458
|
+
|
|
425
459
|
if screenshot_method not in valid_screenshot_methods.get(backend_type, []):
|
|
426
460
|
gr.Warning(f"截图方法 '{screenshot_method}' 不适用于当前选择的模拟器类型,配置未保存。")
|
|
427
461
|
return ""
|
|
428
|
-
|
|
429
|
-
# 验证规则2
|
|
430
|
-
if options.produce.enabled and not options.produce.
|
|
431
|
-
gr.Warning("
|
|
462
|
+
|
|
463
|
+
# 验证规则2:若启用培育,那么必须选择培育方案
|
|
464
|
+
if options.produce.enabled and not options.produce.selected_solution_id:
|
|
465
|
+
gr.Warning("启用培育时,必须选择培育方案,配置未保存。")
|
|
432
466
|
return ""
|
|
433
|
-
|
|
467
|
+
|
|
434
468
|
# 验证规则3:若启用AP/金币购买,对应的商品不能为空
|
|
435
469
|
if options.purchase.ap_enabled and not options.purchase.ap_items:
|
|
436
470
|
gr.Warning("启用AP购买时,AP商店购买物品不能为空,配置未保存。")
|
|
437
471
|
return ""
|
|
438
|
-
|
|
472
|
+
|
|
439
473
|
if options.purchase.money_enabled and not options.purchase.money_items:
|
|
440
474
|
gr.Warning("启用金币购买时,金币商店购买物品不能为空,配置未保存。")
|
|
441
475
|
return ""
|
|
442
|
-
|
|
476
|
+
|
|
443
477
|
# 验证通过,保存配置
|
|
444
478
|
self.current_config.options = options
|
|
445
479
|
try:
|
|
446
480
|
save_config(self.config, "config.json")
|
|
447
|
-
|
|
481
|
+
|
|
482
|
+
# 尝试热重载配置
|
|
483
|
+
if self.reload_config():
|
|
484
|
+
gr.Success("设置已保存并应用!")
|
|
485
|
+
else:
|
|
486
|
+
gr.Warning("设置已保存,但重新加载失败,请重启程序。")
|
|
448
487
|
return ""
|
|
449
488
|
except Exception as e:
|
|
450
489
|
gr.Warning(f"保存设置失败:{str(e)}")
|
|
@@ -457,11 +496,76 @@ class KotoneBotUI:
|
|
|
457
496
|
with gr.Row():
|
|
458
497
|
run_btn = gr.Button("启动", scale=2)
|
|
459
498
|
pause_btn = gr.Button("暂停", scale=1)
|
|
499
|
+
|
|
500
|
+
# 快速功能启停控制区域
|
|
501
|
+
gr.Markdown("### 快速功能启停")
|
|
502
|
+
with gr.Row(elem_classes=["quick-controls-row"]):
|
|
503
|
+
purchase_quick = gr.Checkbox(
|
|
504
|
+
label="商店",
|
|
505
|
+
value=self.current_config.options.purchase.enabled,
|
|
506
|
+
interactive=True,
|
|
507
|
+
elem_classes=["quick-checkbox"]
|
|
508
|
+
)
|
|
509
|
+
assignment_quick = gr.Checkbox(
|
|
510
|
+
label="工作",
|
|
511
|
+
value=self.current_config.options.assignment.enabled,
|
|
512
|
+
interactive=True,
|
|
513
|
+
elem_classes=["quick-checkbox"]
|
|
514
|
+
)
|
|
515
|
+
contest_quick = gr.Checkbox(
|
|
516
|
+
label="竞赛",
|
|
517
|
+
value=self.current_config.options.contest.enabled,
|
|
518
|
+
interactive=True,
|
|
519
|
+
elem_classes=["quick-checkbox"]
|
|
520
|
+
)
|
|
521
|
+
produce_quick = gr.Checkbox(
|
|
522
|
+
label="培育",
|
|
523
|
+
value=self.current_config.options.produce.enabled,
|
|
524
|
+
interactive=True,
|
|
525
|
+
elem_classes=["quick-checkbox"]
|
|
526
|
+
)
|
|
527
|
+
mission_reward_quick = gr.Checkbox(
|
|
528
|
+
label="任务",
|
|
529
|
+
value=self.current_config.options.mission_reward.enabled,
|
|
530
|
+
interactive=True,
|
|
531
|
+
elem_classes=["quick-checkbox"]
|
|
532
|
+
)
|
|
533
|
+
club_reward_quick = gr.Checkbox(
|
|
534
|
+
label="社团",
|
|
535
|
+
value=self.current_config.options.club_reward.enabled,
|
|
536
|
+
interactive=True,
|
|
537
|
+
elem_classes=["quick-checkbox"]
|
|
538
|
+
)
|
|
539
|
+
activity_funds_quick = gr.Checkbox(
|
|
540
|
+
label="活动费",
|
|
541
|
+
value=self.current_config.options.activity_funds.enabled,
|
|
542
|
+
interactive=True,
|
|
543
|
+
elem_classes=["quick-checkbox"]
|
|
544
|
+
)
|
|
545
|
+
presents_quick = gr.Checkbox(
|
|
546
|
+
label="礼物",
|
|
547
|
+
value=self.current_config.options.presents.enabled,
|
|
548
|
+
interactive=True,
|
|
549
|
+
elem_classes=["quick-checkbox"]
|
|
550
|
+
)
|
|
551
|
+
capsule_toys_quick = gr.Checkbox(
|
|
552
|
+
label="扭蛋",
|
|
553
|
+
value=self.current_config.options.capsule_toys.enabled,
|
|
554
|
+
interactive=True,
|
|
555
|
+
elem_classes=["quick-checkbox"]
|
|
556
|
+
)
|
|
557
|
+
upgrade_support_card_quick = gr.Checkbox(
|
|
558
|
+
label="支援卡",
|
|
559
|
+
value=self.current_config.options.upgrade_support_card.enabled,
|
|
560
|
+
interactive=True,
|
|
561
|
+
elem_classes=["quick-checkbox"]
|
|
562
|
+
)
|
|
563
|
+
|
|
460
564
|
if self._kaa.upgrade_msg:
|
|
461
565
|
gr.Markdown('### 配置升级报告')
|
|
462
566
|
gr.Markdown(self._kaa.upgrade_msg)
|
|
463
567
|
gr.Markdown('脚本报错或者卡住?前往"反馈"选项卡可以快速导出报告!')
|
|
464
|
-
|
|
568
|
+
|
|
465
569
|
# 添加调试模式警告
|
|
466
570
|
if self.current_config.keep_screenshots:
|
|
467
571
|
gr.Markdown(
|
|
@@ -485,6 +589,45 @@ class KotoneBotUI:
|
|
|
485
589
|
def on_pause_click(evt: gr.EventData) -> str:
|
|
486
590
|
return self.toggle_pause()
|
|
487
591
|
|
|
592
|
+
# 快速功能控制的事件处理函数
|
|
593
|
+
def save_quick_setting(field_name: str, value: bool, display_name: str):
|
|
594
|
+
"""保存快速设置并立即应用"""
|
|
595
|
+
try:
|
|
596
|
+
# 更新配置
|
|
597
|
+
if field_name == 'purchase':
|
|
598
|
+
self.current_config.options.purchase.enabled = value
|
|
599
|
+
elif field_name == 'assignment':
|
|
600
|
+
self.current_config.options.assignment.enabled = value
|
|
601
|
+
elif field_name == 'contest':
|
|
602
|
+
self.current_config.options.contest.enabled = value
|
|
603
|
+
elif field_name == 'produce':
|
|
604
|
+
self.current_config.options.produce.enabled = value
|
|
605
|
+
elif field_name == 'mission_reward':
|
|
606
|
+
self.current_config.options.mission_reward.enabled = value
|
|
607
|
+
elif field_name == 'club_reward':
|
|
608
|
+
self.current_config.options.club_reward.enabled = value
|
|
609
|
+
elif field_name == 'activity_funds':
|
|
610
|
+
self.current_config.options.activity_funds.enabled = value
|
|
611
|
+
elif field_name == 'presents':
|
|
612
|
+
self.current_config.options.presents.enabled = value
|
|
613
|
+
elif field_name == 'capsule_toys':
|
|
614
|
+
self.current_config.options.capsule_toys.enabled = value
|
|
615
|
+
elif field_name == 'upgrade_support_card':
|
|
616
|
+
self.current_config.options.upgrade_support_card.enabled = value
|
|
617
|
+
elif field_name == 'start_game':
|
|
618
|
+
self.current_config.options.start_game.enabled = value
|
|
619
|
+
|
|
620
|
+
# 保存配置
|
|
621
|
+
save_config(self.config, "config.json")
|
|
622
|
+
|
|
623
|
+
# 尝试热重载配置
|
|
624
|
+
if self.reload_config():
|
|
625
|
+
gr.Success(f"✓ {display_name} 已{'启用' if value else '禁用'}")
|
|
626
|
+
else:
|
|
627
|
+
gr.Warning(f"⚠ {display_name} 已保存,但重新加载失败")
|
|
628
|
+
except Exception as e:
|
|
629
|
+
gr.Error(f"✗ 保存失败:{str(e)}")
|
|
630
|
+
|
|
488
631
|
run_btn.click(
|
|
489
632
|
fn=on_run_click,
|
|
490
633
|
outputs=[run_btn, task_status]
|
|
@@ -495,11 +638,68 @@ class KotoneBotUI:
|
|
|
495
638
|
outputs=[pause_btn]
|
|
496
639
|
)
|
|
497
640
|
|
|
641
|
+
# 绑定快速功能控制的事件
|
|
642
|
+
purchase_quick.change(
|
|
643
|
+
fn=lambda x: save_quick_setting('purchase', x, '商店'),
|
|
644
|
+
inputs=[purchase_quick]
|
|
645
|
+
)
|
|
646
|
+
assignment_quick.change(
|
|
647
|
+
fn=lambda x: save_quick_setting('assignment', x, '工作'),
|
|
648
|
+
inputs=[assignment_quick]
|
|
649
|
+
)
|
|
650
|
+
contest_quick.change(
|
|
651
|
+
fn=lambda x: save_quick_setting('contest', x, '竞赛'),
|
|
652
|
+
inputs=[contest_quick]
|
|
653
|
+
)
|
|
654
|
+
produce_quick.change(
|
|
655
|
+
fn=lambda x: save_quick_setting('produce', x, '培育'),
|
|
656
|
+
inputs=[produce_quick]
|
|
657
|
+
)
|
|
658
|
+
mission_reward_quick.change(
|
|
659
|
+
fn=lambda x: save_quick_setting('mission_reward', x, '任务奖励'),
|
|
660
|
+
inputs=[mission_reward_quick]
|
|
661
|
+
)
|
|
662
|
+
club_reward_quick.change(
|
|
663
|
+
fn=lambda x: save_quick_setting('club_reward', x, '社团奖励'),
|
|
664
|
+
inputs=[club_reward_quick]
|
|
665
|
+
)
|
|
666
|
+
activity_funds_quick.change(
|
|
667
|
+
fn=lambda x: save_quick_setting('activity_funds', x, '活动费'),
|
|
668
|
+
inputs=[activity_funds_quick]
|
|
669
|
+
)
|
|
670
|
+
presents_quick.change(
|
|
671
|
+
fn=lambda x: save_quick_setting('presents', x, '礼物'),
|
|
672
|
+
inputs=[presents_quick]
|
|
673
|
+
)
|
|
674
|
+
capsule_toys_quick.change(
|
|
675
|
+
fn=lambda x: save_quick_setting('capsule_toys', x, '扭蛋'),
|
|
676
|
+
inputs=[capsule_toys_quick]
|
|
677
|
+
)
|
|
678
|
+
upgrade_support_card_quick.change(
|
|
679
|
+
fn=lambda x: save_quick_setting('upgrade_support_card', x, '支援卡升级'),
|
|
680
|
+
inputs=[upgrade_support_card_quick]
|
|
681
|
+
)
|
|
682
|
+
|
|
498
683
|
# 添加定时器,分别更新按钮状态和任务状态
|
|
499
684
|
def update_run_button_status():
|
|
500
685
|
text, interactive = self.get_button_status()
|
|
501
686
|
return gr.Button(value=text, interactive=interactive)
|
|
502
687
|
|
|
688
|
+
def update_quick_checkboxes():
|
|
689
|
+
"""更新快速功能控制的 checkbox 状态,确保与设置同步"""
|
|
690
|
+
return [
|
|
691
|
+
gr.Checkbox(value=self.current_config.options.purchase.enabled),
|
|
692
|
+
gr.Checkbox(value=self.current_config.options.assignment.enabled),
|
|
693
|
+
gr.Checkbox(value=self.current_config.options.contest.enabled),
|
|
694
|
+
gr.Checkbox(value=self.current_config.options.produce.enabled),
|
|
695
|
+
gr.Checkbox(value=self.current_config.options.mission_reward.enabled),
|
|
696
|
+
gr.Checkbox(value=self.current_config.options.club_reward.enabled),
|
|
697
|
+
gr.Checkbox(value=self.current_config.options.activity_funds.enabled),
|
|
698
|
+
gr.Checkbox(value=self.current_config.options.presents.enabled),
|
|
699
|
+
gr.Checkbox(value=self.current_config.options.capsule_toys.enabled),
|
|
700
|
+
gr.Checkbox(value=self.current_config.options.upgrade_support_card.enabled),
|
|
701
|
+
]
|
|
702
|
+
|
|
503
703
|
gr.Timer(1.0).tick(
|
|
504
704
|
fn=update_run_button_status,
|
|
505
705
|
outputs=[run_btn]
|
|
@@ -508,6 +708,14 @@ class KotoneBotUI:
|
|
|
508
708
|
fn=self.get_pause_button_with_interactive,
|
|
509
709
|
outputs=[pause_btn]
|
|
510
710
|
)
|
|
711
|
+
gr.Timer(2.0).tick(
|
|
712
|
+
fn=update_quick_checkboxes,
|
|
713
|
+
outputs=[
|
|
714
|
+
purchase_quick, assignment_quick, contest_quick, produce_quick,
|
|
715
|
+
mission_reward_quick, club_reward_quick, activity_funds_quick, presents_quick,
|
|
716
|
+
capsule_toys_quick, upgrade_support_card_quick
|
|
717
|
+
]
|
|
718
|
+
)
|
|
511
719
|
gr.Timer(1.0).tick(
|
|
512
720
|
fn=self.update_task_status,
|
|
513
721
|
outputs=[task_status]
|
|
@@ -1029,13 +1237,21 @@ class KotoneBotUI:
|
|
|
1029
1237
|
value=self.current_config.options.produce.enabled,
|
|
1030
1238
|
info=ProduceConfig.model_fields['enabled'].description
|
|
1031
1239
|
)
|
|
1240
|
+
|
|
1032
1241
|
with gr.Group(visible=self.current_config.options.produce.enabled) as produce_group:
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1242
|
+
# 培育方案管理区域
|
|
1243
|
+
solution_manager = ProduceSolutionManager()
|
|
1244
|
+
solutions = solution_manager.list()
|
|
1245
|
+
solution_choices = [(f"{sol.name} - {sol.description or '无描述'}", sol.id) for sol in solutions]
|
|
1246
|
+
|
|
1247
|
+
selected_solution_id = self.current_config.options.produce.selected_solution_id
|
|
1248
|
+
solution_dropdown = gr.Dropdown(
|
|
1249
|
+
choices=solution_choices,
|
|
1250
|
+
value=selected_solution_id,
|
|
1251
|
+
label="当前使用的培育方案",
|
|
1252
|
+
interactive=True
|
|
1038
1253
|
)
|
|
1254
|
+
|
|
1039
1255
|
produce_count = gr.Number(
|
|
1040
1256
|
minimum=1,
|
|
1041
1257
|
value=self.current_config.options.produce.produce_count,
|
|
@@ -1043,106 +1259,523 @@ class KotoneBotUI:
|
|
|
1043
1259
|
interactive=True,
|
|
1044
1260
|
info=ProduceConfig.model_fields['produce_count'].description
|
|
1045
1261
|
)
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1262
|
+
|
|
1263
|
+
# 绑定启用状态变化事件
|
|
1264
|
+
def on_produce_enabled_change(enabled):
|
|
1265
|
+
return gr.Group(visible=enabled)
|
|
1266
|
+
|
|
1267
|
+
produce_enabled.change(
|
|
1268
|
+
fn=on_produce_enabled_change,
|
|
1269
|
+
inputs=[produce_enabled],
|
|
1270
|
+
outputs=[produce_group]
|
|
1271
|
+
)
|
|
1272
|
+
|
|
1273
|
+
# 存储设置Tab中的下拉框引用,供培育Tab使用
|
|
1274
|
+
self._settings_solution_dropdown = solution_dropdown
|
|
1275
|
+
|
|
1276
|
+
def set_config(config: BaseConfig, data: dict[ConfigKey, Any]) -> None:
|
|
1277
|
+
config.produce.enabled = data['produce_enabled']
|
|
1278
|
+
config.produce.selected_solution_id = data.get('selected_solution_id')
|
|
1279
|
+
config.produce.produce_count = data.get('produce_count', 1)
|
|
1280
|
+
|
|
1281
|
+
return set_config, {
|
|
1282
|
+
'produce_enabled': produce_enabled,
|
|
1283
|
+
'selected_solution_id': solution_dropdown,
|
|
1284
|
+
'produce_count': produce_count
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
|
|
1288
|
+
def _create_produce_tab(self) -> None:
|
|
1289
|
+
"""创建培育Tab"""
|
|
1290
|
+
with gr.Tab("培育"):
|
|
1291
|
+
gr.Markdown("## 培育管理")
|
|
1292
|
+
|
|
1293
|
+
# 培育方案管理区域
|
|
1294
|
+
solution_manager = ProduceSolutionManager()
|
|
1295
|
+
solutions = solution_manager.list()
|
|
1296
|
+
solution_choices = [(f"{sol.name} - {sol.description or '无描述'}", sol.id) for sol in solutions]
|
|
1297
|
+
|
|
1298
|
+
selected_solution_id = self.current_config.options.produce.selected_solution_id
|
|
1299
|
+
solution_dropdown = gr.Dropdown(
|
|
1300
|
+
choices=solution_choices,
|
|
1301
|
+
value=selected_solution_id,
|
|
1302
|
+
label="选择培育方案",
|
|
1303
|
+
interactive=True
|
|
1304
|
+
)
|
|
1305
|
+
|
|
1306
|
+
# 获取设置Tab中的下拉框引用
|
|
1307
|
+
settings_dropdown = getattr(self, '_settings_solution_dropdown', None)
|
|
1308
|
+
|
|
1309
|
+
with gr.Row():
|
|
1310
|
+
new_solution_btn = gr.Button("新建培育", scale=1)
|
|
1311
|
+
delete_solution_btn = gr.Button("删除当前培育", scale=1)
|
|
1312
|
+
|
|
1313
|
+
# 培育方案详细设置区域
|
|
1314
|
+
with gr.Group() as solution_settings_group:
|
|
1315
|
+
# 获取当前选中的方案数据
|
|
1316
|
+
current_solution = None
|
|
1317
|
+
if selected_solution_id:
|
|
1318
|
+
try:
|
|
1319
|
+
current_solution = solution_manager.read(selected_solution_id)
|
|
1320
|
+
except FileNotFoundError:
|
|
1321
|
+
pass
|
|
1322
|
+
|
|
1323
|
+
if current_solution is None:
|
|
1324
|
+
# 如果没有选中方案,隐藏所有设置组件
|
|
1325
|
+
solution_name = gr.Textbox(label="方案名称", value="", visible=False)
|
|
1326
|
+
solution_description = gr.Textbox(label="方案描述", value="", visible=False)
|
|
1327
|
+
# 其他设置组件都设为不可见
|
|
1328
|
+
produce_mode = gr.Dropdown(
|
|
1329
|
+
choices=["regular", "pro", "master"],
|
|
1330
|
+
label="培育模式",
|
|
1331
|
+
info="进行一次 REGULAR 培育需要 ~30min,进行一次 PRO 培育需要 ~1h(具体视设备性能而定)。",
|
|
1332
|
+
visible=False
|
|
1333
|
+
)
|
|
1334
|
+
produce_count = gr.Number(
|
|
1335
|
+
minimum=1,
|
|
1336
|
+
label="培育次数",
|
|
1337
|
+
info="培育的次数。",
|
|
1338
|
+
visible=False
|
|
1339
|
+
)
|
|
1340
|
+
|
|
1341
|
+
# 添加偶像选择
|
|
1342
|
+
idol_choices = []
|
|
1343
|
+
for idol in IdolCard.all():
|
|
1344
|
+
if idol.is_another:
|
|
1345
|
+
idol_choices.append((f'{idol.name} 「{idol.another_name}」', idol.skin_id))
|
|
1346
|
+
else:
|
|
1347
|
+
idol_choices.append((f'{idol.name}', idol.skin_id))
|
|
1348
|
+
|
|
1349
|
+
produce_idols = gr.Dropdown(
|
|
1350
|
+
choices=idol_choices,
|
|
1351
|
+
label="选择要培育的偶像",
|
|
1352
|
+
multiselect=False,
|
|
1353
|
+
info="要培育偶像的 IdolCardSkin.id。",
|
|
1354
|
+
visible=False
|
|
1355
|
+
)
|
|
1356
|
+
kotone_warning = gr.Markdown(visible=False)
|
|
1357
|
+
auto_set_memory = gr.Checkbox(
|
|
1358
|
+
label="自动编成回忆",
|
|
1359
|
+
info="是否自动编成回忆。此选项优先级高于回忆编成编号。",
|
|
1360
|
+
visible=False
|
|
1361
|
+
)
|
|
1362
|
+
with gr.Group(visible=False) as memory_sets_group:
|
|
1363
|
+
memory_sets = gr.Dropdown(
|
|
1364
|
+
choices=[str(i) for i in range(1, 11)],
|
|
1365
|
+
label="回忆编成编号",
|
|
1366
|
+
multiselect=False,
|
|
1367
|
+
info="要使用的回忆编成编号,从 1 开始。",
|
|
1368
|
+
visible=False
|
|
1369
|
+
)
|
|
1370
|
+
auto_set_support = gr.Checkbox(
|
|
1371
|
+
label="自动编成支援卡",
|
|
1372
|
+
info="是否自动编成支援卡。此选项优先级高于支援卡编成编号。",
|
|
1373
|
+
visible=False
|
|
1374
|
+
)
|
|
1375
|
+
with gr.Group(visible=False) as support_card_sets_group:
|
|
1376
|
+
support_card_sets = gr.Dropdown(
|
|
1377
|
+
choices=[str(i) for i in range(1, 11)],
|
|
1378
|
+
label="支援卡编成编号",
|
|
1379
|
+
multiselect=False,
|
|
1380
|
+
info="要使用的支援卡编成编号,从 1 开始。",
|
|
1381
|
+
visible=False
|
|
1382
|
+
)
|
|
1383
|
+
use_pt_boost = gr.Checkbox(
|
|
1384
|
+
label="使用支援强化 Pt 提升",
|
|
1385
|
+
info="是否使用支援强化 Pt 提升。",
|
|
1386
|
+
visible=False
|
|
1387
|
+
)
|
|
1388
|
+
use_note_boost = gr.Checkbox(
|
|
1389
|
+
label="使用笔记数提升",
|
|
1390
|
+
info="是否使用笔记数提升。",
|
|
1391
|
+
visible=False
|
|
1392
|
+
)
|
|
1393
|
+
follow_producer = gr.Checkbox(
|
|
1394
|
+
label="关注租借了支援卡的制作人",
|
|
1395
|
+
info="是否关注租借了支援卡的制作人。",
|
|
1396
|
+
visible=False
|
|
1397
|
+
)
|
|
1398
|
+
self_study_lesson = gr.Dropdown(
|
|
1399
|
+
choices=['dance', 'visual', 'vocal'],
|
|
1400
|
+
label='文化课自习时选项',
|
|
1401
|
+
info='自习课类型。',
|
|
1402
|
+
visible=False
|
|
1403
|
+
)
|
|
1404
|
+
prefer_lesson_ap = gr.Checkbox(
|
|
1405
|
+
label="SP 课程优先",
|
|
1406
|
+
info="优先 SP 课程。启用后,若出现 SP 课程,则会优先执行 SP 课程,而不是推荐课程。若出现多个 SP 课程,随机选择一个。",
|
|
1407
|
+
visible=False
|
|
1408
|
+
)
|
|
1409
|
+
actions_order = gr.Dropdown(
|
|
1410
|
+
choices=[(action.display_name, action.value) for action in ProduceAction],
|
|
1411
|
+
label="行动优先级",
|
|
1412
|
+
info="每一周的行动将会按这里设置的优先级执行。",
|
|
1078
1413
|
multiselect=True,
|
|
1414
|
+
visible=False
|
|
1415
|
+
)
|
|
1416
|
+
recommend_card_detection_mode = gr.Dropdown(
|
|
1417
|
+
choices=[
|
|
1418
|
+
(RecommendCardDetectionMode.NORMAL.display_name, RecommendCardDetectionMode.NORMAL.value),
|
|
1419
|
+
(RecommendCardDetectionMode.STRICT.display_name, RecommendCardDetectionMode.STRICT.value)
|
|
1420
|
+
],
|
|
1421
|
+
label="推荐卡检测模式",
|
|
1422
|
+
info="推荐卡检测模式。严格模式下,识别速度会降低,但识别准确率会提高。",
|
|
1423
|
+
visible=False
|
|
1424
|
+
)
|
|
1425
|
+
use_ap_drink = gr.Checkbox(
|
|
1426
|
+
label="AP 不足时自动使用 AP 饮料",
|
|
1427
|
+
info="AP 不足时自动使用 AP 饮料",
|
|
1428
|
+
visible=False
|
|
1429
|
+
)
|
|
1430
|
+
skip_commu = gr.Checkbox(
|
|
1431
|
+
label="检测并跳过交流",
|
|
1432
|
+
info="检测并跳过交流",
|
|
1433
|
+
visible=False
|
|
1434
|
+
)
|
|
1435
|
+
save_solution_btn = gr.Button("保存培育方案", variant="primary", visible=False)
|
|
1436
|
+
else:
|
|
1437
|
+
# 显示选中方案的设置
|
|
1438
|
+
solution_name = gr.Textbox(
|
|
1439
|
+
label="方案名称",
|
|
1440
|
+
value=current_solution.name,
|
|
1441
|
+
interactive=True
|
|
1442
|
+
)
|
|
1443
|
+
solution_description = gr.Textbox(
|
|
1444
|
+
label="方案描述",
|
|
1445
|
+
value=current_solution.description or "",
|
|
1446
|
+
interactive=True
|
|
1447
|
+
)
|
|
1448
|
+
|
|
1449
|
+
produce_mode = gr.Dropdown(
|
|
1450
|
+
choices=["regular", "pro", "master"],
|
|
1451
|
+
value=current_solution.data.mode,
|
|
1452
|
+
label="培育模式",
|
|
1453
|
+
info="进行一次 REGULAR 培育需要 ~30min,进行一次 PRO 培育需要 ~1h(具体视设备性能而定)。"
|
|
1454
|
+
)
|
|
1455
|
+
produce_count = gr.Number(
|
|
1456
|
+
minimum=1,
|
|
1457
|
+
value=self.current_config.options.produce.produce_count,
|
|
1458
|
+
label="培育次数",
|
|
1079
1459
|
interactive=True,
|
|
1080
|
-
info=
|
|
1460
|
+
info="培育的次数。"
|
|
1081
1461
|
)
|
|
1082
1462
|
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1463
|
+
# 添加偶像选择
|
|
1464
|
+
idol_choices = []
|
|
1465
|
+
for idol in IdolCard.all():
|
|
1466
|
+
if idol.is_another:
|
|
1467
|
+
idol_choices.append((f'{idol.name} 「{idol.another_name}」', idol.skin_id))
|
|
1468
|
+
else:
|
|
1469
|
+
idol_choices.append((f'{idol.name}', idol.skin_id))
|
|
1470
|
+
|
|
1471
|
+
produce_idols = gr.Dropdown(
|
|
1472
|
+
choices=idol_choices,
|
|
1473
|
+
value=current_solution.data.idol,
|
|
1474
|
+
label="选择要培育的偶像",
|
|
1475
|
+
multiselect=False,
|
|
1476
|
+
interactive=True,
|
|
1477
|
+
info="要培育偶像的 IdolCardSkin.id。"
|
|
1478
|
+
)
|
|
1088
1479
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1480
|
+
has_kotone = bool(current_solution.data.idol and "藤田ことね" in current_solution.data.idol)
|
|
1481
|
+
is_strict_mode = current_solution.data.recommend_card_detection_mode == RecommendCardDetectionMode.STRICT
|
|
1482
|
+
kotone_warning = gr.Markdown(
|
|
1483
|
+
visible=has_kotone and not is_strict_mode,
|
|
1484
|
+
value="使用「藤田ことね」进行培育时,确保将「推荐卡检测模式」设置为「严格模式」"
|
|
1485
|
+
)
|
|
1486
|
+
|
|
1487
|
+
auto_set_memory = gr.Checkbox(
|
|
1488
|
+
label="自动编成回忆",
|
|
1489
|
+
value=current_solution.data.auto_set_memory,
|
|
1490
|
+
info="是否自动编成回忆。此选项优先级高于回忆编成编号。"
|
|
1491
|
+
)
|
|
1492
|
+
|
|
1493
|
+
with gr.Group(visible=not current_solution.data.auto_set_memory) as memory_sets_group:
|
|
1494
|
+
memory_sets = gr.Dropdown(
|
|
1495
|
+
choices=[str(i) for i in range(1, 11)], # 假设最多10个编成位
|
|
1496
|
+
value=str(current_solution.data.memory_set) if current_solution.data.memory_set else None,
|
|
1497
|
+
label="回忆编成编号",
|
|
1498
|
+
multiselect=False,
|
|
1499
|
+
interactive=True,
|
|
1500
|
+
info="要使用的回忆编成编号,从 1 开始。"
|
|
1501
|
+
)
|
|
1502
|
+
|
|
1503
|
+
auto_set_support = gr.Checkbox(
|
|
1504
|
+
label="自动编成支援卡",
|
|
1505
|
+
value=current_solution.data.auto_set_support_card,
|
|
1506
|
+
info="是否自动编成支援卡。此选项优先级高于支援卡编成编号。"
|
|
1507
|
+
)
|
|
1508
|
+
|
|
1509
|
+
with gr.Group(visible=not current_solution.data.auto_set_support_card) as support_card_sets_group:
|
|
1510
|
+
support_card_sets = gr.Dropdown(
|
|
1511
|
+
choices=[str(i) for i in range(1, 11)], # 假设最多10个编成位
|
|
1512
|
+
value=str(current_solution.data.support_card_set) if current_solution.data.support_card_set else None,
|
|
1513
|
+
label="支援卡编成编号",
|
|
1514
|
+
multiselect=False,
|
|
1515
|
+
interactive=True,
|
|
1516
|
+
info="要使用的支援卡编成编号,从 1 开始。"
|
|
1517
|
+
)
|
|
1518
|
+
use_pt_boost = gr.Checkbox(
|
|
1519
|
+
label="使用支援强化 Pt 提升",
|
|
1520
|
+
value=current_solution.data.use_pt_boost,
|
|
1521
|
+
info="是否使用支援强化 Pt 提升。"
|
|
1522
|
+
)
|
|
1523
|
+
use_note_boost = gr.Checkbox(
|
|
1524
|
+
label="使用笔记数提升",
|
|
1525
|
+
value=current_solution.data.use_note_boost,
|
|
1526
|
+
info="是否使用笔记数提升。"
|
|
1527
|
+
)
|
|
1528
|
+
follow_producer = gr.Checkbox(
|
|
1529
|
+
label="关注租借了支援卡的制作人",
|
|
1530
|
+
value=current_solution.data.follow_producer,
|
|
1531
|
+
info="是否关注租借了支援卡的制作人。"
|
|
1532
|
+
)
|
|
1533
|
+
self_study_lesson = gr.Dropdown(
|
|
1534
|
+
choices=['dance', 'visual', 'vocal'],
|
|
1535
|
+
value=current_solution.data.self_study_lesson,
|
|
1536
|
+
label='文化课自习时选项',
|
|
1537
|
+
info='自习课类型。'
|
|
1538
|
+
)
|
|
1539
|
+
prefer_lesson_ap = gr.Checkbox(
|
|
1540
|
+
label="SP 课程优先",
|
|
1541
|
+
value=current_solution.data.prefer_lesson_ap,
|
|
1542
|
+
info="优先 SP 课程。启用后,若出现 SP 课程,则会优先执行 SP 课程,而不是推荐课程。若出现多个 SP 课程,随机选择一个。"
|
|
1543
|
+
)
|
|
1544
|
+
actions_order = gr.Dropdown(
|
|
1545
|
+
choices=[(action.display_name, action.value) for action in ProduceAction],
|
|
1546
|
+
value=[action.value for action in current_solution.data.actions_order],
|
|
1547
|
+
label="行动优先级",
|
|
1548
|
+
info="每一周的行动将会按这里设置的优先级执行。",
|
|
1549
|
+
multiselect=True
|
|
1550
|
+
)
|
|
1551
|
+
recommend_card_detection_mode = gr.Dropdown(
|
|
1552
|
+
choices=[
|
|
1553
|
+
(RecommendCardDetectionMode.NORMAL.display_name, RecommendCardDetectionMode.NORMAL.value),
|
|
1554
|
+
(RecommendCardDetectionMode.STRICT.display_name, RecommendCardDetectionMode.STRICT.value)
|
|
1555
|
+
],
|
|
1556
|
+
value=current_solution.data.recommend_card_detection_mode.value,
|
|
1557
|
+
label="推荐卡检测模式",
|
|
1558
|
+
info="推荐卡检测模式。严格模式下,识别速度会降低,但识别准确率会提高。"
|
|
1559
|
+
)
|
|
1560
|
+
use_ap_drink = gr.Checkbox(
|
|
1561
|
+
label="AP 不足时自动使用 AP 饮料",
|
|
1562
|
+
value=current_solution.data.use_ap_drink,
|
|
1563
|
+
info="AP 不足时自动使用 AP 饮料"
|
|
1564
|
+
)
|
|
1565
|
+
skip_commu = gr.Checkbox(
|
|
1566
|
+
label="检测并跳过交流",
|
|
1567
|
+
value=current_solution.data.skip_commu,
|
|
1568
|
+
info="检测并跳过交流"
|
|
1569
|
+
)
|
|
1570
|
+
|
|
1571
|
+
# 添加保存按钮
|
|
1572
|
+
save_solution_btn = gr.Button("保存培育方案", variant="primary")
|
|
1573
|
+
|
|
1574
|
+
# 添加事件处理
|
|
1575
|
+
def update_kotone_warning(selected_idol, recommend_card_detection_mode):
|
|
1576
|
+
# Handle case where selected_idol is None (no selection)
|
|
1577
|
+
# selected_idol is a single string (skin_id), not a list
|
|
1578
|
+
if selected_idol is None:
|
|
1579
|
+
has_kotone = False
|
|
1580
|
+
else:
|
|
1581
|
+
has_kotone = "藤田ことね" in selected_idol
|
|
1582
|
+
is_strict_mode = recommend_card_detection_mode == RecommendCardDetectionMode.STRICT.value
|
|
1583
|
+
return gr.Markdown(visible=has_kotone and not is_strict_mode)
|
|
1584
|
+
|
|
1585
|
+
def on_solution_change(solution_id):
|
|
1586
|
+
"""当选择的培育方案改变时,更新所有设置组件"""
|
|
1587
|
+
if not solution_id:
|
|
1588
|
+
return [
|
|
1589
|
+
gr.Textbox(value="", visible=False), # solution_name
|
|
1590
|
+
gr.Textbox(value="", visible=False), # solution_description
|
|
1591
|
+
gr.Dropdown(visible=False), # produce_mode
|
|
1592
|
+
gr.Number(visible=False), # produce_count
|
|
1593
|
+
gr.Dropdown(visible=False), # produce_idols
|
|
1594
|
+
gr.Markdown(visible=False), # kotone_warning
|
|
1595
|
+
gr.Checkbox(visible=False), # auto_set_memory
|
|
1596
|
+
gr.Group(visible=False), # memory_sets_group
|
|
1597
|
+
gr.Dropdown(visible=False), # memory_sets
|
|
1598
|
+
gr.Checkbox(visible=False), # auto_set_support
|
|
1599
|
+
gr.Checkbox(visible=False), # use_pt_boost
|
|
1600
|
+
gr.Checkbox(visible=False), # use_note_boost
|
|
1601
|
+
gr.Checkbox(visible=False), # follow_producer
|
|
1602
|
+
gr.Dropdown(visible=False), # self_study_lesson
|
|
1603
|
+
gr.Checkbox(visible=False), # prefer_lesson_ap
|
|
1604
|
+
gr.Dropdown(visible=False), # actions_order
|
|
1605
|
+
gr.Dropdown(visible=False), # recommend_card_detection_mode
|
|
1606
|
+
gr.Checkbox(visible=False), # use_ap_drink
|
|
1607
|
+
gr.Checkbox(visible=False), # skip_commu
|
|
1608
|
+
gr.Button(visible=False), # save_solution_btn
|
|
1609
|
+
]
|
|
1610
|
+
|
|
1611
|
+
try:
|
|
1612
|
+
solution = solution_manager.read(solution_id)
|
|
1613
|
+
has_kotone = bool(solution.data.idol and "藤田ことね" in solution.data.idol)
|
|
1614
|
+
is_strict_mode = solution.data.recommend_card_detection_mode == RecommendCardDetectionMode.STRICT
|
|
1615
|
+
|
|
1616
|
+
return [
|
|
1617
|
+
gr.Textbox(value=solution.name, visible=True),
|
|
1618
|
+
gr.Textbox(value=solution.description or "", visible=True),
|
|
1619
|
+
gr.Dropdown(value=solution.data.mode, visible=True),
|
|
1620
|
+
gr.Number(value=self.current_config.options.produce.produce_count, visible=True),
|
|
1621
|
+
gr.Dropdown(value=solution.data.idol, visible=True),
|
|
1622
|
+
gr.Markdown(visible=has_kotone and not is_strict_mode),
|
|
1623
|
+
gr.Checkbox(value=solution.data.auto_set_memory, visible=True),
|
|
1624
|
+
gr.Group(visible=not solution.data.auto_set_memory),
|
|
1625
|
+
gr.Dropdown(value=str(solution.data.memory_set) if solution.data.memory_set else None, visible=True),
|
|
1626
|
+
gr.Checkbox(value=solution.data.auto_set_support_card, visible=True),
|
|
1627
|
+
gr.Group(visible=not solution.data.auto_set_support_card),
|
|
1628
|
+
gr.Dropdown(value=str(solution.data.support_card_set) if solution.data.support_card_set else None, visible=True),
|
|
1629
|
+
gr.Checkbox(value=solution.data.use_pt_boost, visible=True),
|
|
1630
|
+
gr.Checkbox(value=solution.data.use_note_boost, visible=True),
|
|
1631
|
+
gr.Checkbox(value=solution.data.follow_producer, visible=True),
|
|
1632
|
+
gr.Dropdown(value=solution.data.self_study_lesson, visible=True),
|
|
1633
|
+
gr.Checkbox(value=solution.data.prefer_lesson_ap, visible=True),
|
|
1634
|
+
gr.Dropdown(value=[action.value for action in solution.data.actions_order], visible=True),
|
|
1635
|
+
gr.Dropdown(value=solution.data.recommend_card_detection_mode.value, visible=True),
|
|
1636
|
+
gr.Checkbox(value=solution.data.use_ap_drink, visible=True),
|
|
1637
|
+
gr.Checkbox(value=solution.data.skip_commu, visible=True),
|
|
1638
|
+
gr.Button(visible=True), # save_solution_btn
|
|
1639
|
+
]
|
|
1640
|
+
except FileNotFoundError:
|
|
1641
|
+
gr.Warning(f"培育方案 {solution_id} 不存在")
|
|
1642
|
+
return on_solution_change(None)
|
|
1643
|
+
except Exception as e:
|
|
1644
|
+
gr.Error(f"加载培育方案失败:{str(e)}")
|
|
1645
|
+
return on_solution_change(None)
|
|
1646
|
+
|
|
1647
|
+
def on_new_solution():
|
|
1648
|
+
"""创建新的培育方案"""
|
|
1649
|
+
try:
|
|
1650
|
+
new_solution = solution_manager.new("新培育方案")
|
|
1651
|
+
solution_manager.save(new_solution.id, new_solution)
|
|
1652
|
+
|
|
1653
|
+
# 重新列出所有方案
|
|
1654
|
+
solutions = solution_manager.list()
|
|
1655
|
+
solution_choices = [(f"{sol.name} - {sol.description or '无描述'}", sol.id) for sol in solutions]
|
|
1656
|
+
|
|
1657
|
+
gr.Success("新培育方案创建成功")
|
|
1658
|
+
# 根据是否有设置Tab的下拉框来决定返回值
|
|
1659
|
+
updated_dropdown = gr.Dropdown(choices=solution_choices, value=new_solution.id)
|
|
1660
|
+
if settings_dropdown is not None:
|
|
1661
|
+
return [updated_dropdown, updated_dropdown]
|
|
1662
|
+
else:
|
|
1663
|
+
return updated_dropdown
|
|
1664
|
+
except Exception as e:
|
|
1665
|
+
gr.Error(f"创建培育方案失败:{str(e)}")
|
|
1666
|
+
if settings_dropdown is not None:
|
|
1667
|
+
return [gr.Dropdown(), gr.Dropdown()]
|
|
1668
|
+
else:
|
|
1669
|
+
return gr.Dropdown()
|
|
1670
|
+
|
|
1671
|
+
def on_delete_solution(solution_id):
|
|
1672
|
+
"""删除当前培育方案"""
|
|
1673
|
+
if not solution_id:
|
|
1674
|
+
gr.Warning("请先选择要删除的培育方案")
|
|
1675
|
+
if settings_dropdown is not None:
|
|
1676
|
+
return [gr.Dropdown(), gr.Dropdown()]
|
|
1677
|
+
else:
|
|
1678
|
+
return gr.Dropdown()
|
|
1679
|
+
|
|
1680
|
+
try:
|
|
1681
|
+
solution_manager.delete(solution_id)
|
|
1682
|
+
|
|
1683
|
+
# 重新列出所有方案
|
|
1684
|
+
solutions = solution_manager.list()
|
|
1685
|
+
solution_choices = [(f"{sol.name} - {sol.description or '无描述'}", sol.id) for sol in solutions]
|
|
1686
|
+
|
|
1687
|
+
gr.Success("培育方案删除成功")
|
|
1688
|
+
# 根据是否有设置Tab的下拉框来决定返回值
|
|
1689
|
+
updated_dropdown = gr.Dropdown(choices=solution_choices, value=None)
|
|
1690
|
+
if settings_dropdown is not None:
|
|
1691
|
+
return [updated_dropdown, updated_dropdown]
|
|
1692
|
+
else:
|
|
1693
|
+
return updated_dropdown
|
|
1694
|
+
except Exception as e:
|
|
1695
|
+
gr.Error(f"删除培育方案失败:{str(e)}")
|
|
1696
|
+
if settings_dropdown is not None:
|
|
1697
|
+
return [gr.Dropdown(), gr.Dropdown()]
|
|
1698
|
+
else:
|
|
1699
|
+
return gr.Dropdown()
|
|
1700
|
+
|
|
1701
|
+
def on_save_solution(solution_id, name, description, mode, count, idols, auto_memory, memory_sets,
|
|
1702
|
+
auto_support, support_card_sets, pt_boost, note_boost, follow_producer, study_lesson, prefer_ap,
|
|
1703
|
+
actions, detection_mode, ap_drink, skip_commu_val):
|
|
1704
|
+
"""保存培育方案"""
|
|
1705
|
+
if not solution_id:
|
|
1706
|
+
gr.Warning("请先选择要保存的培育方案")
|
|
1707
|
+
if settings_dropdown is not None:
|
|
1708
|
+
return [gr.Dropdown(), gr.Dropdown()]
|
|
1709
|
+
else:
|
|
1710
|
+
return gr.Dropdown()
|
|
1711
|
+
|
|
1712
|
+
try:
|
|
1713
|
+
# 构建培育数据
|
|
1714
|
+
produce_data = ProduceData(
|
|
1715
|
+
mode=mode,
|
|
1716
|
+
idol=idols if idols else None,
|
|
1717
|
+
memory_set=int(memory_sets) if memory_sets else None,
|
|
1718
|
+
support_card_set=int(support_card_sets) if support_card_sets else None,
|
|
1719
|
+
auto_set_memory=auto_memory,
|
|
1720
|
+
auto_set_support_card=auto_support,
|
|
1721
|
+
use_pt_boost=pt_boost,
|
|
1722
|
+
use_note_boost=note_boost,
|
|
1723
|
+
follow_producer=follow_producer,
|
|
1724
|
+
self_study_lesson=study_lesson,
|
|
1725
|
+
prefer_lesson_ap=prefer_ap,
|
|
1726
|
+
actions_order=[ProduceAction(action) for action in actions] if actions else [],
|
|
1727
|
+
recommend_card_detection_mode=RecommendCardDetectionMode(detection_mode),
|
|
1728
|
+
use_ap_drink=ap_drink,
|
|
1729
|
+
skip_commu=skip_commu_val
|
|
1730
|
+
)
|
|
1731
|
+
|
|
1732
|
+
# 构建方案对象
|
|
1733
|
+
solution = ProduceSolution(
|
|
1734
|
+
id=solution_id,
|
|
1735
|
+
name=name or "未命名方案",
|
|
1736
|
+
description=description,
|
|
1737
|
+
data=produce_data
|
|
1738
|
+
)
|
|
1739
|
+
|
|
1740
|
+
# 保存方案
|
|
1741
|
+
solution_manager.save(solution_id, solution)
|
|
1742
|
+
|
|
1743
|
+
# 同时更新配置中的 produce_count
|
|
1744
|
+
self.current_config.options.produce.produce_count = int(count)
|
|
1745
|
+
|
|
1746
|
+
# 重新列出所有方案(确保没有重复项)
|
|
1747
|
+
solutions = solution_manager.list()
|
|
1748
|
+
solution_choices = [(f"{sol.name} - {sol.description or '无描述'}", sol.id) for sol in solutions]
|
|
1749
|
+
|
|
1750
|
+
gr.Success("培育方案保存成功")
|
|
1751
|
+
# 根据是否有设置Tab的下拉框来决定返回值
|
|
1752
|
+
updated_dropdown = gr.Dropdown(choices=solution_choices, value=solution_id)
|
|
1753
|
+
if settings_dropdown is not None:
|
|
1754
|
+
return [updated_dropdown, updated_dropdown]
|
|
1755
|
+
else:
|
|
1756
|
+
return updated_dropdown
|
|
1757
|
+
except Exception as e:
|
|
1758
|
+
gr.Error(f"保存培育方案失败:{str(e)}")
|
|
1759
|
+
if settings_dropdown is not None:
|
|
1760
|
+
return [gr.Dropdown(), gr.Dropdown()]
|
|
1761
|
+
else:
|
|
1762
|
+
return gr.Dropdown()
|
|
1763
|
+
|
|
1764
|
+
# 绑定事件
|
|
1765
|
+
# 为所有控件绑定change事件,无论是否有选中方案
|
|
1766
|
+
auto_set_memory.change(
|
|
1767
|
+
fn=lambda x: gr.Group(visible=not x),
|
|
1768
|
+
inputs=[auto_set_memory],
|
|
1769
|
+
outputs=[memory_sets_group]
|
|
1770
|
+
)
|
|
1771
|
+
|
|
1772
|
+
auto_set_support.change(
|
|
1773
|
+
fn=lambda x: gr.Group(visible=not x),
|
|
1774
|
+
inputs=[auto_set_support],
|
|
1775
|
+
outputs=[support_card_sets_group]
|
|
1776
|
+
)
|
|
1777
|
+
|
|
1778
|
+
if current_solution is not None:
|
|
1146
1779
|
recommend_card_detection_mode.change(
|
|
1147
1780
|
fn=update_kotone_warning,
|
|
1148
1781
|
inputs=[produce_idols, recommend_card_detection_mode],
|
|
@@ -1154,54 +1787,56 @@ class KotoneBotUI:
|
|
|
1154
1787
|
outputs=kotone_warning
|
|
1155
1788
|
)
|
|
1156
1789
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1790
|
+
# 绑定方案管理事件
|
|
1791
|
+
solution_dropdown.change(
|
|
1792
|
+
fn=on_solution_change,
|
|
1793
|
+
inputs=[solution_dropdown],
|
|
1794
|
+
outputs=[
|
|
1795
|
+
solution_name, solution_description,
|
|
1796
|
+
produce_mode, produce_count, produce_idols, kotone_warning,
|
|
1797
|
+
auto_set_memory, memory_sets_group, memory_sets,
|
|
1798
|
+
auto_set_support, support_card_sets_group, support_card_sets,
|
|
1799
|
+
use_pt_boost, use_note_boost, follow_producer,
|
|
1800
|
+
self_study_lesson, prefer_lesson_ap, actions_order,
|
|
1801
|
+
recommend_card_detection_mode, use_ap_drink, skip_commu,
|
|
1802
|
+
save_solution_btn
|
|
1803
|
+
]
|
|
1161
1804
|
)
|
|
1162
1805
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1806
|
+
# 准备输出列表,如果设置Tab的下拉框存在,则同时更新
|
|
1807
|
+
outputs_for_new = [solution_dropdown]
|
|
1808
|
+
outputs_for_delete = [solution_dropdown]
|
|
1809
|
+
outputs_for_save = [solution_dropdown]
|
|
1810
|
+
|
|
1811
|
+
if settings_dropdown is not None:
|
|
1812
|
+
outputs_for_new.append(settings_dropdown)
|
|
1813
|
+
outputs_for_delete.append(settings_dropdown)
|
|
1814
|
+
outputs_for_save.append(settings_dropdown)
|
|
1815
|
+
|
|
1816
|
+
new_solution_btn.click(
|
|
1817
|
+
fn=on_new_solution,
|
|
1818
|
+
outputs=outputs_for_new
|
|
1819
|
+
)
|
|
1820
|
+
|
|
1821
|
+
delete_solution_btn.click(
|
|
1822
|
+
fn=on_delete_solution,
|
|
1823
|
+
inputs=[solution_dropdown],
|
|
1824
|
+
outputs=outputs_for_delete
|
|
1825
|
+
)
|
|
1826
|
+
|
|
1827
|
+
# 绑定保存按钮事件
|
|
1828
|
+
save_solution_btn.click(
|
|
1829
|
+
fn=on_save_solution,
|
|
1830
|
+
inputs=[
|
|
1831
|
+
solution_dropdown, solution_name, solution_description,
|
|
1832
|
+
produce_mode, produce_count, produce_idols,
|
|
1833
|
+
auto_set_memory, memory_sets, auto_set_support, support_card_sets,
|
|
1834
|
+
use_pt_boost, use_note_boost, follow_producer,
|
|
1835
|
+
self_study_lesson, prefer_lesson_ap, actions_order,
|
|
1836
|
+
recommend_card_detection_mode, use_ap_drink, skip_commu
|
|
1837
|
+
],
|
|
1838
|
+
outputs=outputs_for_save
|
|
1167
1839
|
)
|
|
1168
|
-
|
|
1169
|
-
def set_config(config: BaseConfig, data: dict[ConfigKey, Any]) -> None:
|
|
1170
|
-
config.produce.enabled = data['produce_enabled']
|
|
1171
|
-
config.produce.mode = data['produce_mode']
|
|
1172
|
-
config.produce.produce_count = data['produce_count']
|
|
1173
|
-
config.produce.idols = data['produce_idols']
|
|
1174
|
-
config.produce.memory_sets = [int(i) for i in data['memory_sets']]
|
|
1175
|
-
config.produce.auto_set_memory = data['auto_set_memory']
|
|
1176
|
-
config.produce.auto_set_support_card = data['auto_set_support']
|
|
1177
|
-
config.produce.use_pt_boost = data['use_pt_boost']
|
|
1178
|
-
config.produce.use_note_boost = data['use_note_boost']
|
|
1179
|
-
config.produce.follow_producer = data['follow_producer']
|
|
1180
|
-
config.produce.self_study_lesson = data['self_study_lesson']
|
|
1181
|
-
config.produce.prefer_lesson_ap = data['prefer_lesson_ap']
|
|
1182
|
-
config.produce.actions_order = [ProduceAction(action) for action in data['actions_order']]
|
|
1183
|
-
config.produce.recommend_card_detection_mode = RecommendCardDetectionMode(data['recommend_card_detection_mode'])
|
|
1184
|
-
config.produce.use_ap_drink = data['use_ap_drink']
|
|
1185
|
-
config.produce.skip_commu = data['skip_commu']
|
|
1186
|
-
|
|
1187
|
-
return set_config, {
|
|
1188
|
-
'produce_enabled': produce_enabled,
|
|
1189
|
-
'produce_mode': produce_mode,
|
|
1190
|
-
'produce_count': produce_count,
|
|
1191
|
-
'produce_idols': produce_idols,
|
|
1192
|
-
'memory_sets': memory_sets,
|
|
1193
|
-
'auto_set_memory': auto_set_memory,
|
|
1194
|
-
'auto_set_support': auto_set_support,
|
|
1195
|
-
'use_pt_boost': use_pt_boost,
|
|
1196
|
-
'use_note_boost': use_note_boost,
|
|
1197
|
-
'follow_producer': follow_producer,
|
|
1198
|
-
'self_study_lesson': self_study_lesson,
|
|
1199
|
-
'prefer_lesson_ap': prefer_lesson_ap,
|
|
1200
|
-
'actions_order': actions_order,
|
|
1201
|
-
'recommend_card_detection_mode': recommend_card_detection_mode,
|
|
1202
|
-
'use_ap_drink': use_ap_drink,
|
|
1203
|
-
'skip_commu': skip_commu
|
|
1204
|
-
}
|
|
1205
1840
|
|
|
1206
1841
|
def _create_club_reward_settings(self) -> ConfigBuilderReturnValue:
|
|
1207
1842
|
with gr.Column():
|
|
@@ -1897,7 +2532,20 @@ class KotoneBotUI:
|
|
|
1897
2532
|
self.current_config = self.config.user_configs[0]
|
|
1898
2533
|
|
|
1899
2534
|
def create_ui(self) -> gr.Blocks:
|
|
1900
|
-
|
|
2535
|
+
custom_css = """
|
|
2536
|
+
#container { max-width: 800px; margin: auto; padding: 20px; }
|
|
2537
|
+
.quick-controls-row > div {
|
|
2538
|
+
display: flex !important;
|
|
2539
|
+
flex-wrap: nowrap !important;
|
|
2540
|
+
gap: 0 !important;
|
|
2541
|
+
overflow-x: auto !important;
|
|
2542
|
+
}
|
|
2543
|
+
.quick-controls-row > div > div {
|
|
2544
|
+
min-width: auto !important;
|
|
2545
|
+
padding: 0;
|
|
2546
|
+
}
|
|
2547
|
+
"""
|
|
2548
|
+
with gr.Blocks(title="琴音小助手", css=custom_css) as app:
|
|
1901
2549
|
with gr.Column(elem_id="container"):
|
|
1902
2550
|
gr.Markdown(f"# 琴音小助手 v{self._kaa.version}")
|
|
1903
2551
|
|
|
@@ -1905,6 +2553,7 @@ class KotoneBotUI:
|
|
|
1905
2553
|
self._create_status_tab()
|
|
1906
2554
|
self._create_task_tab()
|
|
1907
2555
|
self._create_settings_tab()
|
|
2556
|
+
self._create_produce_tab()
|
|
1908
2557
|
self._create_log_tab()
|
|
1909
2558
|
self._create_whats_new_tab()
|
|
1910
2559
|
self._create_screen_tab()
|