ksaa 2025.7.27.1__py3-none-any.whl → 2025.8.17.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.
Files changed (163) hide show
  1. kotonebot/__init__.py +2 -1
  2. kotonebot/interop/win/shortcut.py +43 -0
  3. kotonebot/kaa/application/adapter/misc_adapter.py +5 -0
  4. kotonebot/kaa/application/core/misc_core.py +33 -0
  5. kotonebot/kaa/errors.py +14 -0
  6. kotonebot/kaa/main/cli.py +2 -1
  7. kotonebot/kaa/main/gr.py +97 -76
  8. kotonebot/kaa/metadata.py +26 -0
  9. kotonebot/kaa/resources/__pycache__/__init__.cpython-310.pyc +0 -0
  10. kotonebot/kaa/resources/game.db +0 -0
  11. kotonebot/kaa/resources/game_ver.txt +0 -0
  12. kotonebot/kaa/resources/idol_cards/i_card-skin-fktn-3-013_0.png +0 -0
  13. kotonebot/kaa/resources/idol_cards/i_card-skin-fktn-3-013_1.png +0 -0
  14. kotonebot/kaa/resources/idol_cards/i_card-skin-hmsz-3-010_0.png +0 -0
  15. kotonebot/kaa/resources/idol_cards/i_card-skin-hmsz-3-010_1.png +0 -0
  16. kotonebot/kaa/resources/idol_cards/i_card-skin-hume-3-012_0.png +0 -0
  17. kotonebot/kaa/resources/idol_cards/i_card-skin-hume-3-012_1.png +0 -0
  18. kotonebot/kaa/resources/idol_cards/i_card-skin-jsna-3-011_0.png +0 -0
  19. kotonebot/kaa/resources/idol_cards/i_card-skin-jsna-3-011_1.png +0 -0
  20. kotonebot/kaa/tasks/R.py +126 -126
  21. kotonebot/kaa/tasks/actions/scenes.py +4 -10
  22. kotonebot/kaa/tasks/daily/capsule_toys.py +3 -4
  23. kotonebot/kaa/tasks/daily/contest.py +3 -7
  24. kotonebot/kaa/tasks/daily/mission_reward.py +13 -10
  25. kotonebot/kaa/tasks/daily/purchase.py +22 -13
  26. kotonebot/kaa/tasks/produce/cards.py +3 -8
  27. kotonebot/kaa/tasks/produce/common.py +3 -9
  28. kotonebot/kaa/tasks/produce/in_purodyuusu.py +93 -81
  29. kotonebot/kaa/tasks/produce/non_lesson_actions.py +35 -27
  30. kotonebot/kaa/tasks/produce/produce.py +18 -18
  31. kotonebot/kaa/tasks/start_game.py +4 -9
  32. {ksaa-2025.7.27.1.dist-info → ksaa-2025.8.17.0.dist-info}/METADATA +1 -1
  33. {ksaa-2025.7.27.1.dist-info → ksaa-2025.8.17.0.dist-info}/RECORD +163 -152
  34. /kotonebot/kaa/sprites/{4ced1b5f-bbd2-4230-8555-233d082f4d05.png → 00a2e0d4-1683-4c36-88df-081673e2fe1a.png} +0 -0
  35. /kotonebot/kaa/sprites/{093c3fb8-036e-4cf4-917b-d70cabebf571.png → 07578d0c-15d4-42a2-9db1-a1c0c11b55c1.png} +0 -0
  36. /kotonebot/kaa/sprites/{9f2a6935-f462-4726-b56e-8cf23aae3982.png → 079cdbed-7171-42e3-8298-9d1e180982ec.png} +0 -0
  37. /kotonebot/kaa/sprites/{31122061-ea7a-419e-8072-8552013a8255.png → 07c5517b-38f7-44e6-8506-84317ba0fb86.png} +0 -0
  38. /kotonebot/kaa/sprites/{ddc8f913-e9ae-46dc-a91a-d3ee79e9f32d.png → 07d78d3e-4e79-459e-9c41-43f4a618f9e9.png} +0 -0
  39. /kotonebot/kaa/sprites/{14283368-d85d-458a-8f2c-b112bd02256e.png → 0899e636-b767-45e6-ab63-258d19d3f806.png} +0 -0
  40. /kotonebot/kaa/sprites/{f23cb531-18b5-4852-bb11-56dc621e56cc.png → 0b27cdd2-490b-4a6a-ae0d-788ac1601dcc.png} +0 -0
  41. /kotonebot/kaa/sprites/{5033ca17-1327-4554-b939-968b8a78f10a.png → 0b947c81-0ab1-40a8-8c26-26258be572c7.png} +0 -0
  42. /kotonebot/kaa/sprites/{a66625f6-f80c-48e4-a344-e48036085e2b.png → 0da004d8-2cc5-43ab-9ac1-94d4f74dd37d.png} +0 -0
  43. /kotonebot/kaa/sprites/{4c444aaf-a2d1-44f1-aacc-b737f262a746.png → 0de1fa4d-3621-4671-9e1f-b8ed1e767adc.png} +0 -0
  44. /kotonebot/kaa/sprites/{f957fbb8-ba30-47c0-97b8-ff531d6e3831.png → 0e998848-beb2-4d31-9019-6afab9e0180e.png} +0 -0
  45. /kotonebot/kaa/sprites/{5f3937f7-a5de-4a11-bcf9-da586596bf47.png → 0ef0615f-f293-4a4e-93ac-985b3a17c8d7.png} +0 -0
  46. /kotonebot/kaa/sprites/{d0881e29-6da6-4823-b65c-eefa9f9f2208.png → 1135ed8d-4e1c-4896-9d6d-5c2ba3d29761.png} +0 -0
  47. /kotonebot/kaa/sprites/{116bf963-ad4a-401a-91f7-e3a56a4848b9.png → 12b811a3-5b37-4510-9ebd-95455644f253.png} +0 -0
  48. /kotonebot/kaa/sprites/{29fc852e-4c61-416d-80ff-f28c5a64abc1.png → 130ee78a-c201-4fa0-bac5-7be0b842312d.png} +0 -0
  49. /kotonebot/kaa/sprites/{ac0b1f47-ce60-479a-9c5d-d8ced42ec0e0.png → 1339693d-6e77-4058-921a-9079c8eb5a9a.png} +0 -0
  50. /kotonebot/kaa/sprites/{acff3d83-f570-4c65-9bb3-db69cd525262.png → 141b5f13-489d-4271-ac49-4d0bd40bf8fc.png} +0 -0
  51. /kotonebot/kaa/sprites/{36e02aa6-f858-4248-b39e-e16686d6baf1.png → 14488bad-1e16-47b8-9870-f2e18c6b87ee.png} +0 -0
  52. /kotonebot/kaa/sprites/{1b2a0de3-34cc-42b2-8af3-bfeb8d0d679c.png → 1466ba09-8e27-49cd-8606-f9feeecc2915.png} +0 -0
  53. /kotonebot/kaa/sprites/{c157661d-de06-4e34-bc3b-7d79c987e26d.png → 15ce2944-3d27-4073-b969-2ec8fc98ceb4.png} +0 -0
  54. /kotonebot/kaa/sprites/{80c6d473-1eb2-4d65-8e8d-8f267ab61cd9.png → 1777dfb5-2793-4037-9da7-f789cf65896e.png} +0 -0
  55. /kotonebot/kaa/sprites/{7e614cff-b492-4c4d-bbfe-0853ff65fcec.png → 1abdc520-6123-40c9-bf50-d84e46f9420c.png} +0 -0
  56. /kotonebot/kaa/sprites/{661d0e8d-379d-401d-9f29-147e70123adf.png → 1ae6b793-d85f-4b06-ba9f-bdb7fbed26fc.png} +0 -0
  57. /kotonebot/kaa/sprites/{7c7cbe5a-37f0-4cf3-8376-4ceeb7a662b0.png → 1d5835f8-593c-4ec4-a360-81fce8d2f959.png} +0 -0
  58. /kotonebot/kaa/sprites/{d6235144-ce78-4884-88b4-d1a12b76155f.png → 1e540586-c381-4aed-b689-e9cd2708ae85.png} +0 -0
  59. /kotonebot/kaa/sprites/{eea2af85-94b2-4c41-8f51-393059dcc43c.png → 1f8cca6a-ae0a-44c9-a267-989ae508320a.png} +0 -0
  60. /kotonebot/kaa/sprites/{ebb662bb-62b4-404c-bb8f-4a7d5feccaa8.png → 214fad37-3e64-4786-8cfa-b48dd49ddbe4.png} +0 -0
  61. /kotonebot/kaa/sprites/{d32f8851-4fd2-4484-8ae8-66a375a43f3d.png → 21f2fdd8-c6fe-44fe-bcc6-efa8bc7f895a.png} +0 -0
  62. /kotonebot/kaa/sprites/{ff361c63-3f3d-48df-a26f-7698bd459219.png → 255b0e7a-c47a-4f70-9c92-5e3fa06d4d4c.png} +0 -0
  63. /kotonebot/kaa/sprites/{3cd5382a-a679-4f06-ab83-6328a943148d.png → 2ac9bca3-aad6-4d19-a4b7-4d7197d95fba.png} +0 -0
  64. /kotonebot/kaa/sprites/{a148b768-8c8d-4fee-b29f-11d73240a3d0.png → 2c43b51a-7ca5-4401-a05f-d3b3de17c2d3.png} +0 -0
  65. /kotonebot/kaa/sprites/{66c7e6df-5c90-4b3a-9b51-78cff1357ed7.png → 2e279b36-1057-453f-9a7e-7ac61ddce6f9.png} +0 -0
  66. /kotonebot/kaa/sprites/{2585cb7b-af94-46ac-a31d-f50bd09f40a6.png → 2e5cfcf0-34fc-4b17-9283-0c269d04ae98.png} +0 -0
  67. /kotonebot/kaa/sprites/{28e5138d-bcd4-40d2-9e2f-0c845004b8ae.png → 32d066ef-5783-4ab4-8a41-5e948169b1d7.png} +0 -0
  68. /kotonebot/kaa/sprites/{1c14e581-b664-488c-9d29-f5228ee6d328.png → 3303b048-552d-4794-aa57-180b43187d5a.png} +0 -0
  69. /kotonebot/kaa/sprites/{566e641a-a364-415c-a17b-2db7862f2714.png → 3336498e-763b-4b43-9939-a271d2deb64f.png} +0 -0
  70. /kotonebot/kaa/sprites/{dd5ffd48-2ab0-4795-8193-8a8310101574.png → 350736d7-0774-4a48-973c-d9373fc68ea3.png} +0 -0
  71. /kotonebot/kaa/sprites/{8938249c-94d3-4f20-8013-85d481a54d87.png → 368d245a-8777-437a-80c4-e6b0504236e6.png} +0 -0
  72. /kotonebot/kaa/sprites/{9b439501-e57d-4912-9f57-67c4534060f7.png → 394c60cc-1caa-4a29-a387-798316d48d4a.png} +0 -0
  73. /kotonebot/kaa/sprites/{3d7d1e3f-29c7-431d-8621-3f31b8880492.png → 3bf9aa00-7c6d-46ec-b487-7f846588acbe.png} +0 -0
  74. /kotonebot/kaa/sprites/{34dcd41c-b800-43b4-b24f-c569bae59db2.png → 4183bf72-4ca7-4480-a6db-c81632b1a62b.png} +0 -0
  75. /kotonebot/kaa/sprites/{7b552e56-0065-45d8-a0dc-bfe3be62b91f.png → 42092d5b-d11d-4651-9cd5-49302f52d50b.png} +0 -0
  76. /kotonebot/kaa/sprites/{96b12d02-c634-4e9c-a465-7ee61d5fc0bd.png → 4365cb24-54a1-4998-8a2e-bed02fc988f5.png} +0 -0
  77. /kotonebot/kaa/sprites/{7e4a2554-c05b-458f-b31f-ac6930e8078e.png → 471d7204-23f3-4d72-a852-77e8b424ddff.png} +0 -0
  78. /kotonebot/kaa/sprites/{6d225f8d-efc0-42a5-93af-7b81e24377c5.png → 48fc4fee-0d6e-4995-8d29-37791d33759e.png} +0 -0
  79. /kotonebot/kaa/sprites/{8cbbfa8e-17aa-42e7-92f7-319a02c8f7fa.png → 49fa1fd6-8115-476d-aa60-2d63613ef931.png} +0 -0
  80. /kotonebot/kaa/sprites/{d94ce829-a7ab-44aa-bc0c-a4801b650088.png → 4c07fc6b-662a-4216-b1e6-6036fa6f717d.png} +0 -0
  81. /kotonebot/kaa/sprites/{ee8a6029-63b3-4c13-bdc5-9bd8546d3316.png → 4c2fe337-73f6-4ed4-84ae-f17bf4787645.png} +0 -0
  82. /kotonebot/kaa/sprites/{3e558d01-1d7d-4ed3-9200-738252539dc1.png → 54a7603e-fd84-4d7f-99ef-f95d3695aa42.png} +0 -0
  83. /kotonebot/kaa/sprites/{5ba7d61f-282d-4ad0-881a-842c26e7f66c.png → 54e4f9a3-3ae6-4bf4-85b1-680889835137.png} +0 -0
  84. /kotonebot/kaa/sprites/{5a0d6f90-3758-4baa-94fc-a4a412284628.png → 550c0ad2-4c38-4c34-8be2-9ea278b3f822.png} +0 -0
  85. /kotonebot/kaa/sprites/{0f986eac-1e3c-48ed-9850-cae529b30503.png → 5b3f7210-d28b-4117-a664-efb790eec911.png} +0 -0
  86. /kotonebot/kaa/sprites/{d77a936b-c0ae-4dbd-8b44-82288a0957d6.png → 6224165f-3fa9-483f-b4fb-73c44e8009e4.png} +0 -0
  87. /kotonebot/kaa/sprites/{ff5a0417-229f-41bd-8121-708b08417114.png → 63b1d3d9-a0d7-413e-8e67-215ee46e5af7.png} +0 -0
  88. /kotonebot/kaa/sprites/{7fcc8f4c-9d06-4747-8c1e-aaba3a61cc0e.png → 64d7e162-a761-458b-a0c6-083658141032.png} +0 -0
  89. /kotonebot/kaa/sprites/{60cfef80-cd08-4205-8088-8d0b22a59b5a.png → 6b33fe3c-28ff-49ad-ba24-7279c8e9ec19.png} +0 -0
  90. /kotonebot/kaa/sprites/{81fec353-ad18-4223-9ea3-8d128a4a3e77.png → 6b4f820d-8b40-4ac1-9322-550860cbda08.png} +0 -0
  91. /kotonebot/kaa/sprites/{2d902d81-5500-4265-9867-c5c4cac573d7.png → 6ede6499-0efe-4ad2-83c7-5fd8a512c52e.png} +0 -0
  92. /kotonebot/kaa/sprites/{47f4b0a5-5792-4e82-b597-d58ea0b1f494.png → 71293cd1-83de-4f15-9608-1d31678e3566.png} +0 -0
  93. /kotonebot/kaa/sprites/{c2e3d6ac-00b6-4d2a-a30b-52a1190f5f05.png → 71ce4a03-5865-47fb-a2a2-d220dbd8ead3.png} +0 -0
  94. /kotonebot/kaa/sprites/{61f56d51-8d30-4aed-857a-8eff6fab27c1.png → 720cfc0e-74a2-4239-bc08-ea9927871cd0.png} +0 -0
  95. /kotonebot/kaa/sprites/{a2d9b907-f68e-47c7-8aa6-31c07c272d94.png → 73eec0a3-e3ba-40c8-b163-321a5b7feb81.png} +0 -0
  96. /kotonebot/kaa/sprites/{3bd19f01-57f8-4f8b-98b7-b5dd0779f77d.png → 74c8b69c-bceb-438f-a4a4-49e3abd7fa46.png} +0 -0
  97. /kotonebot/kaa/sprites/{432df4be-4970-4ac0-8465-a698bce6fe65.png → 757d08d7-c7a1-430a-8938-edd824ed7117.png} +0 -0
  98. /kotonebot/kaa/sprites/{aab26578-b548-41e5-8996-40ef821ca041.png → 7e00779b-de42-4406-88f9-07d93e47f104.png} +0 -0
  99. /kotonebot/kaa/sprites/{7dcc9134-9e5f-433b-ae5c-7530484f3f5f.png → 82eab6fc-1968-42a4-bb43-d9cee984b33d.png} +0 -0
  100. /kotonebot/kaa/sprites/{bd04472b-eeeb-4ad7-b385-8347b7053887.png → 850d5405-2103-4a2f-9e00-d5c5f43ce9a7.png} +0 -0
  101. /kotonebot/kaa/sprites/{4de619fd-ed06-4210-b1f0-11556deb4dd9.png → 864b57b0-c2f9-49eb-864c-314f72c0f56c.png} +0 -0
  102. /kotonebot/kaa/sprites/{252f1cd3-8e09-4b34-b5ba-47b1137a19c1.png → 88476c65-0056-4ae4-9c9e-3ff1bae964e8.png} +0 -0
  103. /kotonebot/kaa/sprites/{adc38fcc-84d2-4f7c-846d-4fe96dd5d08a.png → 896ed7b5-72c8-4c1d-90ff-eb7f12876f9c.png} +0 -0
  104. /kotonebot/kaa/sprites/{7dfdefa7-d95f-4348-9e0b-640ed17e138f.png → 8e021860-0c8f-4da5-84f8-1ed65ad6f720.png} +0 -0
  105. /kotonebot/kaa/sprites/{b5a58c56-3f09-47e5-ab61-57bab752e735.png → 8e90dc5b-d79a-4133-b722-edbb14f5f0db.png} +0 -0
  106. /kotonebot/kaa/sprites/{dc64e856-2f31-48b1-b17d-32b499f819ce.png → 917be8d3-602c-495c-b2ed-41b1c84e7398.png} +0 -0
  107. /kotonebot/kaa/sprites/{f7a4208f-0373-4f26-907f-84c3f2b810fc.png → 918db28b-0d43-4056-a506-3279f2b724c8.png} +0 -0
  108. /kotonebot/kaa/sprites/{3ace2c73-cf00-4706-9aac-1a0229b1b3f5.png → 93f74a70-acd1-4453-8254-07a797839b5f.png} +0 -0
  109. /kotonebot/kaa/sprites/{464c3d3a-c772-4f85-94d5-970f46c8d213.png → 99967c02-b5cf-43ba-9ca6-23e2781b25d9.png} +0 -0
  110. /kotonebot/kaa/sprites/{04c9d1c8-09b9-402d-b688-796253fdaf0c.png → 9aee770e-1746-4076-b3c4-5da218321614.png} +0 -0
  111. /kotonebot/kaa/sprites/{6468ab50-2d25-4b18-b555-2a56397968b0.png → 9bc1e849-e69d-4849-a849-45ea81829567.png} +0 -0
  112. /kotonebot/kaa/sprites/{e62afa2c-1c5b-426e-8ff1-ea51f75d0f20.png → 9dfde42d-fd40-435b-8a41-50be0fb8781e.png} +0 -0
  113. /kotonebot/kaa/sprites/{1d457687-ff10-41b0-95e1-6c1b3868b2a0.png → 9ec515d0-c177-43fa-bbf3-ea2a57080969.png} +0 -0
  114. /kotonebot/kaa/sprites/{e7a0ea00-2a72-4d74-8664-53726e3e1078.png → a0fc1501-162d-49c6-824c-03e028d8fed7.png} +0 -0
  115. /kotonebot/kaa/sprites/{b92c4308-3778-47aa-8a0b-222d32721beb.png → a2e9d3a5-6f6f-4530-8a35-a09edfd35b8e.png} +0 -0
  116. /kotonebot/kaa/sprites/{c8f444cc-e809-44c2-86a3-3cbb5bcd0356.png → a5e11b99-d89e-47a2-ae67-4e0a04bfc022.png} +0 -0
  117. /kotonebot/kaa/sprites/{7a8c4af3-2ac1-4295-b844-350ad00f2c50.png → a6a23fad-cc30-43cd-b869-d2fad70d32ab.png} +0 -0
  118. /kotonebot/kaa/sprites/{d5a9d7f7-a065-4ff3-ae4c-b027f348ef54.png → a7cc8346-8b35-4f6a-acef-8cd4d29b5591.png} +0 -0
  119. /kotonebot/kaa/sprites/{2c2ff5ed-3b1a-4dcc-89a9-9457908cb184.png → a7f49544-2aaf-4f5c-a217-7203bfa87758.png} +0 -0
  120. /kotonebot/kaa/sprites/{52ae79ea-f4a4-4c19-9fe8-327f285ace1e.png → a885914f-a305-4af3-b2a5-991fdf0101f6.png} +0 -0
  121. /kotonebot/kaa/sprites/{8ed3eab8-779b-4b66-bc24-06b0b1dfac18.png → a914c9d7-3a19-4d9c-940e-579bf3f7fa79.png} +0 -0
  122. /kotonebot/kaa/sprites/{ad9cc197-c83d-4d39-b187-7105cde60ef5.png → a9e30963-0772-401a-85f8-33369ca22267.png} +0 -0
  123. /kotonebot/kaa/sprites/{a6bd2250-81b5-4f54-b6d9-bf9a5a4876d1.png → aa55089d-7b80-4763-a226-cde10e56f8a5.png} +0 -0
  124. /kotonebot/kaa/sprites/{88e4e3c6-3f6b-4192-83c7-4b20a51ad53a.png → aed0fd9a-0e59-4ead-b6a2-497b94f0eb16.png} +0 -0
  125. /kotonebot/kaa/sprites/{c84eada8-ff68-4d73-802b-6de88e73ec6d.png → af5714a6-e4a0-47ef-9151-2a8c9614e931.png} +0 -0
  126. /kotonebot/kaa/sprites/{a1791427-52af-4d1e-8e95-e0533cb66d3c.png → b176f60c-94ba-46e3-b562-7fc86b25c17f.png} +0 -0
  127. /kotonebot/kaa/sprites/{e25468f5-929a-4a49-a2e0-4527075353b5.png → b22260e3-22c6-4c80-b986-f4fd8db22ddc.png} +0 -0
  128. /kotonebot/kaa/sprites/{03821ecf-fdd2-4e89-8249-fc7288ac79be.png → b3debf96-a90b-4de7-b19e-83c2d82075ee.png} +0 -0
  129. /kotonebot/kaa/sprites/{a7e31af5-a896-47bb-af4b-e71936ac6334.png → b3e5704b-63c9-4226-9e49-69c680627b61.png} +0 -0
  130. /kotonebot/kaa/sprites/{f93c7a24-157d-43ef-adcc-3873d313c6d7.png → b66ed448-356e-44f9-ad45-40473d47ee24.png} +0 -0
  131. /kotonebot/kaa/sprites/{f08044bf-8a33-4d6b-8791-94470678efa6.png → b7283194-0e6d-4ac1-84e0-c2062af8eba8.png} +0 -0
  132. /kotonebot/kaa/sprites/{bba3cd68-3023-4a7b-9fe9-36ec7adbfc89.png → bd5190da-d3ed-462e-a573-b8f015cdef97.png} +0 -0
  133. /kotonebot/kaa/sprites/{eb67d908-13f8-4cef-9a86-9770e342ab77.png → be0bca2e-dfd5-48b6-a2ac-e2699991d37b.png} +0 -0
  134. /kotonebot/kaa/sprites/{2a539cb4-827f-449b-9780-14a94678948b.png → be2d7e60-56d2-4891-aae9-b5d2a65a8d03.png} +0 -0
  135. /kotonebot/kaa/sprites/{6a033af8-222c-459a-9ab9-a9a69b27822d.png → c654428b-4f16-4257-800f-da627ddb7595.png} +0 -0
  136. /kotonebot/kaa/sprites/{749bd918-8dfb-4393-bf91-b39e285f1d75.png → ca850faa-154e-4170-9446-91dd325e14af.png} +0 -0
  137. /kotonebot/kaa/sprites/{f03739ee-31e1-40ca-9aaf-6c0447d426a4.png → cce54a7c-bdd5-4063-8a40-e01709e69893.png} +0 -0
  138. /kotonebot/kaa/sprites/{05903cc9-9f7a-43ac-88e4-988a68311e05.png → cd5ba3a7-96aa-4efc-97fc-b72f72d084d2.png} +0 -0
  139. /kotonebot/kaa/sprites/{a3d5b052-526f-45ef-a2ed-5bba8ca9e4b1.png → d3c31276-8395-4aa3-ae1a-4c50a24e8574.png} +0 -0
  140. /kotonebot/kaa/sprites/{d0ad5222-0ee0-412e-819f-3217f9fd854b.png → d40a6e09-4740-41a8-af0f-9da09de38bf1.png} +0 -0
  141. /kotonebot/kaa/sprites/{360bcb7f-c710-49d5-9942-2812ed03a447.png → d559328f-9b26-4ea1-8f96-f432abf0214d.png} +0 -0
  142. /kotonebot/kaa/sprites/{f88f9f3b-e0e7-498c-ad1c-e92a719164f3.png → d597a32e-5ccb-4550-ab18-1905123c22d4.png} +0 -0
  143. /kotonebot/kaa/sprites/{efb31647-3760-4b76-8b5d-ec4b5fb7a975.png → d5a25a5f-8bd0-4f09-aec7-fda24eaf795e.png} +0 -0
  144. /kotonebot/kaa/sprites/{c370b930-9750-4782-9564-5ce4cd609bdd.png → d9432d63-1aef-43a7-8642-d10f3c15b092.png} +0 -0
  145. /kotonebot/kaa/sprites/{31745cd7-226e-4e11-b96d-2e202a7097e7.png → da351a32-c51f-4746-8f89-778343772d08.png} +0 -0
  146. /kotonebot/kaa/sprites/{eec4d7d6-3084-4bab-99c1-10e3a9459393.png → da7ef120-103c-4d5f-b95c-2bcd29757d3c.png} +0 -0
  147. /kotonebot/kaa/sprites/{e54b7482-a348-4252-a373-2ee69b3805b5.png → e4c40e7a-f67c-45d6-9775-8389bcff0b67.png} +0 -0
  148. /kotonebot/kaa/sprites/{75cad2af-b8c5-4f5f-8398-acd90eb4348e.png → e850b360-da95-4498-ab3e-177e0d57e189.png} +0 -0
  149. /kotonebot/kaa/sprites/{6597b7fd-3c5b-442f-a327-d18b555de544.png → e8935f50-3109-4d98-9783-86738763a431.png} +0 -0
  150. /kotonebot/kaa/sprites/{e049018e-9d2b-4537-add1-e902cf8ac69a.png → ed2f8cd2-be82-4d48-acd0-c48cf8bdd800.png} +0 -0
  151. /kotonebot/kaa/sprites/{39882ba6-c9d9-4742-b92d-206781c5f60e.png → ed56bfc1-d3c5-4bc3-a910-f861cfb2f379.png} +0 -0
  152. /kotonebot/kaa/sprites/{9a0c8f11-33f0-4c53-a911-556f3481d952.png → ed822aca-dde6-4235-8776-0c47884c4a9a.png} +0 -0
  153. /kotonebot/kaa/sprites/{3ea31c2c-1421-421c-a7fa-7994c06e4bca.png → ef46ae80-8c34-4948-9076-b0536805e7dc.png} +0 -0
  154. /kotonebot/kaa/sprites/{967b207a-79bb-479a-b50e-b2a04cf7ed54.png → f11ca963-fc05-4486-acf7-aa8f7415e6b5.png} +0 -0
  155. /kotonebot/kaa/sprites/{fbbf4921-ece5-4dc0-875d-8f7182596d4f.png → f404eabd-6b87-48a4-8ad7-1e7d521daa94.png} +0 -0
  156. /kotonebot/kaa/sprites/{1f5f5454-eb1c-45c3-8467-80c224d528e6.png → f61e28cd-9eaa-4d3c-b25d-8bfdaecb1255.png} +0 -0
  157. /kotonebot/kaa/sprites/{15ee94ce-1930-4eff-9ce2-0ebe947aaa05.png → f9bba6f1-6237-43bf-85b1-f6250a64a5d6.png} +0 -0
  158. /kotonebot/kaa/sprites/{76acc2b6-6649-4b1a-bd52-18ab9a2341d0.png → fb2694c2-8f0e-4ec3-9d76-087f085f2e55.png} +0 -0
  159. /kotonebot/kaa/sprites/{6c151fbe-7cf9-4629-b47a-da7be835bb4b.png → fbe45406-81bd-4298-ab4f-ed7346c25eb8.png} +0 -0
  160. {ksaa-2025.7.27.1.dist-info → ksaa-2025.8.17.0.dist-info}/WHEEL +0 -0
  161. {ksaa-2025.7.27.1.dist-info → ksaa-2025.8.17.0.dist-info}/entry_points.txt +0 -0
  162. {ksaa-2025.7.27.1.dist-info → ksaa-2025.8.17.0.dist-info}/licenses/LICENSE +0 -0
  163. {ksaa-2025.7.27.1.dist-info → ksaa-2025.8.17.0.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,7 @@ from kotonebot.kaa.config import conf, Priority
8
8
  from ..actions.loading import wait_loading_end
9
9
  from ..actions.scenes import at_home, goto_home
10
10
  from kotonebot import device, image, color, task, action, rect_expand, sleep
11
+ from kotonebot.backend.loop import Loop
11
12
 
12
13
  logger = logging.getLogger(__name__)
13
14
 
@@ -43,12 +44,14 @@ def claim_mission_reward(name: str):
43
44
  logger.info(f'Claiming {name} mission reward.')
44
45
  device.click()
45
46
  sleep(0.5)
46
- while not image.find(R.Common.ButtonIconArrowShortDisabled, colored=True):
47
- if image.find(R.Common.ButtonIconClose):
48
- logger.debug('Closing popup dialog.')
49
- device.click()
50
- sleep(1)
51
- sleep(0.5)
47
+ for _ in Loop(interval=0.5):
48
+ if not image.find(R.Common.ButtonIconArrowShortDisabled, colored=True):
49
+ if image.find(R.Common.ButtonIconClose):
50
+ logger.debug('Closing popup dialog.')
51
+ device.click()
52
+ sleep(1)
53
+ else:
54
+ break
52
55
  else:
53
56
  logger.info(f'No {name} mission reward to claim.')
54
57
 
@@ -81,13 +84,14 @@ def claim_pass_reward():
81
84
  device.click()
82
85
  # [screenshots/mission/pass.png]
83
86
  # 对话框 [screenshots/mission/pass_dialog.png]
84
- while not image.find(R.Daily.IconTitlePass):
87
+ for _ in Loop(interval=0.2):
85
88
  if image.find(R.Common.ButtonIconClose):
86
89
  logger.debug('Closing popup dialog.')
87
90
  device.click()
88
- sleep(0.2)
91
+ elif image.find(R.Daily.IconTitlePass):
92
+ break
89
93
  logger.debug('Pass screen loaded.')
90
- while True:
94
+ for _ in Loop():
91
95
  if image.find(R.Common.ButtonIconClose):
92
96
  logger.debug('Closing popup dialog.')
93
97
  device.click()
@@ -96,7 +100,6 @@ def claim_pass_reward():
96
100
  device.click()
97
101
  elif not image.find(R.Daily.ButtonPassClaim, colored=True) and image.find(R.Daily.IconTitlePass):
98
102
  break
99
- sleep(0.2)
100
103
  logger.info('All pass rewards claimed.')
101
104
 
102
105
  @action('活动奖励')
@@ -70,8 +70,7 @@ def dispatch_recommended_items():
70
70
  # 前置条件:[screenshots\shop\money1.png]
71
71
  logger.info(f'Start purchasing recommended items.')
72
72
 
73
- while True:
74
- device.screenshot()
73
+ for _ in Loop():
75
74
  if rec := image.find(R.Daily.TextShopRecommended):
76
75
  logger.info(f'Clicking on recommended item.') # TODO: 计数
77
76
  pos = rec.position.offset(dx=0, dy=80)
@@ -82,7 +81,7 @@ def dispatch_recommended_items():
82
81
  logger.info(f'No recommended item found. Finished.')
83
82
  break
84
83
 
85
- @action('确认购买', screenshot_mode='manual-inherit')
84
+ @action('确认购买', screenshot_mode='manual')
86
85
  def confirm_purchase(target_item_pos: Point | None = None):
87
86
  """
88
87
  确认购买
@@ -120,11 +119,13 @@ def confirm_purchase(target_item_pos: Point | None = None):
120
119
  return
121
120
  else:
122
121
  device.screenshot()
123
- while image.find(R.Daily.ButtonShopCountAdd, colored=True):
124
- logger.debug('Adjusting quantity(+1)...')
125
- device.click()
126
- sleep(0.2)
127
- device.screenshot()
122
+ # TODO: 这下面这段代码是干什么的?为什么上面和下面都点击了 Confirm?
123
+ for _ in Loop(interval=0.2):
124
+ if image.find(R.Daily.ButtonShopCountAdd, colored=True):
125
+ logger.debug('Adjusting quantity(+1)...')
126
+ device.click()
127
+ else:
128
+ break
128
129
  logger.debug('Confirming purchase...')
129
130
  device.click(image.expect_wait(R.Common.ButtonConfirm))
130
131
  # 等待对话框动画结束
@@ -157,10 +158,12 @@ def ap_items():
157
158
  continue
158
159
  comfirm = image.expect_wait(R.Common.ButtonConfirm, timeout=2)
159
160
  # 如果数量不是最大,调到最大
160
- while image.find(R.Daily.ButtonShopCountAdd, colored=True):
161
- logger.debug('Adjusting quantity(+1)...')
162
- device.click()
163
- sleep(0.3)
161
+ for _ in Loop(interval=0.3):
162
+ if image.find(R.Daily.ButtonShopCountAdd, colored=True):
163
+ logger.debug('Adjusting quantity(+1)...')
164
+ device.click()
165
+ else:
166
+ break
164
167
  logger.debug(f'Confirming purchase...')
165
168
  device.click(comfirm)
166
169
  sleep(1.5)
@@ -179,7 +182,7 @@ def purchase():
179
182
 
180
183
  goto_shop()
181
184
  # 进入每日商店 [screenshots\shop\shop.png]
182
- device.click(image.expect(R.Daily.ButtonDailyShop)) # TODO: memoable
185
+ device.click(image.expect_wait(R.Daily.ButtonDailyShop)) # TODO: memoable
183
186
  # 等待载入
184
187
  ap_tab = image.expect_wait(R.Daily.TextTabShopAp)
185
188
 
@@ -192,6 +195,12 @@ def purchase():
192
195
  logger.info('Refreshing money shop.')
193
196
  device.click()
194
197
  sleep(0.5)
198
+ # 等待刷新完成
199
+ for _ in Loop():
200
+ if not image.find(R.Daily.ButtonRefreshMoneyShop):
201
+ break
202
+ logger.debug('Waiting for money shop refresh...')
203
+ device.screenshot()
195
204
  money_items2()
196
205
  sleep(0.5)
197
206
  else:
@@ -12,6 +12,7 @@ from kotonebot.kaa.game_ui import dialog
12
12
  from kotonebot.kaa.util.trace import trace
13
13
  from kotonebot.primitives import RectTuple, Rect
14
14
  from kotonebot import action, Interval, Countdown, device, image, sleep, ocr, contains, use_screenshot, color
15
+ from kotonebot.backend.loop import Loop
15
16
 
16
17
  class SkillCard(NamedTuple):
17
18
  available: bool
@@ -121,7 +122,6 @@ def do_cards(
121
122
  :param threshold_predicate: 推荐卡检测阈值判断函数
122
123
  :param end_predicate: 结束条件判断函数
123
124
  """
124
- it = Interval(seconds=1/30)
125
125
  timeout_cd = Countdown(sec=120).start() # 推荐卡检测超时计时器
126
126
  break_cd = Countdown(sec=5) # 满足结束条件计时器
127
127
  no_card_cd = Countdown(sec=4) # 无手牌计时器
@@ -129,10 +129,9 @@ def do_cards(
129
129
  tries = 1
130
130
  card_count = -1
131
131
 
132
- while True:
132
+ for _ in Loop(interval=1/30):
133
133
  device.click(0, 0)
134
134
  img = device.screenshot()
135
- it.wait()
136
135
 
137
136
  # 技能卡自选移动对话框
138
137
  if image.find(R.InPurodyuusu.IconTitleSkillCardMove):
@@ -216,10 +215,8 @@ def handle_skill_card_move():
216
215
  logger.info("No skill cards found")
217
216
  return False
218
217
 
219
- it = Interval()
220
218
  cd = Countdown(sec=3)
221
- while True:
222
- device.screenshot()
219
+ for _ in Loop():
223
220
  # 判断对话框是否关闭
224
221
  # 已关闭,开始计时
225
222
  if not image.find(R.InPurodyuusu.IconTitleSkillCardMove):
@@ -241,8 +238,6 @@ def handle_skill_card_move():
241
238
  device.double_click(card)
242
239
  sleep(1)
243
240
  dialog.yes()
244
-
245
- it.wait()
246
241
  logger.debug("Handle skill card move finished.")
247
242
 
248
243
  @action('获取当前卡牌信息', screenshot_mode='manual-inherit')
@@ -7,6 +7,7 @@ from kotonebot import (
7
7
  image,
8
8
  action,
9
9
  sleep,
10
+ Loop,
10
11
  Interval,
11
12
  )
12
13
  from kotonebot.kaa.config.schema import produce_solution
@@ -28,15 +29,11 @@ def acquire_skill_card():
28
29
  # TODO: 不硬编码坐标
29
30
  logger.debug("Locating all skill cards...")
30
31
 
31
- it = Interval()
32
32
  cards = None
33
33
  card_clicked = False
34
34
  target_card = None
35
35
 
36
- while True:
37
- device.screenshot()
38
- it.wait()
39
-
36
+ for _ in Loop():
40
37
  # 是否显示技能卡选择指导的对话框
41
38
  # [kotonebot-resource/sprites/jp/in_purodyuusu/screenshot_show_skill_card_select_guide_dialog.png]
42
39
  if image.find(R.InPurodyuusu.TextSkillCardSelectGuideDialogTitle):
@@ -146,14 +143,11 @@ def handle_skill_card_removal():
146
143
  logger.info("No skill cards found")
147
144
  return False
148
145
  device.click(card)
149
- it = Interval()
150
- while True:
151
- device.screenshot()
146
+ for _ in Loop():
152
147
  if image.find(R.InPurodyuusu.ButtonRemove):
153
148
  device.click()
154
149
  logger.debug("Remove button clicked.")
155
150
  break
156
- it.wait()
157
151
  logger.debug("Handle skill card removal finished.")
158
152
 
159
153
  AcquisitionType = Literal[
@@ -11,7 +11,7 @@ from ..actions.scenes import at_home
11
11
  from .cards import do_cards, CardDetectResult
12
12
  from ..actions.commu import handle_unread_commu
13
13
  from kotonebot.errors import UnrecoverableError
14
- from kotonebot.util import Countdown, Interval, cropped
14
+ from kotonebot.util import Countdown, cropped
15
15
  from kotonebot.backend.loop import Loop
16
16
  from kotonebot.kaa.config import ProduceAction, RecommendCardDetectionMode
17
17
  from ..produce.common import until_acquisition_clear, commu_event, fast_acquisitions
@@ -74,10 +74,11 @@ def handle_recommended_action(final_week: bool = False) -> ProduceAction | None:
74
74
  device.screenshot()
75
75
  if not image.find(R.InPurodyuusu.IconAsariSenseiAvatar):
76
76
  return None
77
- it = Interval()
78
77
  cd = Countdown(sec=5).start()
79
78
  result = None
80
- while not cd.expired():
79
+ for _ in Loop():
80
+ if cd.expired():
81
+ break
81
82
  logger.debug('Retrieving recommended lesson...')
82
83
  with cropped(device, y1=0.00, y2=0.30):
83
84
  if result := image.find_multi([
@@ -88,8 +89,6 @@ def handle_recommended_action(final_week: bool = False) -> ProduceAction | None:
88
89
  R.InPurodyuusu.TextSenseiTipConsult,
89
90
  ]):
90
91
  break
91
- it.wait()
92
- device.screenshot()
93
92
 
94
93
  logger.debug("image.find_multi: %s", result)
95
94
  if result is None:
@@ -145,32 +144,34 @@ def handle_recommended_action(final_week: bool = False) -> ProduceAction | None:
145
144
  @action('等待进入行动场景')
146
145
  def until_action_scene(week_first: bool = False):
147
146
  """等待进入行动场景"""
148
- # 检测是否到行动页面
149
- while not image.find_multi([
150
- R.InPurodyuusu.TextPDiary, # 普通周
151
- R.InPurodyuusu.ButtonFinalPracticeDance # 离考试剩余一周
152
- ]):
153
- logger.info("Action scene not detected. Retry...")
154
- # commu_event 和 acquisitions 顺序不能颠倒。
155
- # 在 PRO 培育初始饮料、技能卡二选一事件时,右下方的
156
- # 快进按钮会被视为交流。如果先执行 acquisitions(),
157
- # 会因为命中交流而 continue,commut_event() 永远
158
- # 不会执行。
159
- # [screenshots/produce/in_produce/initial_commu_event.png]
160
- if week_first and commu_event():
161
- continue
162
- if fast_acquisitions():
163
- continue
164
- sleep(0.2)
165
- else:
166
- logger.info("Now at action scene.")
167
- return
147
+ for _ in Loop(interval=0.2):
148
+ if not image.find_multi([
149
+ R.InPurodyuusu.TextPDiary, # 普通周
150
+ R.InPurodyuusu.ButtonFinalPracticeDance # 离考试剩余一周
151
+ ]):
152
+ logger.info("Action scene not detected. Retry...")
153
+ # commu_event 和 acquisitions 顺序不能颠倒。
154
+ # 在 PRO 培育初始饮料、技能卡二选一事件时,右下方的
155
+ # 快进按钮会被视为交流。如果先执行 acquisitions(),
156
+ # 会因为命中交流而 continue,commut_event() 永远
157
+ # 不会执行。
158
+ # [screenshots/produce/in_produce/initial_commu_event.png]
159
+ if week_first and commu_event():
160
+ continue
161
+ if fast_acquisitions():
162
+ continue
163
+ else:
164
+ logger.info("Now at action scene.")
165
+ return
168
166
 
169
167
  @action('等待进入练习场景')
170
168
  def until_practice_scene():
171
169
  """等待进入练习场景"""
172
- while image.find(R.InPurodyuusu.TextClearUntil) is None:
173
- until_acquisition_clear()
170
+ for _ in Loop():
171
+ if image.find(R.InPurodyuusu.TextClearUntil) is None:
172
+ until_acquisition_clear()
173
+ else:
174
+ break
174
175
 
175
176
  @action('等待进入考试场景')
176
177
  def until_exam_scene():
@@ -178,8 +179,11 @@ def until_exam_scene():
178
179
  # NOTE: is_exam_scene() 通过 OCR 剩余回合数判断是否处于考试场景。
179
180
  # 本来有可能会与练习场景混淆,
180
181
  # 但是在确定后续只是考试场景的情况下应该不会
181
- while ocr.find(regex("合格条件|三位以上")) is None and not is_exam_scene():
182
- until_acquisition_clear()
182
+ for _ in Loop():
183
+ if ocr.find(regex("合格条件|三位以上")) is None and not is_exam_scene():
184
+ until_acquisition_clear()
185
+ else:
186
+ break
183
187
 
184
188
  @action('执行练习', screenshot_mode='manual')
185
189
  def practice():
@@ -284,8 +288,11 @@ def exam(type: Literal['mid', 'final']):
284
288
  do_cards(threshold_predicate, end_predicate)
285
289
  device.click(image.expect_wait(R.Common.ButtonNext))
286
290
  if type == 'final':
287
- while ocr.wait_for(contains("メモリー"), timeout=7):
288
- device.click_center()
291
+ for _ in Loop():
292
+ if ocr.wait_for(contains("メモリー"), timeout=7):
293
+ device.click_center()
294
+ else:
295
+ break
289
296
 
290
297
  # TODO: 将这个函数改为手动截图模式
291
298
  @action('考试结束流程')
@@ -301,23 +308,24 @@ def produce_end():
301
308
  # 等待选择封面画面 [screenshots/produce_end/select_cover.jpg]
302
309
  # 次へ
303
310
  logger.info("Waiting for select cover screen...")
304
- it = Interval()
305
- while not image.find(R.InPurodyuusu.ButtonNextNoIcon):
306
- # device.screenshot()
307
- # 未读交流
308
- if handle_unread_commu():
309
- logger.info("Skipping unread commu")
310
- # 跳过演出
311
- # [kotonebot-resource\sprites\jp\produce\screenshot_produce_end.png]
312
- elif image.find(R.Produce.ButtonSkipLive, preprocessors=[WhiteFilter()]):
313
- logger.info("Skipping live.")
314
- device.click()
315
- # [kotonebot-resource\sprites\jp\produce\screenshot_produce_end_skip.png]
316
- elif image.find(R.Produce.TextSkipLiveDialogTitle):
317
- logger.info("Confirming skip live.")
318
- device.click(image.expect_wait(R.Common.IconButtonCheck))
319
- it.wait()
320
- device.click(0, 0)
311
+ for _ in Loop():
312
+ if not image.find(R.InPurodyuusu.ButtonNextNoIcon):
313
+ # device.screenshot()
314
+ # 未读交流
315
+ if handle_unread_commu():
316
+ logger.info("Skipping unread commu")
317
+ # 跳过演出
318
+ # [kotonebot-resource\sprites\jp\produce\screenshot_produce_end.png]
319
+ elif image.find(R.Produce.ButtonSkipLive, preprocessors=[WhiteFilter()]):
320
+ logger.info("Skipping live.")
321
+ device.click()
322
+ # [kotonebot-resource\sprites\jp\produce\screenshot_produce_end_skip.png]
323
+ elif image.find(R.Produce.TextSkipLiveDialogTitle):
324
+ logger.info("Confirming skip live.")
325
+ device.click(image.expect_wait(R.Common.IconButtonCheck))
326
+ device.click(0, 0)
327
+ else:
328
+ break
321
329
  # 选择封面
322
330
  logger.info("Use default cover.")
323
331
  sleep(3)
@@ -360,9 +368,11 @@ def produce_end():
360
368
  sleep(2)
361
369
  # 后续动画
362
370
  logger.info("Waiting for memory generation animation completed...")
363
- while not image.find(R.InPurodyuusu.ButtonNextNoIcon):
364
- device.click_center()
365
- sleep(1)
371
+ for _ in Loop(interval=1):
372
+ if not image.find(R.InPurodyuusu.ButtonNextNoIcon):
373
+ device.click_center()
374
+ else:
375
+ break
366
376
 
367
377
  # 结算完毕
368
378
  # logger.info("Finalize")
@@ -385,7 +395,7 @@ def produce_end():
385
395
 
386
396
  # 四个完成画面
387
397
  logger.info("Finalize")
388
- while True:
398
+ for _ in Loop():
389
399
  # [screenshots/produce_end/end_next_1.jpg]
390
400
  # [screenshots/produce_end/end_next_2.png]
391
401
  # [screenshots/produce_end/end_next_3.png]
@@ -406,37 +416,39 @@ def produce_end():
406
416
 
407
417
  # 点击结束后可能还会弹出来:
408
418
  # 活动进度、关注提示
409
- while not at_home():
410
- # 活动积分进度 奖励领取
411
- # [screenshots/produce_end/end_activity1.png]
412
- # 制作人 升级
413
- # [screenshots/produce_end/end_level_up.png]
414
- if image.find(R.Common.ButtonIconClose):
415
- logger.info("Activity award claim dialog found. Click to close.")
416
- device.click()
417
- # 活动积分进度
418
- # [screenshots/produce_end/end_activity.png]
419
- elif image.find(R.Common.ButtonNextNoIcon, colored=True):
420
- logger.debug("Click next")
421
- device.click()
422
- # 关注制作人
423
- # [screenshots/produce_end/end_follow.png]
424
- elif image.find(R.InPurodyuusu.ButtonCancel):
425
- logger.info("Follow producer dialog found. Click to close.")
426
- if produce_solution().data.follow_producer:
427
- logger.info("Follow producer")
428
- device.click(image.expect_wait(R.InPurodyuusu.ButtonFollowNoIcon))
429
- else:
430
- logger.info("Skip follow producer")
419
+ for _ in Loop(interval=1):
420
+ if not at_home():
421
+ # 活动积分进度 奖励领取
422
+ # [screenshots/produce_end/end_activity1.png]
423
+ # 制作人 升级
424
+ # [screenshots/produce_end/end_level_up.png]
425
+ if image.find(R.Common.ButtonIconClose):
426
+ logger.info("Activity award claim dialog found. Click to close.")
431
427
  device.click()
432
- # 偶像强化月 新纪录达成
433
- # [kotonebot-resource/sprites/jp/in_purodyuusu/screenshot_new_record.png]
434
- elif image.find(R.Common.ButtonOK):
435
- logger.info("OK button found. Click to close.")
436
- device.click()
428
+ # 活动积分进度
429
+ # [screenshots/produce_end/end_activity.png]
430
+ elif image.find(R.Common.ButtonNextNoIcon, colored=True):
431
+ logger.debug("Click next")
432
+ device.click()
433
+ # 关注制作人
434
+ # [screenshots/produce_end/end_follow.png]
435
+ elif image.find(R.InPurodyuusu.ButtonCancel):
436
+ logger.info("Follow producer dialog found. Click to close.")
437
+ if produce_solution().data.follow_producer:
438
+ logger.info("Follow producer")
439
+ device.click(image.expect_wait(R.InPurodyuusu.ButtonFollowNoIcon))
440
+ else:
441
+ logger.info("Skip follow producer")
442
+ device.click()
443
+ # 偶像强化月 新纪录达成
444
+ # [kotonebot-resource/sprites/jp/in_purodyuusu/screenshot_new_record.png]
445
+ elif image.find(R.Common.ButtonOK):
446
+ logger.info("OK button found. Click to close.")
447
+ device.click()
448
+ else:
449
+ device.click_center()
437
450
  else:
438
- device.click_center()
439
- sleep(1)
451
+ break
440
452
  logger.info("Produce completed.")
441
453
 
442
454
  @action('执行行动', screenshot_mode='manual-inherit')
@@ -12,7 +12,8 @@ from kotonebot.kaa.tasks import R
12
12
  from kotonebot.kaa.config import conf
13
13
  from ..produce.common import fast_acquisitions
14
14
  from kotonebot.kaa.game_ui.commu_event_buttons import CommuEventButtonUI
15
- from kotonebot.util import Countdown, Interval
15
+ from kotonebot.util import Countdown
16
+ from kotonebot.backend.loop import Loop
16
17
  from kotonebot.errors import UnrecoverableError
17
18
  from kotonebot import device, image, action, sleep
18
19
  from kotonebot.backend.dispatch import SimpleDispatcher
@@ -56,9 +57,12 @@ def enter_study():
56
57
  device.double_click(image.expect_wait(R.InPurodyuusu.ButtonIconStudy))
57
58
  # 等待进入页面。中间可能会出现未读交流
58
59
  # [screenshots/produce/action_study2.png]
59
- while not image.find(R.InPurodyuusu.IconTitleStudy):
60
- logger.debug("Waiting for 授業 screen.")
61
- fast_acquisitions()
60
+ for _ in Loop():
61
+ if not image.find(R.InPurodyuusu.IconTitleStudy):
62
+ logger.debug("Waiting for 授業 screen.")
63
+ fast_acquisitions()
64
+ else:
65
+ break
62
66
  # 首先需要判断是不是自习课
63
67
  # [kotonebot-resource\sprites\jp\in_purodyuusu\screenshot_study_self_study.png]
64
68
  if image.find_multi([
@@ -101,8 +105,11 @@ def enter_study():
101
105
  device.click(target_btn)
102
106
  else:
103
107
  device.double_click(target_btn)
104
- while fast_acquisitions() is None:
105
- logger.info("Waiting for acquisitions finished.")
108
+ for _ in Loop():
109
+ if fast_acquisitions() is None:
110
+ logger.info("Waiting for acquisitions finished.")
111
+ else:
112
+ break
106
113
  logger.info("授業 completed.")
107
114
 
108
115
 
@@ -119,12 +126,14 @@ def enter_allowance():
119
126
  logger.info("Double clicking on 活動支給.")
120
127
  device.double_click(image.expect(R.InPurodyuusu.ButtonTextAllowance), interval=1)
121
128
  # 等待进入页面
122
- while not image.find(R.InPurodyuusu.IconTitleAllowance):
123
- logger.debug("Waiting for 活動支給 screen.")
124
- fast_acquisitions()
129
+ for _ in Loop():
130
+ if not image.find(R.InPurodyuusu.IconTitleAllowance):
131
+ logger.debug("Waiting for 活動支給 screen.")
132
+ fast_acquisitions()
133
+ else:
134
+ break
125
135
  # 领取奖励
126
- it = Interval()
127
- while True:
136
+ for _ in Loop():
128
137
  # TODO: 检测是否在行动页面应当单独一个函数
129
138
  if image.find_multi([
130
139
  R.InPurodyuusu.TextPDiary, # 普通周
@@ -138,7 +147,6 @@ def enter_allowance():
138
147
  continue
139
148
  if fast_acquisitions() is not None:
140
149
  continue
141
- it.wait()
142
150
  logger.info("活動支給 completed.")
143
151
 
144
152
  # TODO: 将逻辑用循环改写
@@ -156,10 +164,13 @@ def enter_consult():
156
164
  device.double_click(image.expect(R.InPurodyuusu.ButtonIconConsult), interval=1)
157
165
 
158
166
  # 等待进入页面
159
- while not image.find(R.InPurodyuusu.IconTitleConsult):
160
- device.screenshot()
161
- logger.debug("Waiting for 相談 screen.")
162
- fast_acquisitions()
167
+ for _ in Loop():
168
+ if not image.find(R.InPurodyuusu.IconTitleConsult):
169
+ device.screenshot()
170
+ logger.debug("Waiting for 相談 screen.")
171
+ fast_acquisitions()
172
+ else:
173
+ break
163
174
  # # 尝试固定购买第一个物品
164
175
  # device.click(R.InPurodyuusu.PointConsultFirstItem)
165
176
  # sleep(0.5)
@@ -179,15 +190,12 @@ def enter_consult():
179
190
  # dialog.yes()
180
191
  device.click(R.InPurodyuusu.PointConsultFirstItem)
181
192
  sleep(0.3)
182
- it = Interval()
183
193
  wait_purchase_cd = Countdown(sec=5)
184
194
  exit_cd = Countdown(sec=5)
185
195
  purchase_clicked = False
186
196
  purchase_confirmed = False
187
197
  exit_clicked = False
188
- while True:
189
- device.screenshot()
190
- it.wait()
198
+ for _ in Loop():
191
199
  if wait_purchase_cd.expired():
192
200
  # 等待购买确认对话框超时后直接认为购买完成
193
201
  purchase_confirmed = True
@@ -268,9 +276,12 @@ def enter_outing():
268
276
  logger.info("Double clicking on おでかけ.")
269
277
  device.double_click(image.expect(R.InPurodyuusu.ButtonIconOuting))
270
278
  # 等待进入页面
271
- while not image.find(R.InPurodyuusu.TitleIconOuting):
272
- logger.debug("Waiting for おでかけ screen.")
273
- fast_acquisitions()
279
+ for _ in Loop():
280
+ if not image.find(R.InPurodyuusu.TitleIconOuting):
281
+ logger.debug("Waiting for おでかけ screen.")
282
+ fast_acquisitions()
283
+ else:
284
+ break
274
285
  # 固定选中第二个选项
275
286
  # TODO: 可能需要二次处理外出事件
276
287
  # [kotonebot-resource\sprites\jp\in_purodyuusu\screenshot_outing.png]
@@ -284,9 +295,7 @@ def enter_outing():
284
295
  device.click(target_btn)
285
296
  else:
286
297
  device.double_click(target_btn)
287
- it = Interval()
288
- while True:
289
- device.screenshot()
298
+ for _ in Loop():
290
299
  if at_action_scene():
291
300
  break
292
301
  elif fast_acquisitions():
@@ -296,7 +305,6 @@ def enter_outing():
296
305
  logger.info("AP max out dialog found. Click to continue.")
297
306
  device.click()
298
307
  sleep(0.1)
299
- it.wait()
300
308
 
301
309
  logger.info("おでかけ completed.")
302
310