ksaa 2025.4.17.2__py3-none-any.whl → 2025.4.26.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 (162) hide show
  1. kotonebot/backend/bot.py +18 -3
  2. kotonebot/client/factory.py +16 -1
  3. kotonebot/client/implements/remote_windows.py +197 -0
  4. kotonebot/config/base_config.py +4 -2
  5. kotonebot/tasks/R.py +156 -138
  6. kotonebot/tasks/common.py +53 -16
  7. kotonebot/tasks/end_game.py +94 -0
  8. kotonebot/tasks/main/cli.py +19 -0
  9. kotonebot/tasks/main/gr.py +189 -73
  10. kotonebot/tasks/metadata.py +18 -0
  11. kotonebot/tasks/produce/in_purodyuusu.py +103 -65
  12. kotonebot/tasks/produce/non_lesson_actions.py +93 -20
  13. kotonebot/tasks/produce/produce.py +29 -15
  14. kotonebot/tasks/resources/__pycache__/__init__.cpython-310.pyc +0 -0
  15. kotonebot/tasks/resources/game.db +0 -0
  16. kotonebot/tasks/resources/game_ver.txt +0 -0
  17. kotonebot/tasks/sprites/208463e9-cbe8-45a7-b721-d72b34ef59db.png +0 -0
  18. kotonebot/tasks/sprites/23d88465-65d9-4718-8725-8dbf0a98a5a4.png +0 -0
  19. kotonebot/tasks/sprites/25f00ee3-8dfe-42d1-a67e-191fa5c3df4b.png +0 -0
  20. kotonebot/tasks/sprites/3c8b477a-8eda-407e-9e9f-7540c8808f89.png +0 -0
  21. kotonebot/tasks/sprites/4096cffa-a889-4622-852e-760fc7022d93.png +0 -0
  22. kotonebot/tasks/sprites/772adec4-a38c-4b3d-b2eb-35c50168783f.png +0 -0
  23. kotonebot/tasks/sprites/9fd0753f-c607-4d49-82d1-40bda27e014f.png +0 -0
  24. kotonebot/tasks/sprites/d83f338d-dde3-494b-9bea-cae511e3517c.png +0 -0
  25. kotonebot/tasks/start_game.py +5 -2
  26. kotonebot/util.py +1 -0
  27. {ksaa-2025.4.17.2.dist-info → ksaa-2025.4.26.0.dist-info}/METADATA +1 -1
  28. {ksaa-2025.4.17.2.dist-info → ksaa-2025.4.26.0.dist-info}/RECORD +162 -152
  29. {ksaa-2025.4.17.2.dist-info → ksaa-2025.4.26.0.dist-info}/WHEEL +1 -1
  30. /kotonebot/tasks/sprites/{05d78c7e-0c5f-4710-9285-8c95fe73b88b.png → 056a629e-242e-4bfc-9bd5-bb974a9fb4ef.png} +0 -0
  31. /kotonebot/tasks/sprites/{7253d078-05b4-4518-af0c-ce0d84445a76.png → 0c188f78-d5b3-4fe1-b486-69cb975aeeb4.png} +0 -0
  32. /kotonebot/tasks/sprites/{a9c4a376-33bc-43ec-a153-a4733d32cd26.png → 0c5b29d4-9595-4739-928a-289ac670727d.png} +0 -0
  33. /kotonebot/tasks/sprites/{68863cef-f992-4458-94c2-e1d428840585.png → 0cbbd1eb-86c4-4155-9101-1dc8bc295c00.png} +0 -0
  34. /kotonebot/tasks/sprites/{e3304287-a0ee-4eff-8ddb-8f0a697188fc.png → 152b54dd-3b06-487e-821a-cc2348cb1113.png} +0 -0
  35. /kotonebot/tasks/sprites/{034e0502-00d2-4e9d-9be3-205b8055f74c.png → 15a9e393-8e42-482c-8706-6b95d419ecf5.png} +0 -0
  36. /kotonebot/tasks/sprites/{84276f4c-50ca-47fc-b5f3-66364abb1b0e.png → 165f585c-1d26-4a3a-baa0-eb1fac8f88f4.png} +0 -0
  37. /kotonebot/tasks/sprites/{b3d90f5c-ded1-4d7c-aeda-0ed252e4fdbe.png → 17bf6042-b4b0-4fa0-89c8-9da8c9569457.png} +0 -0
  38. /kotonebot/tasks/sprites/{d0fe95f8-ebec-4a4e-8132-39500ef0c76e.png → 17efa369-de88-44a7-9fe4-00da62ceaf72.png} +0 -0
  39. /kotonebot/tasks/sprites/{25693c38-d638-47f2-8c02-17a67c101d55.png → 17f53690-ee3c-4479-8014-149775733979.png} +0 -0
  40. /kotonebot/tasks/sprites/{6d30c494-bf10-4a26-b026-11b15682ce03.png → 1a6f4158-d50f-4d3b-b608-f947c4dde26b.png} +0 -0
  41. /kotonebot/tasks/sprites/{c17aab08-bd50-45ec-bfd4-72fd3e3b9e5b.png → 1a6fe30b-bd69-4c46-af93-f93842b0dcd9.png} +0 -0
  42. /kotonebot/tasks/sprites/{24ee9323-9476-48da-aac0-eb9a3da47ce5.png → 1b0e8f53-6fc6-4341-92d8-3e2f4a662676.png} +0 -0
  43. /kotonebot/tasks/sprites/{0b74125e-03dd-46cb-9e6b-41b15334e613.png → 1ce57116-fbad-450d-aa9a-1e59dfe83698.png} +0 -0
  44. /kotonebot/tasks/sprites/{5b9e73f0-9deb-4a59-8907-0aab694e71b4.png → 1d8d20e8-7037-4c80-b2a0-a87597ed25de.png} +0 -0
  45. /kotonebot/tasks/sprites/{bb5f128a-2bf3-42a6-af1f-62643340dece.png → 241f635c-d479-4508-bfcc-e555d4820ccb.png} +0 -0
  46. /kotonebot/tasks/sprites/{27ec16e8-1e39-4694-9c06-5d67d72afb09.png → 258ceabd-efb9-441b-8474-2d64cd8ae229.png} +0 -0
  47. /kotonebot/tasks/sprites/{83f18e1a-90f3-40c4-a01b-eadd21f4a135.png → 262d7636-389e-48b3-94c0-50cd4b9ab3ec.png} +0 -0
  48. /kotonebot/tasks/sprites/{68276791-c4c1-41c5-bf13-eb3e2c708ad0.png → 2658cf2a-ef0d-4849-9309-b35d5c0173f5.png} +0 -0
  49. /kotonebot/tasks/sprites/{f145cdff-2eb0-4429-bdf7-a2701640f4cb.png → 27036a5b-6604-4244-8dd4-57b3f27eecdc.png} +0 -0
  50. /kotonebot/tasks/sprites/{82193e69-a777-48a7-bcf5-fe9b0920db93.png → 2b363bc8-0a17-42f7-8caa-d03ccdf0e15f.png} +0 -0
  51. /kotonebot/tasks/sprites/{9f44c556-c481-4f0b-835b-41091e196141.png → 2c505b36-3c6c-4914-9cd6-dafdfc9cc01c.png} +0 -0
  52. /kotonebot/tasks/sprites/{dc515ece-409b-45e9-8dad-77e09a1cea8c.png → 2ead898a-112c-49e9-a689-14d526144931.png} +0 -0
  53. /kotonebot/tasks/sprites/{18db3c71-061e-4ccb-8fda-ca06a530b64b.png → 2f9cc1c9-915c-405a-8f9d-2b56c822de63.png} +0 -0
  54. /kotonebot/tasks/sprites/{79ce2616-39bb-4143-8d07-253709951185.png → 30e3df65-9bf8-4178-88c1-538e763e47cf.png} +0 -0
  55. /kotonebot/tasks/sprites/{f6171a54-bd80-4207-a61d-4a2ffd3fc5d8.png → 3384166f-5462-41bc-ace1-bf60f2aa19a3.png} +0 -0
  56. /kotonebot/tasks/sprites/{be7a1734-9b8d-4714-96d4-9ce6907906fb.png → 33f831fb-43e7-485f-a4a8-d643126c7837.png} +0 -0
  57. /kotonebot/tasks/sprites/{bcc98e91-1c21-4f5b-9e9a-039af3f8f34f.png → 349698bd-f5ee-497f-ba93-f6baed5b44b4.png} +0 -0
  58. /kotonebot/tasks/sprites/{fad894d2-73a8-49cb-97ac-64c5167d236e.png → 3522aa93-a1aa-4674-a70a-e51a23700413.png} +0 -0
  59. /kotonebot/tasks/sprites/{f5d72cb3-a3c3-41fd-ae61-c65bbe9fa12c.png → 35cea915-cfe5-4d94-88c7-ffba843292d1.png} +0 -0
  60. /kotonebot/tasks/sprites/{2f3b9110-5ddf-4c2c-97ee-0292c3cbf6b6.png → 3bbf29aa-921d-4b7b-be17-881375d03c02.png} +0 -0
  61. /kotonebot/tasks/sprites/{0c4d5dc0-359b-4af4-963e-fd79d13a5a8a.png → 3c261188-de36-4a6b-8255-52bd089557c9.png} +0 -0
  62. /kotonebot/tasks/sprites/{7bafd109-da67-41ad-af00-710693162139.png → 3d6f64ea-95ae-4bce-9ca5-8627e05bd746.png} +0 -0
  63. /kotonebot/tasks/sprites/{b4fb066b-1f49-44d1-8755-e7acc9711afb.png → 3e233f05-c783-4790-aa21-aafc33914a96.png} +0 -0
  64. /kotonebot/tasks/sprites/{b92079f2-88cb-4a8d-bcbd-7248f28e438e.png → 40761930-a1f1-476c-aada-143969076651.png} +0 -0
  65. /kotonebot/tasks/sprites/{facacf54-4273-41d6-9033-aa5a5d133450.png → 40bba601-c36a-41bd-861c-fe13a0f0eb5e.png} +0 -0
  66. /kotonebot/tasks/sprites/{30c1db28-6202-420b-be91-11a433eb14f2.png → 41698ac4-0db8-4539-8876-c5c01cda43c0.png} +0 -0
  67. /kotonebot/tasks/sprites/{1b0dc6cf-62ba-4b99-862a-1ce764c70e26.png → 470b5761-0a7b-4a49-b1a9-4bf4a81371b8.png} +0 -0
  68. /kotonebot/tasks/sprites/{802bf373-cfcf-4d1e-afde-fc21ab00c2ed.png → 470d3807-c50b-46f0-aec5-19b3e55f8674.png} +0 -0
  69. /kotonebot/tasks/sprites/{f3c8afba-c230-4566-ba5a-2668f8b3c4cb.png → 50028cad-b460-4889-9b3f-a915b20aaee2.png} +0 -0
  70. /kotonebot/tasks/sprites/{63c3ac21-c9fd-4879-bd54-81c3f3550639.png → 52b5038f-c10f-4e01-a4f7-14479f51ca94.png} +0 -0
  71. /kotonebot/tasks/sprites/{2c518744-f00f-4a36-b8a5-cb4b8ca7dacc.png → 5732647f-2bf2-47aa-a214-0b883a741ec2.png} +0 -0
  72. /kotonebot/tasks/sprites/{cea6f17a-3269-485c-b507-d5bcace0da4f.png → 57ab058a-e791-4a8d-a811-e3a0c9c85785.png} +0 -0
  73. /kotonebot/tasks/sprites/{8dff2e43-537b-4eaa-860b-93053b52c31c.png → 57bcf309-a634-4a75-a554-1a942dae4a7e.png} +0 -0
  74. /kotonebot/tasks/sprites/{c8e4d52a-d21e-492e-9b7a-6543fd0d5a95.png → 59049d4d-af07-4a98-8be2-174efdca8177.png} +0 -0
  75. /kotonebot/tasks/sprites/{07b46a97-3ed4-48f9-881b-5228f4b3ada9.png → 590ea94a-92db-46c3-84e2-69f413bb16d1.png} +0 -0
  76. /kotonebot/tasks/sprites/{834356a9-b332-46fc-bd04-caea1d58b138.png → 59481a16-05ac-4c96-ac80-d39ee2861821.png} +0 -0
  77. /kotonebot/tasks/sprites/{11e195bb-7107-40b4-aea5-173441f1c9b2.png → 5b49aab0-67a5-4b04-b61f-8c2ef4b56c53.png} +0 -0
  78. /kotonebot/tasks/sprites/{6831a0ce-1803-4138-9e75-83ccaf095745.png → 5b6f1ada-b671-4037-a23a-9ca5556540b7.png} +0 -0
  79. /kotonebot/tasks/sprites/{2ec293e3-8e18-4ffe-ad5e-0d23eebac96d.png → 5cc327f5-ed47-44e7-94dc-ed0ae287f6ec.png} +0 -0
  80. /kotonebot/tasks/sprites/{43fab6cf-6330-4f0a-a560-3e060b1e79fa.png → 5e0b2e63-329c-4ca6-80f5-3a3c7bea3197.png} +0 -0
  81. /kotonebot/tasks/sprites/{3e7a9b6e-e469-41f7-9073-1709cfeaf6cf.png → 5e4838dc-e524-4350-b7d0-070e979b51d0.png} +0 -0
  82. /kotonebot/tasks/sprites/{19ebee01-0a40-4750-9fec-bc9bd1fc1cd4.png → 610d0228-77a8-4d40-8363-668d07852f0f.png} +0 -0
  83. /kotonebot/tasks/sprites/{f332ea63-a58b-41ee-8426-7245f5fd96c2.png → 616370a6-302f-47be-a71b-d1b253ef5d26.png} +0 -0
  84. /kotonebot/tasks/sprites/{e5bc55d2-d2ee-4be9-b068-ef0c1ce6a6ac.png → 64b8f151-f3bb-46a5-b66b-6364644e5c57.png} +0 -0
  85. /kotonebot/tasks/sprites/{db246a45-b3c7-4983-9f1f-db88f8126d38.png → 7298faf9-303d-4b17-b4ec-d72189620415.png} +0 -0
  86. /kotonebot/tasks/sprites/{c840a295-dc0e-4906-94ab-ee3ec24c7416.png → 73d633bf-87dc-4f00-8bab-1cee26bb57f4.png} +0 -0
  87. /kotonebot/tasks/sprites/{f34ccd13-7602-4490-a7a3-1a4bffd82c90.png → 73d6d47c-d47e-4bfa-b37d-94e4546294a7.png} +0 -0
  88. /kotonebot/tasks/sprites/{d0bf1d05-a48d-4895-b5dd-b2b1b9012d37.png → 74ea1223-aa62-4f27-862c-58cfac0f6f1b.png} +0 -0
  89. /kotonebot/tasks/sprites/{1455365d-c213-4476-864b-644d14ba0218.png → 74f05b71-468b-42a7-960d-aec2ee888314.png} +0 -0
  90. /kotonebot/tasks/sprites/{03e0fd71-8b2c-4b65-bbdf-363c5aa96bb7.png → 75b9f513-25ec-4e47-b71e-b9c86bb318d0.png} +0 -0
  91. /kotonebot/tasks/sprites/{903bab6b-e831-4b80-a087-3f213d5678e6.png → 75d35137-25f0-4cb1-b934-aad4b28013c1.png} +0 -0
  92. /kotonebot/tasks/sprites/{799d5bc5-9fe1-416b-ac3c-26d89d2f5ed2.png → 75e16c86-d0bd-42e0-8624-368a95f2b7fa.png} +0 -0
  93. /kotonebot/tasks/sprites/{14e6b7ae-3db6-4fd9-ba6a-fae4ec63064a.png → 76377a1e-92af-4d79-84ba-7d9060411336.png} +0 -0
  94. /kotonebot/tasks/sprites/{da113628-d106-43a0-9e74-99aa93a57aad.png → 77b359e6-7dc9-44cf-baa4-85a8abc40fc5.png} +0 -0
  95. /kotonebot/tasks/sprites/{dea50b1c-7005-4f9e-b188-bf94c157af15.png → 78512fc1-11b8-4a12-b06e-63b09604a27f.png} +0 -0
  96. /kotonebot/tasks/sprites/{a9582588-9809-45ff-9400-fde668480906.png → 7a4e2bc7-7f5e-482a-bbce-0d8a4801b502.png} +0 -0
  97. /kotonebot/tasks/sprites/{7cebfa84-fc03-4544-bdab-71d8940dfc72.png → 7a983ea5-c05f-42ee-95a9-9f1c6ef6deac.png} +0 -0
  98. /kotonebot/tasks/sprites/{373a5761-afaa-4763-9264-c38df17535ec.png → 7e2d836d-cd59-43a9-978b-3e333273712c.png} +0 -0
  99. /kotonebot/tasks/sprites/{dcba6a05-4720-4075-bbce-b76baa8c6ab4.png → 80d0e08b-7179-456f-8228-b9dcf6ccb6f1.png} +0 -0
  100. /kotonebot/tasks/sprites/{5fa367ec-6d48-4891-aa78-80762ec4e958.png → 811dd2d9-6e28-4bf3-97bf-537e068a3701.png} +0 -0
  101. /kotonebot/tasks/sprites/{a9276e58-5764-476b-925d-28854bf5db5f.png → 8520878d-15c6-4bcf-95c9-921666f23525.png} +0 -0
  102. /kotonebot/tasks/sprites/{3bfec2af-854e-4a3c-ad91-a272b0b9b413.png → 85e3c4ba-95ee-46c8-904a-cea3f8ad48db.png} +0 -0
  103. /kotonebot/tasks/sprites/{f872dcba-5174-472c-abda-c44696b4fa43.png → 88d94d19-d1b2-4e7e-a342-4f5c47832542.png} +0 -0
  104. /kotonebot/tasks/sprites/{60e90826-df0a-41d7-bf89-9e820577fc65.png → 8c4895ce-c87c-479d-9b6b-fa4da5e7eca6.png} +0 -0
  105. /kotonebot/tasks/sprites/{eeddb9f2-4f90-443f-8494-6c205ba2f48d.png → 8e3a8e95-b504-490a-9c85-65ce134e9d33.png} +0 -0
  106. /kotonebot/tasks/sprites/{25e5b8da-29c8-40e0-abb0-af288f5d5b3c.png → 8f6df3a3-7bad-4ad2-9f39-7cd2c8a92c68.png} +0 -0
  107. /kotonebot/tasks/sprites/{6e5c8c24-465b-4594-93ba-86558a37d42c.png → 918c27be-ab0e-42bd-b470-cb48907d229e.png} +0 -0
  108. /kotonebot/tasks/sprites/{ce61a356-d19c-4a89-a2d6-0cc1bff147b8.png → 93f973b7-f700-49ec-b484-b74a50fda5b2.png} +0 -0
  109. /kotonebot/tasks/sprites/{36c6e2ca-6ff7-4642-bb91-6847b743eba3.png → 966dafff-c26e-4043-9f7d-39133c860de6.png} +0 -0
  110. /kotonebot/tasks/sprites/{14a90b3a-49cb-4f53-a41b-3e26e0bbd480.png → 973e2f4d-5693-47b4-b555-f243ef2d86fe.png} +0 -0
  111. /kotonebot/tasks/sprites/{be7ba2ab-3405-45c6-86a9-87f5a8fb2335.png → 9ad18387-a834-46fa-ab85-b09fec60b89e.png} +0 -0
  112. /kotonebot/tasks/sprites/{0a619440-9d31-4a76-9dd5-ad4aafb0817e.png → 9b8604fb-6dfa-471a-aeb4-458d5d59f726.png} +0 -0
  113. /kotonebot/tasks/sprites/{51f2ce40-246d-45cf-8c61-00617118fb66.png → 9b86c2e6-2d97-4c49-9e00-27ed7dfe8cd5.png} +0 -0
  114. /kotonebot/tasks/sprites/{caeafb3e-34ee-4996-b22d-01043803023d.png → 9e35b9d0-dfde-41d0-ab10-0d95e7008d99.png} +0 -0
  115. /kotonebot/tasks/sprites/{108999f3-bf8e-4037-b85f-7c9a848d69fe.png → a23742d9-9199-43c1-922b-d7f286bccbde.png} +0 -0
  116. /kotonebot/tasks/sprites/{ff789de2-98d8-4b88-8f70-83d8ce15dc3e.png → a2dae26f-14a7-46d3-bfa6-2bec94cce843.png} +0 -0
  117. /kotonebot/tasks/sprites/{07a2184b-5240-4f60-811c-dd7dfa663e77.png → a3988fad-4f8f-46c8-a6ef-d64dccdfbe5d.png} +0 -0
  118. /kotonebot/tasks/sprites/{6898af97-010a-4640-92bc-853fe563fd31.png → a65bec5b-2875-4bd7-9c06-7c941946b00e.png} +0 -0
  119. /kotonebot/tasks/sprites/{304c44f5-384d-4c94-b801-25974e0071d4.png → a688ef42-79c2-4de5-88d1-4a6e0cb65829.png} +0 -0
  120. /kotonebot/tasks/sprites/{49acc597-207f-48b1-b8ac-2c4246b00585.png → a6895be9-f7c2-4889-88d4-8b3906ed80ff.png} +0 -0
  121. /kotonebot/tasks/sprites/{57ce1f5a-c2cf-4fb7-b066-244b4dcbba98.png → a9567e98-c2fa-42c3-896b-73a6aaeb5379.png} +0 -0
  122. /kotonebot/tasks/sprites/{3e48784d-8fef-4d80-9bc3-dededa66a24e.png → aa01cacc-cf11-488c-a315-3ab807bda741.png} +0 -0
  123. /kotonebot/tasks/sprites/{ad877757-251f-470b-947a-62b31982313c.png → ac238fb2-492d-4f8c-b8d8-5e6b5451aac0.png} +0 -0
  124. /kotonebot/tasks/sprites/{a3618dea-720a-4fa5-be7f-5b171331b027.png → ad0624ab-c9af-4224-8128-1306d63cbbfa.png} +0 -0
  125. /kotonebot/tasks/sprites/{dce05535-a13e-4409-96f9-10a9ab742e85.png → b18ead61-b3de-4a39-9ed0-664b64f45a6a.png} +0 -0
  126. /kotonebot/tasks/sprites/{be5f1221-2bc9-4512-b975-f204c9c28732.png → b210716c-6b40-4fba-887e-50e48a0d53ab.png} +0 -0
  127. /kotonebot/tasks/sprites/{0cfbc864-e698-44b3-9f89-6c1715bf55a8.png → b399e131-25b2-4f26-8757-533c1009dddc.png} +0 -0
  128. /kotonebot/tasks/sprites/{a565cca2-837d-479d-93e7-f3067013958a.png → b6c42310-592a-4cdd-a106-3f8bb0f3df30.png} +0 -0
  129. /kotonebot/tasks/sprites/{6ac60114-3f39-4965-b559-dcd85c072308.png → b8667106-89e4-41e7-b0f4-d13eb8e4ab54.png} +0 -0
  130. /kotonebot/tasks/sprites/{d9b77ac7-6708-4d2b-aef7-ecebb21df573.png → b96bbdef-93c9-4965-9ff4-805c953143d8.png} +0 -0
  131. /kotonebot/tasks/sprites/{913aa235-9ee7-4022-85e5-0611fed1fb08.png → bb46f878-7976-408d-a671-12854f7dcffb.png} +0 -0
  132. /kotonebot/tasks/sprites/{01162a01-9a9a-4cee-b607-7f3a67c47087.png → be4a9682-8828-42ef-88f2-e177dd8f0e01.png} +0 -0
  133. /kotonebot/tasks/sprites/{c46da919-190b-49ec-8b81-669f4f4e4de4.png → bfa4c9ec-f54c-4fbd-92b8-1bca9f2354e7.png} +0 -0
  134. /kotonebot/tasks/sprites/{abf4c9a1-d24f-4559-92d2-98dd30b3a5a2.png → bfbd85ee-5256-4a81-82b5-70da967a0004.png} +0 -0
  135. /kotonebot/tasks/sprites/{b74e708a-6497-4d9a-afdb-16bf2ce99af3.png → c4fded0c-8075-49a9-a56c-9591a004f4e3.png} +0 -0
  136. /kotonebot/tasks/sprites/{5082dc0d-3b59-4282-b714-89f11a0759a1.png → c6177849-daa3-4e1f-92de-2cc68b752e68.png} +0 -0
  137. /kotonebot/tasks/sprites/{587cba78-6af2-4913-8a02-da177c785ad2.png → c6d16470-3952-465d-8e7e-0e1e8c5a79a2.png} +0 -0
  138. /kotonebot/tasks/sprites/{82a2720d-7952-41a8-97e8-cb7986382e36.png → c7632864-0678-4ab1-8f22-414d8f1a1b1d.png} +0 -0
  139. /kotonebot/tasks/sprites/{5ec43604-92db-4256-8aec-f6966af73002.png → cb2c4421-5504-4a0c-b568-3e25a7a568ab.png} +0 -0
  140. /kotonebot/tasks/sprites/{d2d4df1f-d29b-479c-b0a6-5ca1e1de2b47.png → cb9b9cd7-36c1-4c26-9027-11b3ab709e01.png} +0 -0
  141. /kotonebot/tasks/sprites/{83e2ba4c-6a38-4de4-a545-9a5347931fbd.png → d2338793-6d96-4475-bfd5-a0dcaea6ea90.png} +0 -0
  142. /kotonebot/tasks/sprites/{86dcd997-50cd-4efc-8b0c-3e6a639e3316.png → d993723d-da01-494f-a37f-b9242feb1cf7.png} +0 -0
  143. /kotonebot/tasks/sprites/{b00e8013-9475-433d-929f-f16af552fe0d.png → ddc43151-a3ae-4c3f-95bb-ae9f72b8f875.png} +0 -0
  144. /kotonebot/tasks/sprites/{dabecc2b-7938-490b-8bba-a5d26d5b21c4.png → df5e43bb-b9bc-4bb9-a47c-d0077fec3b3c.png} +0 -0
  145. /kotonebot/tasks/sprites/{640f6f78-2e39-45c8-a71f-664eb302d9b5.png → e31acb36-85fc-4ec3-af99-c65e2b9bc35b.png} +0 -0
  146. /kotonebot/tasks/sprites/{77870708-86cd-45b0-b5ee-071bb375f660.png → e4af688e-fa37-4af7-b5d5-bb1784f204ed.png} +0 -0
  147. /kotonebot/tasks/sprites/{4ce0c0a5-2fae-45db-b986-a44e15e3f247.png → e748f660-ac56-4dac-b903-23fa508d8d5b.png} +0 -0
  148. /kotonebot/tasks/sprites/{6f01e188-f901-4d36-ba03-8419842c9b02.png → e949772f-f286-4394-ab9b-ae0620ab6095.png} +0 -0
  149. /kotonebot/tasks/sprites/{00cda413-7e30-44e3-8eed-7567f4cbdb13.png → e9e2db9c-7cee-4990-bcb3-ae8cad0da7dc.png} +0 -0
  150. /kotonebot/tasks/sprites/{7b731a67-d690-4068-939e-1e86496430d0.png → ea12ede1-88cd-4ff2-8997-2f4d0a950ace.png} +0 -0
  151. /kotonebot/tasks/sprites/{e0eeea93-b5c3-4f9e-a368-7080fc8d22b7.png → eae2eaf0-0f97-43f1-891e-0544d609140b.png} +0 -0
  152. /kotonebot/tasks/sprites/{eec6a6c0-b3fd-44f3-8745-7bdb60e63521.png → ec6790e4-2c43-41bc-ac25-b7179e604e04.png} +0 -0
  153. /kotonebot/tasks/sprites/{a40f00e3-f6a3-4f4d-91cd-b9c0f9b9d3f3.png → eec6e59b-e458-4a51-85da-31c9eb11543d.png} +0 -0
  154. /kotonebot/tasks/sprites/{04d9b790-2d53-4b1b-a7ea-08ed06b12046.png → f0ad28dc-568b-4436-962f-e6e024d46373.png} +0 -0
  155. /kotonebot/tasks/sprites/{817a5e76-64f0-4d51-a224-4f6a71f11f23.png → f414d470-3427-4752-a58f-4f2aff55b81c.png} +0 -0
  156. /kotonebot/tasks/sprites/{e8efd7a2-284b-406a-8467-7fb3a71333fd.png → f8cf065b-d071-412c-8f0f-8d8047a612e4.png} +0 -0
  157. /kotonebot/tasks/sprites/{0db7f069-8d5f-4a88-8d39-d36b57b8f8c9.png → f92a8682-acde-4f82-83c1-b2760fc2e915.png} +0 -0
  158. /kotonebot/tasks/sprites/{00e1c918-3c57-4a33-8c97-0b96ddfc3278.png → fa6eadbc-e462-4473-b681-1158c6cca82c.png} +0 -0
  159. /kotonebot/tasks/sprites/{a1ee66f3-25ad-4098-bff8-29ad02056634.png → fc9d1512-76ce-41b5-ad01-c393f2fa169d.png} +0 -0
  160. /kotonebot/tasks/sprites/{d0ebfbfa-fbef-48cb-a337-fa1cc6a1551f.png → fd092b4f-cf20-48e9-9c57-7d38367b893d.png} +0 -0
  161. {ksaa-2025.4.17.2.dist-info → ksaa-2025.4.26.0.dist-info}/entry_points.txt +0 -0
  162. {ksaa-2025.4.17.2.dist-info → ksaa-2025.4.26.0.dist-info}/top_level.txt +0 -0
