ok-script 0.0.63__tar.gz → 0.0.65__tar.gz

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 (185) hide show
  1. {ok-script-0.0.63 → ok-script-0.0.65}/PKG-INFO +1 -1
  2. {ok-script-0.0.63 → ok-script-0.0.65}/ok/OK.py +0 -2
  3. ok-script-0.0.65/ok/alas/emulator_base.py +270 -0
  4. ok-script-0.0.65/ok/alas/emulator_windows.py +548 -0
  5. ok-script-0.0.65/ok/alas/platform_base.py +207 -0
  6. ok-script-0.0.65/ok/alas/platform_windows.py +321 -0
  7. ok-script-0.0.65/ok/alas/utils.py +54 -0
  8. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/HwndWindow.py +23 -1
  9. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/adb/DeviceManager.py +20 -14
  10. ok-script-0.0.65/ok/capture/image/ImageCaptureMethod.py +32 -0
  11. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/BitBltCaptureMethod.py +1 -1
  12. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +1 -1
  13. {ok-script-0.0.63 → ok-script-0.0.65}/ok/firebase/FireBaseAnalytics.py +3 -3
  14. ok-script-0.0.65/ok/gui/debug/DebugTab.py +154 -0
  15. ok-script-0.0.65/ok/gui/start/SelectCaptureListView.py +30 -0
  16. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/start/SelectHwndWindow.py +3 -15
  17. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/start/StartTab.py +4 -2
  18. ok-script-0.0.65/ok/interaction/DoNothingInteraction.py +8 -0
  19. {ok-script-0.0.63 → ok-script-0.0.65}/ok/logging/Logger.py +10 -5
  20. {ok-script-0.0.63 → ok-script-0.0.65}/ok/task/TaskExecutor.py +12 -0
  21. {ok-script-0.0.63 → ok-script-0.0.65}/ok/update/Updater.py +1 -0
  22. ok-script-0.0.65/ok/update/__init__.py +0 -0
  23. ok-script-0.0.65/ok/util/__init__.py +0 -0
  24. {ok-script-0.0.63 → ok-script-0.0.65}/ok_script.egg-info/PKG-INFO +1 -1
  25. {ok-script-0.0.63 → ok-script-0.0.65}/ok_script.egg-info/SOURCES.txt +9 -2
  26. {ok-script-0.0.63 → ok-script-0.0.65}/setup.py +1 -1
  27. ok-script-0.0.63/ok/capture/adb/targets.py +0 -61
  28. ok-script-0.0.63/ok/capture/adb/vbox.py +0 -123
  29. ok-script-0.0.63/ok/gui/debug/DebugTab.py +0 -122
  30. ok-script-0.0.63/ok/gui/start/SelectCaptureListView.py +0 -26
  31. {ok-script-0.0.63 → ok-script-0.0.65}/README.md +0 -0
  32. {ok-script-0.0.63 → ok-script-0.0.65}/ok/__init__.py +0 -0
  33. {ok-script-0.0.63/ok/capture → ok-script-0.0.65/ok/alas}/__init__.py +0 -0
  34. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/BaseCaptureMethod.py +0 -0
  35. {ok-script-0.0.63/ok/capture/adb → ok-script-0.0.65/ok/capture}/__init__.py +0 -0
  36. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/adb/ADBCaptureMethod.py +0 -0
  37. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
  38. {ok-script-0.0.63/ok/capture/adb/bin → ok-script-0.0.65/ok/capture/adb}/__init__.py +0 -0
  39. {ok-script-0.0.63/ok/capture/windows → ok-script-0.0.65/ok/capture/adb/bin}/__init__.py +0 -0
  40. {ok-script-0.0.63/ok/color → ok-script-0.0.65/ok/capture/image}/__init__.py +0 -0
  41. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
  42. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
  43. {ok-script-0.0.63/ok/config → ok-script-0.0.65/ok/capture/windows}/__init__.py +0 -0
  44. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/d3d11.py +0 -0
  45. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/dump.py +0 -0
  46. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/utils.py +0 -0
  47. {ok-script-0.0.63 → ok-script-0.0.65}/ok/capture/windows/window.py +0 -0
  48. {ok-script-0.0.63 → ok-script-0.0.65}/ok/color/Color.py +0 -0
  49. {ok-script-0.0.63/ok/feature → ok-script-0.0.65/ok/color}/__init__.py +0 -0
  50. {ok-script-0.0.63 → ok-script-0.0.65}/ok/config/Config.py +0 -0
  51. {ok-script-0.0.63 → ok-script-0.0.65}/ok/config/InfoDict.py +0 -0
  52. {ok-script-0.0.63/ok/firebase → ok-script-0.0.65/ok/config}/__init__.py +0 -0
  53. {ok-script-0.0.63 → ok-script-0.0.65}/ok/feature/Box.py +0 -0
  54. {ok-script-0.0.63 → ok-script-0.0.65}/ok/feature/Feature.py +0 -0
  55. {ok-script-0.0.63 → ok-script-0.0.65}/ok/feature/FeatureSet.py +0 -0
  56. {ok-script-0.0.63 → ok-script-0.0.65}/ok/feature/FindFeature.py +0 -0
  57. {ok-script-0.0.63/ok/gui/about → ok-script-0.0.65/ok/feature}/__init__.py +0 -0
  58. {ok-script-0.0.63/ok/gui/common → ok-script-0.0.65/ok/firebase}/__init__.py +0 -0
  59. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/App.py +0 -0
  60. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/Communicate.py +0 -0
  61. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/MainWindow.py +0 -0
  62. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/MessageWindow.py +0 -0
  63. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/TabTitles.py +0 -0
  64. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/__init__.py +0 -0
  65. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/about/AboutTab.py +0 -0
  66. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/about/HttpTextEdit.py +0 -0
  67. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/about/VersionCard.py +0 -0
  68. {ok-script-0.0.63/ok/gui/debug → ok-script-0.0.65/ok/gui/about}/__init__.py +0 -0
  69. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/common/OKIcon.py +0 -0
  70. {ok-script-0.0.63/ok/gui/i18n → ok-script-0.0.65/ok/gui/common}/__init__.py +0 -0
  71. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/common/config.py +0 -0
  72. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/common/style_sheet.py +0 -0
  73. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/debug/AspectRatioWidget.py +0 -0
  74. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/debug/FrameWidget.py +0 -0
  75. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/debug/InfoWidget.py +0 -0
  76. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/debug/LoggerWidget.py +0 -0
  77. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/debug/Screenshot.py +0 -0
  78. {ok-script-0.0.63/ok/gui/icon → ok-script-0.0.65/ok/gui/debug}/__init__.py +0 -0
  79. {ok-script-0.0.63/ok/gui/overlay → ok-script-0.0.65/ok/gui/i18n}/__init__.py +0 -0
  80. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/i18n/path.py +0 -0
  81. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/i18n/update.py +0 -0
  82. {ok-script-0.0.63/ok/gui/qss → ok-script-0.0.65/ok/gui/icon}/__init__.py +0 -0
  83. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/icon/icon.py +0 -0
  84. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/overlay/OverlayWindow.py +0 -0
  85. {ok-script-0.0.63/ok/gui/settings → ok-script-0.0.65/ok/gui/overlay}/__init__.py +0 -0
  86. {ok-script-0.0.63/ok/gui/start → ok-script-0.0.65/ok/gui/qss}/__init__.py +0 -0
  87. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/resources.py +0 -0
  88. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/settings/SettingTab.py +0 -0
  89. {ok-script-0.0.63/ok/gui/tasks → ok-script-0.0.65/ok/gui/settings}/__init__.py +0 -0
  90. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/start/StartCard.py +0 -0
  91. {ok-script-0.0.63/ok/gui/util → ok-script-0.0.65/ok/gui/start}/__init__.py +0 -0
  92. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/ConfigItemFactory.py +0 -0
  93. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
  94. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
  95. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/LabelAndDropDown.py +0 -0
  96. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
  97. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/LabelAndList.py +0 -0
  98. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
  99. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
  100. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/LabelAndWidget.py +0 -0
  101. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/ModifyListDialog.py +0 -0
  102. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/ModifyListItem.py +0 -0
  103. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
  104. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/StartButton.py +0 -0
  105. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/TaskCard.py +0 -0
  106. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/TaskOpButton.py +0 -0
  107. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/TooltipTableWidget.py +0 -0
  108. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/tasks/TriggerTaskTab.py +0 -0
  109. {ok-script-0.0.63/ok/gui/widget → ok-script-0.0.65/ok/gui/tasks}/__init__.py +0 -0
  110. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/util/Alert.py +0 -0
  111. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/util/InitWorker.py +0 -0
  112. {ok-script-0.0.63/ok/interaction → ok-script-0.0.65/ok/gui/util}/__init__.py +0 -0
  113. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/Card.py +0 -0
  114. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/EmptyCard.py +0 -0
  115. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/FramelessDialog.py +0 -0
  116. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/ListTableWidgetItem.py +0 -0
  117. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
  118. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/StatusBar.py +0 -0
  119. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/Tab.py +0 -0
  120. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/TabWidget.py +0 -0
  121. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
  122. {ok-script-0.0.63 → ok-script-0.0.65}/ok/gui/widget/YesNonWidgetItem.py +0 -0
  123. {ok-script-0.0.63/ok/logging → ok-script-0.0.65/ok/gui/widget}/__init__.py +0 -0
  124. {ok-script-0.0.63 → ok-script-0.0.65}/ok/interaction/ADBInteraction.py +0 -0
  125. {ok-script-0.0.63 → ok-script-0.0.65}/ok/interaction/BaseInteraction.py +0 -0
  126. {ok-script-0.0.63 → ok-script-0.0.65}/ok/interaction/Win32Interaction.py +0 -0
  127. {ok-script-0.0.63/ok/ocr → ok-script-0.0.65/ok/interaction}/__init__.py +0 -0
  128. {ok-script-0.0.63/ok/rotypes/Windows/Media → ok-script-0.0.65/ok/logging}/__init__.py +0 -0
  129. {ok-script-0.0.63 → ok-script-0.0.65}/ok/ocr/OCR.py +0 -0
  130. {ok-script-0.0.63/ok/rotypes/Windows/Security → ok-script-0.0.65/ok/ocr}/__init__.py +0 -0
  131. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  132. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  133. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  134. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  135. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  136. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  137. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  138. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  139. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  140. {ok-script-0.0.63/ok/rotypes/Windows/Storage → ok-script-0.0.65/ok/rotypes/Windows/Media}/__init__.py +0 -0
  141. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  142. {ok-script-0.0.63/ok/rotypes/Windows → ok-script-0.0.65/ok/rotypes/Windows/Security}/__init__.py +0 -0
  143. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  144. {ok-script-0.0.63/ok/save → ok-script-0.0.65/ok/rotypes/Windows/Storage}/__init__.py +0 -0
  145. {ok-script-0.0.63/ok/scene → ok-script-0.0.65/ok/rotypes/Windows}/__init__.py +0 -0
  146. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/__init__.py +0 -0
  147. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/delegate.py +0 -0
  148. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/export.py +0 -0
  149. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/idldsl.py +0 -0
  150. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/inspectable.py +0 -0
  151. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/roapi.py +0 -0
  152. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/types.py +0 -0
  153. {ok-script-0.0.63 → ok-script-0.0.65}/ok/rotypes/winstring.py +0 -0
  154. {ok-script-0.0.63 → ok-script-0.0.65}/ok/save/BlackBarProcessor.py +0 -0
  155. {ok-script-0.0.63 → ok-script-0.0.65}/ok/save/PostProcessor.py +0 -0
  156. {ok-script-0.0.63 → ok-script-0.0.65}/ok/save/SaveByInterval.py +0 -0
  157. {ok-script-0.0.63 → ok-script-0.0.65}/ok/save/SaveByKeyPress.py +0 -0
  158. {ok-script-0.0.63 → ok-script-0.0.65}/ok/save/SaveMethodBase.py +0 -0
  159. {ok-script-0.0.63/ok/stats → ok-script-0.0.65/ok/save}/__init__.py +0 -0
  160. {ok-script-0.0.63 → ok-script-0.0.65}/ok/scene/FeatureScene.py +0 -0
  161. {ok-script-0.0.63 → ok-script-0.0.65}/ok/scene/Scene.py +0 -0
  162. {ok-script-0.0.63/ok/task → ok-script-0.0.65/ok/scene}/__init__.py +0 -0
  163. {ok-script-0.0.63 → ok-script-0.0.65}/ok/stats/StreamStats.py +0 -0
  164. {ok-script-0.0.63/ok/update → ok-script-0.0.65/ok/stats}/__init__.py +0 -0
  165. {ok-script-0.0.63 → ok-script-0.0.65}/ok/task/BaseTask.py +0 -0
  166. {ok-script-0.0.63 → ok-script-0.0.65}/ok/task/ExecutorOperation.py +0 -0
  167. {ok-script-0.0.63 → ok-script-0.0.65}/ok/task/OneTimeTask.py +0 -0
  168. {ok-script-0.0.63 → ok-script-0.0.65}/ok/task/TriggerTask.py +0 -0
  169. {ok-script-0.0.63/ok/util → ok-script-0.0.65/ok/task}/__init__.py +0 -0
  170. {ok-script-0.0.63 → ok-script-0.0.65}/ok/update/GithubMultiDownloader.py +0 -0
  171. {ok-script-0.0.63 → ok-script-0.0.65}/ok/update/gen_md5.py +0 -0
  172. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/Handler.py +0 -0
  173. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/exit_event.py +0 -0
  174. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/json.py +0 -0
  175. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/list.py +0 -0
  176. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/path.py +0 -0
  177. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/thread.py +0 -0
  178. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/win32_process.py +0 -0
  179. {ok-script-0.0.63 → ok-script-0.0.65}/ok/util/yaml.py +0 -0
  180. {ok-script-0.0.63 → ok-script-0.0.65}/ok_script.egg-info/dependency_links.txt +0 -0
  181. {ok-script-0.0.63 → ok-script-0.0.65}/ok_script.egg-info/requires.txt +0 -0
  182. {ok-script-0.0.63 → ok-script-0.0.65}/ok_script.egg-info/top_level.txt +0 -0
  183. {ok-script-0.0.63 → ok-script-0.0.65}/setup.cfg +0 -0
  184. {ok-script-0.0.63 → ok-script-0.0.65}/tests/__init__.py +0 -0
  185. {ok-script-0.0.63 → ok-script-0.0.65}/tests/test_updater.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ok-script
