ok-script 0.0.68__tar.gz → 0.0.70__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 (182) hide show
  1. {ok-script-0.0.68 → ok-script-0.0.70}/PKG-INFO +1 -1
  2. {ok-script-0.0.68 → ok-script-0.0.70}/ok/OK.py +3 -5
  3. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/BaseCaptureMethod.py +2 -2
  4. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/HwndWindow.py +48 -48
  5. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/adb/DeviceManager.py +52 -23
  6. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/BitBltCaptureMethod.py +9 -2
  7. {ok-script-0.0.68 → ok-script-0.0.70}/ok/firebase/FireBaseAnalytics.py +82 -4
  8. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/App.py +1 -1
  9. {ok-script-0.0.68/ok/capture/adb → ok-script-0.0.70/ok/gui}/StartController.py +2 -1
  10. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/debug/FrameWidget.py +8 -5
  11. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/resources.py +571 -486
  12. {ok-script-0.0.68 → ok-script-0.0.70}/ok/task/TaskExecutor.py +1 -1
  13. {ok-script-0.0.68 → ok-script-0.0.70}/ok_script.egg-info/PKG-INFO +1 -1
  14. {ok-script-0.0.68 → ok-script-0.0.70}/ok_script.egg-info/SOURCES.txt +1 -1
  15. {ok-script-0.0.68 → ok-script-0.0.70}/setup.py +1 -1
  16. {ok-script-0.0.68 → ok-script-0.0.70}/README.md +0 -0
  17. {ok-script-0.0.68 → ok-script-0.0.70}/ok/__init__.py +0 -0
  18. {ok-script-0.0.68 → ok-script-0.0.70}/ok/alas/__init__.py +0 -0
  19. {ok-script-0.0.68 → ok-script-0.0.70}/ok/alas/emulator_base.py +0 -0
  20. {ok-script-0.0.68 → ok-script-0.0.70}/ok/alas/emulator_windows.py +0 -0
  21. {ok-script-0.0.68 → ok-script-0.0.70}/ok/alas/platform_base.py +0 -0
  22. {ok-script-0.0.68 → ok-script-0.0.70}/ok/alas/platform_windows.py +0 -0
  23. {ok-script-0.0.68 → ok-script-0.0.70}/ok/alas/utils.py +0 -0
  24. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/__init__.py +0 -0
  25. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/adb/ADBCaptureMethod.py +0 -0
  26. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
  27. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/adb/__init__.py +0 -0
  28. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/adb/bin/__init__.py +0 -0
  29. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/image/ImageCaptureMethod.py +0 -0
  30. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/image/__init__.py +0 -0
  31. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
  32. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
  33. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +0 -0
  34. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/__init__.py +0 -0
  35. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/d3d11.py +0 -0
  36. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/dump.py +0 -0
  37. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/utils.py +0 -0
  38. {ok-script-0.0.68 → ok-script-0.0.70}/ok/capture/windows/window.py +0 -0
  39. {ok-script-0.0.68 → ok-script-0.0.70}/ok/color/Color.py +0 -0
  40. {ok-script-0.0.68 → ok-script-0.0.70}/ok/color/__init__.py +0 -0
  41. {ok-script-0.0.68 → ok-script-0.0.70}/ok/config/Config.py +0 -0
  42. {ok-script-0.0.68 → ok-script-0.0.70}/ok/config/InfoDict.py +0 -0
  43. {ok-script-0.0.68 → ok-script-0.0.70}/ok/config/__init__.py +0 -0
  44. {ok-script-0.0.68 → ok-script-0.0.70}/ok/feature/Box.py +0 -0
  45. {ok-script-0.0.68 → ok-script-0.0.70}/ok/feature/Feature.py +0 -0
  46. {ok-script-0.0.68 → ok-script-0.0.70}/ok/feature/FeatureSet.py +0 -0
  47. {ok-script-0.0.68 → ok-script-0.0.70}/ok/feature/FindFeature.py +0 -0
  48. {ok-script-0.0.68 → ok-script-0.0.70}/ok/feature/__init__.py +0 -0
  49. {ok-script-0.0.68 → ok-script-0.0.70}/ok/firebase/__init__.py +0 -0
  50. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/Communicate.py +0 -0
  51. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/MainWindow.py +0 -0
  52. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/MessageWindow.py +0 -0
  53. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/TabTitles.py +0 -0
  54. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/__init__.py +0 -0
  55. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/about/AboutTab.py +0 -0
  56. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/about/HttpTextEdit.py +0 -0
  57. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/about/VersionCard.py +0 -0
  58. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/about/__init__.py +0 -0
  59. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/common/OKIcon.py +0 -0
  60. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/common/__init__.py +0 -0
  61. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/common/config.py +0 -0
  62. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/common/style_sheet.py +0 -0
  63. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/debug/AspectRatioWidget.py +0 -0
  64. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/debug/DebugTab.py +0 -0
  65. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/debug/InfoWidget.py +0 -0
  66. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/debug/LoggerWidget.py +0 -0
  67. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/debug/Screenshot.py +0 -0
  68. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/debug/__init__.py +0 -0
  69. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/i18n/__init__.py +0 -0
  70. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/i18n/path.py +0 -0
  71. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/i18n/update.py +0 -0
  72. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/icon/__init__.py +0 -0
  73. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/icon/icon.py +0 -0
  74. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/overlay/OverlayWindow.py +0 -0
  75. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/overlay/__init__.py +0 -0
  76. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/qss/__init__.py +0 -0
  77. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/settings/SettingTab.py +0 -0
  78. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/settings/__init__.py +0 -0
  79. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/start/SelectCaptureListView.py +0 -0
  80. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/start/StartCard.py +0 -0
  81. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/start/StartTab.py +0 -0
  82. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/start/__init__.py +0 -0
  83. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/ConfigItemFactory.py +0 -0
  84. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
  85. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
  86. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/LabelAndDropDown.py +0 -0
  87. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
  88. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/LabelAndList.py +0 -0
  89. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
  90. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
  91. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/LabelAndWidget.py +0 -0
  92. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/ModifyListDialog.py +0 -0
  93. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/ModifyListItem.py +0 -0
  94. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
  95. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/StartButton.py +0 -0
  96. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/TaskCard.py +0 -0
  97. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/TaskOpButton.py +0 -0
  98. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/TooltipTableWidget.py +0 -0
  99. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/TriggerTaskTab.py +0 -0
  100. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/tasks/__init__.py +0 -0
  101. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/util/Alert.py +0 -0
  102. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/util/InitWorker.py +0 -0
  103. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/util/__init__.py +0 -0
  104. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/Card.py +0 -0
  105. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/EmptyCard.py +0 -0
  106. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/FramelessDialog.py +0 -0
  107. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/ListTableWidgetItem.py +0 -0
  108. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
  109. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/StartLoadingDialog.py +0 -0
  110. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/StatusBar.py +0 -0
  111. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/Tab.py +0 -0
  112. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/TabWidget.py +0 -0
  113. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
  114. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/YesNonWidgetItem.py +0 -0
  115. {ok-script-0.0.68 → ok-script-0.0.70}/ok/gui/widget/__init__.py +0 -0
  116. {ok-script-0.0.68 → ok-script-0.0.70}/ok/interaction/ADBInteraction.py +0 -0
  117. {ok-script-0.0.68 → ok-script-0.0.70}/ok/interaction/BaseInteraction.py +0 -0
  118. {ok-script-0.0.68 → ok-script-0.0.70}/ok/interaction/DoNothingInteraction.py +0 -0
  119. {ok-script-0.0.68 → ok-script-0.0.70}/ok/interaction/Win32Interaction.py +0 -0
  120. {ok-script-0.0.68 → ok-script-0.0.70}/ok/interaction/__init__.py +0 -0
  121. {ok-script-0.0.68 → ok-script-0.0.70}/ok/logging/Logger.py +0 -0
  122. {ok-script-0.0.68 → ok-script-0.0.70}/ok/logging/__init__.py +0 -0
  123. {ok-script-0.0.68 → ok-script-0.0.70}/ok/ocr/OCR.py +0 -0
  124. {ok-script-0.0.68 → ok-script-0.0.70}/ok/ocr/__init__.py +0 -0
  125. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  126. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  127. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  128. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  129. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  130. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  131. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  132. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  133. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  134. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Media/__init__.py +0 -0
  135. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  136. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Security/__init__.py +0 -0
  137. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  138. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  139. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/Windows/__init__.py +0 -0
  140. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/__init__.py +0 -0
  141. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/delegate.py +0 -0
  142. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/export.py +0 -0
  143. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/idldsl.py +0 -0
  144. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/inspectable.py +0 -0
  145. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/roapi.py +0 -0
  146. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/types.py +0 -0
  147. {ok-script-0.0.68 → ok-script-0.0.70}/ok/rotypes/winstring.py +0 -0
  148. {ok-script-0.0.68 → ok-script-0.0.70}/ok/save/BlackBarProcessor.py +0 -0
  149. {ok-script-0.0.68 → ok-script-0.0.70}/ok/save/PostProcessor.py +0 -0
  150. {ok-script-0.0.68 → ok-script-0.0.70}/ok/save/SaveByInterval.py +0 -0
  151. {ok-script-0.0.68 → ok-script-0.0.70}/ok/save/SaveByKeyPress.py +0 -0
  152. {ok-script-0.0.68 → ok-script-0.0.70}/ok/save/SaveMethodBase.py +0 -0
  153. {ok-script-0.0.68 → ok-script-0.0.70}/ok/save/__init__.py +0 -0
  154. {ok-script-0.0.68 → ok-script-0.0.70}/ok/scene/FeatureScene.py +0 -0
  155. {ok-script-0.0.68 → ok-script-0.0.70}/ok/scene/Scene.py +0 -0
  156. {ok-script-0.0.68 → ok-script-0.0.70}/ok/scene/__init__.py +0 -0
  157. {ok-script-0.0.68 → ok-script-0.0.70}/ok/stats/StreamStats.py +0 -0
  158. {ok-script-0.0.68 → ok-script-0.0.70}/ok/stats/__init__.py +0 -0
  159. {ok-script-0.0.68 → ok-script-0.0.70}/ok/task/BaseTask.py +0 -0
  160. {ok-script-0.0.68 → ok-script-0.0.70}/ok/task/ExecutorOperation.py +0 -0
  161. {ok-script-0.0.68 → ok-script-0.0.70}/ok/task/OneTimeTask.py +0 -0
  162. {ok-script-0.0.68 → ok-script-0.0.70}/ok/task/TriggerTask.py +0 -0
  163. {ok-script-0.0.68 → ok-script-0.0.70}/ok/task/__init__.py +0 -0
  164. {ok-script-0.0.68 → ok-script-0.0.70}/ok/update/GithubMultiDownloader.py +0 -0
  165. {ok-script-0.0.68 → ok-script-0.0.70}/ok/update/Updater.py +0 -0
  166. {ok-script-0.0.68 → ok-script-0.0.70}/ok/update/__init__.py +0 -0
  167. {ok-script-0.0.68 → ok-script-0.0.70}/ok/update/gen_md5.py +0 -0
  168. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/Handler.py +0 -0
  169. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/__init__.py +0 -0
  170. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/exit_event.py +0 -0
  171. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/json.py +0 -0
  172. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/list.py +0 -0
  173. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/path.py +0 -0
  174. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/thread.py +0 -0
  175. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/win32_process.py +0 -0
  176. {ok-script-0.0.68 → ok-script-0.0.70}/ok/util/yaml.py +0 -0
  177. {ok-script-0.0.68 → ok-script-0.0.70}/ok_script.egg-info/dependency_links.txt +0 -0
  178. {ok-script-0.0.68 → ok-script-0.0.70}/ok_script.egg-info/requires.txt +0 -0
  179. {ok-script-0.0.68 → ok-script-0.0.70}/ok_script.egg-info/top_level.txt +0 -0
  180. {ok-script-0.0.68 → ok-script-0.0.70}/setup.cfg +0 -0
  181. {ok-script-0.0.68 → ok-script-0.0.70}/tests/__init__.py +0 -0
  182. {ok-script-0.0.68 → ok-script-0.0.70}/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.68
