ksaa 2025.8.17.0__py3-none-any.whl → 2025.9b1__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/kaa/application/core/idle_mode.py +172 -0
- kotonebot/kaa/config/__init__.py +2 -0
- kotonebot/kaa/config/schema.py +11 -0
- kotonebot/kaa/main/gr.py +182 -51
- kotonebot/kaa/metadata.py +45 -0
- kotonebot/kaa/resources/__pycache__/__init__.cpython-310.pyc +0 -0
- kotonebot/kaa/resources/game.db +0 -0
- kotonebot/kaa/resources/game_ver.txt +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-amao-3-013_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-amao-3-013_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-fktn-3-014_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-fktn-3-015_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-fktn-3-015_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hmsz-3-002_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hmsz-3-002_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hmsz-3-012_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hmsz-3-012_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hrnm-3-014_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hrnm-3-014_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hski-3-014_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hski-3-014_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hume-3-014_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-hume-3-014_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-jsna-3-008_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-jsna-3-008_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-jsna-3-013_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-jsna-3-013_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-kcna-3-013_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-kcna-3-013_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-kllj-3-013_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-kllj-3-013_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-ssmk-3-014_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-ssmk-3-014_1.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-ttmr-3-014_0.png +0 -0
- kotonebot/kaa/resources/idol_cards/i_card-skin-ttmr-3-014_1.png +0 -0
- kotonebot/kaa/sprites/70898bf8-56c5-4f84-becb-629c9ab6a7da.png +0 -0
- kotonebot/kaa/sprites/9483fae5-3a72-4684-9403-d25d2c602d3d.png +0 -0
- kotonebot/kaa/sprites/9fd0753f-c607-4d49-82d1-40bda27e014f.png +0 -0
- kotonebot/kaa/sprites/a48324ae-7c1a-489e-b3c4-93d12267f88d.png +0 -0
- kotonebot/kaa/sprites/ce20a856-5629-4f8e-a8e1-d1bd14e18e4f.png +0 -0
- kotonebot/kaa/sprites/eaad330d-4e50-4b55-be2c-8da0f72764d9.png +0 -0
- kotonebot/kaa/tasks/R.py +135 -127
- kotonebot/kaa/tasks/actions/scenes.py +2 -0
- kotonebot/kaa/tasks/daily/purchase.py +2 -4
- kotonebot/kaa/tasks/produce/cards.py +3 -0
- kotonebot/kaa/tasks/produce/common.py +88 -0
- kotonebot/kaa/tasks/produce/in_purodyuusu.py +3 -3
- kotonebot/kaa/tasks/produce/non_lesson_actions.py +12 -6
- kotonebot/kaa/tasks/produce/produce.py +36 -55
- {ksaa-2025.8.17.0.dist-info → ksaa-2025.9b1.dist-info}/METADATA +92 -90
- {ksaa-2025.8.17.0.dist-info → ksaa-2025.9b1.dist-info}/RECORD +181 -150
- /kotonebot/kaa/sprites/{9bc1e849-e69d-4849-a849-45ea81829567.png → 002e7b92-11f4-487a-af55-334663e2b8cd.png} +0 -0
- /kotonebot/kaa/sprites/{3336498e-763b-4b43-9939-a271d2deb64f.png → 003c315c-418c-410e-ba45-290150097a25.png} +0 -0
- /kotonebot/kaa/sprites/{cd5ba3a7-96aa-4efc-97fc-b72f72d084d2.png → 01106370-2321-4696-a60e-dc76b565a097.png} +0 -0
- /kotonebot/kaa/sprites/{bd5190da-d3ed-462e-a573-b8f015cdef97.png → 0519d61c-0451-42a2-96ed-baa5ef026655.png} +0 -0
- /kotonebot/kaa/sprites/{0ef0615f-f293-4a4e-93ac-985b3a17c8d7.png → 0c2a1e9f-85be-4fec-a8ae-4e417c58d5a5.png} +0 -0
- /kotonebot/kaa/sprites/{0b947c81-0ab1-40a8-8c26-26258be572c7.png → 0d1ecf0b-b090-42b2-b895-cb1f5b415af8.png} +0 -0
- /kotonebot/kaa/sprites/{be2d7e60-56d2-4891-aae9-b5d2a65a8d03.png → 0d39671a-cfa3-4832-93e8-6ab61cece799.png} +0 -0
- /kotonebot/kaa/sprites/{c654428b-4f16-4257-800f-da627ddb7595.png → 0ffd0b92-78f6-4661-a2c3-3c337b75d3bb.png} +0 -0
- /kotonebot/kaa/sprites/{1e540586-c381-4aed-b689-e9cd2708ae85.png → 105df024-ece9-4c9c-9479-9f7423f4abec.png} +0 -0
- /kotonebot/kaa/sprites/{0da004d8-2cc5-43ab-9ac1-94d4f74dd37d.png → 112f47b8-e71f-426f-9081-0c8efb6ced72.png} +0 -0
- /kotonebot/kaa/sprites/{e850b360-da95-4498-ab3e-177e0d57e189.png → 11c5034e-d258-422d-850c-a4495b346778.png} +0 -0
- /kotonebot/kaa/sprites/{896ed7b5-72c8-4c1d-90ff-eb7f12876f9c.png → 12d59cc0-cef6-472d-b424-edaae52463ca.png} +0 -0
- /kotonebot/kaa/sprites/{6b4f820d-8b40-4ac1-9322-550860cbda08.png → 13338d14-2b0d-4630-a5d2-dc273f62524e.png} +0 -0
- /kotonebot/kaa/sprites/{4c2fe337-73f6-4ed4-84ae-f17bf4787645.png → 13a5d0e7-776e-40c2-8a52-dd3e016913b4.png} +0 -0
- /kotonebot/kaa/sprites/{d559328f-9b26-4ea1-8f96-f432abf0214d.png → 156cb3bd-0523-4a76-8747-8d4ce23fed7b.png} +0 -0
- /kotonebot/kaa/sprites/{da351a32-c51f-4746-8f89-778343772d08.png → 16d914f3-c3be-479e-932a-4c336c08b94e.png} +0 -0
- /kotonebot/kaa/sprites/{ed2f8cd2-be82-4d48-acd0-c48cf8bdd800.png → 1b39e16c-d8e2-4f4c-bc6d-a4511184f8af.png} +0 -0
- /kotonebot/kaa/sprites/{f11ca963-fc05-4486-acf7-aa8f7415e6b5.png → 1b82310e-8422-4be6-b31b-bc7693def4e4.png} +0 -0
- /kotonebot/kaa/sprites/{f61e28cd-9eaa-4d3c-b25d-8bfdaecb1255.png → 1d25aa70-8137-4c63-8dcf-a5b5a8f950e6.png} +0 -0
- /kotonebot/kaa/sprites/{a5e11b99-d89e-47a2-ae67-4e0a04bfc022.png → 1e324ce8-b56f-45d5-9476-713dabfdecf9.png} +0 -0
- /kotonebot/kaa/sprites/{a7f49544-2aaf-4f5c-a217-7203bfa87758.png → 22bda7ef-ad0d-4020-a667-6ae77b4805ca.png} +0 -0
- /kotonebot/kaa/sprites/{7e00779b-de42-4406-88f9-07d93e47f104.png → 23a39277-a6ac-4a49-9c6a-1fca1a3a4d9b.png} +0 -0
- /kotonebot/kaa/sprites/{1339693d-6e77-4058-921a-9079c8eb5a9a.png → 23b37aad-1de3-43e2-84e6-78f6f0f28fba.png} +0 -0
- /kotonebot/kaa/sprites/{d3c31276-8395-4aa3-ae1a-4c50a24e8574.png → 23f8844e-9272-4a5c-badf-a30676fd22da.png} +0 -0
- /kotonebot/kaa/sprites/{394c60cc-1caa-4a29-a387-798316d48d4a.png → 24458a04-ca4d-4330-9dd6-f074feac9a17.png} +0 -0
- /kotonebot/kaa/sprites/{a914c9d7-3a19-4d9c-940e-579bf3f7fa79.png → 246f9799-5367-4fb4-877d-821fb4acad71.png} +0 -0
- /kotonebot/kaa/sprites/{9ec515d0-c177-43fa-bbf3-ea2a57080969.png → 24d55c2b-dfe8-4a80-9f39-94045478f5a5.png} +0 -0
- /kotonebot/kaa/sprites/{21f2fdd8-c6fe-44fe-bcc6-efa8bc7f895a.png → 26262f2d-e12b-4992-8c14-15679cae4298.png} +0 -0
- /kotonebot/kaa/sprites/{0de1fa4d-3621-4671-9e1f-b8ed1e767adc.png → 2704de68-4349-4695-8102-4dcd93fe82c7.png} +0 -0
- /kotonebot/kaa/sprites/{3303b048-552d-4794-aa57-180b43187d5a.png → 279ab0e2-1601-4bfb-8d27-4019fc4dcd3d.png} +0 -0
- /kotonebot/kaa/sprites/{b7283194-0e6d-4ac1-84e0-c2062af8eba8.png → 2ad65f0c-3b9c-46ad-808e-11c6d6db7417.png} +0 -0
- /kotonebot/kaa/sprites/{1777dfb5-2793-4037-9da7-f789cf65896e.png → 2b3a82fd-79b3-400c-988a-248a7b277542.png} +0 -0
- /kotonebot/kaa/sprites/{cce54a7c-bdd5-4063-8a40-e01709e69893.png → 37d24544-1791-474d-8f74-b1dbe0dd3c6b.png} +0 -0
- /kotonebot/kaa/sprites/{6224165f-3fa9-483f-b4fb-73c44e8009e4.png → 3868b12d-8d93-4754-91bd-797680d24e22.png} +0 -0
- /kotonebot/kaa/sprites/{9aee770e-1746-4076-b3c4-5da218321614.png → 3de9bd37-90ef-45ec-88c0-03c4fd50fb51.png} +0 -0
- /kotonebot/kaa/sprites/{850d5405-2103-4a2f-9e00-d5c5f43ce9a7.png → 46198a1d-888e-4a12-827e-51cdd4fc30a2.png} +0 -0
- /kotonebot/kaa/sprites/{42092d5b-d11d-4651-9cd5-49302f52d50b.png → 49587e50-e978-461f-b49c-7f92347923f5.png} +0 -0
- /kotonebot/kaa/sprites/{8e90dc5b-d79a-4133-b722-edbb14f5f0db.png → 4af83157-f237-4072-a732-1e59814485e7.png} +0 -0
- /kotonebot/kaa/sprites/{255b0e7a-c47a-4f70-9c92-5e3fa06d4d4c.png → 4b595d09-a5ed-47d6-9c7b-e471792db801.png} +0 -0
- /kotonebot/kaa/sprites/{15ce2944-3d27-4073-b969-2ec8fc98ceb4.png → 4e284d43-9d58-4afa-be66-b61825ef2be3.png} +0 -0
- /kotonebot/kaa/sprites/{aa55089d-7b80-4763-a226-cde10e56f8a5.png → 50f138f4-7500-42c1-8121-2f03703d8f8f.png} +0 -0
- /kotonebot/kaa/sprites/{e8935f50-3109-4d98-9783-86738763a431.png → 53d082f9-9cac-4ca0-b166-3a3599c4f757.png} +0 -0
- /kotonebot/kaa/sprites/{a6a23fad-cc30-43cd-b869-d2fad70d32ab.png → 5479a383-3e75-4082-a118-fdae784228f4.png} +0 -0
- /kotonebot/kaa/sprites/{64d7e162-a761-458b-a0c6-083658141032.png → 564e9739-a90d-4c17-9d29-b3edb6aef1e9.png} +0 -0
- /kotonebot/kaa/sprites/{14488bad-1e16-47b8-9870-f2e18c6b87ee.png → 5aac4900-ccd2-4a72-9135-0804fe14e6e2.png} +0 -0
- /kotonebot/kaa/sprites/{a885914f-a305-4af3-b2a5-991fdf0101f6.png → 5c926d27-63c7-466f-9e34-65144153e0d2.png} +0 -0
- /kotonebot/kaa/sprites/{e4c40e7a-f67c-45d6-9775-8389bcff0b67.png → 5d51ee71-a2fb-414a-ab48-c5d3c1a3b945.png} +0 -0
- /kotonebot/kaa/sprites/{ef46ae80-8c34-4948-9076-b0536805e7dc.png → 62390db3-c5bc-4868-bfb3-958acceff9cd.png} +0 -0
- /kotonebot/kaa/sprites/{720cfc0e-74a2-4239-bc08-ea9927871cd0.png → 634b1421-7f65-452c-a4e2-e40a5028938a.png} +0 -0
- /kotonebot/kaa/sprites/{130ee78a-c201-4fa0-bac5-7be0b842312d.png → 6588da9e-a9b5-4313-9f67-e03f213f3fa4.png} +0 -0
- /kotonebot/kaa/sprites/{2c43b51a-7ca5-4401-a05f-d3b3de17c2d3.png → 66eee7a5-3d0e-430f-850b-7fff14b3671f.png} +0 -0
- /kotonebot/kaa/sprites/{54a7603e-fd84-4d7f-99ef-f95d3695aa42.png → 67176e48-eaa5-46dd-bbaf-85b1b324ba48.png} +0 -0
- /kotonebot/kaa/sprites/{079cdbed-7171-42e3-8298-9d1e180982ec.png → 6774c674-5100-4422-a82b-deb9bd5d49ee.png} +0 -0
- /kotonebot/kaa/sprites/{73eec0a3-e3ba-40c8-b163-321a5b7feb81.png → 6e9ef52c-937f-47f1-9687-899a528d7599.png} +0 -0
- /kotonebot/kaa/sprites/{1f8cca6a-ae0a-44c9-a267-989ae508320a.png → 704bf40a-4125-4260-9dd7-fa8ac13f00df.png} +0 -0
- /kotonebot/kaa/sprites/{07c5517b-38f7-44e6-8506-84317ba0fb86.png → 71bbe862-b9f7-47ab-b4f1-f0b87732bd39.png} +0 -0
- /kotonebot/kaa/sprites/{ca850faa-154e-4170-9446-91dd325e14af.png → 7516da41-7cbf-4c18-8630-3baecc225764.png} +0 -0
- /kotonebot/kaa/sprites/{d9432d63-1aef-43a7-8642-d10f3c15b092.png → 75f0339c-9acf-4971-a3c2-e302f56b1f93.png} +0 -0
- /kotonebot/kaa/sprites/{fbe45406-81bd-4298-ab4f-ed7346c25eb8.png → 76a65fb7-4429-4288-a164-bd121974ee6b.png} +0 -0
- /kotonebot/kaa/sprites/{82eab6fc-1968-42a4-bb43-d9cee984b33d.png → 783cbcad-eefc-4a04-910e-9ff4288d3c18.png} +0 -0
- /kotonebot/kaa/sprites/{d5a25a5f-8bd0-4f09-aec7-fda24eaf795e.png → 78a12e3b-ac32-4e96-8998-30f92318a36b.png} +0 -0
- /kotonebot/kaa/sprites/{71293cd1-83de-4f15-9608-1d31678e3566.png → 7cddb93a-175c-4875-a2fb-136cdfc365a7.png} +0 -0
- /kotonebot/kaa/sprites/{54e4f9a3-3ae6-4bf4-85b1-680889835137.png → 7d817b98-53ff-491c-b608-b07a0c143009.png} +0 -0
- /kotonebot/kaa/sprites/{214fad37-3e64-4786-8cfa-b48dd49ddbe4.png → 8034f626-ae01-42c0-8f73-a3d1c9aaff5c.png} +0 -0
- /kotonebot/kaa/sprites/{4c07fc6b-662a-4216-b1e6-6036fa6f717d.png → 824c9efd-21ea-4e26-a1fa-9e909d8b98d6.png} +0 -0
- /kotonebot/kaa/sprites/{a0fc1501-162d-49c6-824c-03e028d8fed7.png → 835e3ad1-8f73-4e2e-bdd5-9a5fb866858f.png} +0 -0
- /kotonebot/kaa/sprites/{ed822aca-dde6-4235-8776-0c47884c4a9a.png → 84795df2-e6d9-40fb-aef5-98fbf9c17399.png} +0 -0
- /kotonebot/kaa/sprites/{da7ef120-103c-4d5f-b95c-2bcd29757d3c.png → 848c8b04-c953-473d-94b1-2a2d5cdbd9c4.png} +0 -0
- /kotonebot/kaa/sprites/{0b27cdd2-490b-4a6a-ae0d-788ac1601dcc.png → 8498ac20-4ec2-474b-961f-cbf488da9a23.png} +0 -0
- /kotonebot/kaa/sprites/{1135ed8d-4e1c-4896-9d6d-5c2ba3d29761.png → 85f1cf4f-7d07-403a-917b-02b273680c21.png} +0 -0
- /kotonebot/kaa/sprites/{fb2694c2-8f0e-4ec3-9d76-087f085f2e55.png → 86db7d47-f634-4be4-b9e2-371e7868aded.png} +0 -0
- /kotonebot/kaa/sprites/{6ede6499-0efe-4ad2-83c7-5fd8a512c52e.png → 88d89e04-2242-4ed7-be23-edd6535121ac.png} +0 -0
- /kotonebot/kaa/sprites/{b22260e3-22c6-4c80-b986-f4fd8db22ddc.png → 8cb9d744-6b49-452b-b0b6-e441446050ef.png} +0 -0
- /kotonebot/kaa/sprites/{b176f60c-94ba-46e3-b562-7fc86b25c17f.png → 8df4515c-ff60-432c-a624-ae3658bf7e0c.png} +0 -0
- /kotonebot/kaa/sprites/{1d5835f8-593c-4ec4-a360-81fce8d2f959.png → 8e6b9237-f94a-4e21-9b2c-45e3d4833b6d.png} +0 -0
- /kotonebot/kaa/sprites/{ed56bfc1-d3c5-4bc3-a910-f861cfb2f379.png → 8e7b53fd-d962-43b7-a203-3d480c649c83.png} +0 -0
- /kotonebot/kaa/sprites/{6b33fe3c-28ff-49ad-ba24-7279c8e9ec19.png → 8ed3f006-facb-4ba0-9034-24a3a7729012.png} +0 -0
- /kotonebot/kaa/sprites/{918db28b-0d43-4056-a506-3279f2b724c8.png → 91e2c2d3-b629-4c49-97d5-ed99dada3243.png} +0 -0
- /kotonebot/kaa/sprites/{2ac9bca3-aad6-4d19-a4b7-4d7197d95fba.png → 92c1a9ba-994b-4635-b1b6-1fa157f227f6.png} +0 -0
- /kotonebot/kaa/sprites/{757d08d7-c7a1-430a-8938-edd824ed7117.png → 981e63c5-d615-44dd-9ad6-60f6b415cdaf.png} +0 -0
- /kotonebot/kaa/sprites/{99967c02-b5cf-43ba-9ca6-23e2781b25d9.png → 98a8e860-39cf-416c-b435-64a33579c6e8.png} +0 -0
- /kotonebot/kaa/sprites/{350736d7-0774-4a48-973c-d9373fc68ea3.png → 9932dfd8-7c97-47dd-b6bb-e8c8d593f762.png} +0 -0
- /kotonebot/kaa/sprites/{88476c65-0056-4ae4-9c9e-3ff1bae964e8.png → 9a275932-f760-4373-ab27-86c5caf19136.png} +0 -0
- /kotonebot/kaa/sprites/{07d78d3e-4e79-459e-9c41-43f4a618f9e9.png → 9a7f06a5-448b-4410-84fa-0a4c938620f7.png} +0 -0
- /kotonebot/kaa/sprites/{f9bba6f1-6237-43bf-85b1-f6250a64a5d6.png → 9cdd7af5-0e25-4226-8c7b-93c8c633c27b.png} +0 -0
- /kotonebot/kaa/sprites/{0899e636-b767-45e6-ab63-258d19d3f806.png → a0ddc404-a653-4d76-842f-faf7f93851ed.png} +0 -0
- /kotonebot/kaa/sprites/{74c8b69c-bceb-438f-a4a4-49e3abd7fa46.png → a1087827-1065-4f35-b04f-854ddf2d7e70.png} +0 -0
- /kotonebot/kaa/sprites/{1ae6b793-d85f-4b06-ba9f-bdb7fbed26fc.png → a3f07286-a699-4f5c-9912-835b3781b4f7.png} +0 -0
- /kotonebot/kaa/sprites/{93f74a70-acd1-4453-8254-07a797839b5f.png → a4aabbbe-6400-4bcb-a95f-32a7d611bf5b.png} +0 -0
- /kotonebot/kaa/sprites/{b3e5704b-63c9-4226-9e49-69c680627b61.png → a4b50bf5-7dfe-4bbb-8bd7-528c9147b71e.png} +0 -0
- /kotonebot/kaa/sprites/{b3debf96-a90b-4de7-b19e-83c2d82075ee.png → a4c42000-2421-4b02-b83e-60e1397304b0.png} +0 -0
- /kotonebot/kaa/sprites/{b66ed448-356e-44f9-ad45-40473d47ee24.png → a8aacbc9-1238-414c-b1e6-5ea1a01407c2.png} +0 -0
- /kotonebot/kaa/sprites/{141b5f13-489d-4271-ac49-4d0bd40bf8fc.png → a99307de-c12f-4cf5-921b-b80bf03bbac3.png} +0 -0
- /kotonebot/kaa/sprites/{aed0fd9a-0e59-4ead-b6a2-497b94f0eb16.png → ac02de52-42fa-4767-81f8-97fbac3bd8a0.png} +0 -0
- /kotonebot/kaa/sprites/{d597a32e-5ccb-4550-ab18-1905123c22d4.png → aee9d67f-d6be-4cf5-9c30-331f6d5f0f84.png} +0 -0
- /kotonebot/kaa/sprites/{07578d0c-15d4-42a2-9db1-a1c0c11b55c1.png → b45b4340-65ce-49df-a265-9f3cd876fced.png} +0 -0
- /kotonebot/kaa/sprites/{4183bf72-4ca7-4480-a6db-c81632b1a62b.png → b53035c7-43a6-4d83-a51c-dd6b7cd14a1e.png} +0 -0
- /kotonebot/kaa/sprites/{1abdc520-6123-40c9-bf50-d84e46f9420c.png → b54343ba-8b17-4d72-b379-805ae3062d86.png} +0 -0
- /kotonebot/kaa/sprites/{49fa1fd6-8115-476d-aa60-2d63613ef931.png → b94087df-db46-4ae3-bf93-8548a25a1a23.png} +0 -0
- /kotonebot/kaa/sprites/{00a2e0d4-1683-4c36-88df-081673e2fe1a.png → bd101208-a87c-405c-987a-d46e1b6f0358.png} +0 -0
- /kotonebot/kaa/sprites/{471d7204-23f3-4d72-a852-77e8b424ddff.png → be2c3ab5-9d63-47bc-93f1-110b9668d5e2.png} +0 -0
- /kotonebot/kaa/sprites/{af5714a6-e4a0-47ef-9151-2a8c9614e931.png → c41567a3-84bf-4e71-9eb1-f577c0348215.png} +0 -0
- /kotonebot/kaa/sprites/{1466ba09-8e27-49cd-8606-f9feeecc2915.png → c5127f24-fa81-4d61-876f-ac0a377bf00e.png} +0 -0
- /kotonebot/kaa/sprites/{2e279b36-1057-453f-9a7e-7ac61ddce6f9.png → c542ba3e-e0c0-41a1-8cc7-dd7454b12400.png} +0 -0
- /kotonebot/kaa/sprites/{a2e9d3a5-6f6f-4530-8a35-a09edfd35b8e.png → c6649b6a-7d03-454c-902b-7462092878df.png} +0 -0
- /kotonebot/kaa/sprites/{32d066ef-5783-4ab4-8a41-5e948169b1d7.png → cf5dcb2b-c5bd-4e38-a2bb-2673db821f79.png} +0 -0
- /kotonebot/kaa/sprites/{48fc4fee-0d6e-4995-8d29-37791d33759e.png → d37153d2-f699-4608-abbf-43d6bd8b1469.png} +0 -0
- /kotonebot/kaa/sprites/{be0bca2e-dfd5-48b6-a2ac-e2699991d37b.png → d3bfc1c2-a202-42c2-9e19-61b949a340c7.png} +0 -0
- /kotonebot/kaa/sprites/{368d245a-8777-437a-80c4-e6b0504236e6.png → d5ad9b97-3175-4c49-a1f7-5da663125af3.png} +0 -0
- /kotonebot/kaa/sprites/{864b57b0-c2f9-49eb-864c-314f72c0f56c.png → d5c4ef47-257f-49a2-81e3-ba7ab6fa0f62.png} +0 -0
- /kotonebot/kaa/sprites/{917be8d3-602c-495c-b2ed-41b1c84e7398.png → d7ceaf00-e488-4273-968c-315962bf4837.png} +0 -0
- /kotonebot/kaa/sprites/{d40a6e09-4740-41a8-af0f-9da09de38bf1.png → d7e25596-8452-4eb3-aaa8-5997be3dd851.png} +0 -0
- /kotonebot/kaa/sprites/{3bf9aa00-7c6d-46ec-b487-7f846588acbe.png → db4ca499-5cd3-4332-b232-28ddbedd4741.png} +0 -0
- /kotonebot/kaa/sprites/{f404eabd-6b87-48a4-8ad7-1e7d521daa94.png → e0effef4-869d-4a0c-8db3-1c41cd255555.png} +0 -0
- /kotonebot/kaa/sprites/{71ce4a03-5865-47fb-a2a2-d220dbd8ead3.png → e8407109-ffa8-496b-a499-e78db90db540.png} +0 -0
- /kotonebot/kaa/sprites/{0e998848-beb2-4d31-9019-6afab9e0180e.png → e857f00d-81bd-4fbc-9043-c9252a075da3.png} +0 -0
- /kotonebot/kaa/sprites/{550c0ad2-4c38-4c34-8be2-9ea278b3f822.png → e872aa76-2947-4209-abd7-5ecb56fdc9d6.png} +0 -0
- /kotonebot/kaa/sprites/{a9e30963-0772-401a-85f8-33369ca22267.png → ea7dd69b-b02f-499d-acee-6bd35a033a73.png} +0 -0
- /kotonebot/kaa/sprites/{4365cb24-54a1-4998-8a2e-bed02fc988f5.png → f1fcc488-584d-4c61-8489-8b1b539151a9.png} +0 -0
- /kotonebot/kaa/sprites/{a7cc8346-8b35-4f6a-acef-8cd4d29b5591.png → f62bfba7-3d6b-4bdd-9821-ca8370ee2ff4.png} +0 -0
- /kotonebot/kaa/sprites/{2e5cfcf0-34fc-4b17-9283-0c269d04ae98.png → f7084b2c-5411-4180-9404-377240af1857.png} +0 -0
- /kotonebot/kaa/sprites/{8e021860-0c8f-4da5-84f8-1ed65ad6f720.png → f7c7f2cf-337b-4dd6-a90b-7f5c452a1640.png} +0 -0
- /kotonebot/kaa/sprites/{12b811a3-5b37-4510-9ebd-95455644f253.png → fbba87fb-50e5-4c2f-9218-82f1ffb7a5ba.png} +0 -0
- /kotonebot/kaa/sprites/{9dfde42d-fd40-435b-8a41-50be0fb8781e.png → fc7e4b97-0d87-4de9-b7ac-87ca670b6ff2.png} +0 -0
- /kotonebot/kaa/sprites/{63b1d3d9-a0d7-413e-8e67-215ee46e5af7.png → fe0a26ac-906c-4809-9de5-43cb4a467a9d.png} +0 -0
- /kotonebot/kaa/sprites/{5b3f7210-d28b-4117-a664-efb790eec911.png → ff232b25-39b4-4dcb-9e21-1d82b9e0bb7d.png} +0 -0
- {ksaa-2025.8.17.0.dist-info → ksaa-2025.9b1.dist-info}/WHEEL +0 -0
- {ksaa-2025.8.17.0.dist-info → ksaa-2025.9b1.dist-info}/entry_points.txt +0 -0
- {ksaa-2025.8.17.0.dist-info → ksaa-2025.9b1.dist-info}/licenses/LICENSE +0 -0
- {ksaa-2025.8.17.0.dist-info → ksaa-2025.9b1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import time
|
|
3
|
+
import logging
|
|
4
|
+
import threading
|
|
5
|
+
from contextlib import suppress
|
|
6
|
+
from typing import Callable, Optional
|
|
7
|
+
|
|
8
|
+
with suppress(ImportError):
|
|
9
|
+
keyboard = None
|
|
10
|
+
win32api = None
|
|
11
|
+
win32gui = None
|
|
12
|
+
win32con = None
|
|
13
|
+
import keyboard # type: ignore
|
|
14
|
+
import win32api # type: ignore
|
|
15
|
+
import win32gui # type: ignore
|
|
16
|
+
import win32con # type: ignore
|
|
17
|
+
|
|
18
|
+
from kotonebot.backend.context.context import vars
|
|
19
|
+
from kotonebot.kaa.config.schema import IdleModeConfig
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
def _get_system_idle_seconds_windows() -> int:
|
|
24
|
+
if win32api is None:
|
|
25
|
+
return 0
|
|
26
|
+
try:
|
|
27
|
+
last_input_tick = win32api.GetLastInputInfo()
|
|
28
|
+
tick_count = win32api.GetTickCount()
|
|
29
|
+
elapsed_ms = tick_count - last_input_tick
|
|
30
|
+
return max(0, int(elapsed_ms / 1000))
|
|
31
|
+
except Exception:
|
|
32
|
+
logger.exception('win32api.GetLastInputInfo failed')
|
|
33
|
+
return 0
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_system_idle_seconds() -> int:
|
|
37
|
+
if sys.platform.startswith('win'):
|
|
38
|
+
try:
|
|
39
|
+
return _get_system_idle_seconds_windows()
|
|
40
|
+
except Exception:
|
|
41
|
+
logger.exception('GetLastInputInfo failed')
|
|
42
|
+
return 0
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class IdleModeManager:
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
*,
|
|
50
|
+
get_is_running: Callable[[], bool],
|
|
51
|
+
get_is_paused: Callable[[], bool],
|
|
52
|
+
get_config: Callable[[], IdleModeConfig],
|
|
53
|
+
) -> None:
|
|
54
|
+
self._get_is_running = get_is_running
|
|
55
|
+
self._get_is_paused = get_is_paused
|
|
56
|
+
self._get_config = get_config
|
|
57
|
+
self._stop_event = threading.Event()
|
|
58
|
+
self._thread: Optional[threading.Thread] = None
|
|
59
|
+
self._keyboard_hook = None
|
|
60
|
+
self._last_key_ts: float = 0.0
|
|
61
|
+
|
|
62
|
+
def start(self) -> None:
|
|
63
|
+
if self._thread and self._thread.is_alive():
|
|
64
|
+
return
|
|
65
|
+
self._stop_event.clear()
|
|
66
|
+
self._thread = threading.Thread(target=self._loop, name='IdleModeThread', daemon=True)
|
|
67
|
+
self._thread.start()
|
|
68
|
+
self._install_keyboard_hook()
|
|
69
|
+
logger.info('IdleModeManager started')
|
|
70
|
+
|
|
71
|
+
def stop(self) -> None:
|
|
72
|
+
self._remove_keyboard_hook()
|
|
73
|
+
if self._thread and self._thread.is_alive():
|
|
74
|
+
self._stop_event.set()
|
|
75
|
+
self._thread.join(timeout=2.0)
|
|
76
|
+
logger.info('IdleModeManager stopped')
|
|
77
|
+
|
|
78
|
+
def notify_on_start(self) -> None:
|
|
79
|
+
# 运行态切换时可根据需要做重置
|
|
80
|
+
self._last_key_ts = 0.0
|
|
81
|
+
|
|
82
|
+
def notify_on_stop(self) -> None:
|
|
83
|
+
self._last_key_ts = 0.0
|
|
84
|
+
|
|
85
|
+
def _loop(self) -> None:
|
|
86
|
+
while not self._stop_event.is_set():
|
|
87
|
+
conf = self._get_config()
|
|
88
|
+
if not conf.enabled:
|
|
89
|
+
time.sleep(0.8)
|
|
90
|
+
continue
|
|
91
|
+
try:
|
|
92
|
+
if self._get_is_paused():
|
|
93
|
+
idle_sec = get_system_idle_seconds()
|
|
94
|
+
if idle_sec >= max(0, int(conf.idle_seconds)):
|
|
95
|
+
logger.info('System idle for %ss while paused. Requesting resume...', idle_sec)
|
|
96
|
+
try:
|
|
97
|
+
vars.flow.request_resume()
|
|
98
|
+
except Exception:
|
|
99
|
+
logger.exception('request_resume failed')
|
|
100
|
+
time.sleep(0.8)
|
|
101
|
+
except Exception:
|
|
102
|
+
logger.exception('IdleMode loop error')
|
|
103
|
+
time.sleep(1.0)
|
|
104
|
+
|
|
105
|
+
def _install_keyboard_hook(self) -> None:
|
|
106
|
+
if keyboard is None:
|
|
107
|
+
logger.warning('keyboard module not available; key-to-pause disabled')
|
|
108
|
+
return
|
|
109
|
+
if self._keyboard_hook is not None:
|
|
110
|
+
return
|
|
111
|
+
|
|
112
|
+
def _on_key_event(_: object) -> None:
|
|
113
|
+
conf = self._get_config()
|
|
114
|
+
if not conf.enabled:
|
|
115
|
+
return
|
|
116
|
+
now = time.time()
|
|
117
|
+
if (now - self._last_key_ts) < 0.3:
|
|
118
|
+
return
|
|
119
|
+
self._last_key_ts = now
|
|
120
|
+
try:
|
|
121
|
+
if self._get_is_running() and not self._get_is_paused():
|
|
122
|
+
logger.info('Any key pressed -> pause requested')
|
|
123
|
+
vars.flow.request_pause()
|
|
124
|
+
if conf.minimize_on_pause:
|
|
125
|
+
self._minimize_game_window()
|
|
126
|
+
except Exception:
|
|
127
|
+
logger.exception('key handler failed')
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
self._keyboard_hook = keyboard.on_press(_on_key_event, suppress=False)
|
|
131
|
+
except Exception:
|
|
132
|
+
logger.warning('Failed to install keyboard hook; degraded behavior')
|
|
133
|
+
self._keyboard_hook = None
|
|
134
|
+
|
|
135
|
+
def _remove_keyboard_hook(self) -> None:
|
|
136
|
+
if keyboard is None:
|
|
137
|
+
return
|
|
138
|
+
if self._keyboard_hook is None:
|
|
139
|
+
return
|
|
140
|
+
try:
|
|
141
|
+
keyboard.unhook(self._keyboard_hook)
|
|
142
|
+
except Exception:
|
|
143
|
+
logger.exception('Failed to remove keyboard hook')
|
|
144
|
+
finally:
|
|
145
|
+
self._keyboard_hook = None
|
|
146
|
+
|
|
147
|
+
def _minimize_game_window(self) -> None:
|
|
148
|
+
# Send the window to background (bottom of Z-order) via pywin32
|
|
149
|
+
if not sys.platform.startswith('win'):
|
|
150
|
+
return
|
|
151
|
+
if win32gui is None or win32con is None:
|
|
152
|
+
logger.warning('pywin32 (win32gui/win32con) not available; skip backgrounding')
|
|
153
|
+
return
|
|
154
|
+
try:
|
|
155
|
+
hwnd = win32gui.FindWindow(None, 'gakumas') # type: ignore
|
|
156
|
+
if hwnd:
|
|
157
|
+
flags = (
|
|
158
|
+
win32con.SWP_NOMOVE
|
|
159
|
+
| win32con.SWP_NOSIZE
|
|
160
|
+
| win32con.SWP_NOACTIVATE
|
|
161
|
+
| win32con.SWP_NOOWNERZORDER
|
|
162
|
+
)
|
|
163
|
+
win32gui.SetWindowPos(hwnd, win32con.HWND_BOTTOM, 0, 0, 0, 0, flags)
|
|
164
|
+
try:
|
|
165
|
+
win32gui.ShowWindow(hwnd, win32con.SW_SHOWNOACTIVATE)
|
|
166
|
+
except Exception:
|
|
167
|
+
pass
|
|
168
|
+
logger.info('Sent game window to background (HWND=%s)', hwnd)
|
|
169
|
+
else:
|
|
170
|
+
logger.warning('Game window not found; cannot send to background')
|
|
171
|
+
except Exception:
|
|
172
|
+
logger.warning('Failed to send game window to background', exc_info=True)
|
kotonebot/kaa/config/__init__.py
CHANGED
|
@@ -14,6 +14,7 @@ from .schema import (
|
|
|
14
14
|
StartGameConfig,
|
|
15
15
|
EndGameConfig,
|
|
16
16
|
MiscConfig,
|
|
17
|
+
IdleModeConfig,
|
|
17
18
|
conf,
|
|
18
19
|
)
|
|
19
20
|
from .const import (
|
|
@@ -46,6 +47,7 @@ __all__ = [
|
|
|
46
47
|
"StartGameConfig",
|
|
47
48
|
"EndGameConfig",
|
|
48
49
|
"MiscConfig",
|
|
50
|
+
"IdleModeConfig",
|
|
49
51
|
"conf",
|
|
50
52
|
# const 导出
|
|
51
53
|
"ConfigEnum",
|
kotonebot/kaa/config/schema.py
CHANGED
|
@@ -180,6 +180,14 @@ class MiscConfig(ConfigBaseModel):
|
|
|
180
180
|
启用后,局域网内的其他设备可以通过本机 IP 地址访问 Web 界面。
|
|
181
181
|
"""
|
|
182
182
|
|
|
183
|
+
class IdleModeConfig(ConfigBaseModel):
|
|
184
|
+
enabled: bool = False
|
|
185
|
+
"""是否启用闲置挂机(任意键暂停、闲置自动恢复)"""
|
|
186
|
+
idle_seconds: int = 30
|
|
187
|
+
"""暂停状态下,超过该闲置秒数将自动恢复"""
|
|
188
|
+
minimize_on_pause: bool = True
|
|
189
|
+
"""按键触发暂停时最小化游戏窗口"""
|
|
190
|
+
|
|
183
191
|
class BaseConfig(ConfigBaseModel):
|
|
184
192
|
purchase: PurchaseConfig = PurchaseConfig()
|
|
185
193
|
"""商店购买配置"""
|
|
@@ -223,6 +231,9 @@ class BaseConfig(ConfigBaseModel):
|
|
|
223
231
|
misc: MiscConfig = MiscConfig()
|
|
224
232
|
"""杂项配置"""
|
|
225
233
|
|
|
234
|
+
idle: IdleModeConfig = IdleModeConfig()
|
|
235
|
+
"""闲置挂机配置"""
|
|
236
|
+
|
|
226
237
|
|
|
227
238
|
def conf() -> BaseConfig:
|
|
228
239
|
"""获取当前配置数据"""
|
kotonebot/kaa/main/gr.py
CHANGED
|
@@ -28,9 +28,11 @@ from kotonebot.kaa.config import (
|
|
|
28
28
|
PresentsConfig, AssignmentConfig, ContestConfig, ProduceConfig,
|
|
29
29
|
MissionRewardConfig, DailyMoneyShopItems, ProduceAction,
|
|
30
30
|
RecommendCardDetectionMode, TraceConfig, StartGameConfig, EndGameConfig, UpgradeSupportCardConfig, MiscConfig,
|
|
31
|
+
IdleModeConfig,
|
|
31
32
|
)
|
|
32
33
|
from kotonebot.kaa.config.produce import ProduceSolution, ProduceSolutionManager, ProduceData
|
|
33
34
|
from kotonebot.kaa.application.adapter.misc_adapter import create_desktop_shortcut
|
|
35
|
+
from kotonebot.kaa.application.core.idle_mode import IdleModeManager
|
|
34
36
|
|
|
35
37
|
logger = logging.getLogger(__name__)
|
|
36
38
|
GradioInput = gr.Textbox | gr.Number | gr.Checkbox | gr.Dropdown | gr.Radio | gr.Slider | gr.Tabs | gr.Tab
|
|
@@ -91,6 +93,9 @@ ConfigKey = Literal[
|
|
|
91
93
|
# misc
|
|
92
94
|
'check_update', 'auto_install_update', 'expose_to_lan',
|
|
93
95
|
|
|
96
|
+
# idle
|
|
97
|
+
'idle_enabled', 'idle_seconds', 'idle_minimize_on_pause',
|
|
98
|
+
|
|
94
99
|
'_selected_backend_index'
|
|
95
100
|
|
|
96
101
|
]
|
|
@@ -228,6 +233,24 @@ class KotoneBotUI:
|
|
|
228
233
|
self.is_single_task_stopping: bool = False # 新增:标记单个任务是否正在停止
|
|
229
234
|
self._kaa = kaa
|
|
230
235
|
self._load_config()
|
|
236
|
+
# IdleModeManager 空闲检测
|
|
237
|
+
def safe_get_is_running():
|
|
238
|
+
try:
|
|
239
|
+
return (self.is_running or self.single_task_running) and not self.is_stopping and not self.is_single_task_stopping and not vars.flow.is_paused
|
|
240
|
+
except ContextNotInitializedError:
|
|
241
|
+
return False
|
|
242
|
+
|
|
243
|
+
def safe_get_is_paused():
|
|
244
|
+
try:
|
|
245
|
+
return vars.flow.is_paused
|
|
246
|
+
except ContextNotInitializedError:
|
|
247
|
+
return False
|
|
248
|
+
|
|
249
|
+
self.idle_mgr = IdleModeManager(
|
|
250
|
+
get_is_running=safe_get_is_running,
|
|
251
|
+
get_is_paused=safe_get_is_paused,
|
|
252
|
+
get_config=lambda: self.current_config.options.idle,
|
|
253
|
+
)
|
|
231
254
|
self._setup_kaa()
|
|
232
255
|
|
|
233
256
|
def _setup_kaa(self) -> None:
|
|
@@ -322,6 +345,8 @@ class KotoneBotUI:
|
|
|
322
345
|
def start_run(self) -> Tuple[str, List[List[str]]]:
|
|
323
346
|
self.is_running = True
|
|
324
347
|
self.run_status = self._kaa.start_all()
|
|
348
|
+
# 通知 Idle 管理器进入运行态
|
|
349
|
+
self.idle_mgr.notify_on_start()
|
|
325
350
|
return "停止", self.update_task_status()
|
|
326
351
|
|
|
327
352
|
def stop_run(self) -> Tuple[str, List[List[str]]]:
|
|
@@ -336,6 +361,8 @@ class KotoneBotUI:
|
|
|
336
361
|
if self._kaa:
|
|
337
362
|
self.run_status.interrupt()
|
|
338
363
|
gr.Info("正在停止任务...")
|
|
364
|
+
# 通知 Idle 管理器停止态
|
|
365
|
+
self.idle_mgr.notify_on_stop()
|
|
339
366
|
|
|
340
367
|
return "停止中...", self.update_task_status()
|
|
341
368
|
|
|
@@ -369,6 +396,8 @@ class KotoneBotUI:
|
|
|
369
396
|
if hasattr(self, 'run_status') and self._kaa:
|
|
370
397
|
self.run_status.interrupt()
|
|
371
398
|
gr.Info("正在停止任务...")
|
|
399
|
+
# 通知 Idle 管理器停止态
|
|
400
|
+
self.idle_mgr.notify_on_stop()
|
|
372
401
|
return "停止中...", "正在停止任务..."
|
|
373
402
|
|
|
374
403
|
def toggle_pause(self) -> str:
|
|
@@ -501,6 +530,13 @@ class KotoneBotUI:
|
|
|
501
530
|
|
|
502
531
|
# 快速设置控制区域
|
|
503
532
|
gr.Markdown("### 快速设置")
|
|
533
|
+
|
|
534
|
+
with gr.Row():
|
|
535
|
+
select_all_btn = gr.Button("全选", scale=1)
|
|
536
|
+
unselect_all_btn = gr.Button("清空", scale=1)
|
|
537
|
+
select_produce_only_btn = gr.Button("只选培育", scale=1)
|
|
538
|
+
unselect_produce_only_btn = gr.Button("只不选培育", scale=1)
|
|
539
|
+
|
|
504
540
|
with gr.Row(elem_classes=["quick-controls-row"]):
|
|
505
541
|
purchase_quick = gr.Checkbox(
|
|
506
542
|
label="商店",
|
|
@@ -595,6 +631,8 @@ class KotoneBotUI:
|
|
|
595
631
|
label="任务状态"
|
|
596
632
|
)
|
|
597
633
|
|
|
634
|
+
# MARK: 状态 - 监听函数
|
|
635
|
+
|
|
598
636
|
def on_run_click(evt: gr.EventData) -> Tuple[gr.Button, List[List[str]]]:
|
|
599
637
|
result = self.toggle_run()
|
|
600
638
|
# 如果正在停止,禁用按钮
|
|
@@ -606,43 +644,66 @@ class KotoneBotUI:
|
|
|
606
644
|
return self.toggle_pause()
|
|
607
645
|
|
|
608
646
|
# 快速设置控制的事件处理函数
|
|
609
|
-
def save_quick_setting(
|
|
647
|
+
def save_quick_setting(success_msg: str, failed_msg: str):
|
|
610
648
|
"""保存快速设置并立即应用"""
|
|
611
649
|
try:
|
|
612
|
-
# 更新配置
|
|
613
|
-
if field_name == 'purchase':
|
|
614
|
-
self.current_config.options.purchase.enabled = value
|
|
615
|
-
elif field_name == 'assignment':
|
|
616
|
-
self.current_config.options.assignment.enabled = value
|
|
617
|
-
elif field_name == 'contest':
|
|
618
|
-
self.current_config.options.contest.enabled = value
|
|
619
|
-
elif field_name == 'produce':
|
|
620
|
-
self.current_config.options.produce.enabled = value
|
|
621
|
-
elif field_name == 'mission_reward':
|
|
622
|
-
self.current_config.options.mission_reward.enabled = value
|
|
623
|
-
elif field_name == 'club_reward':
|
|
624
|
-
self.current_config.options.club_reward.enabled = value
|
|
625
|
-
elif field_name == 'activity_funds':
|
|
626
|
-
self.current_config.options.activity_funds.enabled = value
|
|
627
|
-
elif field_name == 'presents':
|
|
628
|
-
self.current_config.options.presents.enabled = value
|
|
629
|
-
elif field_name == 'capsule_toys':
|
|
630
|
-
self.current_config.options.capsule_toys.enabled = value
|
|
631
|
-
elif field_name == 'upgrade_support_card':
|
|
632
|
-
self.current_config.options.upgrade_support_card.enabled = value
|
|
633
|
-
elif field_name == 'start_game':
|
|
634
|
-
self.current_config.options.start_game.enabled = value
|
|
635
|
-
|
|
636
650
|
# 保存配置
|
|
637
651
|
save_config(self.config, "config.json")
|
|
638
652
|
|
|
639
653
|
# 尝试热重载配置
|
|
640
654
|
if self.reload_config():
|
|
641
|
-
gr.Success(
|
|
655
|
+
gr.Success(success_msg)
|
|
642
656
|
else:
|
|
643
|
-
gr.Warning(
|
|
657
|
+
gr.Warning(failed_msg)
|
|
644
658
|
except Exception as e:
|
|
645
659
|
gr.Error(f"✗ 保存失败:{str(e)}")
|
|
660
|
+
|
|
661
|
+
def update_and_save_quick_setting(field_name: str, value: bool, display_name: str):
|
|
662
|
+
"""更新字段,并保存快速设置并立即应用"""
|
|
663
|
+
|
|
664
|
+
# 更新配置
|
|
665
|
+
if field_name == 'purchase':
|
|
666
|
+
self.current_config.options.purchase.enabled = value
|
|
667
|
+
elif field_name == 'assignment':
|
|
668
|
+
self.current_config.options.assignment.enabled = value
|
|
669
|
+
elif field_name == 'contest':
|
|
670
|
+
self.current_config.options.contest.enabled = value
|
|
671
|
+
elif field_name == 'produce':
|
|
672
|
+
self.current_config.options.produce.enabled = value
|
|
673
|
+
elif field_name == 'mission_reward':
|
|
674
|
+
self.current_config.options.mission_reward.enabled = value
|
|
675
|
+
elif field_name == 'club_reward':
|
|
676
|
+
self.current_config.options.club_reward.enabled = value
|
|
677
|
+
elif field_name == 'activity_funds':
|
|
678
|
+
self.current_config.options.activity_funds.enabled = value
|
|
679
|
+
elif field_name == 'presents':
|
|
680
|
+
self.current_config.options.presents.enabled = value
|
|
681
|
+
elif field_name == 'capsule_toys':
|
|
682
|
+
self.current_config.options.capsule_toys.enabled = value
|
|
683
|
+
elif field_name == 'upgrade_support_card':
|
|
684
|
+
self.current_config.options.upgrade_support_card.enabled = value
|
|
685
|
+
|
|
686
|
+
# 保存并重载配置
|
|
687
|
+
save_quick_setting(
|
|
688
|
+
f"✓ {display_name} 已{'启用' if value else '禁用'}",
|
|
689
|
+
f"⚠ {display_name} 已保存,但重新加载失败"
|
|
690
|
+
)
|
|
691
|
+
|
|
692
|
+
def batch_select(default: bool, produce_only: bool, success_msg: str) -> None:
|
|
693
|
+
self.current_config.options.purchase.enabled = default
|
|
694
|
+
self.current_config.options.assignment.enabled = default
|
|
695
|
+
self.current_config.options.contest.enabled = default
|
|
696
|
+
self.current_config.options.produce.enabled = produce_only
|
|
697
|
+
self.current_config.options.mission_reward.enabled = default
|
|
698
|
+
self.current_config.options.club_reward.enabled = default
|
|
699
|
+
self.current_config.options.activity_funds.enabled = default
|
|
700
|
+
self.current_config.options.presents.enabled = default
|
|
701
|
+
self.current_config.options.capsule_toys.enabled = default
|
|
702
|
+
self.current_config.options.upgrade_support_card.enabled = default
|
|
703
|
+
|
|
704
|
+
save_quick_setting(success_msg, f"⚠ 数据已保存,但重新加载失败")
|
|
705
|
+
|
|
706
|
+
# MARK: 状态 - UI回调函数
|
|
646
707
|
|
|
647
708
|
run_btn.click(
|
|
648
709
|
fn=on_run_click,
|
|
@@ -654,45 +715,67 @@ class KotoneBotUI:
|
|
|
654
715
|
outputs=[pause_btn]
|
|
655
716
|
)
|
|
656
717
|
|
|
718
|
+
select_all_btn.click(
|
|
719
|
+
fn=lambda: batch_select(True, True, f"✓ 全选成功"),
|
|
720
|
+
outputs=[]
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
unselect_all_btn.click(
|
|
724
|
+
fn=lambda: batch_select(False, False, f"✓ 清空成功"),
|
|
725
|
+
outputs=[]
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
select_produce_only_btn.click(
|
|
729
|
+
fn=lambda: batch_select(False, True, f"✓ 只选培育成功"),
|
|
730
|
+
outputs=[]
|
|
731
|
+
)
|
|
732
|
+
|
|
733
|
+
unselect_produce_only_btn.click(
|
|
734
|
+
fn=lambda: batch_select(True, False, f"✓ 只不选培育成功"),
|
|
735
|
+
outputs=[]
|
|
736
|
+
)
|
|
737
|
+
|
|
657
738
|
# 绑定快速设置控制的事件
|
|
658
|
-
|
|
659
|
-
|
|
739
|
+
|
|
740
|
+
# 以下回调函数均由.change修改为.input,这样回调函数就只会在用户操作时触发,避免全选功能导致反复触发
|
|
741
|
+
purchase_quick.input(
|
|
742
|
+
fn=lambda x: update_and_save_quick_setting('purchase', x, '商店'),
|
|
660
743
|
inputs=[purchase_quick]
|
|
661
744
|
)
|
|
662
|
-
assignment_quick.
|
|
663
|
-
fn=lambda x:
|
|
745
|
+
assignment_quick.input(
|
|
746
|
+
fn=lambda x: update_and_save_quick_setting('assignment', x, '工作'),
|
|
664
747
|
inputs=[assignment_quick]
|
|
665
748
|
)
|
|
666
|
-
contest_quick.
|
|
667
|
-
fn=lambda x:
|
|
749
|
+
contest_quick.input(
|
|
750
|
+
fn=lambda x: update_and_save_quick_setting('contest', x, '竞赛'),
|
|
668
751
|
inputs=[contest_quick]
|
|
669
752
|
)
|
|
670
|
-
produce_quick.
|
|
671
|
-
fn=lambda x:
|
|
753
|
+
produce_quick.input(
|
|
754
|
+
fn=lambda x: update_and_save_quick_setting('produce', x, '培育'),
|
|
672
755
|
inputs=[produce_quick]
|
|
673
756
|
)
|
|
674
|
-
mission_reward_quick.
|
|
675
|
-
fn=lambda x:
|
|
757
|
+
mission_reward_quick.input(
|
|
758
|
+
fn=lambda x: update_and_save_quick_setting('mission_reward', x, '任务奖励'),
|
|
676
759
|
inputs=[mission_reward_quick]
|
|
677
760
|
)
|
|
678
|
-
club_reward_quick.
|
|
679
|
-
fn=lambda x:
|
|
761
|
+
club_reward_quick.input(
|
|
762
|
+
fn=lambda x: update_and_save_quick_setting('club_reward', x, '社团奖励'),
|
|
680
763
|
inputs=[club_reward_quick]
|
|
681
764
|
)
|
|
682
|
-
activity_funds_quick.
|
|
683
|
-
fn=lambda x:
|
|
765
|
+
activity_funds_quick.input(
|
|
766
|
+
fn=lambda x: update_and_save_quick_setting('activity_funds', x, '活动费'),
|
|
684
767
|
inputs=[activity_funds_quick]
|
|
685
768
|
)
|
|
686
|
-
presents_quick.
|
|
687
|
-
fn=lambda x:
|
|
769
|
+
presents_quick.input(
|
|
770
|
+
fn=lambda x: update_and_save_quick_setting('presents', x, '礼物'),
|
|
688
771
|
inputs=[presents_quick]
|
|
689
772
|
)
|
|
690
|
-
capsule_toys_quick.
|
|
691
|
-
fn=lambda x:
|
|
773
|
+
capsule_toys_quick.input(
|
|
774
|
+
fn=lambda x: update_and_save_quick_setting('capsule_toys', x, '扭蛋'),
|
|
692
775
|
inputs=[capsule_toys_quick]
|
|
693
776
|
)
|
|
694
|
-
upgrade_support_card_quick.
|
|
695
|
-
fn=lambda x:
|
|
777
|
+
upgrade_support_card_quick.input(
|
|
778
|
+
fn=lambda x: update_and_save_quick_setting('upgrade_support_card', x, '支援卡升级'),
|
|
696
779
|
inputs=[upgrade_support_card_quick]
|
|
697
780
|
)
|
|
698
781
|
|
|
@@ -1553,7 +1636,7 @@ class KotoneBotUI:
|
|
|
1553
1636
|
|
|
1554
1637
|
with gr.Group(visible=not current_solution.data.auto_set_memory) as memory_sets_group:
|
|
1555
1638
|
memory_sets = gr.Dropdown(
|
|
1556
|
-
choices=[str(i) for i in range(1,
|
|
1639
|
+
choices=[str(i) for i in range(1, 21)], # 最多20个编成位
|
|
1557
1640
|
value=str(current_solution.data.memory_set) if current_solution.data.memory_set else None,
|
|
1558
1641
|
label="回忆编成编号",
|
|
1559
1642
|
multiselect=False,
|
|
@@ -1569,7 +1652,7 @@ class KotoneBotUI:
|
|
|
1569
1652
|
|
|
1570
1653
|
with gr.Group(visible=not current_solution.data.auto_set_support_card) as support_card_sets_group:
|
|
1571
1654
|
support_card_sets = gr.Dropdown(
|
|
1572
|
-
choices=[str(i) for i in range(1,
|
|
1655
|
+
choices=[str(i) for i in range(1, 21)], # 最多20个编成位
|
|
1573
1656
|
value=str(current_solution.data.support_card_set) if current_solution.data.support_card_set else None,
|
|
1574
1657
|
label="支援卡编成编号",
|
|
1575
1658
|
multiselect=False,
|
|
@@ -2253,6 +2336,42 @@ class KotoneBotUI:
|
|
|
2253
2336
|
create_desktop_shortcut(start_immediately)
|
|
2254
2337
|
gr.Success("快捷方式创建成功")
|
|
2255
2338
|
return _inner
|
|
2339
|
+
|
|
2340
|
+
def _create_idle_settings(self) -> ConfigBuilderReturnValue:
|
|
2341
|
+
with gr.Column():
|
|
2342
|
+
gr.Markdown("### 闲置挂机")
|
|
2343
|
+
idle_enabled = gr.Checkbox(
|
|
2344
|
+
label="启用闲置挂机(任意键暂停、闲置自动恢复)",
|
|
2345
|
+
value=self.current_config.options.idle.enabled,
|
|
2346
|
+
info=IdleModeConfig.model_fields['enabled'].description,
|
|
2347
|
+
interactive=True
|
|
2348
|
+
)
|
|
2349
|
+
idle_seconds = gr.Slider(
|
|
2350
|
+
label="自动恢复触发时间(秒)",
|
|
2351
|
+
minimum=30,
|
|
2352
|
+
maximum=3600,
|
|
2353
|
+
step=10,
|
|
2354
|
+
value=self.current_config.options.idle.idle_seconds,
|
|
2355
|
+
info=IdleModeConfig.model_fields['idle_seconds'].description,
|
|
2356
|
+
interactive=True
|
|
2357
|
+
)
|
|
2358
|
+
idle_minimize_on_pause = gr.Checkbox(
|
|
2359
|
+
label="暂停时最小化游戏窗口",
|
|
2360
|
+
value=self.current_config.options.idle.minimize_on_pause,
|
|
2361
|
+
info=IdleModeConfig.model_fields['minimize_on_pause'].description,
|
|
2362
|
+
interactive=True
|
|
2363
|
+
)
|
|
2364
|
+
|
|
2365
|
+
def set_config(config: BaseConfig, data: dict[ConfigKey, Any]) -> None:
|
|
2366
|
+
config.idle.enabled = data['idle_enabled']
|
|
2367
|
+
config.idle.idle_seconds = int(data['idle_seconds'])
|
|
2368
|
+
config.idle.minimize_on_pause = data['idle_minimize_on_pause']
|
|
2369
|
+
|
|
2370
|
+
return set_config, {
|
|
2371
|
+
'idle_enabled': idle_enabled,
|
|
2372
|
+
'idle_seconds': idle_seconds,
|
|
2373
|
+
'idle_minimize_on_pause': idle_minimize_on_pause,
|
|
2374
|
+
}
|
|
2256
2375
|
|
|
2257
2376
|
def _create_debug_settings(self) -> ConfigBuilderReturnValue:
|
|
2258
2377
|
"""调试设置:仅在调试时使用"""
|
|
@@ -2316,9 +2435,12 @@ class KotoneBotUI:
|
|
|
2316
2435
|
# 社团奖励设置
|
|
2317
2436
|
club_reward_settings = self._create_club_reward_settings()
|
|
2318
2437
|
|
|
2319
|
-
#
|
|
2438
|
+
# 扭蛋设置
|
|
2320
2439
|
capsule_toys_settings = self._create_capsule_toys_settings()
|
|
2321
2440
|
|
|
2441
|
+
# 升级支援卡设置
|
|
2442
|
+
upgrade_support_card_settings = self._create_upgrade_support_card_settings()
|
|
2443
|
+
|
|
2322
2444
|
# 启动游戏设置
|
|
2323
2445
|
start_game_settings = self._create_start_game_settings()
|
|
2324
2446
|
|
|
@@ -2328,6 +2450,9 @@ class KotoneBotUI:
|
|
|
2328
2450
|
# 杂项设置
|
|
2329
2451
|
misc_settings = self._create_misc_settings()
|
|
2330
2452
|
|
|
2453
|
+
# 闲置挂机设置
|
|
2454
|
+
idle_settings = self._create_idle_settings()
|
|
2455
|
+
|
|
2331
2456
|
# 调试设置(放在最后)
|
|
2332
2457
|
debug_settings = self._create_debug_settings()
|
|
2333
2458
|
|
|
@@ -2346,9 +2471,11 @@ class KotoneBotUI:
|
|
|
2346
2471
|
mission_reward_settings,
|
|
2347
2472
|
club_reward_settings,
|
|
2348
2473
|
capsule_toys_settings,
|
|
2474
|
+
upgrade_support_card_settings,
|
|
2349
2475
|
start_game_settings,
|
|
2350
2476
|
end_game_settings,
|
|
2351
2477
|
misc_settings,
|
|
2478
|
+
idle_settings,
|
|
2352
2479
|
debug_settings
|
|
2353
2480
|
] # list of (set_func, { 'key': component, ... })
|
|
2354
2481
|
all_components = [list(ret[1].values()) for ret in all_return_values] # [[c1, c2], [c3], ...]
|
|
@@ -2426,7 +2553,7 @@ class KotoneBotUI:
|
|
|
2426
2553
|
try:
|
|
2427
2554
|
# 构建命令,使用清华镜像源
|
|
2428
2555
|
cmd = [
|
|
2429
|
-
sys.executable, "-m", "pip", "index", "versions", "ksaa", "--json",
|
|
2556
|
+
sys.executable, "-m", "pip", "index", "versions", "ksaa", "--json", "--pre",
|
|
2430
2557
|
"--index-url", "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple",
|
|
2431
2558
|
"--trusted-host", "mirrors.tuna.tsinghua.edu.cn"
|
|
2432
2559
|
]
|
|
@@ -2650,6 +2777,7 @@ class KotoneBotUI:
|
|
|
2650
2777
|
self.config.user_configs.append(default_config)
|
|
2651
2778
|
self.current_config = self.config.user_configs[0]
|
|
2652
2779
|
|
|
2780
|
+
|
|
2653
2781
|
def create_ui(self) -> gr.Blocks:
|
|
2654
2782
|
custom_css = """
|
|
2655
2783
|
#container { max-width: 800px; margin: auto; padding: 20px; }
|
|
@@ -2677,6 +2805,9 @@ class KotoneBotUI:
|
|
|
2677
2805
|
self._create_whats_new_tab()
|
|
2678
2806
|
self._create_screen_tab()
|
|
2679
2807
|
|
|
2808
|
+
# 启动 IdleModeManager 后台线程
|
|
2809
|
+
self.idle_mgr.start()
|
|
2810
|
+
|
|
2680
2811
|
return app
|
|
2681
2812
|
|
|
2682
2813
|
def main(kaa: Kaa | None = None, start_immidiately: bool = False) -> None:
|
kotonebot/kaa/metadata.py
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
WHATS_NEW = """
|
|
2
2
|
# 更新日志
|
|
3
3
|
## kaa
|
|
4
|
+
### v2025.09b1
|
|
5
|
+
发布日期:2025-09-06
|
|
6
|
+
|
|
7
|
+
> **注意**
|
|
8
|
+
>
|
|
9
|
+
> 自此版本开始,版本号格式从 `v{YYYY}.{MM}.{DD}.{Minor}` 改为 `v{YYYY}.{MM}` 与 `v{YYYY}.{MM}b{BetaVersion}` 。
|
|
10
|
+
> 前者为正式版,每一到两个月发布一次,后者为测试版,一到两周发布一次。对于只更新了游戏数据的正式版,使用 `post` 后缀。
|
|
11
|
+
>
|
|
12
|
+
> 【例】
|
|
13
|
+
> - v2025.08 为 2025 年 9 月发布的正式版
|
|
14
|
+
> - v2025.09b3 为 2025 年 9 月发布的第 3 个测试版
|
|
15
|
+
> - v2025.08.post1 为 2025 年 8 月发布的正式版,但只更新了游戏数据
|
|
16
|
+
|
|
17
|
+
脚本:
|
|
18
|
+
* [修复] 修复培育中打牌时无法处理日期变更弹窗的问题(#de27888)
|
|
19
|
+
* [修复] 修复了produce模块中循环引用,导致produce子模块失效的问题(#e08ec22)
|
|
20
|
+
* [修复] 再次修复进入商店时,错误进入交换所的问题(#a425ae9)
|
|
21
|
+
* [修复] 修复了上一次培育为NIA培育时,错误地进入Hajime培育的问题(#f8686b8)
|
|
22
|
+
* [修复] 修复了自动使用AP饮料时有几率卡在点击「使う」按钮上的问题(#dd5dbdf)
|
|
23
|
+
* [修复] 修复了'休息'时按钮点击过快,导致第二次点击丢失的问题(#070f052)
|
|
24
|
+
* [修复] 修复了进入商店时,错误进入交换所的问题(#bfabf3e)
|
|
25
|
+
* [新增] 新增了处理'培育时,日期变更'的功能(#e15f4e3)
|
|
26
|
+
|
|
27
|
+
界面:
|
|
28
|
+
* [修复] 在详细设置中添加了缺失的‘升级支援卡设置’(#89793c7)
|
|
29
|
+
* [新增] 在'状态'页新增了全选、全不选、只选培育、只不选培育这四个新按键(#93f03b3)
|
|
30
|
+
* [新增] UI 内支持检索测试版本的 kaa(#5a66777)
|
|
31
|
+
|
|
32
|
+
框架:
|
|
33
|
+
* [修复] 修复启用空闲模式后,反复报错 ContextNotInitializedError 的问题(#0a8293e)
|
|
34
|
+
|
|
35
|
+
其他:
|
|
36
|
+
* [文档] 新增开发指南(#4b7dea5)
|
|
37
|
+
|
|
38
|
+
### v2025.8.23.0
|
|
39
|
+
脚本:
|
|
40
|
+
* [新增] 新增闲置挂机功能(#54e2101)
|
|
41
|
+
* [修复] 再次修复商店刷新后第二次购买会跳过第一行的问题(#b72cdf4)
|
|
42
|
+
* [修复] 修复游戏更新导致的培育时识别编成编号失败(#24d14d4)
|
|
43
|
+
* [修复] 修复培育内周数识别失败的问题(#3a84994)
|
|
44
|
+
* [修复] 培育商店中有时候会因为结束按钮被挡住而卡住(#e93cfa8)
|
|
45
|
+
|
|
46
|
+
其他:
|
|
47
|
+
* [文档] 更新 README(#841fcf2)
|
|
48
|
+
|
|
4
49
|
### v2025.8.17.0
|
|
5
50
|
脚本:
|
|
6
51
|
* [修复] 尝试修复进入每日商店时报错的问题(#e9529b7)
|
|
Binary file
|
kotonebot/kaa/resources/game.db
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|