3
- Version: 0.0.63
3
+ Version: 0.0.65
4
4
  Summary: Automation with Computer Vision for Python
5
5
  Home-page: https://github.com/ok-oldking/ok-script
6
6
  Author: ok-oldking
@@ -128,8 +128,6 @@ class OK:
128
128
  def quit(self):
129
129
  logger.debug('quit app')
130
130
  self.exit_event.set()
131
- if self.device_manager is not None:
132
- self.device_manager.stop()
133
131
  if self.app:
134
132
  self.app.quit()
135
133
 
@@ -0,0 +1,270 @@
1
+ import os
2
+ import re
3
+ import typing as t
4
+ from dataclasses import dataclass
5
+
6
+ from ok.alas.utils import cached_property, iter_folder
7
+
8
+
9
+ def abspath(path):
10
+ return os.path.abspath(path)
11
+
12
+
13
+ def get_serial_pair(serial):
14
+ """
15
+ Args:
16
+ serial (str):
17
+
18
+ Returns:
19
+ str, str: `127.0.0.1:5555+{X}` and `emulator-5554+{X}`, 0 <= X <= 32
20
+ """
21
+ if serial.startswith('127.0.0.1:'):
22
+ try:
23
+ port = int(serial[10:])
24
+ if 5555 <= port <= 5555 + 32:
25
+ return f'127.0.0.1:{port}', f'emulator-{port - 1}'
26
+ except (ValueError, IndexError):
27
+ pass
28
+ if serial.startswith('emulator-'):
29
+ try:
30
+ port = int(serial[9:])
31
+ if 5554 <= port <= 5554 + 32:
32
+ return f'127.0.0.1:{port + 1}', f'emulator-{port}'
33
+ except (ValueError, IndexError):
34
+ pass
35
+
36
+ return None, None
37
+
38
+
39
+ def remove_duplicated_path(paths):
40
+ """
41
+ Args:
42
+ paths (list[str]):
43
+
44
+ Returns:
45
+ list[str]:
46
+ """
47
+ paths = sorted(set(paths))
48
+ dic = {}
49
+ for path in paths:
50
+ dic.setdefault(path.lower(), path)
51
+ return list(dic.values())
52
+
53
+
54
+ @dataclass
55
+ class EmulatorInstanceBase:
56
+ # Serial for adb connection
57
+ serial: str
58
+ # Emulator instance name, used for start/stop emulator
59
+ name: str
60
+ # Path to emulator .exe
61
+ path: str
62
+
63
+ def __str__(self):
64
+ return f'{self.type}(serial="{self.serial}", name="{self.name}", path="{self.path}")'
65
+
66
+ @cached_property
67
+ def type(self) -> str:
68
+ """
69
+ Returns:
70
+ str: Emulator type, such as Emulator.NoxPlayer
71
+ """
72
+ return self.emulator.type
73
+
74
+ @cached_property
75
+ def emulator(self):
76
+ """
77
+ Returns:
78
+ Emulator:
79
+ """
80
+ return EmulatorBase(self.path)
81
+
82
+ def __eq__(self, other):
83
+ if isinstance(other, str) and self.type == other:
84
+ return True
85
+ if isinstance(other, list) and self.type in other:
86
+ return True
87
+ if isinstance(other, EmulatorInstanceBase):
88
+ return super().__eq__(other) and self.type == other.type
89
+ return super().__eq__(other)
90
+
91
+ def __hash__(self):
92
+ return hash(str(self))
93
+
94
+ def __bool__(self):
95
+ return True
96
+
97
+ @cached_property
98
+ def MuMuPlayer12_id(self):
99
+ """
100
+ Convert MuMu 12 instance name to instance id.
101
+ Example names:
102
+ MuMuPlayer-12.0-3
103
+ YXArkNights-12.0-1
104
+
105
+ Returns:
106
+ int: Instance ID, or None if this is not a MuMu 12 instance
107
+ """
108
+ res = re.search(r'MuMuPlayer(?:Global)?-12.0-(\d+)', self.name)
109
+ if res:
110
+ return int(res.group(1))
111
+ res = re.search(r'YXArkNights-12.0-(\d+)', self.name)
112
+ if res:
113
+ return int(res.group(1))
114
+
115
+ return None
116
+
117
+
118
+ class EmulatorBase:
119
+ # Values here must match those in argument.yaml EmulatorInfo.Emulator.option
120
+ NoxPlayer = 'NoxPlayer'
121
+ NoxPlayer64 = 'NoxPlayer64'
122
+ NoxPlayerFamily = [NoxPlayer, NoxPlayer64]
123
+ BlueStacks4 = 'BlueStacks4'
124
+ BlueStacks5 = 'BlueStacks5'
125
+ BlueStacks4HyperV = 'BlueStacks4HyperV'
126
+ BlueStacks5HyperV = 'BlueStacks5HyperV'
127
+ BlueStacksFamily = [BlueStacks4, BlueStacks5]
128
+ LDPlayer3 = 'LDPlayer3'
129
+ LDPlayer4 = 'LDPlayer4'
130
+ LDPlayer9 = 'LDPlayer9'
131
+ LDPlayerFamily = [LDPlayer3, LDPlayer4, LDPlayer9]
132
+ MuMuPlayer = 'MuMuPlayer'
133
+ MuMuPlayerX = 'MuMuPlayerX'
134
+ MuMuPlayer12 = 'MuMuPlayer12'
135
+ MuMuPlayerFamily = [MuMuPlayer, MuMuPlayerX, MuMuPlayer12]
136
+ MEmuPlayer = 'MEmuPlayer'
137
+
138
+ @classmethod
139
+ def path_to_type(cls, path: str) -> str:
140
+ """
141
+ Args:
142
+ path: Path to .exe file
143
+
144
+ Returns:
145
+ str: Emulator type, such as Emulator.NoxPlayer,
146
+ or '' if this is not a emulator.
147
+ """
148
+ return ''
149
+
150
+ def iter_instances(self) -> t.Iterable[EmulatorInstanceBase]:
151
+ """
152
+ Yields:
153
+ EmulatorInstance: Emulator instances found in this emulator
154
+ """
155
+ pass
156
+
157
+ def iter_adb_binaries(self) -> t.Iterable[str]:
158
+ """
159
+ Yields:
160
+ str: Filepath to adb binaries found in this emulator
161
+ """
162
+ pass
163
+
164
+ def __init__(self, path):
165
+ # Path to .exe file
166
+ self.path = path
167
+ # Path to emulator folder
168
+ self.dir = os.path.dirname(path)
169
+ # str: Emulator type, or '' if this is not a emulator.
170
+ self.type = self.__class__.path_to_type(path)
171
+
172
+ def __eq__(self, other):
173
+ if isinstance(other, str) and self.type == other:
174
+ return True
175
+ if isinstance(other, list) and self.type in other:
176
+ return True
177
+ return super().__eq__(other)
178
+
179
+ def __str__(self):
180
+ return f'{self.type}(path="{self.path}")'
181
+
182
+ __repr__ = __str__
183
+
184
+ def __hash__(self):
185
+ return hash(self.path)
186
+
187
+ def __bool__(self):
188
+ return True
189
+
190
+ def abspath(self, path, folder=None):
191
+ if folder is None:
192
+ folder = self.dir
193
+ return abspath(os.path.join(folder, path))
194
+
195
+ @classmethod
196
+ def is_emulator(cls, path: str) -> bool:
197
+ """
198
+ Args:
199
+ path: Path to .exe file.
200
+
201
+ Returns:
202
+ bool: If this is a emulator.
203
+ """
204
+ return bool(cls.path_to_type(path))
205
+
206
+ def list_folder(self, folder, is_dir=False, ext=None):
207
+ """
208
+ Safely list files in a folder
209
+
210
+ Args:
211
+ folder:
212
+ is_dir:
213
+ ext:
214
+
215
+ Returns:
216
+ list[str]:
217
+ """
218
+ folder = self.abspath(folder)
219
+ return list(iter_folder(folder, is_dir=is_dir, ext=ext))
220
+
221
+
222
+ class EmulatorManagerBase:
223
+ @staticmethod
224
+ def iter_running_emulator():
225
+ """
226
+ Yields:
227
+ str: Path to emulator executables, may contains duplicate values
228
+ """
229
+ return
230
+
231
+ @cached_property
232
+ def all_emulators(self) -> t.List[EmulatorBase]:
233
+ """
234
+ Get all emulators installed on current computer.
235
+ """
236
+ return []
237
+
238
+ @cached_property
239
+ def all_emulator_instances(self) -> t.List[EmulatorInstanceBase]:
240
+ """
241
+ Get all emulator instances installed on current computer.
242
+ """
243
+ return []
244
+
245
+ @cached_property
246
+ def all_emulator_serials(self) -> t.List[str]:
247
+ """
248
+ Returns:
249
+ list[str]: All possible serials on current computer.
250
+ """
251
+ out = []
252
+ for emulator in self.all_emulator_instances:
253
+ out.append(emulator.serial)
254
+ # Also add serial like `emulator-5554`
255
+ port_serial, emu_serial = get_serial_pair(emulator.serial)
256
+ if emu_serial:
257
+ out.append(emu_serial)
258
+ return out
259
+
260
+ @cached_property
261
+ def all_adb_binaries(self) -> t.List[str]:
262
+ """
263
+ Returns:
264
+ list[str]: All adb binaries of emulators on current computer.
265
+ """
266
+ out = []
267
+ for emulator in self.all_emulators:
268
+ for exe in emulator.iter_adb_binaries():
269
+ out.append(exe)
270
+ return out