3
+ Version: 0.0.70
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
@@ -34,7 +34,8 @@ class OK:
34
34
  config_logger(config)
35
35
  logger.info(f"AutoHelper init, config: {config}")
36
36
  ok.gui.ok = self
37
- self.debug = config.get("debug", False)
37
+ config['debug'] = config.get("debug", False)
38
+ self.debug = config['debug']
38
39
  try:
39
40
  self.config = config
40
41
  self.init_device_manager()
@@ -135,9 +136,6 @@ class OK:
135
136
  def init_device_manager(self):
136
137
  if self.device_manager is None:
137
138
  from ok.capture.adb.DeviceManager import DeviceManager
138
- self.device_manager = DeviceManager(self.config.get("config_folder") or "config",
139
- self.config.get('windows'),
140
- self.config.get('adb'),
141
- self.config.get("debug"),
139
+ self.device_manager = DeviceManager(self.config,
142
140
  self.exit_event)
143
141
  ok.gui.device_manager = self.device_manager
@@ -28,7 +28,7 @@ class BaseCaptureMethod:
28
28
  try:
29
29
  self.get_frame()
30
30
  except Exception as e:
31
- logger.error('get frame error')
31
+ logger.error('width get frame error', e)
32
32
  return self._size[0]
33
33
 
34
34
  @property
@@ -37,7 +37,7 @@ class BaseCaptureMethod:
37
37
  try:
38
38
  self.get_frame()
39
39
  except Exception as e:
40
- logger.error('get frame error')
40
+ logger.error('height get frame error', e)
41
41
  return self._size[1]
42
42
 
43
43
  def get_frame(self) -> np.ndarray | None:
@@ -1,5 +1,4 @@
1
1
  # original https://github.com/dantmnf & https://github.com/hakaboom/winAuto
2
- import os.path
3
2
  import re
4
3
  import threading
5
4
  import time
@@ -75,13 +74,13 @@ class HwndWindow:
75
74
  def update_frame_size(self, width, height):
76
75
  logger.debug(f"update_frame_size:{self.frame_width}x{self.frame_height} to {width}x{height}")
77
76
  if width != self.frame_width or height != self.frame_height:
78
- self.hwnd = None
79
77
  self.frame_width = width
80
78
  self.frame_height = height
81
79
  if width > 0 and height > 0:
82
80
  self.frame_aspect_ratio = width / height
83
- logger.debug(f"HwndWindow: frame ratio:{self.frame_aspect_ratio} width: {width}, height: {height}")
84
- self.do_update_window_size()
81
+ logger.debug(f"HwndWindow: frame ratio: width: {width}, height: {height}")
82
+ self.hwnd = None
83
+ self.do_update_window_size()
85
84
 
86
85
  def update_window_size(self):
87
86
  while not self.app_exit_event.is_set() and not self.stop_event.is_set():
@@ -101,7 +100,7 @@ class HwndWindow:
101
100
  name, self.hwnd, self.exe_full_path, self.real_x_offset, self.real_y_offset, self.real_width, self.real_height = find_hwnd(
102
101
  self.title,
103
102
  self.exe_name,
104
- self.frame_aspect_ratio)
103
+ self.frame_width, self.frame_height)
105
104
  self.exists = self.hwnd is not None
