ksaa 2025.6.8.0__py3-none-any.whl → 2025.6.23.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 (196) hide show
  1. kotonebot/backend/context/context.py +31 -25
  2. kotonebot/backend/debug/server.py +0 -2
  3. kotonebot/backend/dispatch.py +1 -17
  4. kotonebot/backend/loop.py +277 -0
  5. kotonebot/client/__init__.py +4 -1
  6. kotonebot/client/device.py +23 -21
  7. kotonebot/client/host/__init__.py +2 -1
  8. kotonebot/client/host/custom.py +26 -3
  9. kotonebot/client/host/leidian_host.py +22 -11
  10. kotonebot/client/host/mumu12_host.py +25 -3
  11. kotonebot/client/host/protocol.py +40 -18
  12. kotonebot/client/implements/__init__.py +6 -0
  13. kotonebot/client/implements/adb.py +67 -7
  14. kotonebot/client/implements/adb_raw.py +12 -5
  15. kotonebot/client/implements/remote_windows.py +20 -18
  16. kotonebot/client/implements/uiautomator2.py +8 -0
  17. kotonebot/client/implements/windows.py +38 -15
  18. kotonebot/client/protocol.py +13 -0
  19. kotonebot/client/registration.py +89 -0
  20. kotonebot/config/base_config.py +5 -1
  21. kotonebot/debug_entry.py +7 -2
  22. kotonebot/kaa/clear_logs.py +0 -3
  23. kotonebot/kaa/game_ui/common.py +4 -7
  24. kotonebot/kaa/game_ui/dialog.py +24 -4
  25. kotonebot/kaa/game_ui/idols_overview.py +28 -12
  26. kotonebot/kaa/game_ui/primary_button.py +55 -0
  27. kotonebot/kaa/game_ui/scrollable.py +0 -5
  28. kotonebot/kaa/main/cli.py +9 -4
  29. kotonebot/kaa/main/dmm_host.py +33 -7
  30. kotonebot/kaa/main/kaa.py +113 -41
  31. kotonebot/kaa/metadata.py +15 -0
  32. kotonebot/kaa/resources/__pycache__/__init__.cpython-310.pyc +0 -0
  33. kotonebot/kaa/resources/game.db +0 -0
  34. kotonebot/kaa/resources/game_ver.txt +0 -0
  35. kotonebot/kaa/resources/idol_cards/i_card-skin-kllj-3-012_0.png +0 -0
  36. kotonebot/kaa/resources/idol_cards/i_card-skin-kllj-3-012_1.png +0 -0
  37. kotonebot/kaa/resources/idol_cards/i_card-skin-ssmk-3-012_0.png +0 -0
  38. kotonebot/kaa/resources/idol_cards/i_card-skin-ssmk-3-012_1.png +0 -0
  39. kotonebot/kaa/sprites/24e99232-9434-457f-a9a0-69dd7ecf675f.png +0 -0
  40. kotonebot/kaa/sprites/2ededcf5-1d80-4e2a-9c83-2a31998331ce.png +0 -0
  41. kotonebot/kaa/sprites/3b473fe6-e147-477f-b088-9b8fb042a4f6.png +0 -0
  42. kotonebot/kaa/sprites/55f7db71-0a18-4b3d-b847-57959b8d2e32.png +0 -0
  43. kotonebot/kaa/sprites/6cd80be8-c9b3-4ba5-bf17-3ffc9b000743.png +0 -0
  44. kotonebot/kaa/sprites/74ec3510-583d-4a76-ac69-38480fbf1387.png +0 -0
  45. kotonebot/kaa/sprites/a0bd6a5f-784d-4f0a-9d66-10f4b80c8d3e.png +0 -0
  46. kotonebot/kaa/sprites/d3424d31-0502-4623-996e-f0194e5085ce.png +0 -0
  47. kotonebot/kaa/sprites/e6b45405-cd9f-4c6e-a9f1-6ec953747c65.png +0 -0
  48. kotonebot/kaa/sprites/f5c16d2f-ebc5-4617-9b96-971696af7c52.png +0 -0
  49. kotonebot/kaa/tasks/R.py +157 -135
  50. kotonebot/kaa/tasks/produce/in_purodyuusu.py +0 -4
  51. kotonebot/kaa/tasks/produce/non_lesson_actions.py +0 -3
  52. kotonebot/kaa/tasks/produce/produce.py +119 -70
  53. kotonebot/kaa/tasks/start_game.py +7 -6
  54. kotonebot/kaa/util/paths.py +6 -1
  55. kotonebot/tools/mirror.py +23 -13
  56. kotonebot/util.py +32 -0
  57. {ksaa-2025.6.8.0.dist-info → ksaa-2025.6.23.0.dist-info}/METADATA +1 -1
  58. {ksaa-2025.6.8.0.dist-info → ksaa-2025.6.23.0.dist-info}/RECORD +194 -179
  59. kotonebot/client/factory.py +0 -92
  60. kotonebot/kaa/sprites/38b8f119-8de1-49bf-8a5f-a44371de4569.png +0 -0
  61. /kotonebot/kaa/sprites/{321b54c8-c69b-4437-931d-655882dabeed.png → 0235ae3d-1741-4a81-8053-f60bc395ee85.png} +0 -0
  62. /kotonebot/kaa/sprites/{4d6c198a-0e34-4c80-86d1-7789b2082d64.png → 038c69e6-7cb0-4c8d-99da-b537e48a86b7.png} +0 -0
  63. /kotonebot/kaa/sprites/{4bd66b38-78d3-4a27-816b-d315039a8bb6.png → 080b3cf5-ce35-4382-9bfa-d6a12efb09b3.png} +0 -0
  64. /kotonebot/kaa/sprites/{ecd44a4a-e1ca-4a86-ae0d-2306a672613f.png → 09fb5e41-6caa-4246-a415-8317b12d8d81.png} +0 -0
  65. /kotonebot/kaa/sprites/{4f58031c-36b9-4baf-bccf-11c05d83bd19.png → 0a6c6b1e-7a80-428e-a483-1858bfb8ac59.png} +0 -0
  66. /kotonebot/kaa/sprites/{e41bb5df-164d-4760-9db6-d5d5d763bb5f.png → 0ad2f603-a3ad-4a92-a398-c411145fd8e9.png} +0 -0
  67. /kotonebot/kaa/sprites/{c1b1125f-542b-4e63-9c86-5d2e35a89a10.png → 0d4b669e-5e43-4458-b65a-5565797335ae.png} +0 -0
  68. /kotonebot/kaa/sprites/{74521b6f-de5e-4ba8-a3c9-c6ba01070498.png → 0fbcb3f6-9ca0-43c7-975b-e7c15c26c897.png} +0 -0
  69. /kotonebot/kaa/sprites/{7b3c6860-fbbe-48aa-aadf-8062fa88f1fe.png → 15465879-eb84-4ca6-ae0f-d3c5ac71e723.png} +0 -0
  70. /kotonebot/kaa/sprites/{309105d4-073a-47c9-8c5c-d593aa497723.png → 1639278d-67e0-4452-a2b5-ec4cf4011f42.png} +0 -0
  71. /kotonebot/kaa/sprites/{157dd58d-e319-4e0c-a37a-638e1a31c60b.png → 17414e9e-b046-49e0-9596-cad1f4673a9e.png} +0 -0
  72. /kotonebot/kaa/sprites/{05ff5efd-0f76-47ce-bc89-237266bc17c0.png → 17a8b0a5-5b71-4612-8a68-16c51f03c71b.png} +0 -0
  73. /kotonebot/kaa/sprites/{54bb5fcf-be61-4af8-bb19-a3c5113cf9e1.png → 1aaceb21-dc5c-4a58-96d3-d2c66b2fb357.png} +0 -0
  74. /kotonebot/kaa/sprites/{1f8f8c46-43ec-4449-be9f-2e96da11da1e.png → 1aae0ab3-f619-47e0-8bf6-3d3791f7d445.png} +0 -0
  75. /kotonebot/kaa/sprites/{b1e88fda-434a-4d06-8891-883a7beafa12.png → 1b6be6dd-2711-441a-9fa6-3281a6ad10c7.png} +0 -0
  76. /kotonebot/kaa/sprites/{ef39804e-8d2d-40f6-8d13-bd2877d1353a.png → 1bb00a74-2fdc-4973-84ae-dc1edee15f81.png} +0 -0
  77. /kotonebot/kaa/sprites/{804a4b05-1ca3-4915-bf23-a66ccdc34404.png → 1ccdcacf-4f7d-442c-8e2f-09aa7fe14e56.png} +0 -0
  78. /kotonebot/kaa/sprites/{6a7d061e-682b-42c1-97d5-121c52921e8b.png → 1d5f7454-672d-4e87-a368-ec4bb32f9b1f.png} +0 -0
  79. /kotonebot/kaa/sprites/{624555b9-31e3-46a3-8078-55619eaa40b9.png → 1f2981d8-5eb6-4332-aa9b-17f4db2d4163.png} +0 -0
  80. /kotonebot/kaa/sprites/{ff77d221-8444-4d0f-8c93-0223a97e2a98.png → 25910d8e-d57f-409f-b0be-ee68c5af4920.png} +0 -0
  81. /kotonebot/kaa/sprites/{fbd816df-7ae6-40a4-b4d4-5708f5ba4a7c.png → 264e056f-3bcc-4b16-94d4-f767c78ab6f5.png} +0 -0
  82. /kotonebot/kaa/sprites/{0bbfb5b0-f0f7-4ad9-86f7-a2adb01a6371.png → 26580772-ff20-4dcf-8496-f939e0f2890d.png} +0 -0
  83. /kotonebot/kaa/sprites/{0a430873-8c12-4ce2-a5de-ab9790c08344.png → 29cb7b0f-5684-4516-8fae-4439f7f28e08.png} +0 -0
  84. /kotonebot/kaa/sprites/{52620946-b92c-42c7-9fcc-0ff13388fd0d.png → 2d145ade-b926-4276-b872-baec4ef78308.png} +0 -0
  85. /kotonebot/kaa/sprites/{7e8164f6-a9e4-4600-b776-77b35a490933.png → 2dd34393-ee6f-4b19-8a9c-76556d1bd7d7.png} +0 -0
  86. /kotonebot/kaa/sprites/{550fc45d-22c0-4a7c-a324-2c4ff107ab39.png → 2e00ac54-d23a-4d51-82f2-829c012552a6.png} +0 -0
  87. /kotonebot/kaa/sprites/{d58d9987-b1ca-4669-a9a6-9a0fd1847fa6.png → 2f74b04f-1992-4584-8dc6-e789b081ddc3.png} +0 -0
  88. /kotonebot/kaa/sprites/{668002b6-805b-467b-a703-203fb75444f4.png → 302fde7d-de85-44c7-ba57-fe4b5f6db5fa.png} +0 -0
  89. /kotonebot/kaa/sprites/{80fb515c-4323-422d-a24c-80a3bf702f1d.png → 3cc9685d-6347-4114-9d39-7683c2dc9df6.png} +0 -0
  90. /kotonebot/kaa/sprites/{869b1771-b2ce-4872-ab75-2157c47c5b13.png → 42d8b5dc-ef27-4411-b8b5-d981e562990b.png} +0 -0
  91. /kotonebot/kaa/sprites/{ba955365-1328-4018-83a2-bfe818f8f172.png → 448ea37d-a10d-4102-ac9f-a58403ee8914.png} +0 -0
  92. /kotonebot/kaa/sprites/{111a03e6-e401-4ad5-b5dc-d5124e8f1ab0.png → 4a310bdd-0a7d-4669-9d57-6ae69bc8f022.png} +0 -0
  93. /kotonebot/kaa/sprites/{05bfd235-2077-479a-8c43-11fb49316000.png → 4b20b364-5f5f-4b34-960e-b0cfd08b1662.png} +0 -0
  94. /kotonebot/kaa/sprites/{cd4cbd7b-df80-45bb-a053-cc333a806934.png → 4e8f3e59-edfa-4523-939d-bc46988fc909.png} +0 -0
  95. /kotonebot/kaa/sprites/{67a81c23-4ce4-45e3-bfa8-1136fb14b831.png → 4eaa5db2-d624-4df4-b2e4-01f72755f1a4.png} +0 -0
  96. /kotonebot/kaa/sprites/{705d9ecf-faf8-40f4-b701-637cec822c1e.png → 5152e3fa-079c-4592-8df7-656101694df8.png} +0 -0
  97. /kotonebot/kaa/sprites/{4e21f02d-d5e1-49eb-946a-8edc74d0f1f7.png → 52f7c8b1-af88-43c5-a999-de4da3caa03a.png} +0 -0
  98. /kotonebot/kaa/sprites/{f74fc514-61f1-4068-bdf4-754fcaf8ac89.png → 534d1310-3503-46d3-8ecd-426d9bcf183e.png} +0 -0
  99. /kotonebot/kaa/sprites/{9bb1a400-935a-4c5e-838b-fca502c49aba.png → 5868ebfb-5e61-4ac6-b270-acb1e89b738f.png} +0 -0
  100. /kotonebot/kaa/sprites/{82a5e224-a161-43d4-8e15-2946480336dd.png → 58a5f51d-d1a3-480b-8dde-ecead34d9f02.png} +0 -0
  101. /kotonebot/kaa/sprites/{c1ad996a-925e-41b5-b26c-d48b8ded21d2.png → 5d3d61e9-bf13-4668-b0c7-fed730ea2ed6.png} +0 -0
  102. /kotonebot/kaa/sprites/{ad784a29-f0e2-4037-976b-45143db8441c.png → 5dd0cc39-4102-4f0f-8ad3-342bbf825977.png} +0 -0
  103. /kotonebot/kaa/sprites/{4a235eaa-46f1-4f71-b54d-ada0ade44572.png → 5ee8e9a8-b133-4ab7-a52c-e7e4e1d1ce7b.png} +0 -0
  104. /kotonebot/kaa/sprites/{09433024-3dfe-4fcb-9d67-cf442b58f31b.png → 60be53a6-98e9-4fc6-9285-85506dc0e335.png} +0 -0
  105. /kotonebot/kaa/sprites/{90a9c819-ee6b-4b3e-a0e4-ce484c6e413d.png → 6114d53e-dd69-4cee-82a7-7e43b338ff8d.png} +0 -0
  106. /kotonebot/kaa/sprites/{4c72f39e-1182-4479-867f-8207744ee4fd.png → 6156116e-56dd-4b41-a6de-ccec55dab7c8.png} +0 -0
  107. /kotonebot/kaa/sprites/{559df9b9-e74d-45af-a300-77d3424e69c6.png → 65d2a5e5-48aa-4390-bb87-bfd8e044e4f6.png} +0 -0
  108. /kotonebot/kaa/sprites/{c0fc7de5-b842-4c70-9cf2-89d833bfe7a6.png → 66172bc0-3869-4a48-a26d-0dc3fa404ab8.png} +0 -0
  109. /kotonebot/kaa/sprites/{fdfecda8-2fe0-487e-b5fe-6358274bb9ff.png → 66678caa-7b25-4ff7-8c3a-017f67279349.png} +0 -0
  110. /kotonebot/kaa/sprites/{f8cbb089-a63e-4e40-9238-26d14da2c459.png → 68838f92-5916-424e-a37e-47e0b3834eb3.png} +0 -0
  111. /kotonebot/kaa/sprites/{fb927b92-7a82-4869-8c61-581d49cd7201.png → 694d3a07-9697-4bda-984d-967779d530f7.png} +0 -0
  112. /kotonebot/kaa/sprites/{db94ffb7-a09d-4a51-b420-b930851c9db4.png → 69b022a8-e42f-4985-bd16-b4a530ad8a20.png} +0 -0
  113. /kotonebot/kaa/sprites/{13535ecd-bdf5-4ff7-aa2c-6ecb20fe9c06.png → 6aa34982-e7ab-4001-808f-8c5cf370d087.png} +0 -0
  114. /kotonebot/kaa/sprites/{572077d4-7ee2-449a-b4f0-66239b0d7aff.png → 7516c9a1-87ec-4d2f-ac5e-40d1aec27104.png} +0 -0
  115. /kotonebot/kaa/sprites/{d7f604a6-c663-44db-b1d3-c9792eb3daa4.png → 7aa2435c-da90-4d52-b831-88dbec57dde9.png} +0 -0
  116. /kotonebot/kaa/sprites/{56a8c0ca-4659-4de2-9bce-55ce86a40d75.png → 7b7dad18-a838-4267-b3c7-6ab43b8361f0.png} +0 -0
  117. /kotonebot/kaa/sprites/{1f9165e6-77ee-403e-9b76-99c114527dbb.png → 7cabdf91-2f15-4991-b165-eb9cdd557af6.png} +0 -0
  118. /kotonebot/kaa/sprites/{5ca50448-cc21-499a-a685-c5e1c4240c48.png → 7f6cb60e-6ab3-4db4-86e1-8558250062a4.png} +0 -0
  119. /kotonebot/kaa/sprites/{a82e06fb-a02e-4be5-a7b4-4d2758914fcf.png → 83acbca8-3567-4262-a1e7-50f158348d45.png} +0 -0
  120. /kotonebot/kaa/sprites/{b3d1f8d4-1393-4206-b78e-a5495d8fb930.png → 83cf48ba-d1af-4674-a52e-6bb80a626db7.png} +0 -0
  121. /kotonebot/kaa/sprites/{22d5a7d5-59a0-4137-b02e-1a7af86d4250.png → 83f17b06-2792-4035-bc90-1800279ae131.png} +0 -0
  122. /kotonebot/kaa/sprites/{1bfce48a-b151-406e-a6f5-863cb68cbbf2.png → 84bb4986-0295-4a45-9486-86e31fcdf1f1.png} +0 -0
  123. /kotonebot/kaa/sprites/{73f4204e-8281-47cc-9dce-6bb8280c4ce5.png → 8b9c115b-d4ce-492e-88cb-08bd01c43570.png} +0 -0
  124. /kotonebot/kaa/sprites/{f0786a26-81b5-4e76-b577-db70ab3fab50.png → 8e48af2b-c083-4480-a27c-c59c31a7ede1.png} +0 -0
  125. /kotonebot/kaa/sprites/{c7aa3f89-8a5e-4685-9297-4fc892bfdd81.png → 8f1e5644-1079-44b1-9d44-97bae3817bc5.png} +0 -0
  126. /kotonebot/kaa/sprites/{cc829886-23e8-4d47-b4c4-37ca20381180.png → 90def878-cd6e-46e5-9dc4-9c92dd904b80.png} +0 -0
  127. /kotonebot/kaa/sprites/{d8136469-6d73-4f82-a79c-fee83c3e93a8.png → 920a3974-4875-4d2b-bbac-caa175c03ce0.png} +0 -0
  128. /kotonebot/kaa/sprites/{c4f28132-4aba-40ba-be6c-b1a31d014635.png → 94433cf2-dd04-4b74-ae14-e5e3d945f579.png} +0 -0
  129. /kotonebot/kaa/sprites/{ad8ee599-88a8-429c-8982-99086e552dcc.png → 969eb98c-f761-4007-b8bd-2b3fb8d1f08c.png} +0 -0
  130. /kotonebot/kaa/sprites/{31a52dc8-b7fb-4ff6-a261-eb90a918603c.png → 97adee05-1586-4589-93e6-c6c3a9cdae9d.png} +0 -0
  131. /kotonebot/kaa/sprites/{02e0aa0d-4094-4bdc-8625-1a063733615b.png → 9aef1aa8-41e1-42a7-83ad-b4e212ee3976.png} +0 -0
  132. /kotonebot/kaa/sprites/{e2fae2a4-bb19-4f49-b382-47e504ec26d3.png → 9c7f1bcc-0bc8-454b-95fb-56a803030771.png} +0 -0
  133. /kotonebot/kaa/sprites/{8e8a0b57-0231-4ed6-958e-3196f7c9ca7b.png → 9cd7e1f1-13c4-471e-abee-223ffd9126cb.png} +0 -0
  134. /kotonebot/kaa/sprites/{5bf00cba-9aab-4ffe-b20b-8f5e74279276.png → 9d5dd50c-3341-41a4-a3dd-ccc00edcf201.png} +0 -0
  135. /kotonebot/kaa/sprites/{e866d8b1-4f61-45bf-8170-5229f53c047a.png → 9f99b0e9-8cc0-4877-8f8a-d26257ef5386.png} +0 -0
  136. /kotonebot/kaa/sprites/{1a3d18a4-7d91-4182-9e40-e60d73fed365.png → a1853223-d6b9-4660-af4e-91e59bdddc3c.png} +0 -0
  137. /kotonebot/kaa/sprites/{ed5d2bf3-405c-4165-88d0-9f8a4be968c6.png → a1bba683-a740-4eaf-8c37-3b1042b963b0.png} +0 -0
  138. /kotonebot/kaa/sprites/{910d307b-6461-4950-badb-509975d0b797.png → a1cf80ee-64bf-4d54-a7db-ffadf3c97026.png} +0 -0
  139. /kotonebot/kaa/sprites/{645744c4-3bbf-4ea2-8f46-4725fff874b3.png → a3b15425-0bfd-4668-a3a9-2ab64da8505f.png} +0 -0
  140. /kotonebot/kaa/sprites/{7cea265a-fca5-43d0-b2da-067c8fff4d72.png → a4075991-98da-4d06-bcde-28054cd124d2.png} +0 -0
  141. /kotonebot/kaa/sprites/{89c0e675-3fd4-456a-8ae7-3bfb248b7281.png → a7da51c2-8444-4770-a16b-b6543e40197f.png} +0 -0
  142. /kotonebot/kaa/sprites/{5be4f6c7-2baa-42f3-a5a5-99ca0830cc30.png → a8b3fdce-9e4a-495c-839e-0142f67fee69.png} +0 -0
  143. /kotonebot/kaa/sprites/{72c1804f-db8c-40fa-bc79-6533f2861a5d.png → aa3b717f-67f8-445f-a6bf-b89f7200d95b.png} +0 -0
  144. /kotonebot/kaa/sprites/{7736a171-9221-4cda-8288-908997abeff2.png → abcc709c-1f4d-4832-a063-eafbad94ac31.png} +0 -0
  145. /kotonebot/kaa/sprites/{12e8d3f1-494a-46f5-908f-f621a0c57ec6.png → ad172750-d1a6-4a25-8ce8-9483f4b5affb.png} +0 -0
  146. /kotonebot/kaa/sprites/{a33ae1c3-ac69-4783-977e-9f0f1b1a2f8d.png → aefdec38-e3b6-4762-aed8-33107686ddac.png} +0 -0
  147. /kotonebot/kaa/sprites/{22ee3f1b-ddcb-48bf-85dd-8423f85e3199.png → b01c25d2-21bf-4db9-b5b2-ec35817f1b04.png} +0 -0
  148. /kotonebot/kaa/sprites/{5edef075-4843-4dc9-840f-ae445cbe0730.png → b1e7f24e-f246-406e-9073-58e2f3e4e819.png} +0 -0
  149. /kotonebot/kaa/sprites/{a105d17d-d44c-4798-aeff-70808c91cb47.png → b5d4265c-82e0-470d-a48e-8aa4edbdef5a.png} +0 -0
  150. /kotonebot/kaa/sprites/{48c257f8-3583-49f7-b01a-ba7d251086ac.png → b65724b4-ec8f-48a9-9ab2-e7ce5b8f35b2.png} +0 -0
  151. /kotonebot/kaa/sprites/{469006bc-a011-46e4-bcde-992be888456e.png → b8aada91-eedd-4c53-99f3-f903d547235e.png} +0 -0
  152. /kotonebot/kaa/sprites/{e5d15c50-45ee-4de9-8b97-4630cbd8f01a.png → ba759205-ce99-4417-8cab-d32fe55dff4c.png} +0 -0
  153. /kotonebot/kaa/sprites/{afa0f85f-dcb7-48a1-a1ae-624456b9b65c.png → bb0ae68d-44d5-47c6-91dd-a529bc34225b.png} +0 -0
  154. /kotonebot/kaa/sprites/{79bc56c5-eae6-4389-9116-4a9e182d6bf3.png → bed9575d-ccad-4f4e-825e-47b2a9cb0925.png} +0 -0
  155. /kotonebot/kaa/sprites/{f9b2f64d-f829-4b13-9704-c5f00fb956be.png → bfec58df-2628-454f-92aa-769cad186448.png} +0 -0
  156. /kotonebot/kaa/sprites/{9c1fa1d4-2ae5-4093-abaa-cebb51135721.png → c25c7ce5-ad8d-4b2c-83eb-ae6d4871a6c3.png} +0 -0
  157. /kotonebot/kaa/sprites/{05f8f996-a38a-45d9-8ff9-720b6c4fd599.png → c3ec61aa-f62e-46fd-b359-48864ea7a150.png} +0 -0
  158. /kotonebot/kaa/sprites/{826bf80a-112e-4356-9111-4b7e692ccc82.png → c484ca57-6b19-46b5-a107-1805a7488d48.png} +0 -0
  159. /kotonebot/kaa/sprites/{cd8d3d55-f102-419e-a6fd-2ad5ecc4fd2e.png → c571e1c0-ff85-4b2e-97ed-97d33b8d92e3.png} +0 -0
  160. /kotonebot/kaa/sprites/{0decaa6a-b9a9-4d9b-829a-0fc1f67538b4.png → c5e16f75-9b5a-4853-a144-275f3d20c186.png} +0 -0
  161. /kotonebot/kaa/sprites/{d747239f-7620-4f23-9ac7-cf2d34889266.png → c5ea3dfd-6761-466e-b44c-86592ef05323.png} +0 -0
  162. /kotonebot/kaa/sprites/{695f8d57-b2c9-4a6d-9ae9-1b49ee3eb22a.png → ca2adfb8-1e88-4a31-b3cc-1f70568ce4a3.png} +0 -0
  163. /kotonebot/kaa/sprites/{333fe6d3-0be7-40fb-a2a3-364f98758f2a.png → cb24b3df-1ec3-4ffd-95f1-ca4b0dd5b7da.png} +0 -0
  164. /kotonebot/kaa/sprites/{0bab7080-9a37-4c27-9821-8df36d49b678.png → cdbbb5ba-5117-488a-8172-48cfc92c14c6.png} +0 -0
  165. /kotonebot/kaa/sprites/{a3c12040-2b11-4038-b830-215fb7b6f359.png → cf66ae12-48bc-4512-a988-0e5de337c76d.png} +0 -0
  166. /kotonebot/kaa/sprites/{994aa6a6-0189-4a79-8125-56136973b581.png → d1699baa-467b-46d1-9276-aae78fe8f589.png} +0 -0
  167. /kotonebot/kaa/sprites/{48d2f007-8c1b-43fc-bd3f-f0b10d2a0c88.png → d3e6e2e9-c5b5-463f-98f4-de72c9320d9d.png} +0 -0
  168. /kotonebot/kaa/sprites/{b2f7a430-5777-4861-8435-5419394e5ee8.png → d4c47cc7-5b3e-4c3e-8e80-78cb94e7eed9.png} +0 -0
  169. /kotonebot/kaa/sprites/{fd610de1-b023-4747-8c1b-72f89b1c5647.png → d5d854fc-1b87-43d4-b32d-66eccb66fa41.png} +0 -0
  170. /kotonebot/kaa/sprites/{c2667677-cbff-4dd4-a401-e0963e7224f4.png → d60a395b-d907-416a-b091-36bfee4948b3.png} +0 -0
  171. /kotonebot/kaa/sprites/{43d65b3f-bbae-4e29-a7bf-539379c1b072.png → dad4ff8c-07f4-4b07-abd3-5d02bbcc4562.png} +0 -0
  172. /kotonebot/kaa/sprites/{b44f5e5b-e999-4427-8a9f-f76c6485f4a5.png → dbd537c7-d1d3-4d64-9ccd-43dd4519bedd.png} +0 -0
  173. /kotonebot/kaa/sprites/{2f81e70a-f2af-420f-9b6b-6338c391911f.png → dde03640-6c3a-4b13-a783-f672816bfec4.png} +0 -0
  174. /kotonebot/kaa/sprites/{da3e7cee-d77b-4e62-b703-ed257706dd39.png → df97421e-4b74-430e-b3d1-ed9bac6918a7.png} +0 -0
  175. /kotonebot/kaa/sprites/{0439399f-5fca-43f9-a105-99342ff04d2e.png → dfb14c98-f672-4906-80bd-d2a18bdd62cd.png} +0 -0
  176. /kotonebot/kaa/sprites/{03458cf9-8ab0-4908-9a56-9c5c7e06bc9b.png → e1e0d751-9006-4fa4-a933-4c0dc5e1f3d2.png} +0 -0
  177. /kotonebot/kaa/sprites/{f65a4495-f044-44de-bf0d-c869e637d5d3.png → e394ff91-09d3-41e1-bbf5-bc42a71a623b.png} +0 -0
  178. /kotonebot/kaa/sprites/{de709296-e411-465f-86fc-5daf5ca83cef.png → e5259dfb-3a49-4cfc-9f89-b42958ce6eec.png} +0 -0
  179. /kotonebot/kaa/sprites/{371a3192-101c-45ef-9da4-2ed389770c0f.png → e5eeb9af-8003-4981-bf56-2e32e76cec5d.png} +0 -0
  180. /kotonebot/kaa/sprites/{73af305f-840f-4325-abae-b3519fba672a.png → e9c45a73-2011-4584-87b7-c4e566eba87f.png} +0 -0
  181. /kotonebot/kaa/sprites/{7a479871-547e-4098-9cdd-6c9bb9f7449a.png → eae83523-e58c-4db9-a356-4335a5da3dc8.png} +0 -0
  182. /kotonebot/kaa/sprites/{e7022542-4317-4a61-8098-f3f733d8400e.png → ed6d3e3d-0f04-4fa4-b0f9-fdbf324649f6.png} +0 -0
  183. /kotonebot/kaa/sprites/{24cd42fd-bb3b-4fc6-b40d-d3e3e36fe9f1.png → efb28e1d-7b52-4e20-aec5-117c798b7fbe.png} +0 -0
  184. /kotonebot/kaa/sprites/{6bf5556a-8f4e-41d7-8ab5-d683ad1b47a8.png → f025027f-daa0-4943-8395-5d7d44cc7f15.png} +0 -0
  185. /kotonebot/kaa/sprites/{b3e72de2-e103-49a3-b0f2-8593cff87c4e.png → f12c2b0b-8273-4197-a8c6-2a8ef2788a9b.png} +0 -0
  186. /kotonebot/kaa/sprites/{d22ca9e0-001d-43d6-a557-1c76c5a27c81.png → f528ea0e-1e55-4e41-844f-bb1db9185ef8.png} +0 -0
  187. /kotonebot/kaa/sprites/{b604e25d-680a-4e02-a012-2e593b5bc276.png → f611bbd9-c062-4989-96a4-65ff6c59673c.png} +0 -0
  188. /kotonebot/kaa/sprites/{b1d1dfab-51f5-4ae9-b718-cdf46774c0ff.png → f6bfbf6a-6e53-4563-9345-3f3756d6ea9a.png} +0 -0
  189. /kotonebot/kaa/sprites/{7344e180-251b-465a-a8cf-974477f7ad44.png → f72bd3d6-850d-4190-9775-938f474d263c.png} +0 -0
  190. /kotonebot/kaa/sprites/{96cf0633-6531-499b-b1cc-6670ab710293.png → f8eec9b2-55ca-4195-b098-a5393d02a98a.png} +0 -0
  191. /kotonebot/kaa/sprites/{92b7d830-3db5-434e-b156-0ac855db480d.png → faf069e1-f623-47c1-b879-cfa246fbc7df.png} +0 -0
  192. /kotonebot/kaa/sprites/{a00fcf77-2800-4f7d-993d-4636b36045bb.png → faf360e8-7845-4fcf-b0a6-0f5f93c050f1.png} +0 -0
  193. {ksaa-2025.6.8.0.dist-info → ksaa-2025.6.23.0.dist-info}/WHEEL +0 -0
  194. {ksaa-2025.6.8.0.dist-info → ksaa-2025.6.23.0.dist-info}/entry_points.txt +0 -0
  195. {ksaa-2025.6.8.0.dist-info → ksaa-2025.6.23.0.dist-info}/licenses/LICENSE +0 -0
  196. {ksaa-2025.6.8.0.dist-info → ksaa-2025.6.23.0.dist-info}/top_level.txt +0 -0
