ok-script 0.0.95__tar.gz → 0.0.97__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 (183) hide show
  1. {ok-script-0.0.95 → ok-script-0.0.97}/PKG-INFO +1 -1
  2. {ok-script-0.0.95 → ok-script-0.0.97}/ok/OK.py +1 -1
  3. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/HwndWindow.py +10 -7
  4. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/adb/DeviceManager.py +2 -1
  5. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +6 -4
  6. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/dump.py +3 -5
  7. {ok-script-0.0.95 → ok-script-0.0.97}/ok/color/Color.py +6 -1
  8. {ok-script-0.0.95 → ok-script-0.0.97}/ok/feature/Box.py +3 -0
  9. {ok-script-0.0.95 → ok-script-0.0.97}/ok/feature/CompressCoco.py +9 -5
  10. {ok-script-0.0.95 → ok-script-0.0.97}/ok/feature/FeatureSet.py +14 -9
  11. {ok-script-0.0.95 → ok-script-0.0.97}/ok/feature/FindFeature.py +16 -5
  12. {ok-script-0.0.95 → ok-script-0.0.97}/ok/firebase/Analytics.py +2 -2
  13. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/App.py +0 -7
  14. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/debug/DebugTab.py +31 -3
  15. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/debug/LogWindow.py +11 -9
  16. ok-script-0.0.97/ok/gui/tasks/OneTimeTaskTab.py +20 -0
  17. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/TaskCard.py +6 -6
  18. ok-script-0.0.95/ok/gui/tasks/OneTimeTaskTab.py → ok-script-0.0.97/ok/gui/tasks/TaskTab.py +5 -7
  19. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/TriggerTaskTab.py +6 -3
  20. {ok-script-0.0.95 → ok-script-0.0.97}/ok/interaction/Win32Interaction.py +1 -1
  21. {ok-script-0.0.95 → ok-script-0.0.97}/ok/ocr/OCR.py +2 -2
  22. {ok-script-0.0.95 → ok-script-0.0.97}/ok/task/ExecutorOperation.py +9 -10
  23. {ok-script-0.0.95 → ok-script-0.0.97}/ok/task/TaskExecutor.py +27 -9
  24. {ok-script-0.0.95 → ok-script-0.0.97}/ok_script.egg-info/PKG-INFO +1 -1
  25. {ok-script-0.0.95 → ok-script-0.0.97}/ok_script.egg-info/SOURCES.txt +1 -0
  26. {ok-script-0.0.95 → ok-script-0.0.97}/setup.py +1 -1
  27. {ok-script-0.0.95 → ok-script-0.0.97}/README.md +0 -0
  28. {ok-script-0.0.95 → ok-script-0.0.97}/ok/__init__.py +0 -0
  29. {ok-script-0.0.95 → ok-script-0.0.97}/ok/alas/__init__.py +0 -0
  30. {ok-script-0.0.95 → ok-script-0.0.97}/ok/alas/emulator_base.py +0 -0
  31. {ok-script-0.0.95 → ok-script-0.0.97}/ok/alas/emulator_windows.py +0 -0
  32. {ok-script-0.0.95 → ok-script-0.0.97}/ok/alas/platform_base.py +0 -0
  33. {ok-script-0.0.95 → ok-script-0.0.97}/ok/alas/platform_windows.py +0 -0
  34. {ok-script-0.0.95 → ok-script-0.0.97}/ok/alas/utils.py +0 -0
  35. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/BaseCaptureMethod.py +0 -0
  36. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/__init__.py +0 -0
  37. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/adb/ADBCaptureMethod.py +0 -0
  38. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
  39. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/adb/__init__.py +0 -0
  40. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/adb/bin/__init__.py +0 -0
  41. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/image/ImageCaptureMethod.py +0 -0
  42. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/image/__init__.py +0 -0
  43. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
  44. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/BitBltCaptureMethod.py +0 -0
  45. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
  46. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/__init__.py +0 -0
  47. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/d3d11.py +0 -0
  48. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/utils.py +0 -0
  49. {ok-script-0.0.95 → ok-script-0.0.97}/ok/capture/windows/window.py +0 -0
  50. {ok-script-0.0.95 → ok-script-0.0.97}/ok/color/__init__.py +0 -0
  51. {ok-script-0.0.95 → ok-script-0.0.97}/ok/config/Config.py +0 -0
  52. {ok-script-0.0.95 → ok-script-0.0.97}/ok/config/InfoDict.py +0 -0
  53. {ok-script-0.0.95 → ok-script-0.0.97}/ok/config/__init__.py +0 -0
  54. {ok-script-0.0.95 → ok-script-0.0.97}/ok/feature/Feature.py +0 -0
  55. {ok-script-0.0.95 → ok-script-0.0.97}/ok/feature/__init__.py +0 -0
  56. {ok-script-0.0.95 → ok-script-0.0.97}/ok/firebase/__init__.py +0 -0
  57. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/Communicate.py +0 -0
  58. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/MainWindow.py +0 -0
  59. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/MessageWindow.py +0 -0
  60. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/StartController.py +0 -0
  61. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/TabTitles.py +0 -0
  62. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/__init__.py +0 -0
  63. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/about/AboutTab.py +0 -0
  64. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/about/HttpTextEdit.py +0 -0
  65. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/about/VersionCard.py +0 -0
  66. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/about/__init__.py +0 -0
  67. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/common/OKIcon.py +0 -0
  68. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/common/__init__.py +0 -0
  69. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/common/config.py +0 -0
  70. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/common/style_sheet.py +0 -0
  71. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/debug/AspectRatioWidget.py +0 -0
  72. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/debug/FrameWidget.py +0 -0
  73. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/debug/InfoWidget.py +0 -0
  74. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/debug/Screenshot.py +0 -0
  75. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/debug/__init__.py +0 -0
  76. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/i18n/__init__.py +0 -0
  77. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/i18n/path.py +0 -0
  78. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/i18n/update.py +0 -0
  79. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/icon/__init__.py +0 -0
  80. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/icon/icon.py +0 -0
  81. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/overlay/OverlayWindow.py +0 -0
  82. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/overlay/__init__.py +0 -0
  83. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/qss/__init__.py +0 -0
  84. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/resources.py +0 -0
  85. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/settings/SettingTab.py +0 -0
  86. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/settings/__init__.py +0 -0
  87. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/start/SelectCaptureListView.py +0 -0
  88. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/start/StartCard.py +0 -0
  89. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/start/StartTab.py +0 -0
  90. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/start/__init__.py +0 -0
  91. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/ConfigItemFactory.py +0 -0
  92. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
  93. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
  94. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/LabelAndDropDown.py +0 -0
  95. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
  96. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/LabelAndList.py +0 -0
  97. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
  98. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
  99. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/LabelAndWidget.py +0 -0
  100. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/ModifyListDialog.py +0 -0
  101. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/ModifyListItem.py +0 -0
  102. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/StartButton.py +0 -0
  103. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/TaskOpButton.py +0 -0
  104. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/TooltipTableWidget.py +0 -0
  105. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/tasks/__init__.py +0 -0
  106. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/util/Alert.py +0 -0
  107. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/util/InitWorker.py +0 -0
  108. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/util/__init__.py +0 -0
  109. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/Card.py +0 -0
  110. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/EmptyCard.py +0 -0
  111. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/FramelessDialog.py +0 -0
  112. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/ListTableWidgetItem.py +0 -0
  113. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
  114. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/StartLoadingDialog.py +0 -0
  115. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/StatusBar.py +0 -0
  116. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/Tab.py +0 -0
  117. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/TabWidget.py +0 -0
  118. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
  119. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/YesNonWidgetItem.py +0 -0
  120. {ok-script-0.0.95 → ok-script-0.0.97}/ok/gui/widget/__init__.py +0 -0
  121. {ok-script-0.0.95 → ok-script-0.0.97}/ok/interaction/ADBInteraction.py +0 -0
  122. {ok-script-0.0.95 → ok-script-0.0.97}/ok/interaction/BaseInteraction.py +0 -0
  123. {ok-script-0.0.95 → ok-script-0.0.97}/ok/interaction/DoNothingInteraction.py +0 -0
  124. {ok-script-0.0.95 → ok-script-0.0.97}/ok/interaction/__init__.py +0 -0
  125. {ok-script-0.0.95 → ok-script-0.0.97}/ok/logging/Logger.py +0 -0
  126. {ok-script-0.0.95 → ok-script-0.0.97}/ok/logging/__init__.py +0 -0
  127. {ok-script-0.0.95 → ok-script-0.0.97}/ok/ocr/__init__.py +0 -0
  128. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  129. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  130. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  131. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  132. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  133. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  134. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  135. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  136. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  137. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Media/__init__.py +0 -0
  138. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  139. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Security/__init__.py +0 -0
  140. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  141. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  142. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/Windows/__init__.py +0 -0
  143. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/__init__.py +0 -0
  144. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/delegate.py +0 -0
  145. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/export.py +0 -0
  146. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/idldsl.py +0 -0
  147. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/inspectable.py +0 -0
  148. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/roapi.py +0 -0
  149. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/types.py +0 -0
  150. {ok-script-0.0.95 → ok-script-0.0.97}/ok/rotypes/winstring.py +0 -0
  151. {ok-script-0.0.95 → ok-script-0.0.97}/ok/save/BlackBarProcessor.py +0 -0
  152. {ok-script-0.0.95 → ok-script-0.0.97}/ok/save/PostProcessor.py +0 -0
  153. {ok-script-0.0.95 → ok-script-0.0.97}/ok/save/SaveByInterval.py +0 -0
  154. {ok-script-0.0.95 → ok-script-0.0.97}/ok/save/SaveByKeyPress.py +0 -0
  155. {ok-script-0.0.95 → ok-script-0.0.97}/ok/save/SaveMethodBase.py +0 -0
  156. {ok-script-0.0.95 → ok-script-0.0.97}/ok/save/__init__.py +0 -0
  157. {ok-script-0.0.95 → ok-script-0.0.97}/ok/scene/FeatureScene.py +0 -0
  158. {ok-script-0.0.95 → ok-script-0.0.97}/ok/scene/Scene.py +0 -0
  159. {ok-script-0.0.95 → ok-script-0.0.97}/ok/scene/__init__.py +0 -0
  160. {ok-script-0.0.95 → ok-script-0.0.97}/ok/stats/StreamStats.py +0 -0
  161. {ok-script-0.0.95 → ok-script-0.0.97}/ok/stats/__init__.py +0 -0
  162. {ok-script-0.0.95 → ok-script-0.0.97}/ok/task/BaseTask.py +0 -0
  163. {ok-script-0.0.95 → ok-script-0.0.97}/ok/task/TriggerTask.py +0 -0
  164. {ok-script-0.0.95 → ok-script-0.0.97}/ok/task/__init__.py +0 -0
  165. {ok-script-0.0.95 → ok-script-0.0.97}/ok/update/GithubMultiDownloader.py +0 -0
  166. {ok-script-0.0.95 → ok-script-0.0.97}/ok/update/Updater.py +0 -0
  167. {ok-script-0.0.95 → ok-script-0.0.97}/ok/update/__init__.py +0 -0
  168. {ok-script-0.0.95 → ok-script-0.0.97}/ok/update/gen_md5.py +0 -0
  169. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/Handler.py +0 -0
  170. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/__init__.py +0 -0
  171. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/exit_event.py +0 -0
  172. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/json.py +0 -0
  173. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/list.py +0 -0
  174. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/path.py +0 -0
  175. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/thread.py +0 -0
  176. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/win32_process.py +0 -0
  177. {ok-script-0.0.95 → ok-script-0.0.97}/ok/util/yaml.py +0 -0
  178. {ok-script-0.0.95 → ok-script-0.0.97}/ok_script.egg-info/dependency_links.txt +0 -0
  179. {ok-script-0.0.95 → ok-script-0.0.97}/ok_script.egg-info/requires.txt +0 -0
  180. {ok-script-0.0.95 → ok-script-0.0.97}/ok_script.egg-info/top_level.txt +0 -0
  181. {ok-script-0.0.95 → ok-script-0.0.97}/setup.cfg +0 -0
  182. {ok-script-0.0.95 → ok-script-0.0.97}/tests/__init__.py +0 -0
  183. {ok-script-0.0.95 → ok-script-0.0.97}/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.95