106
105
  if self.hwnd is not None:
107
106
  self.exists = win32gui.IsWindow(self.hwnd)
@@ -131,8 +130,8 @@ class HwndWindow:
131
130
  self.x, self.y, self.border, self.title_height, self.width, self.height, self.ext_left_bounds, self.ext_top_bounds = x, y, border, title_height, width, height, ext_left_bounds, ext_top_bounds
132
131
  changed = True
133
132
  if changed:
134
- logger.debug(
135
- f"do_update_window_size changed,visible:{self.visible} x:{self.x} y:{self.y} border:{self.border} width:{self.width} height:{self.height} self.title_height:{self.title_height} scaling:{self.scaling}")
133
+ logger.info(
134
+ f"do_update_window_size changed,visible:{self.visible} x:{self.x} y:{self.y} border:{self.border} window:{self.width}x{self.height} self.title_height:{self.title_height} real:{self.real_width}x{self.real_height} scaling:{self.scaling}")
136
135
  communicate.window.emit(self.visible, self.x, self.y, self.border, self.title_height, self.width,
137
136
  self.height, self.scaling)
138
137
  except Exception as e:
@@ -153,10 +152,11 @@ class HwndWindow:
153
152
  return f"title:{self.title}_{self.exe_name}_{self.width}x{self.height}_{self.hwnd}_{self.exists}_{self.visible}"
