ksaa 2025.5.23.3__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 (202) hide show
  1. kotonebot/backend/bot.py +3 -3
  2. kotonebot/backend/context/context.py +52 -36
  3. kotonebot/backend/debug/server.py +3 -5
  4. kotonebot/backend/dispatch.py +1 -17
  5. kotonebot/backend/flow_controller.py +195 -0
  6. kotonebot/backend/loop.py +277 -0
  7. kotonebot/client/__init__.py +4 -1
  8. kotonebot/client/device.py +23 -21
  9. kotonebot/client/host/__init__.py +2 -1
  10. kotonebot/client/host/custom.py +26 -3
  11. kotonebot/client/host/leidian_host.py +22 -11
  12. kotonebot/client/host/mumu12_host.py +25 -3
  13. kotonebot/client/host/protocol.py +40 -18
  14. kotonebot/client/implements/__init__.py +6 -0
  15. kotonebot/client/implements/adb.py +67 -7
  16. kotonebot/client/implements/adb_raw.py +12 -5
  17. kotonebot/client/implements/remote_windows.py +20 -18
  18. kotonebot/client/implements/uiautomator2.py +8 -0
  19. kotonebot/client/implements/windows.py +56 -28
  20. kotonebot/client/protocol.py +13 -0
  21. kotonebot/client/registration.py +89 -0
  22. kotonebot/config/base_config.py +5 -1
  23. kotonebot/debug_entry.py +7 -2
  24. kotonebot/kaa/clear_logs.py +0 -3
  25. kotonebot/kaa/common.py +21 -0
  26. kotonebot/kaa/game_ui/common.py +4 -7
  27. kotonebot/kaa/game_ui/dialog.py +24 -4
  28. kotonebot/kaa/game_ui/idols_overview.py +28 -12
  29. kotonebot/kaa/game_ui/primary_button.py +55 -0
  30. kotonebot/kaa/game_ui/scrollable.py +0 -5
  31. kotonebot/kaa/main/cli.py +9 -4
  32. kotonebot/kaa/main/dmm_host.py +33 -7
  33. kotonebot/kaa/main/gr.py +156 -26
  34. kotonebot/kaa/main/kaa.py +113 -41
  35. kotonebot/kaa/metadata.py +27 -0
  36. kotonebot/kaa/resources/__pycache__/__init__.cpython-310.pyc +0 -0
  37. kotonebot/kaa/resources/game.db +0 -0
  38. kotonebot/kaa/resources/game_ver.txt +0 -0
  39. kotonebot/kaa/resources/idol_cards/i_card-skin-kllj-3-012_0.png +0 -0
  40. kotonebot/kaa/resources/idol_cards/i_card-skin-kllj-3-012_1.png +0 -0
  41. kotonebot/kaa/resources/idol_cards/i_card-skin-ssmk-3-012_0.png +0 -0
  42. kotonebot/kaa/resources/idol_cards/i_card-skin-ssmk-3-012_1.png +0 -0
  43. kotonebot/kaa/sprites/24e99232-9434-457f-a9a0-69dd7ecf675f.png +0 -0
  44. kotonebot/kaa/sprites/2ededcf5-1d80-4e2a-9c83-2a31998331ce.png +0 -0
  45. kotonebot/kaa/sprites/3b473fe6-e147-477f-b088-9b8fb042a4f6.png +0 -0
  46. kotonebot/kaa/sprites/55f7db71-0a18-4b3d-b847-57959b8d2e32.png +0 -0
  47. kotonebot/kaa/sprites/6cd80be8-c9b3-4ba5-bf17-3ffc9b000743.png +0 -0
  48. kotonebot/kaa/sprites/74ec3510-583d-4a76-ac69-38480fbf1387.png +0 -0
  49. kotonebot/kaa/sprites/a0bd6a5f-784d-4f0a-9d66-10f4b80c8d3e.png +0 -0
  50. kotonebot/kaa/sprites/d3424d31-0502-4623-996e-f0194e5085ce.png +0 -0
  51. kotonebot/kaa/sprites/e6b45405-cd9f-4c6e-a9f1-6ec953747c65.png +0 -0
  52. kotonebot/kaa/sprites/f5c16d2f-ebc5-4617-9b96-971696af7c52.png +0 -0
  53. kotonebot/kaa/tasks/R.py +157 -135
  54. kotonebot/kaa/tasks/end_game.py +14 -0
  55. kotonebot/kaa/tasks/produce/common.py +1 -0
  56. kotonebot/kaa/tasks/produce/in_purodyuusu.py +0 -4
  57. kotonebot/kaa/tasks/produce/non_lesson_actions.py +1 -4
  58. kotonebot/kaa/tasks/produce/produce.py +119 -70
  59. kotonebot/kaa/tasks/start_game.py +56 -7
  60. kotonebot/kaa/util/paths.py +6 -1
  61. kotonebot/tools/mirror.py +23 -13
  62. kotonebot/util.py +32 -0
  63. {ksaa-2025.5.23.3.dist-info → ksaa-2025.6.23.0.dist-info}/METADATA +38 -1
  64. {ksaa-2025.5.23.3.dist-info → ksaa-2025.6.23.0.dist-info}/RECORD +200 -183
  65. ksaa-2025.6.23.0.dist-info/licenses/LICENSE +674 -0
  66. kotonebot/client/factory.py +0 -92
  67. kotonebot/kaa/sprites/b260d390-2b1a-4974-92db-d68ff7b5b8e6.png +0 -0
  68. /kotonebot/kaa/sprites/{f6d36222-847e-4300-8f90-c98c7a8f36e3.png → 0235ae3d-1741-4a81-8053-f60bc395ee85.png} +0 -0
  69. /kotonebot/kaa/sprites/{48a02c33-b7af-4ab5-bda1-3a2ec62a7076.png → 038c69e6-7cb0-4c8d-99da-b537e48a86b7.png} +0 -0
  70. /kotonebot/kaa/sprites/{b99f0684-8200-4080-9b54-808c4ec12c99.png → 080b3cf5-ce35-4382-9bfa-d6a12efb09b3.png} +0 -0
  71. /kotonebot/kaa/sprites/{7c65fc91-602b-4d1b-82f9-c9b561a55d9b.png → 09fb5e41-6caa-4246-a415-8317b12d8d81.png} +0 -0
  72. /kotonebot/kaa/sprites/{5e74dc61-0ad5-4e57-b331-e3d2ed67b6d2.png → 0a6c6b1e-7a80-428e-a483-1858bfb8ac59.png} +0 -0
  73. /kotonebot/kaa/sprites/{aad29ac0-b9ad-4c38-93f5-e8036ad7b96b.png → 0ad2f603-a3ad-4a92-a398-c411145fd8e9.png} +0 -0
  74. /kotonebot/kaa/sprites/{e98037f8-3b4a-4de8-adc1-ca0f736b6c98.png → 0d4b669e-5e43-4458-b65a-5565797335ae.png} +0 -0
  75. /kotonebot/kaa/sprites/{382bc600-72f6-433f-809e-9fe2fdb31b32.png → 0fbcb3f6-9ca0-43c7-975b-e7c15c26c897.png} +0 -0
  76. /kotonebot/kaa/sprites/{6d39d7a2-0b1f-4f49-9ab8-062bca9b5470.png → 15465879-eb84-4ca6-ae0f-d3c5ac71e723.png} +0 -0
  77. /kotonebot/kaa/sprites/{474ce25b-8a3d-435e-8d7a-ab6566ae61a0.png → 1639278d-67e0-4452-a2b5-ec4cf4011f42.png} +0 -0
  78. /kotonebot/kaa/sprites/{7d4f53fb-02bc-4139-b32c-3345a5f92a79.png → 17414e9e-b046-49e0-9596-cad1f4673a9e.png} +0 -0
  79. /kotonebot/kaa/sprites/{9a72b63e-8bd1-47dc-8298-cdf02220201e.png → 17a8b0a5-5b71-4612-8a68-16c51f03c71b.png} +0 -0
  80. /kotonebot/kaa/sprites/{a1610e9f-93f0-4ef2-b32a-b2effd1673e8.png → 1aaceb21-dc5c-4a58-96d3-d2c66b2fb357.png} +0 -0
  81. /kotonebot/kaa/sprites/{237636f2-aec0-40be-b7bb-e08607a89307.png → 1aae0ab3-f619-47e0-8bf6-3d3791f7d445.png} +0 -0
  82. /kotonebot/kaa/sprites/{872c37e7-e596-4449-86f4-5ba65836a7a7.png → 1b6be6dd-2711-441a-9fa6-3281a6ad10c7.png} +0 -0
  83. /kotonebot/kaa/sprites/{a829f038-5421-4cc4-a494-105a973351e2.png → 1bb00a74-2fdc-4973-84ae-dc1edee15f81.png} +0 -0
  84. /kotonebot/kaa/sprites/{e5922ce7-9aa7-4806-acdd-9c35408a0f37.png → 1ccdcacf-4f7d-442c-8e2f-09aa7fe14e56.png} +0 -0
  85. /kotonebot/kaa/sprites/{1df6ff4b-17f8-4ee6-8df0-0b53e26b7f1e.png → 1d5f7454-672d-4e87-a368-ec4bb32f9b1f.png} +0 -0
  86. /kotonebot/kaa/sprites/{51f38e84-56c8-4c80-9a67-35196ef54b89.png → 1f2981d8-5eb6-4332-aa9b-17f4db2d4163.png} +0 -0
  87. /kotonebot/kaa/sprites/{f4b226eb-ed9e-4e5e-9ba0-1b777e401aa3.png → 25910d8e-d57f-409f-b0be-ee68c5af4920.png} +0 -0
  88. /kotonebot/kaa/sprites/{e9e399f7-4e2f-4392-bb8f-850c4a272dfa.png → 264e056f-3bcc-4b16-94d4-f767c78ab6f5.png} +0 -0
  89. /kotonebot/kaa/sprites/{cc0ac4cf-01fd-48f9-8707-2d6a2aa0ba8c.png → 26580772-ff20-4dcf-8496-f939e0f2890d.png} +0 -0
  90. /kotonebot/kaa/sprites/{7dd31493-9f3b-4382-a43a-f8eb1c745ad8.png → 29cb7b0f-5684-4516-8fae-4439f7f28e08.png} +0 -0
  91. /kotonebot/kaa/sprites/{415c45a8-9b71-4e0b-8cd2-f80a0a4aafb7.png → 2d145ade-b926-4276-b872-baec4ef78308.png} +0 -0
  92. /kotonebot/kaa/sprites/{d2732870-dd6b-4b7b-b21e-4ff2a4958b32.png → 2dd34393-ee6f-4b19-8a9c-76556d1bd7d7.png} +0 -0
  93. /kotonebot/kaa/sprites/{0d1918db-e000-4452-8490-ace623127e76.png → 2e00ac54-d23a-4d51-82f2-829c012552a6.png} +0 -0
  94. /kotonebot/kaa/sprites/{267fcd93-6a5c-4954-a06b-e97f327e9141.png → 2f74b04f-1992-4584-8dc6-e789b081ddc3.png} +0 -0
  95. /kotonebot/kaa/sprites/{08c2352f-0150-453a-aa0e-948dd0deef49.png → 302fde7d-de85-44c7-ba57-fe4b5f6db5fa.png} +0 -0
  96. /kotonebot/kaa/sprites/{e508161a-e595-4daf-a364-625aaf67e481.png → 3cc9685d-6347-4114-9d39-7683c2dc9df6.png} +0 -0
  97. /kotonebot/kaa/sprites/{d0c085fa-3089-4adf-979c-d4b274b32c3b.png → 42d8b5dc-ef27-4411-b8b5-d981e562990b.png} +0 -0
  98. /kotonebot/kaa/sprites/{2ef87b7f-d69e-4da2-878f-1cc35e48b15c.png → 448ea37d-a10d-4102-ac9f-a58403ee8914.png} +0 -0
  99. /kotonebot/kaa/sprites/{6dcc0bb3-984f-4c92-b0a3-74281d684182.png → 4a310bdd-0a7d-4669-9d57-6ae69bc8f022.png} +0 -0
  100. /kotonebot/kaa/sprites/{52e2b832-7837-47ca-a089-1f1593a99b08.png → 4b20b364-5f5f-4b34-960e-b0cfd08b1662.png} +0 -0
  101. /kotonebot/kaa/sprites/{34ec068a-d6fd-47ac-bd2f-0c31f93c19f3.png → 4e8f3e59-edfa-4523-939d-bc46988fc909.png} +0 -0
  102. /kotonebot/kaa/sprites/{157cfa99-d40c-48c2-8cf4-70835535522f.png → 4eaa5db2-d624-4df4-b2e4-01f72755f1a4.png} +0 -0
  103. /kotonebot/kaa/sprites/{56a70bc5-bd16-493b-b5b6-770f42f13de5.png → 5152e3fa-079c-4592-8df7-656101694df8.png} +0 -0
  104. /kotonebot/kaa/sprites/{b5009ffd-7e53-41ae-b78d-918ba0e7eda4.png → 52f7c8b1-af88-43c5-a999-de4da3caa03a.png} +0 -0
  105. /kotonebot/kaa/sprites/{465f1030-e538-4b22-a6f7-0087287b2e12.png → 534d1310-3503-46d3-8ecd-426d9bcf183e.png} +0 -0
  106. /kotonebot/kaa/sprites/{465d4e1a-c5f9-41b7-aa31-ce26d5c69c45.png → 5868ebfb-5e61-4ac6-b270-acb1e89b738f.png} +0 -0
  107. /kotonebot/kaa/sprites/{3e10014e-2063-424c-aeda-df985d351c12.png → 58a5f51d-d1a3-480b-8dde-ecead34d9f02.png} +0 -0
  108. /kotonebot/kaa/sprites/{4ffd7c97-86dd-4171-92e7-8e8e83e8f394.png → 5d3d61e9-bf13-4668-b0c7-fed730ea2ed6.png} +0 -0
  109. /kotonebot/kaa/sprites/{f4a1201f-9305-4ec5-8962-2bef0144ab46.png → 5dd0cc39-4102-4f0f-8ad3-342bbf825977.png} +0 -0
  110. /kotonebot/kaa/sprites/{dc17dea0-7749-4ecb-bbc0-1a52fb992dcf.png → 5ee8e9a8-b133-4ab7-a52c-e7e4e1d1ce7b.png} +0 -0
  111. /kotonebot/kaa/sprites/{172318e0-5e7b-4b61-9a17-6e2e66b27e69.png → 60be53a6-98e9-4fc6-9285-85506dc0e335.png} +0 -0
  112. /kotonebot/kaa/sprites/{8da0b45e-3d90-40f0-9781-c1ff4cd0e060.png → 6114d53e-dd69-4cee-82a7-7e43b338ff8d.png} +0 -0
  113. /kotonebot/kaa/sprites/{26433c9e-0ea2-4da4-9207-8f3fbad04235.png → 6156116e-56dd-4b41-a6de-ccec55dab7c8.png} +0 -0
  114. /kotonebot/kaa/sprites/{bdb09790-f702-4af2-ab67-0b3f05fd93ca.png → 65d2a5e5-48aa-4390-bb87-bfd8e044e4f6.png} +0 -0
  115. /kotonebot/kaa/sprites/{5a4a763f-b69b-4405-994d-470a78476f67.png → 66172bc0-3869-4a48-a26d-0dc3fa404ab8.png} +0 -0
  116. /kotonebot/kaa/sprites/{e0a5c772-49d3-468a-bcf5-0e3f24365253.png → 66678caa-7b25-4ff7-8c3a-017f67279349.png} +0 -0
  117. /kotonebot/kaa/sprites/{7f0783fe-89d9-4405-b7a3-6334ba543826.png → 68838f92-5916-424e-a37e-47e0b3834eb3.png} +0 -0
  118. /kotonebot/kaa/sprites/{c4fed66b-e195-4288-8b1f-ef4b0ef35174.png → 694d3a07-9697-4bda-984d-967779d530f7.png} +0 -0
  119. /kotonebot/kaa/sprites/{37e3a757-bcbc-4a37-bbf9-a38162a8627e.png → 69b022a8-e42f-4985-bd16-b4a530ad8a20.png} +0 -0
  120. /kotonebot/kaa/sprites/{5eddc669-dff6-462c-a495-81ddf951429e.png → 6aa34982-e7ab-4001-808f-8c5cf370d087.png} +0 -0
  121. /kotonebot/kaa/sprites/{428f770b-e149-417e-bb8a-38c1cba024e1.png → 7516c9a1-87ec-4d2f-ac5e-40d1aec27104.png} +0 -0
  122. /kotonebot/kaa/sprites/{63bfee9f-546e-4c3c-a82f-c2707bc62b90.png → 7aa2435c-da90-4d52-b831-88dbec57dde9.png} +0 -0
  123. /kotonebot/kaa/sprites/{d3b97b8f-f13a-413d-a097-5c456b8aea0d.png → 7b7dad18-a838-4267-b3c7-6ab43b8361f0.png} +0 -0
  124. /kotonebot/kaa/sprites/{ef539419-d100-43d5-83a1-14e65b85d816.png → 7cabdf91-2f15-4991-b165-eb9cdd557af6.png} +0 -0
  125. /kotonebot/kaa/sprites/{12356f5d-4188-4aa5-abb3-d219ca0167ca.png → 7f6cb60e-6ab3-4db4-86e1-8558250062a4.png} +0 -0
  126. /kotonebot/kaa/sprites/{1d6d5160-9525-42bf-a8d4-43c347d213eb.png → 83acbca8-3567-4262-a1e7-50f158348d45.png} +0 -0
  127. /kotonebot/kaa/sprites/{4b121018-f5c8-4c31-a5d9-48947982b191.png → 83cf48ba-d1af-4674-a52e-6bb80a626db7.png} +0 -0
  128. /kotonebot/kaa/sprites/{76c07ba7-afea-405c-806a-7691ce73f83a.png → 83f17b06-2792-4035-bc90-1800279ae131.png} +0 -0
  129. /kotonebot/kaa/sprites/{c287899b-b9a3-4ee2-a8fd-ebda89099b4b.png → 84bb4986-0295-4a45-9486-86e31fcdf1f1.png} +0 -0
  130. /kotonebot/kaa/sprites/{7b46a3e5-18d3-45a0-9500-1d7c854a12bb.png → 8b9c115b-d4ce-492e-88cb-08bd01c43570.png} +0 -0
  131. /kotonebot/kaa/sprites/{263708c5-0177-4c6a-8df3-611ec314fa56.png → 8e48af2b-c083-4480-a27c-c59c31a7ede1.png} +0 -0
  132. /kotonebot/kaa/sprites/{ced345fa-b375-457d-8b72-802424512e6c.png → 8f1e5644-1079-44b1-9d44-97bae3817bc5.png} +0 -0
  133. /kotonebot/kaa/sprites/{c94488b2-0ff0-4467-bbb0-405d3a2c55a3.png → 90def878-cd6e-46e5-9dc4-9c92dd904b80.png} +0 -0
  134. /kotonebot/kaa/sprites/{a69febc4-2d01-4628-be92-29b421604c4d.png → 920a3974-4875-4d2b-bbac-caa175c03ce0.png} +0 -0
  135. /kotonebot/kaa/sprites/{ddb2e9ee-e16a-4745-8598-b3f9c2f011be.png → 94433cf2-dd04-4b74-ae14-e5e3d945f579.png} +0 -0
  136. /kotonebot/kaa/sprites/{4ddc656f-ef7e-4580-ad12-9e382ea76e4f.png → 969eb98c-f761-4007-b8bd-2b3fb8d1f08c.png} +0 -0
  137. /kotonebot/kaa/sprites/{7d968a7f-f4a8-40a0-b9bf-e73ec1f2d7b5.png → 97adee05-1586-4589-93e6-c6c3a9cdae9d.png} +0 -0
  138. /kotonebot/kaa/sprites/{d364470a-d077-405f-a242-0d4fad32bc40.png → 9aef1aa8-41e1-42a7-83ad-b4e212ee3976.png} +0 -0
  139. /kotonebot/kaa/sprites/{9ce49f31-6b3a-4bc7-a9c8-9330d6f650f7.png → 9c7f1bcc-0bc8-454b-95fb-56a803030771.png} +0 -0
  140. /kotonebot/kaa/sprites/{99c36126-0173-49f3-a6b8-819bf9bd9306.png → 9cd7e1f1-13c4-471e-abee-223ffd9126cb.png} +0 -0
  141. /kotonebot/kaa/sprites/{370afc82-eea9-4063-afb7-5d5fec075510.png → 9d5dd50c-3341-41a4-a3dd-ccc00edcf201.png} +0 -0
  142. /kotonebot/kaa/sprites/{a5d05106-5a60-414c-972d-a886664abde4.png → 9f99b0e9-8cc0-4877-8f8a-d26257ef5386.png} +0 -0
  143. /kotonebot/kaa/sprites/{3720275d-cbf7-4513-a4a4-09f712b2286a.png → a1853223-d6b9-4660-af4e-91e59bdddc3c.png} +0 -0
  144. /kotonebot/kaa/sprites/{588f3405-4110-48dd-99ec-f89c004cf02e.png → a1bba683-a740-4eaf-8c37-3b1042b963b0.png} +0 -0
  145. /kotonebot/kaa/sprites/{60e43a33-18ee-45f1-bd9a-57bb6539611b.png → a1cf80ee-64bf-4d54-a7db-ffadf3c97026.png} +0 -0
  146. /kotonebot/kaa/sprites/{14cc953d-0ff6-493f-9478-691b5cbd0d07.png → a3b15425-0bfd-4668-a3a9-2ab64da8505f.png} +0 -0
  147. /kotonebot/kaa/sprites/{f400e1fe-a04d-442b-a6de-a448813443fd.png → a4075991-98da-4d06-bcde-28054cd124d2.png} +0 -0
  148. /kotonebot/kaa/sprites/{cecd2638-070f-4710-9142-2dc492660241.png → a7da51c2-8444-4770-a16b-b6543e40197f.png} +0 -0
  149. /kotonebot/kaa/sprites/{9d7a7bbb-b48b-458c-9964-963a57e10a7d.png → a8b3fdce-9e4a-495c-839e-0142f67fee69.png} +0 -0
  150. /kotonebot/kaa/sprites/{e55da40e-5fb5-48e0-91b1-2db0b3b32750.png → aa3b717f-67f8-445f-a6bf-b89f7200d95b.png} +0 -0
  151. /kotonebot/kaa/sprites/{8cc764de-f162-40a4-ba6f-40d60eac5633.png → abcc709c-1f4d-4832-a063-eafbad94ac31.png} +0 -0
  152. /kotonebot/kaa/sprites/{e6e66cdf-69c8-4862-a770-1f81c62f96ac.png → ad172750-d1a6-4a25-8ce8-9483f4b5affb.png} +0 -0
  153. /kotonebot/kaa/sprites/{eb229797-bffc-4a48-96de-85480af1608a.png → aefdec38-e3b6-4762-aed8-33107686ddac.png} +0 -0
  154. /kotonebot/kaa/sprites/{23217053-c549-4ac7-b8c0-3324728e6acd.png → b01c25d2-21bf-4db9-b5b2-ec35817f1b04.png} +0 -0
  155. /kotonebot/kaa/sprites/{9d908390-6f0f-46e6-a8fc-a7dfe23eda18.png → b1e7f24e-f246-406e-9073-58e2f3e4e819.png} +0 -0
  156. /kotonebot/kaa/sprites/{863550ee-e9b8-4aa2-8ebb-e906b09dde3b.png → b5d4265c-82e0-470d-a48e-8aa4edbdef5a.png} +0 -0
  157. /kotonebot/kaa/sprites/{608de0a3-ce93-4344-8f9b-3cb3fab5ad12.png → b65724b4-ec8f-48a9-9ab2-e7ce5b8f35b2.png} +0 -0
  158. /kotonebot/kaa/sprites/{22ab93e6-0192-48e1-a85f-73ee8db00395.png → b8aada91-eedd-4c53-99f3-f903d547235e.png} +0 -0
  159. /kotonebot/kaa/sprites/{09a01092-0d32-4894-a47e-9983b39753df.png → ba759205-ce99-4417-8cab-d32fe55dff4c.png} +0 -0
  160. /kotonebot/kaa/sprites/{934e5383-b63c-472e-afdb-d184c92bdfe3.png → bb0ae68d-44d5-47c6-91dd-a529bc34225b.png} +0 -0
  161. /kotonebot/kaa/sprites/{55d105dc-c488-47d8-9b95-aba5707cfc2a.png → bed9575d-ccad-4f4e-825e-47b2a9cb0925.png} +0 -0
  162. /kotonebot/kaa/sprites/{3a0e917b-f419-4398-8638-77f696d47cd4.png → bfec58df-2628-454f-92aa-769cad186448.png} +0 -0
  163. /kotonebot/kaa/sprites/{1e9e795c-5dc1-4851-8d49-86181b9f4efe.png → c25c7ce5-ad8d-4b2c-83eb-ae6d4871a6c3.png} +0 -0
  164. /kotonebot/kaa/sprites/{c30d08f7-5c07-487a-86c3-122c082bb07b.png → c3ec61aa-f62e-46fd-b359-48864ea7a150.png} +0 -0
  165. /kotonebot/kaa/sprites/{685a7a90-8196-4a6a-a67a-4e7078965982.png → c484ca57-6b19-46b5-a107-1805a7488d48.png} +0 -0
  166. /kotonebot/kaa/sprites/{9e74a9e6-6ea5-4551-9578-8e561195bd3d.png → c571e1c0-ff85-4b2e-97ed-97d33b8d92e3.png} +0 -0
  167. /kotonebot/kaa/sprites/{a2ea2e0f-4f92-4769-9bc4-1ee10c43712c.png → c5e16f75-9b5a-4853-a144-275f3d20c186.png} +0 -0
  168. /kotonebot/kaa/sprites/{37f421f8-f615-43d1-a10f-f9a915a940d1.png → c5ea3dfd-6761-466e-b44c-86592ef05323.png} +0 -0
  169. /kotonebot/kaa/sprites/{276a66cc-95b1-4f86-b700-afa9c9f18149.png → ca2adfb8-1e88-4a31-b3cc-1f70568ce4a3.png} +0 -0
  170. /kotonebot/kaa/sprites/{bbfcc1ea-b441-4e81-85d2-52ce3bf4eb62.png → cb24b3df-1ec3-4ffd-95f1-ca4b0dd5b7da.png} +0 -0
  171. /kotonebot/kaa/sprites/{9f6aef36-f2e5-4208-9748-b6bbdb5546fd.png → cdbbb5ba-5117-488a-8172-48cfc92c14c6.png} +0 -0
  172. /kotonebot/kaa/sprites/{3851e552-fd41-4a15-a6b6-9636c773f67a.png → cf66ae12-48bc-4512-a988-0e5de337c76d.png} +0 -0
  173. /kotonebot/kaa/sprites/{74db3d1c-d6be-4d1f-92be-9bb3ffad7f51.png → d1699baa-467b-46d1-9276-aae78fe8f589.png} +0 -0
  174. /kotonebot/kaa/sprites/{8383a31c-a075-4b5f-b839-cbeb63a7aef3.png → d3e6e2e9-c5b5-463f-98f4-de72c9320d9d.png} +0 -0
  175. /kotonebot/kaa/sprites/{51b836ff-5f2c-4612-85f1-9db74761f300.png → d4c47cc7-5b3e-4c3e-8e80-78cb94e7eed9.png} +0 -0
  176. /kotonebot/kaa/sprites/{2e0f97d4-ce0b-4930-addd-cbdaedffc918.png → d5d854fc-1b87-43d4-b32d-66eccb66fa41.png} +0 -0
  177. /kotonebot/kaa/sprites/{593f4c04-4ca4-4bb0-8fea-ad3af32316f7.png → d60a395b-d907-416a-b091-36bfee4948b3.png} +0 -0
  178. /kotonebot/kaa/sprites/{19fae7eb-addd-4ea2-99ac-0f9262a4d9d6.png → dad4ff8c-07f4-4b07-abd3-5d02bbcc4562.png} +0 -0
  179. /kotonebot/kaa/sprites/{8778f70d-6bb8-4378-aed7-d77c798ab032.png → dbd537c7-d1d3-4d64-9ccd-43dd4519bedd.png} +0 -0
  180. /kotonebot/kaa/sprites/{7250e776-3195-406c-ac6f-ec7dbed49cbe.png → dde03640-6c3a-4b13-a783-f672816bfec4.png} +0 -0
  181. /kotonebot/kaa/sprites/{4b87be27-868a-40fb-b7e4-67c963c6c4b2.png → df97421e-4b74-430e-b3d1-ed9bac6918a7.png} +0 -0
  182. /kotonebot/kaa/sprites/{7079f76b-e2a3-487c-8616-28ce505f5a0e.png → dfb14c98-f672-4906-80bd-d2a18bdd62cd.png} +0 -0
  183. /kotonebot/kaa/sprites/{b3f1b38f-77d0-4dd5-8c19-8a35bbc39516.png → e1e0d751-9006-4fa4-a933-4c0dc5e1f3d2.png} +0 -0
  184. /kotonebot/kaa/sprites/{aa8c4533-bd58-496e-a460-6fa47f7ded83.png → e394ff91-09d3-41e1-bbf5-bc42a71a623b.png} +0 -0
  185. /kotonebot/kaa/sprites/{72b7124a-baf2-4d60-9553-2634370a6d49.png → e5259dfb-3a49-4cfc-9f89-b42958ce6eec.png} +0 -0
  186. /kotonebot/kaa/sprites/{c072da5f-bd35-4e8b-8f32-6c5df18c3aea.png → e5eeb9af-8003-4981-bf56-2e32e76cec5d.png} +0 -0
  187. /kotonebot/kaa/sprites/{46ed11a3-f89e-4d5c-b534-da88d38b382b.png → e9c45a73-2011-4584-87b7-c4e566eba87f.png} +0 -0
  188. /kotonebot/kaa/sprites/{e3cfea3a-3dc4-412b-b226-f9034f5b51f1.png → eae83523-e58c-4db9-a356-4335a5da3dc8.png} +0 -0
  189. /kotonebot/kaa/sprites/{f3b4bb3b-f8d6-4ed0-8bde-0d3322bd8391.png → ed6d3e3d-0f04-4fa4-b0f9-fdbf324649f6.png} +0 -0
  190. /kotonebot/kaa/sprites/{fe031296-8000-4fdc-ab3f-b4aae2af6e5d.png → efb28e1d-7b52-4e20-aec5-117c798b7fbe.png} +0 -0
  191. /kotonebot/kaa/sprites/{b4afb6bd-e049-4b2e-b1ca-26333c7afcb0.png → f025027f-daa0-4943-8395-5d7d44cc7f15.png} +0 -0
  192. /kotonebot/kaa/sprites/{cd53bad6-81fa-4e15-8fe7-5a992367bf90.png → f12c2b0b-8273-4197-a8c6-2a8ef2788a9b.png} +0 -0
  193. /kotonebot/kaa/sprites/{86bcda3a-c7a6-4abf-ae4c-968788f3c667.png → f528ea0e-1e55-4e41-844f-bb1db9185ef8.png} +0 -0
  194. /kotonebot/kaa/sprites/{9b798f35-e745-4964-931d-3e0ae811174d.png → f611bbd9-c062-4989-96a4-65ff6c59673c.png} +0 -0
  195. /kotonebot/kaa/sprites/{de0b3d75-7dc8-4433-a275-2584e9d7ed0b.png → f6bfbf6a-6e53-4563-9345-3f3756d6ea9a.png} +0 -0
  196. /kotonebot/kaa/sprites/{6e338dd7-6834-4e9b-8ac1-afecdff16c43.png → f72bd3d6-850d-4190-9775-938f474d263c.png} +0 -0
  197. /kotonebot/kaa/sprites/{86501f18-e5fd-4a66-a360-20e34935f1a9.png → f8eec9b2-55ca-4195-b098-a5393d02a98a.png} +0 -0
  198. /kotonebot/kaa/sprites/{a1a03d83-6a3b-481a-a807-931f2b0f7cd2.png → faf069e1-f623-47c1-b879-cfa246fbc7df.png} +0 -0
  199. /kotonebot/kaa/sprites/{8e04cb5c-ce45-49d9-81a9-2e5f717d3eb2.png → faf360e8-7845-4fcf-b0a6-0f5f93c050f1.png} +0 -0
  200. {ksaa-2025.5.23.3.dist-info → ksaa-2025.6.23.0.dist-info}/WHEEL +0 -0
  201. {ksaa-2025.5.23.3.dist-info → ksaa-2025.6.23.0.dist-info}/entry_points.txt +0 -0
  202. {ksaa-2025.5.23.3.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
@@ -1,4 +1,5 @@
1
1
  """启动游戏,领取登录奖励,直到首页为止"""
2
+ import json
2
3
  import os
3
4
  import ctypes
4
5
  import logging
@@ -14,6 +15,37 @@ from kotonebot import task, action, sleep, device, image, ocr, config
14
15
 
15
16
  logger = logging.getLogger(__name__)
16
17
 
18
+ def locate_game_path() -> str | None:
19
+ """自动获取 DMM 版游戏路径。"""
20
+ logger.info('Locating DMM game path...')
21
+ app_data = os.getenv('APPDATA')
22
+ if not app_data:
23
+ logger.info('APPDATA not found. Location failed.')
24
+ return None
25
+ dmm_config_path = os.path.join(app_data, 'dmmgameplayer5', 'dmmgame.cnf')
26
+ if not os.path.exists(dmm_config_path):
27
+ logger.warning('DMM config does not exist. Location failed.')
28
+ return None
29
+ with open(dmm_config_path, 'r', encoding='utf-8') as f:
30
+ dmm_config = json.load(f)
31
+ for content in dmm_config.get('contents', []):
32
+ if content.get('productId') == 'gakumas':
33
+ game_path = content.get('detail', {}).get('path')
34
+ if game_path:
35
+ break
36
+ else:
37
+ logger.warning('Game "gakumas" not found in DMM config.')
38
+ return None
39
+ logger.info(f'Game path: {game_path}')
40
+ if game_path:
41
+ game_path = os.path.join(game_path, 'gakumas.exe')
42
+ if game_path and not conf().start_game.dmm_game_path:
43
+ logger.info('Saving game path to config...')
44
+ conf().start_game.dmm_game_path = game_path
45
+ config.save()
46
+ return game_path
47
+
48
+
17
49
  @action('启动游戏.进入首页', screenshot_mode='manual-inherit')
18
50
  def wait_for_home():
19
51
  """
@@ -63,8 +95,9 @@ def android_launch():
63
95
  前置条件:-
64
96
  结束状态:-
65
97
  """
98
+ _device = device.of_android()
66
99
  # 如果已经在游戏中,直接返回home
67
- if device.current_package() == conf().start_game.game_package_name:
100
+ if _device.current_package() == conf().start_game.game_package_name:
68
101
  logger.info("Game already started")
69
102
  if not at_home():
70
103
  logger.info("Not at home, going to home")
@@ -74,15 +107,15 @@ def android_launch():
74
107
  # 如果不在游戏中,启动游戏
75
108
  if not conf().start_game.start_through_kuyo:
76
109
  # 直接启动
77
- device.launch_app(conf().start_game.game_package_name)
110
+ _device.launch_app(conf().start_game.game_package_name)
78
111
  else:
79
112
  # 通过Kuyo启动
80
- if device.current_package() == conf().start_game.kuyo_package_name:
113
+ if _device.current_package() == conf().start_game.kuyo_package_name:
81
114
  logger.warning("Kuyo already started. Auto start game failed.")
82
115
  # TODO: Kuyo支持改进
83
116
  return
84
117
  # 启动kuyo
85
- device.launch_app('org.kuyo.game')
118
+ _device.launch_app('org.kuyo.game')
86
119
  # 点击"加速"
87
120
  device.click(image.expect_wait(R.Kuyo.ButtonTab3Speedup, timeout=10))
88
121
  # Kuyo会延迟加入广告,导致识别后,原位置突然弹出广告,导致进入广告页面
@@ -106,10 +139,26 @@ def windows_launch():
106
139
  is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0
107
140
  if not is_admin:
108
141
  raise PermissionError("Please run as administrator.")
109
-
142
+
143
+ # 处理汉化插件
144
+ if conf().start_game.disable_gakumas_localify:
145
+ logger.info('Disabling Gakumas Localify...')
146
+ game_path = conf().start_game.dmm_game_path or locate_game_path()
147
+ logger.debug('Game path: %s', game_path)
148
+ if not game_path:
149
+ raise ValueError('dmm_game_path unset and auto-locate failed.')
150
+
151
+ plugin_path = os.path.join(os.path.dirname(game_path), 'version.dll')
152
+ logger.debug('Plugin path: %s', plugin_path)
153
+ if not os.path.exists(plugin_path):
154
+ logger.warning('Gakumas Localify not found. Skipped disable.')
155
+ else:
156
+ os.rename(plugin_path, plugin_path + '.disabled')
157
+ logger.info('Gakumas Localify disabled.')
158
+
110
159
  from ahk import AHK
111
- from importlib import resources
112
- 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()
113
162
  ahk = AHK(executable_path=ahk_path)
114
163
 
115
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,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ksaa
3
- Version: 2025.5.23.3
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
7
+ License-File: LICENSE
7
8
  Requires-Dist: opencv-python==4.10.0.84
8
9
  Requires-Dist: rapidocr_onnxruntime==1.4.3
9
10
  Requires-Dist: av==14.0.1
@@ -25,6 +26,7 @@ Requires-Dist: onnxruntime==1.14.0
25
26
  Requires-Dist: numpy<2.0
26
27
  Requires-Dist: pywin32==310
27
28
  Requires-Dist: ahk==1.8.3
29
+ Dynamic: license-file
28
30
 
29
31
  # Kotone's Auto Assistant 琴音小助手
30
32
  ## 功能
@@ -96,6 +98,41 @@ TODO
96
98
  > 建议**使用亲密度至少为 7 的偶像**进行培育,
97
99
  > 因为琴音小助手暂时无法处理亲密度提升事件。
98
100
 
101
+ ## 开源协议
102
+ kaa 本体及框架(kotonebot 文件夹)、相关辅助脚本(tools 文件夹)使用 **GPLv3 协议**开源。kaa 开发工具(kotonebot-devtool)、启动器(bootstrap 文件夹)以 **MIT 协议**开源。
103
+
104
+ kaa 的开发主要用到了以下开源项目:
105
+ * [GkmasObjectManager
106
+ ](https://github.com/AllenHeartcore/GkmasObjectManager):用于提取游戏图像资源,以 GPLv3 协议开源。
107
+ * [gakumasu-diff](https://github.com/vertesan/gakumasu-diff):游戏数据。
108
+
109
+
110
+ ## 免责声明
111
+ **请在使用本项目前仔细阅读以下内容。使用本脚本将带来包括但不限于账号被封禁的风险。**
112
+
113
+ ### 总则
114
+ 本项目(琴音小助手)是一个为游戏 **《学园偶像大师》(学園アイドルマスター)** 设计的自动操作脚本。本项目的创建目的仅为技术学习与研究,并非为了提供商业服务或鼓励不正当的游戏行为。
115
+
116
+ ### 版权声明
117
+ 本项目所使用的部分资源文件,包括但不限于图像、音频、模型等,其版权归属于其原始权利人。该游戏的开发商为 **QualiArts**,发行商为**万代南梦宫娱乐(Bandai Namco Entertainment Inc.)**。
118
+
119
+ 1. **权利归属**:本项目中使用的所有相关游戏资源文件的版权、商标权及其他一切知识产权,均归 **QualiArts**、**万代南梦宫娱乐**或其相关权利方所有。
120
+
121
+ 2. **非官方性质**:本项目为非官方、非商业性质的开源项目。本项目的开发者与 **QualiArts** 及 **万代南梦宫娱乐**没有任何形式的关联、合作或官方授权。
122
+
123
+ ### 核心风险与责任限制
124
+ 1. **账号封禁风险**:**您必须清楚地认识到,使用任何形式的第三方自动操作脚本(包括本项目)都有违反《学园偶像大师》的用户协议(利用規約)的潜在风险。游戏运营商有权对使用此类脚本的账号采取惩罚措施,包括但不限于临时或永久封禁账号。对于因使用本脚本而导致的任何账号损失(如封号、数据回滚等),项目作者概不负责。**
125
+
126
+ > ・对本服务的服务器等进行非法访问、窃取数据、使用使软件进行非法处理的程序、使用工具等获取信息或使用工具等不正当推进游戏的行为。
127
+
128
+ > ・本サービスのサーバー等への不正アクセス行為、データ窃取行為、ソフトウェアに不正な処理を行わせるプログラムを使用する行為、ツール等を使用して情報を取得する行為またはツール等を使用して不正にゲームを有利に進める行為
129
+
130
+ 2. **使用限制**:本项目的全部内容**严禁用于任何商业用途或恶意破坏游戏平衡的行为**。任何将本项目用于此类活动的行为,均可能构成对版权方的侵权和对游戏运营商的违约,由此产生的一切法律责任由使用者自行承担。
131
+
132
+ 3. **无担保与责任限制**:本项目按“原样”提供,不附带任何形式的明示或暗示担保,包括其功能的稳定性、准确性或持续可用性。对于因使用或无法使用本项目而导致的任何直接、间接、偶然、特殊或继发性损害(**包括但不限于账号封禁**),项目作者概不负责。
133
+
134
+ **继续下载、安装或使用本项目,即表示您已完全阅读、理解并同意承担以上所有风险和条款。如果您不同意,请立即停止使用并删除本项目的所有相关文件。**
135
+
99
136
  ## 开发
100
137
  见 [DEVELOPMENT.md](./docs/DEVELOPMENT.md)
101
138