@@ -4,15 +4,14 @@ from typing import Optional, Literal
4
4
  from typing_extensions import assert_never
5
5
 
6
6
  from kotonebot.ui import user
7
- from kotonebot.util import Countdown, Interval
8
- from kotonebot.backend.context.context import wait
9
- from kotonebot.backend.dispatch import SimpleDispatcher
10
-
11
7
  from kotonebot.kaa.tasks import R
12
8
  from kotonebot.kaa.common import conf
13
9
  from kotonebot.kaa.game_ui import dialog
14
10
  from ..actions.scenes import at_home, goto_home
15
- from kotonebot.kaa.game_ui.idols_overview import locate_idol
11
+ from kotonebot.backend.loop import Loop, StatedLoop
12
+ from kotonebot.util import Countdown, Interval, Throttler
13
+ from kotonebot.kaa.game_ui.primary_button import find_button
14
+ from kotonebot.kaa.game_ui.idols_overview import locate_idol, match_idol
16
15
  from ..produce.in_purodyuusu import hajime_pro, hajime_regular, hajime_master, resume_pro_produce, resume_regular_produce, \
17
16
  resume_master_produce
18
17
  from kotonebot import device, image, ocr, task, action, sleep, contains, regex
@@ -193,10 +192,15 @@ def do_produce(
193
192
  前置条件:可导航至首页的任意页面\n
194
193
  结束状态:游戏首页\n
195
194
 
196
- :param idol: 要培育的偶像。如果为 None,则使用配置文件中的偶像。
195
+ :param memory_set_index: 回忆编成编号。
196
+ :param idol_skin_id: 要培育的偶像。如果为 None,则使用配置文件中的偶像。
197
197
  :param mode: 培育模式。
198
198
  :return: 是否因为 AP 不足而跳过本次培育。
199
+ :raises ValueError: 如果 `memory_set_index` 不在 [1, 10] 的范围内。
199
200
  """
201
+ if memory_set_index is not None and not 1 <= memory_set_index <= 10:
202
+ raise ValueError('`memory_set_index` must be in range [1, 10].')
203
+
200
204
  if not at_home():
201
205
  goto_home()
202
206
 
@@ -208,16 +212,28 @@ def do_produce(
208
212
  return True
209
213
 
210
214
  # 0. 进入培育页面
211
- mode_text = mode.upper()
212
- if mode_text == 'MASTER':
213
- mode_text = 'MASTER|MIASTER'
214
- logger.info(f'Enter produce page. Mode: {mode_text}')
215
- result = (SimpleDispatcher('enter_produce')
216
- .click(R.Produce.ButtonProduce)
217
- .click(regex(mode_text))
218
- .until(R.Produce.ButtonPIdolOverview, result=True)
219
- .until(R.Produce.TextAPInsufficient, result=False)
220
- ).run()
215
+ logger.info(f'Enter produce page. Mode: {mode}')
216
+ match mode:
217
+ case 'regular':
218
+ target_buttons = [R.Produce.ButtonHajime0Regular, R.Produce.ButtonHajime1Regular]
219
+ case 'pro':
220
+ target_buttons = [R.Produce.ButtonHajime0Pro, R.Produce.ButtonHajime1Pro]
221
+ case 'master':
222
+ target_buttons = [R.Produce.ButtonHajime1Master]
223
+ case _:
224
+ assert_never(mode)
225
+ result = None
226
+ for _ in Loop():
227
+ if image.find(R.Produce.ButtonProduce):
228
+ device.click()
229
+ elif image.find_multi(target_buttons):
230
+ device.click()
231
+ elif image.find(R.Produce.ButtonPIdolOverview):
232
+ result = True
233
+ break
234
+ elif image.find(R.Produce.TextAPInsufficient):
235
+ result = False
236
+ break
221
237
  if not result:
222
238
  if conf().produce.use_ap_drink:
223
239
  # [kotonebot-resource\sprites\jp\produce\screenshot_no_enough_ap_1.png]
@@ -230,7 +246,7 @@ def do_produce(
230
246
  device.click()
231
247
  elif image.find(R.Produce.ButtonRefillAP):
232
248
  device.click()
233
- elif ocr.find(contains(mode_text)):
249
+ elif image.find_multi(target_buttons):
234
250
  device.click()
235
251
  elif image.find(R.Produce.ButtonPIdolOverview):
236
252
  break
@@ -240,49 +256,91 @@ def do_produce(
240
256
  logger.info('AP insufficient. Exiting produce.')
241
257
  device.click(image.expect_wait(R.InPurodyuusu.ButtonCancel))
242
258
  return False
243
- # 1. 选择 PIdol [screenshots/produce/screenshot_produce_start_1_p_idol.png]
244
- select_idol(idol_skin_id)
245
- it = Interval()
246
- while True:
247
- it.wait()
248
- device.screenshot()
249
- if image.find(R.Produce.TextAnotherIdolAvailableDialog):
250
- dialog.no()
251
- elif image.find(R.Common.ButtonNextNoIcon):
252
- device.click()
253
- if image.find(R.Produce.TextStepIndicator2):
254
- break
255
- # 2. 选择支援卡 自动编成 [screenshots/produce/screenshot_produce_start_2_support_card.png]
256
- image.expect_wait(R.Produce.TextStepIndicator2)
257
- it = Interval()
258
- while True:
259
- if image.find(R.Common.ButtonNextNoIcon, colored=True):
260
- device.click()
261
- break
262
- elif image.find(R.Produce.ButtonAutoSet):
263
- device.click()
264
- sleep(1)
265
- elif image.find(R.Common.ButtonConfirm, colored=True):
266
- device.click()
267
- device.screenshot()
268
- it.wait()
269
- # 3. 选择回忆 自动编成 [screenshots/produce/screenshot_produce_start_3_memory.png]
270
- image.expect_wait(R.Produce.TextStepIndicator3)
271
- # 自动编成
272
- if memory_set_index is not None and not 1 <= memory_set_index <= 10:
273
- raise ValueError('`memory_set_index` must be in range [1, 10].')
274
- if memory_set_index is None:
275
- device.click(image.expect_wait(R.Produce.ButtonAutoSet))
276
- wait(0.5, before='screenshot')
277
- device.screenshot()
278
- # 指定编号
279
- else:
280
- select_set(memory_set_index)
281
- (SimpleDispatcher('do_produce.step_3')
282
- .until(R.Produce.TextStepIndicator4)
283
- .click(R.Common.ButtonNextNoIcon)
284
- .click(R.Common.IconButtonCheck)
285
- ).run()
259
+
260
+ idol_located = False
261
+ memory_set_selected = False
262
+ support_auto_set_done = False
263
+ next_throttler = Throttler(interval=4)
264
+ for lp in StatedLoop[Literal[0, 1, 2, 3]]():
265
+ if image.find(R.Produce.TextStepIndicator1):
266
+ lp.state = 1
267
+
268
+ if lp.state == 0:
269
+ pass
270
+ # 1. 选择 PIdol [screenshots/produce/screenshot_produce_start_1_p_idol.png]
271
+ if lp.state == 1:
272
+ if image.find(R.Produce.TextStepIndicator2):
273
+ lp.state = 2
274
+ continue
275
+ if lp.when(R.Produce.TextAnotherIdolAvailableDialog):
276
+ dialog.no(msg='Closed another idol available dialog.')
277
+ # 首先判断是否已选中目标偶像
278
+ img = lp.screenshot
279
+ x, y, w, h = R.Produce.BoxSelectedIdol.xywh
280
+ if img is not None and match_idol(idol_skin_id, img[y:y+h, x:x+w]):
281
+ logger.info('Idol %s selected.', idol_skin_id)
282
+ idol_located = True
283
+ # 如果没有,才选择
284
+ if not idol_located:
285
+ select_idol(idol_skin_id)
286
+ idol_located = True
287
+
288
+ # 下一步「次へ」
289
+ if idol_located and find_button(R.Common.ButtonNextNoIcon, True) and next_throttler.request():
290
+ device.click()
291
+ # 2. 选择支援卡 自动编成 [screenshots/produce/screenshot_produce_start_2_support_card.png]
292
+ elif lp.state == 2:
293
+ if image.find(R.Produce.TextStepIndicator3):
294
+ lp.state = 3
295
+ continue
296
+
297
+ # 下一步「次へ」
298
+ if find_button(R.Common.ButtonNextNoIcon, True) and next_throttler.request():
299
+ device.click()
300
+ # 今天仍然有租用回忆次数提示(第三步的提示)
301
+ # (第二步选完之后点「次へ」大概率会卡几秒钟,这个时候脚本很可能会重复点击,
302
+ # 卡住时候的点击就会在第三步生效,出现这个提示。而此时脚本仍然处于第二步,
303
+ # 这样就会报错,或者出现误自动编成。因此需要在第二步里处理掉这个对话框。
304
+ # 理论上应该避免这种情况,但是没找到办法,只能这样 workaround 了。)
305
+ elif image.find(R.Produce.TextRentAvailable):
306
+ dialog.no(msg='Closed rent available dialog. (Step 2)')
307
+ # 确认自动编成提示
308
+ elif image.find(R.Produce.TextAutoSet):
309
+ dialog.yes(msg='Confirmed auto set.')
310
+ sleep(1) # 等对话框消失
311
+ elif not support_auto_set_done and image.find(R.Produce.ButtonAutoSet):
312
+ device.click()
313
+ support_auto_set_done = True
314
+ sleep(1)
315
+ # 3. 选择回忆 自动编成 [screenshots/produce/screenshot_produce_start_3_memory.png]
316
+ elif lp.state == 3:
317
+ if image.find(R.Produce.TextStepIndicator4):
318
+ break
319
+
320
+ # 确认自动编成提示
321
+ if image.find(R.Produce.TextAutoSet):
322
+ dialog.yes(msg='Confirmed auto set.')
323
+ continue
324
+ # 今天仍然有租用回忆次数提示
325
+ elif image.find(R.Produce.TextRentAvailable):
326
+ dialog.yes(msg='Confirmed rent available. (Step 3)')
327
+ continue
328
+
329
+ if not memory_set_selected:
330
+ # 自动编成
331
+ if memory_set_index is None:
332
+ lp.click_if(R.Produce.ButtonAutoSet)
333
+ # 指定编号
334
+ else:
335
+ # dialog.no() # TODO: 这是什么?
336
+ select_set(memory_set_index)
337
+ memory_set_selected = True
338
+ # 下一步「次へ」
339
+ if find_button(R.Common.ButtonNextNoIcon, True) and next_throttler.request():
340
+ device.click()
341
+ continue
342
+ else:
343
+ assert False, f'Invalid state of {lp.state}.'
286
344
 
287
345
  # 4. 选择道具 [screenshots/produce/screenshot_produce_start_4_end.png]
288
346
  # TODO: 如果道具不足,这里加入推送提醒
@@ -357,19 +415,10 @@ if __name__ == '__main__':
357
415
  logging.basicConfig(level=logging.INFO, format='[%(asctime)s] [%(levelname)s] [%(name)s] [%(funcName)s] [%(lineno)d] %(message)s')
358
416
  logging.getLogger('kotonebot').setLevel(logging.DEBUG)
359
417
  logger.setLevel(logging.DEBUG)
360
- import os
361
- from datetime import datetime
362
- os.makedirs('logs', exist_ok=True)
363
- log_filename = datetime.now().strftime('logs/task-%y-%m-%d-%H-%M-%S.log')
364
- file_handler = logging.FileHandler(log_filename, encoding='utf-8')
365
- file_handler.setFormatter(logging.Formatter('[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s'))
366
- logging.getLogger().addHandler(file_handler)
367
-
368
- import time
369
418
  from kotonebot.backend.context import init_context
370
419
  from kotonebot.kaa.common import BaseConfig
420
+ from kotonebot.kaa.main import Kaa
371
421
 
372
- init_context(config_type=BaseConfig)
373
422
  conf().produce.enabled = True
374
423
  conf().produce.mode = 'pro'
375
424
  conf().produce.produce_count = 1
@@ -95,8 +95,9 @@ def android_launch():
95
95
  前置条件:-
96
96
  结束状态:-
97
97
  """
98
+ _device = device.of_android()
98
99
  # 如果已经在游戏中,直接返回home
99
- if device.current_package() == conf().start_game.game_package_name:
100
+ if _device.current_package() == conf().start_game.game_package_name:
100
101
  logger.info("Game already started")
101
102
  if not at_home():
102
103
  logger.info("Not at home, going to home")
@@ -106,15 +107,15 @@ def android_launch():
106
107
  # 如果不在游戏中,启动游戏
107
108
  if not conf().start_game.start_through_kuyo:
108
109
  # 直接启动
109
- device.launch_app(conf().start_game.game_package_name)
110
+ _device.launch_app(conf().start_game.game_package_name)
110
111
  else:
111
112
  # 通过Kuyo启动
112
- if device.current_package() == conf().start_game.kuyo_package_name:
113
+ if _device.current_package() == conf().start_game.kuyo_package_name:
113
114
  logger.warning("Kuyo already started. Auto start game failed.")
114
115
  # TODO: Kuyo支持改进
115
116
  return
116
117
  # 启动kuyo
117
- device.launch_app('org.kuyo.game')
118
+ _device.launch_app('org.kuyo.game')
118
119
  # 点击"加速"
119
120
  device.click(image.expect_wait(R.Kuyo.ButtonTab3Speedup, timeout=10))
120
121
  # Kuyo会延迟加入广告,导致识别后,原位置突然弹出广告,导致进入广告页面
@@ -156,8 +157,8 @@ def windows_launch():
156
157
  logger.info('Gakumas Localify disabled.')
157
158
 
158
159
  from ahk import AHK
159
- from importlib import resources
160
- ahk_path = str(resources.files('kaa.res.bin') / 'AutoHotkey.exe')
160
+ from kotonebot.kaa.util.paths import get_ahk_path
161
+ ahk_path = get_ahk_path()
161
162
  ahk = AHK(executable_path=ahk_path)
162
163
 
163
164
  if ahk.find_window(title='gakumas', title_match_mode=3): # 3=精确匹配
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  from typing import cast
3
+ from importlib import resources
3
4
 
4
5
  from kotonebot.kaa import resources as res
5
6
 
@@ -15,4 +16,8 @@ def cache(path: str) -> str:
15
16
  return p
16
17
 
17
18
  def resource(path: str) -> str:
18
- return os.path.join(RESOURCE, path)
19
+ return os.path.join(RESOURCE, path)
20
+
21
+ def get_ahk_path() -> str:
22
+ """获取 AutoHotkey 可执行文件路径"""
23
+ return str(resources.files('kaa.res.bin') / 'AutoHotkey.exe')
kotonebot/tools/mirror.py CHANGED
@@ -297,19 +297,27 @@ class DeviceMirrorFrame(wx.Frame):
297
297
  self.log("请输入包名")
298
298
  return
299
299
  try:
300
- self.device.launch_app(package_name)
301
- self.log(f"启动APP: {package_name}")
300
+ # 使用新的 API 通过 commands 属性访问平台特定方法
301
+ if hasattr(self.device, 'commands') and hasattr(self.device.commands, 'launch_app'):
302
+ self.device.commands.launch_app(package_name)
303
+ self.log(f"启动APP: {package_name}")
304
+ else:
305
+ self.log("当前设备不支持启动APP功能")
302
306
  except Exception as e:
303
307
  self.log(f"启动APP失败: {e}")
304
308
 
305
309
  def on_get_current_app(self, event):
306
310
  """获取前台APP"""
307
311
  try:
308
- package = self.device.current_package()
309
- if package:
310
- self.log(f"前台APP: {package}")
312
+ # 使用新的 API 通过 commands 属性访问平台特定方法
313
+ if hasattr(self.device, 'commands') and hasattr(self.device.commands, 'current_package'):
314
+ package = self.device.commands.current_package()
315
+ if package:
316
+ self.log(f"前台APP: {package}")
317
+ else:
318
+ self.log("未获取到前台APP")
311
319
  else:
312
- self.log("获取前台APP失败")
320
+ self.log("当前设备不支持获取前台APP功能")
313
321
  except Exception as e:
314
322
  self.log(f"获取前台APP失败: {e}")
315
323
 
@@ -326,19 +334,21 @@ def show_device_mirror(device: Device):
326
334
 
327
335
  if __name__ == "__main__":
328
336
  # 测试代码
337
+ from kotonebot.client.device import AndroidDevice
329
338
  from kotonebot.client.implements.adb import AdbImpl
330
339
  from kotonebot.client.implements.uiautomator2 import UiAutomator2Impl
331
340
  from adbutils import adb
332
-
341
+
333
342
  print("server version:", adb.server_version())
334
343
  adb.connect("127.0.0.1:5555")
335
344
  print("devices:", adb.device_list())
336
345
  d = adb.device_list()[-1]
337
-
338
- dd = Device(d)
339
- adb_imp = AdbImpl(dd)
340
- dd._command = adb_imp
346
+
347
+ # 使用新的 API
348
+ dd = AndroidDevice(d)
349
+ adb_imp = AdbImpl(d) # 直接传入 adb 连接
341
350
  dd._touch = adb_imp
342
- dd._screenshot = UiAutomator2Impl(dd)
343
-
351
+ dd._screenshot = UiAutomator2Impl(dd) # UiAutomator2Impl 可能还需要 device 对象
352
+ dd.commands = adb_imp # 设置 Android 特定命令
353
+
344
354
  show_device_mirror(dd)
kotonebot/util.py CHANGED
@@ -263,6 +263,38 @@ class Interval:
263
263
  def reset(self):
264
264
  self.start_time = time.time()
265
265
 
266
+ class Throttler:
267
+ """
268
+ 限流器,在循环中用于限制某操作的频率。
269
+
270
+ 示例代码:
271
+ ```python
272
+ while True:
273
+ device.screenshot()
274
+ if throttler.request() and image.find(...):
275
+ do_something()
276
+ ```
277
+ """
278
+ def __init__(self, interval: float, max_requests: int | None = None):
279
+ self.max_requests = max_requests
280
+ self.interval = interval
281
+ self.last_request_time: float | None = None
282
+ self.request_count = 0
283
+
284
+ def request(self) -> bool:
285
+ """
286
+ 检查是否允许请求。此函数立即返回,不会阻塞。
287
+
288
+ :return: 如果允许,返回 True,否则返回 False
289
+ """
290
+ current_time = time.time()
291
+ if self.last_request_time is None or current_time - self.last_request_time >= self.interval:
292
+ self.last_request_time = current_time
293
+ self.request_count = 0
294
+ return True
295
+ else:
296
+ return False
297
+
266
298
  def lf_path(path: str) -> str:
267
299
  standalone = os.path.join('kotonebot-resource', path)
268
300
  if os.path.exists(standalone):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ksaa
3
- Version: 2025.6.8.0
3
+ Version: 2025.6.23.0
4
4
  Summary: Kotones Auto Assistant(kaa) is a script for game 'Gakuen Idol M@ster' that automates the dailies and produces.
5
5
  Requires-Python: ~=3.10
6
6
  Description-Content-Type: text/markdown