154
153
 
155
154
 
156
- def find_hwnd(title, exe_name, frame_aspect_ratio=0):
155
+ def find_hwnd(title, exe_name, frame_width, frame_height):
157
156
  results = []
158
157
  if exe_name is None and title is None:
159
158
  return None, None, None, 0, 0, 0, 0
159
+ frame_aspect_ratio = frame_width / frame_height if frame_height != 0 else 0
160
160
 
161
161
  def callback(hwnd, lParam):
162
162
  if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
@@ -179,33 +179,54 @@ def find_hwnd(title, exe_name, frame_aspect_ratio=0):
179
179
 
180
180
  win32gui.EnumWindows(callback, None)
181
181
  biggest = None
182
- ratio_match = None
183
182
  if len(results) > 0:
184
183
  for result in results:
185
184
  from ok.capture.windows.BitBltCaptureMethod import bit_blt_test_hwnd
186
185
  if (biggest is None or (result[2] * result[3]) > biggest[2] * biggest[3]) and bit_blt_test_hwnd(result[0]):
187
186
  biggest = result
188
- for result in results:
189
- if frame_aspect_ratio != 0:
190
- ratio = result[2] / result[3]
191
- difference = abs(ratio - frame_aspect_ratio)
192
- support = difference <= 0.01 * frame_aspect_ratio
193
- if support and biggest != result:
194
- ratio_match = result
195
187
  x_offset = 0
196
188
  y_offset = 0
197
189
  real_width, real_height = biggest[2], biggest[3]
198
- if ratio_match is not None and ratio_match[4] - biggest[4] >= 0 and ratio_match[5] - biggest[5] >= 0:
199
- x_offset = ratio_match[4] - biggest[4]
200
- y_offset = ratio_match[5] - biggest[5]
201
- real_width = ratio_match[2]
202
- real_height = ratio_match[3]
203
- logger.debug(f'find_hwnd {results} {biggest} {ratio_match} {x_offset, y_offset, real_width, real_height}')
190
+ if biggest is not None and frame_aspect_ratio != 0:
191
+ matching_child = enum_child_windows(biggest, frame_aspect_ratio)
192
+ if matching_child is not None:
193
+ x_offset, y_offset, real_width, real_height = matching_child
194
+ logger.info(f'find_hwnd {frame_width, frame_height} {biggest} {x_offset, y_offset, real_width, real_height}')
204
195
  return biggest[6], biggest[0], biggest[1], x_offset, y_offset, real_width, real_height,
205
196
  else:
206
197
  return None, None, None, 0, 0, 0, 0
207
198
 
208
199
 