kotonebot/backend/bot.py CHANGED
@@ -207,6 +207,7 @@ class KotoneBot:
207
207
  """
208
208
  self.check_backend()
209
209
  init_context(config_type=self.config_type)
210
+ vars.interrupted.clear()
210
211
 
211
212
  if by_priority:
212
213
  tasks = sorted(tasks, key=lambda x: x.priority, reverse=True)
@@ -249,7 +250,14 @@ class KotoneBot:
249
250
  def run_all(self) -> None:
250
251
  return self.run(list(task_registry.values()), by_priority=True)
251
252
 
252
- def start_all(self) -> RunStatus:
253
+ def start(self, tasks: list[Task], *, by_priority: bool = True) -> RunStatus:
254
+ """
255
+ 在单独的线程中按优先级顺序运行指定的任务。
256
+
257
+ :param tasks: 要运行的任务列表
258
+ :param by_priority: 是否按优先级排序
259
+ :return: 运行状态对象
260
+ """
253
261
  run_status = RunStatus(running=True)
254
262
  def _on_finished():
255
263
  run_status.running = False
@@ -271,7 +279,14 @@ class KotoneBot:
271
279
 
272
280
  self.events.task_status_changed += _on_task_status_changed
273
281
  self.events.finished += _on_finished
274
- thread = threading.Thread(target=self.run_all)
282
+ thread = threading.Thread(target=lambda: self.run(tasks, by_priority=by_priority))
275
283
  thread.start()
276
284
  return run_status
277
-
285
+
286
+ def start_all(self) -> RunStatus:
287
+ """
288
+ 在单独的线程中运行所有任务。
289
+
290
+ :return: 运行状态对象
291
+ """
292
+ return self.start(list(task_registry.values()), by_priority=True)
@@ -4,12 +4,13 @@ from typing import Literal
4
4
  from .implements.adb import AdbImpl
5
5
  from .implements.adb_raw import AdbRawImpl
6
6
  from .implements.windows import WindowsImpl
7
+ from .implements.remote_windows import RemoteWindowsImpl
7
8
  from .implements.uiautomator2 import UiAutomator2Impl
8
9
  from .device import Device, AndroidDevice, WindowsDevice
9
10
 
10
11
  from adbutils import adb
11
12
 
12
- DeviceImpl = Literal['adb', 'adb_raw', 'uiautomator2', 'windows']
13
+ DeviceImpl = Literal['adb', 'adb_raw', 'uiautomator2', 'windows', 'remote_windows']
13
14
 
14
15
  def create_device(
15
16
  addr: str,
@@ -40,4 +41,18 @@ def create_device(
40
41
  device = WindowsDevice()
41
42
  device._touch = WindowsImpl(device)
42
43
  device._screenshot = WindowsImpl(device)
44
+ elif impl == 'remote_windows':
45
+ # For remote_windows, addr should be in the format 'host:port'
46
+ if ':' not in addr:
47
+ raise ValueError(f"Invalid address format for remote_windows: {addr}. Expected format: 'host:port'")
48
+ host, port_str = addr.split(':', 1)
49
+ try:
50
+ port = int(port_str)
51
+ except ValueError:
52
+ raise ValueError(f"Invalid port in address: {port_str}")
53
+
54
+ device = WindowsDevice()
55
+ remote_impl = RemoteWindowsImpl(device, host, port)
56
+ device._touch = remote_impl
57
+ device._screenshot = remote_impl
43
58
  return device
@@ -0,0 +1,197 @@
1
+ """
2
+ Remote Windows implementation using XML-RPC.
3
+
4
+ This module provides:
5
+ 1. RemoteWindowsImpl - Client implementation that connects to a remote Windows machine
6
+ 2. RemoteWindowsServer - Server implementation that exposes a WindowsImpl instance via XML-RPC
7
+ """
8
+
9
+ import io
10
+ import base64
11
+ import logging
12
+ import xmlrpc.client
13
+ import xmlrpc.server
14
+ from typing import Literal, cast, Any, Tuple
15
+ from functools import cached_property
16
+ from threading import Thread
17
+
18
+ import cv2
19
+ import numpy as np
20
+ from cv2.typing import MatLike
21
+
22
+ from kotonebot import logging
23
+ from ..device import Device, WindowsDevice
24
+ from ..protocol import Touchable, Screenshotable
25
+ from .windows import WindowsImpl
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+ def _encode_image(image: MatLike) -> str:
30
+ """Encode an image as a base64 string."""
31
+ success, buffer = cv2.imencode('.png', image)
32
+ if not success:
33
+ raise RuntimeError("Failed to encode image")
34
+ return base64.b64encode(buffer.tobytes()).decode('ascii')
35
+
36
+ def _decode_image(encoded_image: str) -> MatLike:
37
+ """Decode a base64 string to an image."""
38
+ buffer = base64.b64decode(encoded_image)
39
+ image = cv2.imdecode(np.frombuffer(buffer, np.uint8), cv2.IMREAD_COLOR)
40
+ if image is None:
41
+ raise RuntimeError("Failed to decode image")
42
+ return image
43
+
44
+ class RemoteWindowsServer:
45
+ """
46
+ XML-RPC server that exposes a WindowsImpl instance.
47
+
48
+ This class wraps a WindowsImpl instance and exposes its methods via XML-RPC.
49
+ """
50
+
51
+ def __init__(self, host="localhost", port=8000):
52
+ """Initialize the server with the given host and port."""
53
+ self.host = host
54
+ self.port = port
55
+ self.server = None
56
+ self.device = WindowsDevice()
57
+ self.impl = WindowsImpl(self.device)
58
+ self.device._screenshot = self.impl
59
+ self.device._touch = self.impl
60
+
61
+ def start(self):
62
+ """Start the XML-RPC server."""
63
+ self.server = xmlrpc.server.SimpleXMLRPCServer(
64
+ (self.host, self.port),
65
+ logRequests=True,
66
+ allow_none=True
67
+ )
68
+ self.server.register_instance(self)
69
+ logger.info(f"Starting RemoteWindowsServer on {self.host}:{self.port}")
70
+ self.server.serve_forever()
71
+
72
+ def start_in_thread(self):
73
+ """Start the XML-RPC server in a separate thread."""
74
+ thread = Thread(target=self.start, daemon=True)
75
+ thread.start()
76
+ return thread
77
+
78
+ # Screenshotable methods
79
+
80
+ def screenshot(self) -> str:
81
+ """Take a screenshot and return it as a base64-encoded string."""
82
+ try:
83
+ image = self.impl.screenshot()
84
+ return _encode_image(image)
85
+ except Exception as e:
86
+ logger.error(f"Error taking screenshot: {e}")
87
+ raise
88
+
89
+ def get_screen_size(self) -> tuple[int, int]:
90
+ """Get the screen size."""
91
+ return self.impl.screen_size
92
+
93
+ def detect_orientation(self) -> str | None:
94
+ """Detect the screen orientation."""
95
+ return self.impl.detect_orientation()
96
+
97
+ # Touchable methods
98
+
99
+ def click(self, x: int, y: int) -> bool:
100
+ """Click at the given coordinates."""
101
+ try:
102
+ self.impl.click(x, y)
103
+ return True
104
+ except Exception as e:
105
+ logger.error(f"Error clicking at ({x}, {y}): {e}")
106
+ return False
107
+
108
+ def swipe(self, x1: int, y1: int, x2: int, y2: int, duration: float | None = None) -> bool:
109
+ """Swipe from (x1, y1) to (x2, y2)."""
110
+ try:
111
+ self.impl.swipe(x1, y1, x2, y2, duration)
112
+ return True
113
+ except Exception as e:
114
+ logger.error(f"Error swiping from ({x1}, {y1}) to ({x2}, {y2}): {e}")
115
+ return False
116
+
117
+ # Other methods
118
+
119
+ def get_scale_ratio(self) -> float:
120
+ """Get the scale ratio."""
121
+ return self.impl.scale_ratio
122
+
123
+ def ping(self) -> bool:
124
+ """Check if the server is alive."""
125
+ return True
126
+
127
+
128
+ class RemoteWindowsImpl(Touchable, Screenshotable):
129
+ """
130
+ Client implementation that connects to a remote Windows machine via XML-RPC.
131
+
132
+ This class implements the same interfaces as WindowsImpl but forwards all
133
+ method calls to a remote server.
134
+ """
135
+
136
+ def __init__(self, device: Device, host="localhost", port=8000):
137
+ """Initialize the client with the given device, host, and port."""
138
+ self.device = device
139
+ self.host = host
140
+ self.port = port
141
+ self.proxy = xmlrpc.client.ServerProxy(
142
+ f"http://{host}:{port}/",
143
+ allow_none=True
144
+ )
145
+ # Test connection
146
+ try:
147
+ if not self.proxy.ping():
148
+ raise ConnectionError(f"Failed to connect to RemoteWindowsServer at {host}:{port}")
149
+ logger.info(f"Connected to RemoteWindowsServer at {host}:{port}")
150
+ except Exception as e:
151
+ raise ConnectionError(f"Failed to connect to RemoteWindowsServer at {host}:{port}: {e}")
152
+
153
+ @cached_property
154
+ def scale_ratio(self) -> float:
155
+ """Get the scale ratio from the remote server."""
156
+ return cast(float, self.proxy.get_scale_ratio())
157
+
158
+ @property
159
+ def screen_size(self) -> tuple[int, int]:
160
+ """Get the screen size from the remote server."""
161
+ return cast(Tuple[int, int], self.proxy.get_screen_size())
162
+
163
+ def detect_orientation(self) -> None | Literal['portrait'] | Literal['landscape']:
164
+ """Detect the screen orientation from the remote server."""
165
+ return cast(None | Literal['portrait'] | Literal['landscape'], self.proxy.detect_orientation())
166
+
167
+ def screenshot(self) -> MatLike:
168
+ """Take a screenshot from the remote server."""
169
+ encoded_image = cast(str, self.proxy.screenshot())
170
+ return _decode_image(encoded_image)
171
+
172
+ def click(self, x: int, y: int) -> None:
173
+ """Click at the given coordinates on the remote server."""
174
+ if not self.proxy.click(x, y):
175
+ raise RuntimeError(f"Failed to click at ({x}, {y})")
176
+
177
+ def swipe(self, x1: int, y1: int, x2: int, y2: int, duration: float | None = None) -> None:
178
+ """Swipe from (x1, y1) to (x2, y2) on the remote server."""
179
+ if not self.proxy.swipe(x1, y1, x2, y2, duration):
180
+ raise RuntimeError(f"Failed to swipe from ({x1}, {y1}) to ({x2}, {y2})")
181
+
182
+
183
+ if __name__ == "__main__":
184
+ import argparse
185
+
186
+ parser = argparse.ArgumentParser(description="Remote Windows XML-RPC Server")
187
+ parser.add_argument("--host", default="0.0.0.0", help="Host to bind to")
188
+ parser.add_argument("--port", type=int, default=8000, help="Port to bind to")
189
+ args = parser.parse_args()
190
+
191
+ logging.basicConfig(level=logging.INFO)
192
+
193
+ server = RemoteWindowsServer(args.host, args.port)
194
+ try:
195
+ server.start()
196
+ except KeyboardInterrupt:
197
+ logger.info("Server stopped by user")
@@ -22,9 +22,11 @@ class BackendConfig(ConfigBaseModel):
22
22
  雷电模拟器需要设置正确的模拟器名,否则 自动启动模拟器 功能将无法正常工作。
23
23
  其他功能不受影响。
24
24
  """
25
- screenshot_impl: Literal['adb', 'adb_raw', 'uiautomator2', 'windows'] = 'adb'
25
+ screenshot_impl: Literal['adb', 'adb_raw', 'uiautomator2', 'windows', 'remote_windows'] = 'adb'
26
26
  """
27
27
  截图方法。暂时推荐使用【adb】截图方式。
28
+
29
+ 如果使用 remote_windows,需要在 adb_ip 中填写远程 Windows 的 IP 地址,在 adb_port 中填写远程 Windows 的端口号。
28
30
  """
29
31
  check_emulator: bool = False
30
32
  """
@@ -72,7 +74,7 @@ class UserConfig(ConfigBaseModel, Generic[T]):
72
74
 
73
75
 
74
76
  class RootConfig(ConfigBaseModel, Generic[T]):
75
- version: int = 3
77
+ version: int = 4
76
78
  """配置版本。"""
77
79
  user_configs: list[UserConfig[T]] = []
78
80
  """用户配置。"""