3
+ Version: 0.0.97
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
@@ -114,7 +114,7 @@ class OK:
114
114
  trigger_tasks=self.config.get('trigger_tasks', []),
115
115
  scenes=self.config['scenes'],
116
116
  feature_set=self.feature_set,
117
- config_folder=self.config.get("config_folder"))
117
+ config_folder=self.config.get("config_folder"), debug=self.debug)
118
118
 
119
119
  ok.gui.executor = self.task_executor
120
120
 
@@ -29,7 +29,6 @@ class HwndWindow:
29
29
  left_cut = 0
30
30
  ext_left_bounds = 0 # for BitBlt
31
31
  ext_top_bounds = 0 # for BitBlt
32
- window_change_listeners = []
33
32
  frame_aspect_ratio = 0
34
33
  hwnd = None
35
34
  frame_width = 0
@@ -244,13 +243,17 @@ def enum_child_windows(biggest, frame_aspect_ratio):
244
243
 
245
244
  def get_exe_by_hwnd(hwnd):
246
245
  # Get the process ID associated with the window
247
- _, pid = win32process.GetWindowThreadProcessId(hwnd)
246
+ try:
247
+ _, pid = win32process.GetWindowThreadProcessId(hwnd)
248
248
 
249
- # Get the process name and executable path
250
- if pid > 0:
251
- process = psutil.Process(pid)
252
- return process.name(), process.exe(), process.cmdline()
253
- else:
249
+ # Get the process name and executable path
250
+ if pid > 0:
251
+ process = psutil.Process(pid)
252
+ return process.name(), process.exe(), process.cmdline()
253
+ else:
254
+ return None, None, None
255
+ except Exception as e:
256
+ logger.error('get_exe_by_hwnd error', e)
254
257
  return None, None, None