200
+ def enum_child_windows(biggest, frame_aspect_ratio):
201
+ ratio_match = []
202
+ """
203
+ A function to enumerate all child windows of the given parent window handle
204
+ and print their handle and window title.
205
+ """
206
+
207
+ def child_callback(hwnd, _):
208
+ visible = win32gui.IsWindowVisible(hwnd)
209
+ parent = win32gui.GetParent(hwnd)
210
+ rect = win32gui.GetWindowRect(hwnd)
211
+ real_width = rect[2] - rect[0]
212
+ real_height = rect[3] - rect[1]
213
+ logger.info(f'find_hwnd child_callback {visible} {biggest[0]} {parent} {rect} {real_width} {real_height}')
214
+ if visible and parent == biggest[0]:
215
+ ratio = real_width / real_height
216
+ difference = abs(ratio - frame_aspect_ratio)
217
+ support = difference <= 0.01 * frame_aspect_ratio
218
+ percent = (real_width * real_height) / (biggest[2] * biggest[3])
219
+ if support and percent >= 0.7:
220
+ x_offset = rect[0] - biggest[4]
221
+ y_offset = rect[1] - biggest[5]
222
+ ratio_match.append((x_offset, y_offset, real_width, real_height))
223
+ return True
224
+
225
+ win32gui.EnumChildWindows(biggest[0], child_callback, None)
226
+ if len(ratio_match) > 0:
227
+ return ratio_match[0]
228
+
229
+
209
230
  def get_exe_by_hwnd(hwnd):
210
231
  # Get the process ID associated with the window
211
232
  _, pid = win32process.GetWindowThreadProcessId(hwnd)
@@ -215,31 +236,10 @@ def get_exe_by_hwnd(hwnd):
215
236
  return process.name(), process.exe()
216
237
 
217
238
 
218
- def enum_windows(emulator_path=None):
219
- if emulator_path is not None:
220
- emulator_path = os.path.normpath(emulator_path)
221
-
222
- def callback(hwnd, extra):
223
- name, full_path = get_exe_by_hwnd(hwnd)
224
- if emulator_path and emulator_path != full_path:
225
- return True
226
- buff = win32gui.GetWindowText(hwnd)
227
- if buff and win32gui.IsWindowVisible(hwnd):
228
- rect = win32gui.GetWindowRect(hwnd)
229
- width = rect[2] - rect[0]
230
- height = rect[3] - rect[1]
231
- extra.append((hwnd, buff, width, height))
232
- return True
233
-
234
- windows = []
235
- win32gui.EnumWindows(callback, windows)
236
- return windows
237
-
238
-
239
239
  if __name__ == '__main__':
240
240
  print(find_hwnd("MuMu模拟器12", None))
241
- hwnd_window = HwndWindow(threading.Event(), None, 'D:\\MuMuPlayer-12.0\\shell\\MuMuPlayer.exe', 16, 9)
242
- from ok.capture.windows.BitBltCaptureMethod import BitBltCaptureMethod
243
-
244
- method = BitBltCaptureMethod(hwnd_window)
245
- method.get_frame()
241
+ # hwnd_window = HwndWindow(threading.Event(), None, 'D:\\MuMuPlayer-12.0\\shell\\MuMuPlayer.exe', 16, 9)
242
+ # from ok.capture.windows.BitBltCaptureMethod import BitBltCaptureMethod
243
+ #
244
+ # method = BitBltCaptureMethod(hwnd_window)
245
+ # method.get_frame()
@@ -16,19 +16,25 @@ logger = get_logger(__name__)
16
16
 
17
17
  class DeviceManager:
18
18
 
19
- def __init__(self, config_folder, windows_capture_config, adb_capture_config, debug=False, exit_event=None):
19
+ def __init__(self, app_config, exit_event=None):
20
20
  self._device = None
21
21
  self._adb = None
22
- self.windows_capture_config = windows_capture_config
23
- self.adb_capture_config = adb_capture_config
24
- self.debug = debug
22
+ self.supported_ratio = parse_ratio(app_config.get(
23
+ 'supported_screen_ratio'))
24
+ self.windows_capture_config = app_config.get('windows')
25
+ self.adb_capture_config = app_config.get('adb')
26
+ self.debug = app_config.get('debug')
25
27
  self.interaction = None
26
28
  self.device_dict = {}
27
29
  self.exit_event = exit_event
28
- if windows_capture_config is not None:
29
- self.hwnd = HwndWindow(exit_event, windows_capture_config.get('title'),
30
- windows_capture_config.get('exe'))
31
- self.config = Config({"preferred": "none", "pc_full_path": "none", 'capture': 'windows'}, config_folder,
30
+ self.resolution_dict = {}
31
+ if self.windows_capture_config is not None:
32
+ self.hwnd = HwndWindow(exit_event, self.windows_capture_config.get('title'),
33
+ self.windows_capture_config.get('exe'))
34
+ else:
35
+ self.hwnd = None
36
+ self.config = Config({"preferred": "none", "pc_full_path": "none", 'capture': 'windows'},
37
+ app_config.get('config_folder'),
32
38
  "devices")
33
39
  self.capture_method = None
34
40
  self.handler = Handler(exit_event, 'RefreshAdb')
@@ -73,7 +79,7 @@ class DeviceManager:
73
79
  def update_pc_device(self):
74
80
  if self.windows_capture_config is not None:
75
81
  name, hwnd, full_path, x, y, width, height = find_hwnd(self.windows_capture_config.get('title'),
76
- self.windows_capture_config.get('exe'))
82
+ self.windows_capture_config.get('exe'), 0, 0)
77
83
  nick = name or self.windows_capture_config.get('exe')
78
84
  pc_device = {"address": "", "imei": 'pc', "device": "windows",
79
85
  "model": "", "nick": nick, "width": width,
@@ -98,7 +104,7 @@ class DeviceManager:
98
104
 
99
105
  if self.exit_event.is_set():
100
106
  return
101
- self.start()
107
+ self.do_start()
102
108
 
103
109
  logger.debug(f'refresh {self.device_dict}')
104
110
 
@@ -112,10 +118,11 @@ class DeviceManager:
112
118
  found = True
113
119
  break
114
120
  if not found:
121
+ width, height = self.get_resolution(adb_device)
115
122
  logger.debug(f'refresh_phones found an phone {adb_device}')
116
123
  phone_device = {"address": adb_device.serial, "device": "adb", "connected": True, "imei": imei,
117
124
  "nick": adb_device.prop.model or imei,
118
- "resolution": self.get_resolution(adb_device)}
125
+ "resolution": f'{width}x{height}'}
119
126
  self.device_dict[imei] = phone_device
120
127
 
121
128
  def refresh_emulators(self):
@@ -124,8 +131,9 @@ class DeviceManager:
124
131
  installed_emulators = manager.all_emulator_instances
125
132
  for emulator in installed_emulators:
126
133
  adb_device = self.adb_connect(emulator.serial)
134
+ width, height = self.get_resolution(adb_device)
127
135
  name, hwnd, full_path, x, y, width, height = find_hwnd(None,
128
- emulator.path)
136
+ emulator.path, width, height)
129
137
  connected = adb_device is not None and name is not None