255
258
 
256
259
 
@@ -137,11 +137,12 @@ class DeviceManager:
137
137
  from ok.alas.emulator_windows import EmulatorManager
138
138
  manager = EmulatorManager()
139
139
  installed_emulators = manager.all_emulator_instances
140
+ logger.info(f'installed emulators {installed_emulators}')
140
141
  for emulator in installed_emulators:
141
142
  preferred = self.get_preferred_device()
142
143
  if current and preferred is not None and preferred['imei'] != emulator.name:
143
144
  logger.debug(f"refresh current only skip others {preferred['imei']} != {emulator.name}")
144
- break
145
+ continue
145
146
  adb_device = self.adb_connect(emulator.serial)
146
147
  width, height = self.get_resolution(adb_device) if adb_device is not None else 0, 0
147
148
  name, hwnd, full_path, x, y, width, height = find_hwnd(None,
@@ -51,11 +51,12 @@ class WindowsGraphicsCaptureMethod(BaseWindowsCaptureMethod):
51
51
 
52
52
  def convert_dx_frame(self):
53
53
  frame = self.last_dx_frame
54
- self.last_dx_frame = None
55
54
  if not frame:
56
- logger.warning('convert_dx_frame self.last_dx_frame is none')
55
+ # logger.warning('convert_dx_frame self.last_dx_frame is none')
57
56
  return None
58
-
57
+ start = time.time()
58
+ dx_time = self.last_frame_time
59
+ self.last_dx_frame = None
59
60
  need_reset_framepool = False
60
61
  if frame.ContentSize.Width != self.last_size.Width or frame.ContentSize.Height != self.last_size.Height:
61
62
  need_reset_framepool = True
@@ -94,6 +95,7 @@ class WindowsGraphicsCaptureMethod(BaseWindowsCaptureMethod):
94
95
  (desc.Height, mapinfo.RowPitch // 4, 4))[
95
96
  :, :desc.Width].copy()
96
97
  self.immediatedc.Unmap(cputex, 0)
98
+ # logger.debug(f'frame latency {(time.time() - start):.3f} {(time.time() - dx_time):.3f}')
97
99
  return img
98
100
  except OSError as e:
99
101
  if e.winerror == d3d11.DXGI_ERROR_DEVICE_REMOVED or e.winerror == d3d11.DXGI_ERROR_DEVICE_RESET:
@@ -150,7 +152,7 @@ class WindowsGraphicsCaptureMethod(BaseWindowsCaptureMethod):
150
152
  self.evtoken = item.add_Closed(delegate)
151
153
  self.frame_pool = Direct3D11CaptureFramePool.CreateFreeThreaded(self.rtdevice,
152
154
  DirectXPixelFormat.B8G8R8A8UIntNormalized,
153
- 2, item.Size)
155
+ 1, item.Size)
154
156
  self.session = self.frame_pool.CreateCaptureSession(item)
155
157
  pool = self.frame_pool
156
158
  pool.add_FrameArrived(
@@ -27,12 +27,10 @@ def dump_threads():
27
27
  output_file = get_path_relative_to_exe(os.path.join('logs', "thread_dumps.txt"))
28
28
  print(f'Dumping threads to {output_file}')
29
29
 
30
- with open(output_file, "w") as file:
31
- # Open the file with UTF-8 encoding
32
- with open('file.txt', 'w', encoding='utf-8') as f:
33
- f.write("\n\n".join(thread_dumps))
30
+ with open(output_file, "w", encoding='utf-8') as f:
31
+ f.write("\n\n".join(thread_dumps))
34
32
 
35
- # subprocess.Popen(r'explorer /select,"{}"'.format(output_file))
33
+ # subprocess.Popen(r'explorer /select,"{}"'.format(output_file))
36
34
 
37
35
 
38
36
  def kill_dump():
@@ -104,6 +104,11 @@ def find_color_rectangles(image, color_range, min_width, min_height, max_width=-
104
104
  raise ValueError("Image not found or path is incorrect")
105
105
  if box is not None:
106
106
  image = image[box.y:box.y + box.height, box.x:box.x + box.width, :3]
107
+ x_offset = box.x
108
+ y_offset = box.y
109
+ else:
110
+ x_offset = 0
111
+ y_offset = 0
107
112
 
108
113
  # Convert color range to BGR format for OpenCV
109
114
  lower_bound = np.array([color_range['b'][0], color_range['g'][0], color_range['r'][0]], dtype="uint8")
@@ -139,7 +144,7 @@ def find_color_rectangles(image, color_range, min_width, min_height, max_width=-
139
144
  if percent >= threshold:
140
145
  # Store the result
141
146
  results.append(
142
- Box(x, y, w, h, confidence=percent)
147
+ Box(x + x_offset, y + y_offset, w, h, confidence=percent)
143
148
  )
144
149
 
145
150
  return results
@@ -95,6 +95,9 @@ class Box:
95
95
  return Box(self.x + x_offset, self.y + y_offset, self.width + width_offset, self.height + height_offset,
96
96
  self.confidence, name or self.name)
97
97
 
98
+ def crop_frame(self, frame):
99
+ return frame[self.y:self.y + self.height, self.x:self.x + self.width]
100
+
98
101
  def center(self):
99
102
  return self.x + self.width / 2, self.y + self.height / 2
100
103
 
@@ -5,6 +5,7 @@ import sys
5
5
  import cv2
6
6
  import numpy as np
7
7
  from PIL import Image
8
+ from PIL.PngImagePlugin import PngInfo
8
9
 
9
10
  from ok.feature.FeatureSet import read_from_json
10
11
 
@@ -51,19 +52,22 @@ def compress_coco(coco_json, canny_upper, canny_lower) -> None:
51
52
  }
52
53
 
53
54
  # Save the image with metadata
54
- save_image_with_metadata(background, image_path, metadata)
55
+ save_image_with_metadata(background, image_path)
55
56
 
56
57
 
57
- def save_image_with_metadata(image, image_path, metadata):
58
+ def save_image_with_metadata(image, image_path):
58
59
  # Convert OpenCV image (numpy array) to PIL Image
59
60
  pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
60
61
 
62
+ metadata = PngInfo()
63
+
61
64
  # Add metadata
62
- for key, value in metadata.items():
63
- pil_image.info[key] = value
65
+ metadata.add_text('ok_compressed', '1')
66
+ metadata.add_text("Author", "ok_compress")
67
+ metadata.add_text("Description", "This is a sample image")
64
68
 
65
69
  # Save the image with metadata
66
- pil_image.save(image_path, 'PNG', optimize=True)
70
+ pil_image.save(image_path, 'PNG', optimize=True, pnginfo=metadata)
67
71
 
68
72
 
69
73
  if __name__ == '__main__':
@@ -172,8 +172,12 @@ class FeatureSet:
172
172
  if use_gray_scale:
173
173
  search_area = cv2.cvtColor(search_area, cv2.COLOR_BGR2GRAY)
174
174
  template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
175
- # if category_name.startswith('edge_'):
176
- # search_area =
175
+ if category_name.startswith('edge_'):
176
+ search_area = cv2.cvtColor(search_area, cv2.COLOR_BGR2GRAY)
177
+ search_area = cv2.Canny(search_area, self.canny_lower, self.canny_higher)
178
+ elif category_name.startswith('gray_'):
179
+ search_area = cv2.cvtColor(search_area, cv2.COLOR_BGR2GRAY)
180
+
177
181
  result = cv2.matchTemplate(search_area, template, cv2.TM_CCOEFF_NORMED)
178
182
 
179
183
  # Define a threshold for acceptable matches
@@ -213,7 +217,7 @@ def read_from_json(coco_json, width=-1, height=-1, canny_lower=50, canny_upper=1
213
217
  image_path = str(os.path.join(coco_folder, file_name))
214
218
  if ok_compressed is None:
215
219
  image = Image.open(image_path)
216
- ok_compressed = 'ok_compressed' in image.info.items()
220
+ ok_compressed = 'ok_compressed' in image.info.keys()
217
221
  whole_image = cv2.imread(image_path)
218
222
  if whole_image is None:
219
223
  logger.error(f'Could not read image {image_path}')
@@ -251,13 +255,14 @@ def read_from_json(coco_json, width=-1, height=-1, canny_lower=50, canny_upper=1
251
255
  if category_name in feature_dict:
252
256
  raise ValueError(f"Multiple boxes found for category {category_name}")
253
257
  if not category_name.startswith('box_'):
254
- if category_name.startswith('edge_'):
255
- image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
256
- image = cv2.Canny(image, canny_lower, canny_upper)
257
- elif category_name.startswith('gray_'):
258
- image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
258
+ if ok_compressed:
259
+ if category_name.startswith('edge_'):
260
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
261
+ image = cv2.Canny(image, canny_lower, canny_upper)
262
+ elif category_name.startswith('gray_'):
263
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
259
264
  feature_dict[category_name] = Feature(image, x, y)
260
- box_dict[category_name] = Box(x, y, image.shape[1], image.shape[2], name=category_name)
265
+ box_dict[category_name] = Box(x, y, image.shape[1], image.shape[0], name=category_name)
261
266
 
262
267
  return feature_dict, box_dict, ok_compressed
263
268
 
@@ -31,13 +31,24 @@ class FindFeature:
31
31
  setattr(self, feature, result)
32
32
  return ret
33
33
 
34
+ def wait_feature(self, feature, horizontal_variance=0, vertical_variance=0, threshold=0, wait_until_before_delay=-1,
35
+ time_out=0, pre_action=None, post_action=None, use_gray_scale=False, box=None,
36
+ raise_if_not_found=False):
37
+ return self.wait_until(
38
+ lambda: self.find_one(feature, horizontal_variance, vertical_variance, threshold,
39
+ use_gray_scale=use_gray_scale, box=box),
40
+ time_out,
41
+ pre_action,
42
+ post_action, wait_until_before_delay, raise_if_not_found)
43
+
34
44
  def wait_click_feature(self, feature, horizontal_variance=0, vertical_variance=0, threshold=0, relative_x=0.5,
35
45
  relative_y=0.5,
36
- time_out=0, pre_action=None, post_action=None):
37
- box = self.wait_until(lambda: self.find_one(feature, horizontal_variance, vertical_variance, threshold),
38
- time_out,
39
- pre_action,
40
- post_action)
46
+ time_out=0, pre_action=None, post_action=None, box=None, raise_if_not_found=True):
47
+ box = self.wait_until(
48
+ lambda: self.find_one(feature, horizontal_variance, vertical_variance, threshold, box=box),
49
+ time_out,
50
+ pre_action,
51
+ post_action, raise_if_not_found)
41
52
  if box is not None:
42
53
  self.click_box(box, relative_x, relative_y)
43
54
  return True
@@ -103,14 +103,14 @@ class Analytics:
103
103
 
104
104
  params.update(self.user_properties)
105
105
 
106
- logger.debug(f'send report {params}')
106
+ logger.info(f'send report {params}')
107
107
 
108
108
  response = requests.post(self.report_url, json=params)
109
109
 
110
110
  if response.status_code == 200:
111
111
  logger.debug(f'Successfully send report')
112
112
  else:
113
- logger.debug(f'Failed to send event: {response.status_code} - {response.text}')
113
+ logger.error(f'Failed to send event: {response.status_code} - {response.text}')
114
114
 
115
115
  self._handler.post(self.send_alive, 3600)
116
116
 
@@ -47,7 +47,6 @@ class App:
47
47
  self.loading_window = None
48
48
  self.overlay_window = None
49
49
  self.main_window = None
50
- self.log_window = None
51
50
  self.exit_event = exit_event
52
51
  self.icon = QIcon(self.config.get('gui_icon') or ":/icon/icon.ico")
53
52
  if self.config.get('analytics'):
@@ -98,12 +97,6 @@ class App:
98
97
  if self.overlay and ok.gui.device_manager.hwnd is not None:
99
98
  self.overlay_window = OverlayWindow(ok.gui.device_manager.hwnd)
100
99
 
101
- if self.config.get('debug'):
102
- from ok.gui.debug.LogWindow import LogWindow
103
- self.log_window = LogWindow(self.config)
104
- self.log_window.show()
105
- logger.debug('showing log_window')
106
-
107
100
  self.main_window = MainWindow(self.config, self.icon, self.title, self.version, self.overlay, self.about,
108
101
  self.exit_event)
109
102
  # Set the window title here
@@ -29,6 +29,9 @@ class DebugTab(Tab):
29
29
 
30
30
  self.config = Config({'target_task': "", 'target_images': [], 'target_function': ""},
31
31
  app_config.get('config_folder'), 'debug')
32
+ self.log_window_config = Config({'width': 800, 'height': 300, 'x': 0, 'y': 0, 'keyword': '',
33
+ 'level': 'ALL', 'show': True},
34
+ app_config.get('config_folder'), 'log_window')
32
35
  tool_widget = QWidget()
33
36
  layout = FlowLayout(tool_widget, False)
34
37
 
@@ -53,7 +56,14 @@ class DebugTab(Tab):
53
56
  ocr_button.clicked.connect(lambda: self.handler.post(self.ocr))
54
57
  layout.addWidget(ocr_button)
55
58
 
56
- open_log_folder = PushButton(self.tr("Open Logs"))
59
+ self.log_window = None
60
+
61
+ log_window_button = PushButton(self.tr("Open Logs"))
62
+ log_window_button.clicked.connect(self.toggle_log_window)
63
+ layout.addWidget(log_window_button)
64
+
65
+ if self.log_window_config.get('show'):
66
+ self.toggle_log_window()
57
67
 
58
68
  call_task_widget = QWidget()
59
69
  call_task_container = QVBoxLayout(call_task_widget)
@@ -98,6 +108,22 @@ class DebugTab(Tab):
98
108
  self.handler.post(self.bind_hot_keys)
99
109
  self.handler.post(self.check_hotkey, 0.1)
100
110
 
111
+ ok.gui.app.app.aboutToQuit.connect(self.unregister)
112
+
113
+ def toggle_log_window(self):
114
+ if self.log_window is None:
115
+ from ok.gui.debug.LogWindow import LogWindow
116
+ self.log_window = LogWindow(self.log_window_config)
117
+ self.log_window.show()
118
+ self.log_window_config['show'] = True
119
+ elif self.log_window.isVisible():
120
+ self.log_window.hide()
121
+ self.log_window_config['show'] = False
122
+ else:
123
+ self.log_window_config['show'] = True
124
+ self.log_window.show()
125
+ logger.debug('showing log_window')
126
+
101
127
  def check_hotkey(self):
102
128
  # Example event type, you should use the appropriate QEvent.Type for your case
103
129
  msg = wintypes.MSG()
@@ -110,7 +136,7 @@ class DebugTab(Tab):
110
136
  logger.debug('dumping threads')
111
137
  dump_threads()
112
138
  elif msg.wParam == 2:
113
- self.handler.post(self.capture)
139
+ self.handler.post(capture)
114
140
 
115
141
  # Repost the check_hotkey method to be called after 100 ms
116
142
  self.handler.post(self.check_hotkey, 0.1)
@@ -127,8 +153,10 @@ class DebugTab(Tab):
127
153
  logger.debug("Failed to register hotkey for Alt+Ctrl+S")
128
154
  logger.debug('bind_hot_keys')
129
155
 
130
- def __del__(self):
156
+ @staticmethod
157
+ def unregister():
131
158
  # Unregister the hotkeys
159
+ logger.debug('Unregister the hotkeys')
132
160
  windll.user32.UnregisterHotKey(None, 1)
133
161
  windll.user32.UnregisterHotKey(None, 2)
134
162
 
@@ -4,7 +4,6 @@ from PySide6.QtWidgets import QWidget, \
4
4
  QStyledItemDelegate, QListView, QVBoxLayout, QHBoxLayout, QAbstractItemView, QComboBox, QLineEdit, QLabel, \
5
5
  QPushButton
6
6
 
7
- from ok.config.Config import Config
8
7
  from ok.gui.Communicate import communicate
9
8
 
10
9
  LOG_BG_TRANS = 80
@@ -70,9 +69,6 @@ class LogModel(QAbstractListModel):
70
69
  self.do_filter_logs()
71
70
  self.endInsertRows()
72
71
 
73
- # self.layoutChanged.emit()
74
- # self.log_list.scrollToBottom()
75
-
76
72
  def do_filter_logs(self):
77
73
 
78
74
  keyword = self.current_keyword.lower()
@@ -109,15 +105,13 @@ level_severity = {v: k for k, v in log_levels.items()}
109
105
 
110
106
 
111
107
  class LogWindow(QWidget):
112
- def __init__(self, app_config):
108
+ def __init__(self, config):
113
109
  super().__init__()
114
110
  self.setWindowTitle('Log Viewer')
115
111
  self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
116
112
  self.setAttribute(Qt.WA_TranslucentBackground)
117
113
 
118
- self.config = Config({'width': 800, 'height': 300, 'x': 0, 'y': 0,
119
- 'level': 'ALL'},
120
- app_config.get('config_folder'), 'log_window')
114
+ self.config = config
121
115
  self.setGeometry(self.config['x'], self.config['y'], self.config['width'], self.config['height'])
122
116
 
123
117
  self.old_pos = None
@@ -139,6 +133,8 @@ class LogWindow(QWidget):
139
133
 
140
134
  self.keyword_filter = QLineEdit()
141
135
  self.keyword_filter.setPlaceholderText("Filter by keyword")
136
+ if keyword := self.config.get('keyword'):
137
+ self.keyword_filter.setText(keyword)
142
138
  self.keyword_filter.textChanged.connect(self.filter_logs)
143
139
 
144
140
  self.drag_button = QLabel(self.tr("Drag"))
@@ -162,6 +158,11 @@ class LogWindow(QWidget):
162
158
  self.log_list.setModel(self.log_model)
163
159
 
164
160
  communicate.log.connect(self.add_log)
161
+ self.filter_logs()
162
+
163
+ def close(self):
164
+ super().close()
165
+ self.config['show'] = False
165
166
 
166
167
  def add_log(self, level_no, message):
167
168
  # print('add_log', level_no, message)
@@ -170,8 +171,9 @@ class LogWindow(QWidget):
170
171
 
171
172
  def filter_logs(self):
172
173
  level = self.level_filter.currentText()
173
- self.config['level'] = level
174
174
  keyword = self.keyword_filter.text()
175
+ self.config['keyword'] = keyword
176
+ self.config['level'] = level
175
177
  self.log_model.filter_logs(level, keyword)
176
178
 
177
179
  def mousePressEvent(self, event):
@@ -0,0 +1,20 @@
1
+ from typing import List
2
+
3
+ import ok.gui
4
+ from ok.gui.tasks.TaskCard import TaskCard
5
+ from ok.gui.tasks.TaskTab import TaskTab
6
+ from ok.logging.Logger import get_logger
7
+
8
+ logger = get_logger(__name__)
9
+
10
+
11
+ class OneTimeTaskTab(TaskTab):
12
+ def __init__(self):
13
+ super().__init__()
14
+
15
+ for task in ok.gui.executor.onetime_tasks:
16
+ task_card = TaskCard(task, True)
17
+ self.addWidget(task_card)
18
+
19
+ def in_current_list(self, task):
20
+ return task in ok.gui.executor.onetime_tasks
@@ -7,19 +7,19 @@ from ok.gui.Communicate import communicate
7
7
  from ok.gui.common.OKIcon import OKIcon
8
8
  from ok.gui.tasks.ConfigItemFactory import config_widget
9
9
  from ok.task.BaseTask import BaseTask
10
- from ok.task.TriggerTask import TriggerTask
11
10
 
12
11
 
13
12
  class TaskCard(ExpandSettingCard):
14
- def __init__(self, task: BaseTask):
13
+ def __init__(self, task: BaseTask, onetime):
15
14
  super().__init__(FluentIcon.INFO, task.name, task.description)
16
15
  self.task = task
16
+ self.onetime = onetime
17
17
  if task.default_config:
18
18
  self.reset_config = PushButton(FluentIcon.CANCEL, self.tr("Reset Config"), self)
19
19
  self.addWidget(self.reset_config)
20
20
  self.reset_config.clicked.connect(self.reset_clicked)
21
21
 
22
- if not isinstance(task, TriggerTask):
22
+ if onetime:
23
23
  self.task_buttons = TaskButtons(self.task)
24
24
  self.addWidget(self.task_buttons)
25
25
  else:
@@ -49,10 +49,10 @@ class TaskCard(ExpandSettingCard):
49
49
 
50
50
  def update_buttons(self, task):
51
51
  if task == self.task:
52
- if isinstance(task, TriggerTask):
53
- self.enable_button.setChecked(task.enabled)
54
- else:
52
+ if self.onetime:
55
53
  self.task_buttons.update_buttons()
54
+ else:
55
+ self.enable_button.setChecked(task.enabled)
56
56
 
57
57
  def check_changed(self, checked):
58
58
  if checked:
@@ -5,7 +5,6 @@ from PySide6.QtWidgets import QTableWidgetItem
5
5
 
6
6
  import ok.gui
7
7
  from ok.gui.Communicate import communicate
8
- from ok.gui.tasks.TaskCard import TaskCard
9
8
  from ok.gui.tasks.TooltipTableWidget import TooltipTableWidget
10
9
  from ok.gui.widget.Tab import Tab
11
10
  from ok.gui.widget.UpdateConfigWidgetItem import value_to_string
@@ -14,7 +13,7 @@ from ok.logging.Logger import get_logger
14
13
  logger = get_logger(__name__)
15
14
 
16
15
 
17
- class OneTimeTaskTab(Tab):
16
+ class TaskTab(Tab):
18
17
  def __init__(self):
19
18
  super().__init__()
20
19
 
@@ -23,10 +22,6 @@ class OneTimeTaskTab(Tab):
23
22
  self.task_info_container = self.addCard(self.tr("Choose Window"), self.task_info_table)
24
23
  self.addWidget(self.task_info_container)
25
24
 
26
- for task in ok.gui.executor.onetime_tasks:
27
- task_card = TaskCard(task)
28
- self.addWidget(task_card)
29
-
30
25
  self.task_info_labels = [self.tr('Info'), self.tr('Value')]
31
26
  self.task_info_table.setColumnCount(len(self.task_info_labels)) # Name and Value
32
27
  self.task_info_table.setHorizontalHeaderLabels(self.task_info_labels)
@@ -38,9 +33,12 @@ class OneTimeTaskTab(Tab):
38
33
  def task_update(self, task):
39
34
  self.update_info_table()
40
35
 
36
+ def in_current_list(self, task):
37
+ return True
38
+
41
39
  def update_info_table(self):
42
40
  task = ok.gui.executor.current_task
43
- if task is None:
41
+ if task is None or not self.in_current_list(task):
44
42
  self.task_info_container.hide()
45
43
  else:
46
44
  self.task_info_container.show()
@@ -2,16 +2,19 @@ from typing import List
2
2
 
3
3
  import ok.gui
4
4
  from ok.gui.tasks.TaskCard import TaskCard
5
- from ok.gui.widget.Tab import Tab
5
+ from ok.gui.tasks.TaskTab import TaskTab
6
6
  from ok.logging.Logger import get_logger
7
7
 
8
8
  logger = get_logger(__name__)
9
9
 
10
10
 
11
- class TriggerTaskTab(Tab):
11
+ class TriggerTaskTab(TaskTab):
12
12
  def __init__(self):
13
13
  super().__init__()
14
14
 
15
15
  for task in ok.gui.executor.trigger_tasks:
16
- task_card = TaskCard(task)
16
+ task_card = TaskCard(task, False)
17
17
  self.addWidget(task_card)
18
+
19
+ def in_current_list(self, task):
20
+ return task in ok.gui.executor.trigger_tasks
@@ -20,7 +20,7 @@ class Win32Interaction(BaseInteraction):
20
20
  if not is_admin():
21
21
  logger.error(f"You must be an admin to use Win32Interaction")
22
22
 
23
- def send_key(self, key, down_time=0.02):
23
+ def send_key(self, key, down_time=0.01):
24
24
  if not self.capture.clickable():
25
25
  logger.error(f"can't click on {key}, because capture is not clickable")
26
26
  return
@@ -12,7 +12,7 @@ logger = get_logger(__name__)
12
12
 
13
13
  class OCR:
14
14
  executor = None
15
- ocr_default_threshold = 0.5
15
+ ocr_default_threshold = 0.8
16
16
  ocr_target_height = 0
17
17
 
18
18
  def ocr(self, x=0, y=0, to_x=1, to_y=1, match: str | List[str] | Pattern[str] | List[Pattern[str]] | None = None,
@@ -75,7 +75,7 @@ class OCR:
75
75
  communicate.emit_draw_box("ocr", detected_boxes, "red")
76
76
  communicate.emit_draw_box("ocr_zone", box, "blue")
77
77
  logger.debug(
78
- f"ocr_zone {box} found result: {len(detected_boxes)}) time: {(time.time() - start):.2f} scale_factor: {scale_factor:.2f}")
78
+ f"ocr_zone {box} found result: {detected_boxes}) time: {(time.time() - start):.2f} scale_factor: {scale_factor:.2f}")
79
79
  if not detected_boxes and ocr_boxes:
80
80
  logger.info(f'ocr detected but no match: {match} {ocr_boxes}')
81
81
  return sort_boxes(detected_boxes)
@@ -1,4 +1,3 @@
1
- import queue
2
1
  from typing import List
3
2
 
4
3
  from ok.color.Color import calculate_color_percentage
@@ -26,10 +25,9 @@ class ExecutorOperation:
26
25
  else:
27
26
  return False
28
27
 
29
- def new_queue(self):
30
- q = queue.Queue()
31
- self.executor.exit_event.bind_queue(q)
32
- return q
28
+ @property
29
+ def debug(self):
30
+ return self.executor.debug
33
31
 
34
32
  def is_scene(self, the_scene):
35
33
  return isinstance(self.executor.current_scene, the_scene)
@@ -140,7 +138,7 @@ class ExecutorOperation:
140
138
  def move_relative(self, x, y):
141
139
  self.executor.interaction.move_relative(x, y)
142
140
 
143
- def click_box(self, box: Box | List[Box] = None, relative_x=0.5, relative_y=0.5, raise_if_not_found=True,
141
+ def click_box(self, box: Box | List[Box] = None, relative_x=0.5, relative_y=0.5, raise_if_not_found=False,
144
142
  move_back=False):
145
143
  if isinstance(box, list):
146
144
  if len(box) > 0:
@@ -158,7 +156,6 @@ class ExecutorOperation:
158
156
  return self.executor.wait_scene(scene_type, time_out, pre_action, post_action)
159
157
 
160
158
  def sleep(self, timeout):
161
- self.executor.reset_scene()
162
159
  self.executor.sleep(timeout)
163
160
 
164
161
  def send_key(self, key, down_time=0.02):
@@ -176,10 +173,12 @@ class ExecutorOperation:
176
173
  self.executor.reset_scene()
177
174
  self.executor.interaction.send_key_up(key)
178
175
 
179
- def wait_until(self, condition, time_out=0, pre_action=None, post_action=None, wait_until_before_delay=0):
180
- return self.executor.wait_condition(condition, time_out, pre_action, post_action, wait_until_before_delay)
176
+ def wait_until(self, condition, time_out=0, pre_action=None, post_action=None, wait_until_before_delay=-1,
177
+ raise_if_not_found=False):
178
+ return self.executor.wait_condition(condition, time_out, pre_action, post_action, wait_until_before_delay,
179
+ raise_if_not_found)
181
180
 
182
- def wait_click_box(self, condition, time_out=0, pre_action=None, post_action=None, raise_if_not_found=True):
181
+ def wait_click_box(self, condition, time_out=0, pre_action=None, post_action=None, raise_if_not_found=False):
183
182
  target = self.wait_until(condition, time_out, pre_action, post_action)
184
183
  self.click_box(box=target, raise_if_not_found=raise_if_not_found)
185
184
  return target