130
138
  emulator_device = {"address": emulator.serial, "device": "adb",
131
139
  "full_path": emulator.path, "connected": connected,
@@ -142,10 +150,16 @@ class DeviceManager:
142
150
  device = self.device
143
151
  width, height = 0, 0
144
152
  if device is not None:
153
+ if resolution := self.resolution_dict.get(device.serial):
154
+ return resolution
145
155
  frame = do_screencap(device)
146
156
  if frame is not None:
147
157
  height, width, _ = frame.shape
148
- return height, width
158
+ if self.supported_ratio is None or abs(width / height - self.supported_ratio) < 0.01:
159
+ self.resolution_dict[device.serial] = (width, height)
160
+ else:
161
+ logger.warning(f'resolution error {device.serial} {self.supported_ratio} {width, height}')
162
+ return width, height
149
163
 
150
164
  def set_preferred_device(self, imei=None, index=-1):
151
165
  logger.debug(f"set_preferred_device {imei} {index}")
@@ -156,7 +170,12 @@ class DeviceManager:
156
170
  preferred = self.device_dict.get(imei)
157
171
  if preferred is None:
158
172
  if len(self.device_dict) > 0:
159
- preferred = next(iter(self.device_dict.values()))
173
+ connected_device = None
174
+ for device in self.device_dict.values():
175
+ if device.get('connected') or connected_device is None:
176
+ connected_device = device
177
+ logger.info(f'first start use first or connected device {connected_device}')
178
+ preferred = connected_device
160
179
  imei = preferred['imei']
161
180
  else:
162
181
  logger.warning(f'no devices')
@@ -233,17 +252,18 @@ class DeviceManager:
233
252
  self.interaction = Win32Interaction(self.capture_method)
234
253
  preferred['connected'] = self.capture_method.connected()
235
254
  else:
236
- height, width = self.get_resolution()
255
+ width, height = self.get_resolution()
237
256
  if self.config.get('capture') == "windows":
238
257
  self.ensure_hwnd(None, preferred.get('full_path'), width, height)
239
258
  self.use_windows_capture({'can_bit_blt': True}, require_bg=True, use_bit_blt_only=True)
240
- elif not isinstance(self.capture_method, ADBCaptureMethod):
241
- logger.debug(f'use adb capture')
242
- if self.capture_method is not None:
243
- self.capture_method.close()
244
- self.capture_method = ADBCaptureMethod(self, self.exit_event, width=width,
245
- height=height)
246
- if self.debug:
259
+ else:
260
+ if not isinstance(self.capture_method, ADBCaptureMethod):
261
+ logger.debug(f'use adb capture')
262
+ if self.capture_method is not None:
263
+ self.capture_method.close()
264
+ self.capture_method = ADBCaptureMethod(self, self.exit_event, width=width,
265
+ height=height)
266
+ if self.debug and preferred.get('full_path'):
247
267
  self.ensure_hwnd(None, preferred.get('full_path'), width, height)
248
268
  elif self.hwnd is not None:
249
269
  self.hwnd.stop()
@@ -259,7 +279,7 @@ class DeviceManager:
259
279
 
260
280
  def update_resolution_for_hwnd(self):
261
281
  if self.hwnd is not None and self.hwnd.frame_aspect_ratio == 0:
262
- height, width = self.get_resolution()
282
+ width, height = self.get_resolution()
263
283
  logger.debug(f'update resolution for {self.hwnd} {width}x{height}')
264
284
  self.hwnd.update_frame_size(width, height)
265
285
 
@@ -363,3 +383,12 @@ class DeviceManager:
363
383
  elif installed := self.adb_check_installed(packages):
364
384
  self.adb_start_package(installed)
365
385
  return True
386
+
387
+
388
+ def parse_ratio(ratio_str):
389
+ if ratio_str:
390
+ # Split the string into two parts: '16' and '9'
391
+ numerator, denominator = ratio_str.split(':')
392
+ # Convert the strings to integers and perform the division
393
+ ratio_float = int(numerator) / int(denominator)
394
+ return ratio_float
@@ -40,8 +40,15 @@ class BitBltCaptureMethod(BaseWindowsCaptureMethod):
40
40
 
41
41
  @override
42
42
  def do_get_frame(self) -> MatLike | None:
43
- return bit_blt_capture_frame(self.hwnd_window.hwnd, self.hwnd_window.real_x_offset or self.hwnd_window.border,
44
- self.hwnd_window.real_y_offset or self.hwnd_window.title_height,
43
+ if self.hwnd_window.real_x_offset != 0 or self.hwnd_window.real_y_offset != 0:
44
+ x = self.hwnd_window.real_x_offset
45
+ y = self.hwnd_window.real_y_offset
46
+ else:
47
+ x = self.hwnd_window.border
48
+ y = self.hwnd_window.title_height
49
+
50
+ return bit_blt_capture_frame(self.hwnd_window.hwnd, x,
51
+ y,
45
52
  self.hwnd_window.real_width or self.hwnd_window.width,
46
53
  self.hwnd_window.real_height or self.hwnd_window.height,
47
54
  self.hwnd_window.ext_left_bounds, self.hwnd_window.ext_top_bounds)
@@ -1,5 +1,10 @@
1
+ import ctypes
1
2
  import json
3
+ import locale
4
+ import random
5
+ import time
2
6
  import uuid
7
+ from urllib.parse import urlencode
3
8
 
4
9
  import requests
5
10
  import wmi
@@ -10,6 +15,8 @@ from ok.util.Handler import Handler
10
15
 
11
16
  FIREBASE_ENDPOINT = 'https://www.google-analytics.com/mp/collect'
12
17
 
18
+ GTAG_ENDPOINT = "https://www.google-analytics.com/g/collect"
19
+
13
20
  logger = get_logger(__name__)
14
21
 
15
22
 
@@ -20,8 +27,9 @@ class FireBaseAnalytics:
20
27
  self.app_config = app_config
21
28
  self._config = None
22
29
  self._handler = Handler(exit_event, __name__)
23
- self._handler.post(self.report_open, 10)
30
+ self._handler.post(self.send_gtag, 0)
24
31
  self._user_properties = None
32
+ self._fv = 1
25
33
 
26
34
  @property
27
35
  def user_properties(self):
@@ -64,8 +72,10 @@ class FireBaseAnalytics:
64
72
  }
65
73
  return self._user_properties
66
74
 
67
- def report_open(self):
68
- self.send_event('app_open', {'version': self.app_config.get('version'), 'debug': self.app_config.get('debug')})
75
+ #
76
+ # def report_open(self):
77
+ # self._handler.post(self.send_gtag, 5)
78
+ # # self.send_event('app_open', {'version': self.app_config.get('version'), 'debug': self.app_config.get('debug')})
69
79
 
70
80
  @property
71
81
  def client_id(self):
@@ -73,8 +83,66 @@ class FireBaseAnalytics:
73
83
  self._config = Config({'client_id': ''}, self.app_config.get("config_folder") or "config", 'statistics')
74
84
  if not self._config.get('client_id'):
75
85
  self._config['client_id'] = get_unique_client_id()
86
+ else:
87
+ self._fv = 0
76
88
  return self._config.get('client_id')
77
89
 
90
+ def send_gtag(self):
91
+ # Define the parameters in a dictionary
92
+ params = {
93
+ 'v': '2',
94
+ 'tid': self.measurement_id,
95
+ 'gtm': '45je4630v9186643593za200',
96
+ '_p': random_number(),
97
+ # 'gcd': '13l3l3l3l1',
98
+ 'npa': '0',
99
+ 'dma': '0',
100
+ 'tag_exp': '0',
101
+ 'cid': self.client_id,
102
+ 'ul': locale.getdefaultlocale()[0],
103
+ 'sr': get_screen_resolution(),
104
+ 'uaa': 'x86',
105
+ 'uab': '64',
106
+ # 'uafvl': 'Microsoft Edge;125.0.2535.85|Chromium;125.0.6422.142|Not.A/Brand;24.0.0.0',
107
+ 'uamb': '0',
108
+ 'uam': '',
109
+ 'uap': 'Windows',
110
+ 'uapv': '15.0.0',
111
+ 'uaw': '0',
112
+ 'are': '1',
113
+ 'frm': '0',
114
+ 'pscdl': 'noapi',
115
+ '_s': '1',
116
+ 'sid': int(time.time()),
117
+ 'sct': '1',
118
+ 'seg': '1',
119
+ 'dl': 'https://ok-script.com/',
120
+ 'dt': 'AppStartGTAG2',
121
+ 'en': 'page_view',
122
+ '_ee': '1',
123
+ 'ep.version': self.app_config.get('version')
124
+ # 'tfd': '5133'
125
+ }
126
+ if self._fv:
127
+ params['_fv'] = self._fv
128
+
129
+ # Send the GET request
130
+
131
+ headers = {
132
+ 'Content-Type': 'application/json',
133
+ 'Origin': 'https://ok-script.com',
134
+ 'Referer': 'https://ok-script.com/'
135
+ }
136
+ query_string = urlencode(params)
137
+
138
+ response = requests.post(f'{GTAG_ENDPOINT}', data=params)
139
+
140
+ logger.debug(f'send gtag {GTAG_ENDPOINT}?{query_string}')
141
+ if response.status_code == 204:
142
+ logger.debug(f'Successfully sent gtag')
143
+ else:
144
+ logger.debug(f'Failed to send event: {response.status_code} - {response.text}')
145
+
78
146
  def send_event(self, event_name, params=None):
79
147
  if params is None:
80
148
  params = dict()
@@ -107,7 +175,17 @@ class FireBaseAnalytics:
107
175
 
108
176
 
109
177
  def get_unique_client_id():
110
- return str(uuid.uuid4())
178
+ return f'{random_number()}.{random_number()}'
179
+
180
+
181
+ def random_number():
182
+ return random.randint(0, 2147483647)
183
+
184
+
185
+ def get_screen_resolution():
186
+ user32 = ctypes.windll.user32
187
+ screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
188
+ return f"{screensize[0]}x{screensize[1]}"
111
189
 
112
190
 
113
191
  if __name__ == '__main__':
@@ -8,11 +8,11 @@ from qfluentwidgets import FluentTranslator, qconfig, Theme
8
8
 
9
9
  import ok
10
10
  import ok.gui.resources
11
- from ok.capture.adb.StartController import StartController
12
11
  from ok.firebase.FireBaseAnalytics import FireBaseAnalytics
13
12
  from ok.gui.Communicate import communicate
14
13
  from ok.gui.MainWindow import MainWindow
15
14
  from ok.gui.MessageWindow import MessageWindow
15
+ from ok.gui.StartController import StartController
16
16
  from ok.gui.i18n.path import i18n_path
17
17
  from ok.gui.overlay.OverlayWindow import OverlayWindow
18
18
  from ok.logging.Logger import get_logger
@@ -26,7 +26,7 @@ class StartController(QObject):
26
26
 
27
27
  def do_start(self, task=None):
28
28
  communicate.starting_emulator.emit(False, None, 30)
29
- self.device_manager.do_refresh(fast=True)
29
+ self.device_manager.do_refresh()
30
30
 
31
31
  device = self.device_manager.get_preferred_device()
32
32
 
@@ -37,6 +37,7 @@ class StartController(QObject):
37
37
  execute(path)
38
38
  wait_until = time.time() + 30
39
39
  while not self.exit_event.is_set():
40
+ self.device_manager.do_refresh()
40
41
  error = self.check_device_error()
41
42
  if error is None:
42
43
  break
@@ -30,11 +30,14 @@ class FrameWidget(QWidget):
30
30
  communicate.update_overlay.connect(self.update)
31
31
 
32
32
  def update_mouse_position(self):
33
- x, y = win32api.GetCursorPos()
34
- relative = self.mapFromGlobal(QPoint(x / self.scaling, y / self.scaling))
35
- if self._mouse_position != relative and relative.x() > 0 and relative.y() > 0 and self._visible:
36
- self._mouse_position = relative
37
- self.update()
33
+ try:
34
+ x, y = win32api.GetCursorPos()
35
+ relative = self.mapFromGlobal(QPoint(x / self.scaling, y / self.scaling))
36
+ if self._mouse_position != relative and relative.x() > 0 and relative.y() > 0 and self._visible:
37
+ self._mouse_position = relative
38
+ self.update()
39
+ except Exception as e:
40
+ logger.warning(f'GetCursorPos exception {e}')
38
41
 
39
42
  def frame_ratio(self):
40
43
  if ok.gui.device_manager.width == 0: