ok-script 0.0.48__tar.gz → 0.0.50__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.
- {ok-script-0.0.48 → ok-script-0.0.50}/PKG-INFO +2 -1
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/OK.py +3 -2
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/adb/DeviceManager.py +3 -4
- ok-script-0.0.50/ok/config/Config.py +132 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/App.py +6 -2
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/Communicate.py +2 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/MainWindow.py +3 -3
- ok-script-0.0.50/ok/gui/about/AboutTab.py +135 -0
- ok-script-0.0.50/ok/gui/about/VersionCard.py +40 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/debug/Screenshot.py +0 -1
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/resources.py +2 -2
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/start/SelectCaptureListView.py +5 -7
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/start/StartCard.py +13 -8
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/Tab.py +7 -3
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/task/TaskExecutor.py +8 -2
- ok-script-0.0.50/ok/update/Updater.py +251 -0
- ok-script-0.0.50/ok/update/gen_md5.py +23 -0
- ok-script-0.0.50/ok/util/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/util/path.py +46 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok_script.egg-info/PKG-INFO +2 -1
- {ok-script-0.0.48 → ok-script-0.0.50}/ok_script.egg-info/SOURCES.txt +7 -1
- {ok-script-0.0.48 → ok-script-0.0.50}/ok_script.egg-info/requires.txt +1 -0
- ok-script-0.0.50/ok_script.egg-info/top_level.txt +2 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/setup.py +3 -2
- ok-script-0.0.50/tests/__init__.py +3 -0
- ok-script-0.0.50/tests/test_updater.py +25 -0
- ok-script-0.0.48/ok/config/Config.py +0 -100
- ok-script-0.0.48/ok/gui/about/AboutTab.py +0 -24
- ok-script-0.0.48/ok_script.egg-info/top_level.txt +0 -1
- {ok-script-0.0.48 → ok-script-0.0.50}/README.md +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/BaseCaptureMethod.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/HwndWindow.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/adb/ADBCaptureMethod.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/adb/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/adb/bin/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/adb/targets.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/adb/vbox.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/BitBltCaptureMethod.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/d3d11.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/dump.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/utils.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/capture/windows/window.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/color/Color.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/color/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/config/InfoDict.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/config/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/feature/Box.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/feature/Feature.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/feature/FeatureSet.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/feature/FindFeature.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/feature/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/MessageWindow.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/TabTitles.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/about/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/common/OKIcon.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/common/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/common/config.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/common/style_sheet.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/debug/AspectRatioWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/debug/DebugTab.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/debug/FrameWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/debug/InfoWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/debug/LoggerWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/debug/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/i18n/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/i18n/path.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/i18n/update.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/icon/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/icon/icon.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/overlay/OverlayWindow.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/overlay/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/qss/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/settings/SettingTab.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/settings/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/start/SelectHwndWindow.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/start/StartTab.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/start/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/ConfigItemFactory.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/LabelAndDropDown.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/LabelAndList.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/LabelAndWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/ModifyListDialog.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/ModifyListItem.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/StartButton.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/TaskCard.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/TaskOpButton.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/TooltipTableWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/TriggerTaskTab.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/tasks/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/util/Alert.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/util/InitWorker.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/util/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/Card.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/FramelessDialog.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/ListTableWidgetItem.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/StatusBar.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/TabWidget.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/YesNonWidgetItem.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/gui/widget/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/interaction/ADBInteraction.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/interaction/BaseInteraction.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/interaction/Win32Interaction.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/interaction/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/logging/Logger.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/logging/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/ocr/OCR.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/ocr/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Media/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Security/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/Storage/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/Windows/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/delegate.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/export.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/idldsl.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/inspectable.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/roapi.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/types.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/rotypes/winstring.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/save/BlackBarProcessor.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/save/PostProcessor.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/save/SaveByInterval.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/save/SaveByKeyPress.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/save/SaveMethodBase.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/save/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/scene/FeatureScene.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/scene/Scene.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/scene/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/stats/StreamStats.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/stats/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/task/BaseTask.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/task/ExecutorOperation.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/task/OneTimeTask.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/task/TriggerTask.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/task/__init__.py +0 -0
- {ok-script-0.0.48/ok/util → ok-script-0.0.50/ok/update}/__init__.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/util/exit_event.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/util/json.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/util/list.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/util/thread.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/util/win32_process.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok/util/yaml.py +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/ok_script.egg-info/dependency_links.txt +0 -0
- {ok-script-0.0.48 → ok-script-0.0.50}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ok-script
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.50
|
|
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
|
|
@@ -21,6 +21,7 @@ Requires-Dist: PySide6-Fluent-Widgets>=1.5.6
|
|
|
21
21
|
Requires-Dist: psutil>=5.9.8
|
|
22
22
|
Requires-Dist: opencv-python>=4.9.0.80
|
|
23
23
|
Requires-Dist: ok-d3dshot>=0.1.5
|
|
24
|
+
Requires-Dist: py7zr>=0.21.0
|
|
24
25
|
|
|
25
26
|
# ok-script
|
|
26
27
|
|
|
@@ -28,6 +28,8 @@ class OK:
|
|
|
28
28
|
|
|
29
29
|
def __init__(self, config: Dict[str, Any]):
|
|
30
30
|
print(f"AutoHelper init, config: {config}")
|
|
31
|
+
config_logger(config)
|
|
32
|
+
logger.info(f"AutoHelper init, config: {config}")
|
|
31
33
|
ok.gui.ok = self
|
|
32
34
|
self.debug = config.get("debug", False)
|
|
33
35
|
try:
|
|
@@ -44,6 +46,7 @@ class OK:
|
|
|
44
46
|
self.device_manager.start()
|
|
45
47
|
self.do_init()
|
|
46
48
|
except Exception as e:
|
|
49
|
+
logger.error(f'__init__ error', e)
|
|
47
50
|
self.quit()
|
|
48
51
|
raise e
|
|
49
52
|
|
|
@@ -94,8 +97,6 @@ class OK:
|
|
|
94
97
|
inference_num_threads = self.config.get('ocr').get('inference_num_threads', -1)
|
|
95
98
|
self.ocr = RapidOCR(inference_num_threads=inference_num_threads)
|
|
96
99
|
|
|
97
|
-
config_logger(self.config)
|
|
98
|
-
|
|
99
100
|
if self.config.get('coco_feature_folder') is not None:
|
|
100
101
|
coco_feature_folder = self.config.get('coco_feature_folder')
|
|
101
102
|
from ok.feature.FeatureSet import FeatureSet
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import threading
|
|
2
2
|
|
|
3
3
|
import win32gui
|
|
4
|
-
from adbutils import AdbError
|
|
5
4
|
|
|
6
5
|
from ok.capture.HwndWindow import HwndWindow, find_hwnd_by_title_and_exe
|
|
7
6
|
from ok.capture.adb.ADBCaptureMethod import ADBCaptureMethod, do_screencap
|
|
8
7
|
from ok.capture.adb.WindowsCaptureFactory import update_capture_method
|
|
9
|
-
from ok.capture.adb.vbox import installed_emulator
|
|
10
8
|
from ok.capture.windows.window import get_window_bounds
|
|
11
9
|
from ok.config.Config import Config
|
|
12
10
|
from ok.gui.Communicate import communicate
|
|
@@ -36,8 +34,7 @@ class DeviceManager:
|
|
|
36
34
|
"DeviceManager")
|
|
37
35
|
self.thread = None
|
|
38
36
|
self.capture_method = None
|
|
39
|
-
self.
|
|
40
|
-
self.start()
|
|
37
|
+
self.refresh()
|
|
41
38
|
|
|
42
39
|
def refresh(self):
|
|
43
40
|
if self.thread is None or not self.thread.is_alive():
|
|
@@ -121,6 +118,7 @@ class DeviceManager:
|
|
|
121
118
|
return
|
|
122
119
|
if not fast:
|
|
123
120
|
self.connect_all()
|
|
121
|
+
from ok.capture.adb.vbox import installed_emulator
|
|
124
122
|
installed_emulators = [] if fast else installed_emulator()
|
|
125
123
|
for device in self.adb.list():
|
|
126
124
|
logger.debug(f'adb.list() {device}')
|
|
@@ -295,6 +293,7 @@ class DeviceManager:
|
|
|
295
293
|
def shell(self, *args, **kwargs):
|
|
296
294
|
device = self.device
|
|
297
295
|
if device is not None:
|
|
296
|
+
from adbutils import AdbError
|
|
298
297
|
try:
|
|
299
298
|
return device.shell(*args, **kwargs)
|
|
300
299
|
except AdbError as e:
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from ok.gui.Communicate import communicate
|
|
2
|
+
from ok.logging.Logger import get_logger
|
|
3
|
+
from ok.util.json import read_json_file, write_json_file
|
|
4
|
+
from ok.util.path import get_path_relative_to_exe
|
|
5
|
+
|
|
6
|
+
logger = get_logger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Config(dict):
|
|
10
|
+
def __init__(self, default, folder, name, validator=None):
|
|
11
|
+
"""
|
|
12
|
+
Initialize the Config object.
|
|
13
|
+
|
|
14
|
+
:param default: Default configuration values.
|
|
15
|
+
:param folder: Folder where the config file is stored.
|
|
16
|
+
:param name: Name of the config file.
|
|
17
|
+
:param validator: Optional function to validate key-value pairs.
|
|
18
|
+
"""
|
|
19
|
+
self.default = default
|
|
20
|
+
self.validator = validator
|
|
21
|
+
self.config_file = get_path_relative_to_exe(folder, f"{name}.json")
|
|
22
|
+
|
|
23
|
+
# Read the config file, if it exists, otherwise use default
|
|
24
|
+
config = read_json_file(self.config_file)
|
|
25
|
+
if config is None:
|
|
26
|
+
self.reset_to_default()
|
|
27
|
+
else:
|
|
28
|
+
super().__init__(config)
|
|
29
|
+
modified = self.verify_config(default)
|
|
30
|
+
if modified:
|
|
31
|
+
self.save_file()
|
|
32
|
+
logger.debug(f'init self.config = {self}')
|
|
33
|
+
|
|
34
|
+
def save_file(self):
|
|
35
|
+
"""
|
|
36
|
+
Save the current configuration to the file.
|
|
37
|
+
"""
|
|
38
|
+
try:
|
|
39
|
+
write_json_file(self.config_file, self)
|
|
40
|
+
except Exception as e:
|
|
41
|
+
logger.error(f'save_file error: {e}')
|
|
42
|
+
|
|
43
|
+
def reset_to_default(self):
|
|
44
|
+
"""
|
|
45
|
+
Reset the configuration to the default values.
|
|
46
|
+
"""
|
|
47
|
+
super().clear()
|
|
48
|
+
self.update(self.default)
|
|
49
|
+
self.save_file()
|
|
50
|
+
logger.debug(f'reset_to_default self.config = {self}')
|
|
51
|
+
|
|
52
|
+
def pop(self, key, default=None):
|
|
53
|
+
"""
|
|
54
|
+
Remove and return a value from the configuration.
|
|
55
|
+
|
|
56
|
+
:param key: The key to remove.
|
|
57
|
+
:param default: The default value if the key does not exist.
|
|
58
|
+
:return: The removed value.
|
|
59
|
+
"""
|
|
60
|
+
result = super().pop(key, default)
|
|
61
|
+
self.save_file()
|
|
62
|
+
return result
|
|
63
|
+
|
|
64
|
+
def popitem(self):
|
|
65
|
+
"""
|
|
66
|
+
Remove and return the last key-value pair from the configuration.
|
|
67
|
+
"""
|
|
68
|
+
result = super().popitem()
|
|
69
|
+
self.save_file()
|
|
70
|
+
return result
|
|
71
|
+
|
|
72
|
+
def clear(self):
|
|
73
|
+
"""
|
|
74
|
+
Clear all configuration values.
|
|
75
|
+
"""
|
|
76
|
+
super().clear()
|
|
77
|
+
self.save_file()
|
|
78
|
+
|
|
79
|
+
def __setitem__(self, key, value):
|
|
80
|
+
if self.validate(key, value):
|
|
81
|
+
super().__setitem__(key, value)
|
|
82
|
+
self.save_file()
|
|
83
|
+
|
|
84
|
+
def __getitem__(self, key):
|
|
85
|
+
try:
|
|
86
|
+
return super().__getitem__(key)
|
|
87
|
+
except KeyError as e:
|
|
88
|
+
logger.error(f'KeyError: {key} not found in config: {self}')
|
|
89
|
+
raise e
|
|
90
|
+
|
|
91
|
+
def validate(self, key, value):
|
|
92
|
+
"""
|
|
93
|
+
Validate a configuration key-value pair.
|
|
94
|
+
|
|
95
|
+
:param key: The key to validate.
|
|
96
|
+
:param value: The value to validate.
|
|
97
|
+
:return: True if valid, False otherwise.
|
|
98
|
+
"""
|
|
99
|
+
if self.validator is not None:
|
|
100
|
+
valid, message = self.validator(key, value)
|
|
101
|
+
if not valid:
|
|
102
|
+
communicate.config_validation.emit(message)
|
|
103
|
+
return False
|
|
104
|
+
return True
|
|
105
|
+
|
|
106
|
+
def verify_config(self, default_config):
|
|
107
|
+
"""
|
|
108
|
+
Verify the configuration against the default configuration.
|
|
109
|
+
|
|
110
|
+
:param default_config: The default configuration.
|
|
111
|
+
:return: True if the config was modified, False otherwise.
|
|
112
|
+
"""
|
|
113
|
+
modified = False
|
|
114
|
+
|
|
115
|
+
# Remove entries that do not exist in default_config
|
|
116
|
+
for key in list(self.keys()):
|
|
117
|
+
if key not in default_config:
|
|
118
|
+
del self[key]
|
|
119
|
+
modified = True
|
|
120
|
+
|
|
121
|
+
# Check entries in default_config
|
|
122
|
+
for key, default_value in default_config.items():
|
|
123
|
+
if key not in self or not isinstance(self[key], type(default_value)):
|
|
124
|
+
self[key] = default_value
|
|
125
|
+
modified = True
|
|
126
|
+
elif self.validator is not None:
|
|
127
|
+
valid = self.validate(key, self[key])
|
|
128
|
+
if not valid:
|
|
129
|
+
self[key] = default_value
|
|
130
|
+
modified = True
|
|
131
|
+
|
|
132
|
+
return modified
|
|
@@ -13,6 +13,7 @@ from ok.gui.MessageWindow import MessageWindow
|
|
|
13
13
|
from ok.gui.i18n.path import i18n_path
|
|
14
14
|
from ok.gui.overlay.OverlayWindow import OverlayWindow
|
|
15
15
|
from ok.logging.Logger import get_logger
|
|
16
|
+
from ok.update.Updater import Updater
|
|
16
17
|
|
|
17
18
|
logger = get_logger(__name__)
|
|
18
19
|
|
|
@@ -32,6 +33,8 @@ class App:
|
|
|
32
33
|
self.app.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings)
|
|
33
34
|
qconfig.theme = Theme.AUTO
|
|
34
35
|
|
|
36
|
+
self.updater = Updater(self.config, exit_event)
|
|
37
|
+
|
|
35
38
|
self.about = self.config.get('about')
|
|
36
39
|
self.title = self.config.get('gui_title')
|
|
37
40
|
self.version = self.config.get('version')
|
|
@@ -75,8 +78,9 @@ class App:
|
|
|
75
78
|
self.show_message_window(title, content)
|
|
76
79
|
|
|
77
80
|
def show_main_window(self):
|
|
78
|
-
self.main_window = MainWindow(self.icon, self.
|
|
79
|
-
|
|
81
|
+
self.main_window = MainWindow(self.icon, self.title, self.version, self.overlay, self.about,
|
|
82
|
+
exit_event=self.exit_event)
|
|
83
|
+
# Set the window title here
|
|
80
84
|
self.main_window.setWindowIcon(self.icon)
|
|
81
85
|
if self.overlay and ok.gui.device_manager.hwnd is not None:
|
|
82
86
|
self.overlay_window = OverlayWindow(ok.gui.device_manager.hwnd)
|
|
@@ -20,6 +20,8 @@ class Communicate(QObject):
|
|
|
20
20
|
config_validation: Signal = Signal(str)
|
|
21
21
|
tab = Signal(str)
|
|
22
22
|
capture_error = Signal()
|
|
23
|
+
check_update = Signal()
|
|
24
|
+
download_update = Signal(float, str, str, bool)
|
|
23
25
|
|
|
24
26
|
def emit_draw_box(self, key: str = None, boxes=None, color=None, frame=None):
|
|
25
27
|
self.draw_box.emit(key, boxes, color, frame)
|
|
@@ -20,7 +20,7 @@ class Communicate(QObject):
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class MainWindow(MSFluentWindow):
|
|
23
|
-
def __init__(self, icon, debug=False, about=None, exit_event=None):
|
|
23
|
+
def __init__(self, icon, title, version, debug=False, about=None, exit_event=None):
|
|
24
24
|
super().__init__()
|
|
25
25
|
self.exit_event = exit_event
|
|
26
26
|
self.start_tab = StartTab()
|
|
@@ -42,11 +42,11 @@ class MainWindow(MSFluentWindow):
|
|
|
42
42
|
# self.addSubInterface(debug_tab, FluentIcon.COMMAND_PROMPT, self.tr('Debug'))
|
|
43
43
|
# ... Add other tabs similarly
|
|
44
44
|
if about:
|
|
45
|
-
about_tab = AboutTab(about)
|
|
45
|
+
about_tab = AboutTab(icon, title, version, about)
|
|
46
46
|
self.addSubInterface(about_tab, FluentIcon.QUESTION, self.tr('About'),
|
|
47
47
|
position=NavigationItemPosition.BOTTOM)
|
|
48
48
|
# Styling the tabs and content if needed, for example:
|
|
49
|
-
self.setWindowTitle(
|
|
49
|
+
self.setWindowTitle(f'{title} {version}')
|
|
50
50
|
|
|
51
51
|
communicate.executor_paused.connect(self.executor_paused)
|
|
52
52
|
communicate.tab.connect(self.navigate_tab)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
from PySide6.QtCore import Qt
|
|
2
|
+
from PySide6.QtWidgets import QHBoxLayout, QLabel
|
|
3
|
+
from qfluentwidgets import TextEdit, PushButton, InfoBar, InfoBarPosition, ProgressBar
|
|
4
|
+
|
|
5
|
+
import ok.gui
|
|
6
|
+
from ok.capture.windows.dump import dump_threads
|
|
7
|
+
from ok.gui.Communicate import communicate
|
|
8
|
+
from ok.gui.about.VersionCard import VersionCard
|
|
9
|
+
from ok.gui.widget.Tab import Tab
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AboutTab(Tab):
|
|
13
|
+
def __init__(self, icon, title, version, about):
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.version_card = VersionCard(icon, title, version, self)
|
|
16
|
+
# Create a QTextEdit instance
|
|
17
|
+
self.addWidget(self.version_card, align=Qt.AlignCenter)
|
|
18
|
+
if ok.gui.app.updater.enabled():
|
|
19
|
+
self.update_hbox = QHBoxLayout()
|
|
20
|
+
self.update_hbox.addStretch()
|
|
21
|
+
self.check_update_button = PushButton(self.tr("Check for updates"))
|
|
22
|
+
self.check_update_button.clicked.connect(self.check_update)
|
|
23
|
+
self.update_hbox.addWidget(self.check_update_button)
|
|
24
|
+
self.download_latest_button = PushButton()
|
|
25
|
+
self.download_latest_button.clicked.connect(self.download_latest)
|
|
26
|
+
|
|
27
|
+
self.update_hbox.addWidget(self.download_latest_button)
|
|
28
|
+
self.download_stable_button = PushButton(self.tr("Download stable version {version}").format(version=1))
|
|
29
|
+
self.download_stable_button.clicked.connect(self.download_stable)
|
|
30
|
+
|
|
31
|
+
self.update_hbox.addWidget(self.download_stable_button)
|
|
32
|
+
|
|
33
|
+
self.download_bar = ProgressBar(self)
|
|
34
|
+
self.download_bar.setFixedWidth(200)
|
|
35
|
+
self.update_hbox.addWidget(self.download_bar)
|
|
36
|
+
|
|
37
|
+
self.downloading_text = QLabel()
|
|
38
|
+
self.update_hbox.addWidget(self.downloading_text)
|
|
39
|
+
|
|
40
|
+
self.update_hbox.addStretch()
|
|
41
|
+
self.addLayout(self.update_hbox)
|
|
42
|
+
communicate.download_update.connect(self.download_update)
|
|
43
|
+
communicate.check_update.connect(self.update_update)
|
|
44
|
+
self.update_update_buttons(0)
|
|
45
|
+
text_edit = TextEdit()
|
|
46
|
+
text_edit.setHtml(about)
|
|
47
|
+
text_edit.setReadOnly(True)
|
|
48
|
+
|
|
49
|
+
# Set the layout on the widget
|
|
50
|
+
self.addWidget(text_edit)
|
|
51
|
+
if ok.gui.ok.debug:
|
|
52
|
+
dump_button = PushButton(self.tr("Dump Threads(HotKey:Ctrl+Alt+D)"))
|
|
53
|
+
dump_button.clicked.connect(dump_threads)
|
|
54
|
+
self.addWidget(dump_button)
|
|
55
|
+
|
|
56
|
+
def update_update_buttons(self, percent, progress=""):
|
|
57
|
+
if ok.gui.app.updater.latest_release and not ok.gui.app.updater.downloading:
|
|
58
|
+
self.download_latest_button.setText(self.tr("Download latest version {version} ({size})").format(
|
|
59
|
+
version=ok.gui.app.updater.latest_release.get('version'),
|
|
60
|
+
size=ok.gui.app.updater.latest_release.get('readable_size')))
|
|
61
|
+
self.download_latest_button.show()
|
|
62
|
+
else:
|
|
63
|
+
self.download_latest_button.hide()
|
|
64
|
+
if ok.gui.app.updater.stable_release and not ok.gui.app.updater.downloading:
|
|
65
|
+
self.download_stable_button.setText(self.tr("Download stable version {version} ({size})").format(
|
|
66
|
+
version=ok.gui.app.updater.stable_release.get('version'),
|
|
67
|
+
size=ok.gui.app.updater.stable_release.get('readable_size')))
|
|
68
|
+
self.download_stable_button.show()
|
|
69
|
+
else:
|
|
70
|
+
self.download_stable_button.hide()
|
|
71
|
+
if ok.gui.app.updater.downloading:
|
|
72
|
+
self.downloading_text.show()
|
|
73
|
+
self.downloading_text.setText(
|
|
74
|
+
self.tr('Downloading {progress} {percent}%').format(progress=progress, percent=format(percent, '.1f')))
|
|
75
|
+
self.download_bar.show()
|
|
76
|
+
self.download_bar.setValue(percent)
|
|
77
|
+
else:
|
|
78
|
+
self.downloading_text.hide()
|
|
79
|
+
self.download_bar.hide()
|
|
80
|
+
|
|
81
|
+
def download_update(self, percent, progress, done, error):
|
|
82
|
+
message = ""
|
|
83
|
+
if done:
|
|
84
|
+
if error:
|
|
85
|
+
bar = InfoBar.error
|
|
86
|
+
title = self.tr('Download Error:')
|
|
87
|
+
message = error
|
|
88
|
+
else:
|
|
89
|
+
bar = InfoBar.info
|
|
90
|
+
title = self.tr('Download Complete!')
|
|
91
|
+
bar(
|
|
92
|
+
title=title,
|
|
93
|
+
content=message,
|
|
94
|
+
orient=Qt.Horizontal,
|
|
95
|
+
isClosable=True,
|
|
96
|
+
position=InfoBarPosition.TOP,
|
|
97
|
+
duration=5000, # won't disappear automatically
|
|
98
|
+
parent=self
|
|
99
|
+
)
|
|
100
|
+
self.update_update_buttons(percent, progress)
|
|
101
|
+
|
|
102
|
+
def download_latest(self):
|
|
103
|
+
ok.gui.app.updater.async_run(lambda: ok.gui.app.updater.download(ok.gui.app.updater.latest_release))
|
|
104
|
+
|
|
105
|
+
def download_stable(self):
|
|
106
|
+
ok.gui.app.updater.async_run(lambda: ok.gui.app.updater.download(ok.gui.app.updater.stable_release))
|
|
107
|
+
|
|
108
|
+
def update_update(self):
|
|
109
|
+
self.check_update_button.setText(
|
|
110
|
+
self.tr("Check for update"))
|
|
111
|
+
self.check_update_button.setEnabled(True)
|
|
112
|
+
if ok.gui.app.updater.latest_release or ok.gui.app.updater.stable_release:
|
|
113
|
+
bar = InfoBar.info
|
|
114
|
+
message = self.tr('Found new version!')
|
|
115
|
+
elif ok.gui.app.updater.error:
|
|
116
|
+
bar = InfoBar.error
|
|
117
|
+
message = self.tr('Found new version!')
|
|
118
|
+
else:
|
|
119
|
+
bar = InfoBar.info
|
|
120
|
+
message = self.tr("This is the newest version!")
|
|
121
|
+
bar(
|
|
122
|
+
title="",
|
|
123
|
+
content=message,
|
|
124
|
+
orient=Qt.Horizontal,
|
|
125
|
+
isClosable=True,
|
|
126
|
+
position=InfoBarPosition.TOP,
|
|
127
|
+
duration=5000, # won't disappear automatically
|
|
128
|
+
parent=self
|
|
129
|
+
)
|
|
130
|
+
self.update_update_buttons(0)
|
|
131
|
+
|
|
132
|
+
def check_update(self):
|
|
133
|
+
ok.gui.app.updater.async_run(lambda: ok.gui.app.updater.check_for_updates())
|
|
134
|
+
self.check_update_button.setText(self.tr("Checking for updates"))
|
|
135
|
+
self.check_update_button.setEnabled(False)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from PySide6.QtCore import Qt
|
|
2
|
+
from PySide6.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout
|
|
3
|
+
from qfluentwidgets import IconWidget, TextWrap, CardWidget
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class VersionCard(CardWidget):
|
|
7
|
+
""" Sample card """
|
|
8
|
+
|
|
9
|
+
def __init__(self, icon, title, version, parent=None):
|
|
10
|
+
super().__init__(parent=parent)
|
|
11
|
+
|
|
12
|
+
self.iconWidget = IconWidget(icon, self)
|
|
13
|
+
self.titleLabel = QLabel(title, self)
|
|
14
|
+
self.contentLabel = QLabel(TextWrap.wrap(version, 45, False)[0], self)
|
|
15
|
+
|
|
16
|
+
self.hBoxLayout = QHBoxLayout(self)
|
|
17
|
+
self.vBoxLayout = QVBoxLayout()
|
|
18
|
+
|
|
19
|
+
self.setFixedSize(360, 90)
|
|
20
|
+
self.iconWidget.setFixedSize(48, 48)
|
|
21
|
+
|
|
22
|
+
self.hBoxLayout.setSpacing(28)
|
|
23
|
+
self.hBoxLayout.setContentsMargins(20, 0, 0, 0)
|
|
24
|
+
self.vBoxLayout.setSpacing(2)
|
|
25
|
+
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
|
|
26
|
+
self.vBoxLayout.setAlignment(Qt.AlignVCenter)
|
|
27
|
+
|
|
28
|
+
self.hBoxLayout.setAlignment(Qt.AlignVCenter)
|
|
29
|
+
self.hBoxLayout.addWidget(self.iconWidget)
|
|
30
|
+
self.hBoxLayout.addLayout(self.vBoxLayout)
|
|
31
|
+
self.vBoxLayout.addStretch(1)
|
|
32
|
+
self.vBoxLayout.addWidget(self.titleLabel)
|
|
33
|
+
self.vBoxLayout.addWidget(self.contentLabel)
|
|
34
|
+
self.vBoxLayout.addStretch(1)
|
|
35
|
+
|
|
36
|
+
self.titleLabel.setObjectName('titleLabel')
|
|
37
|
+
self.contentLabel.setObjectName('contentLabel')
|
|
38
|
+
|
|
39
|
+
def mouseReleaseEvent(self, e):
|
|
40
|
+
super().mouseReleaseEvent(e)
|
|
@@ -36,7 +36,6 @@ class Screenshot(QObject):
|
|
|
36
36
|
self.click_screenshot_folder = get_path_relative_to_exe(ok.gui.ok.config.get("click_screenshots_folder"))
|
|
37
37
|
self.screenshot_folder = get_path_relative_to_exe(ok.gui.ok.config.get("screenshots_folder"))
|
|
38
38
|
logger.debug(f"init Screenshot {self.screenshot_folder} {self.click_screenshot_folder}")
|
|
39
|
-
print(f"init Screenshot {self.screenshot_folder} {self.screenshot_folder}")
|
|
40
39
|
if self.click_screenshot_folder is not None or self.screenshot_folder is not None:
|
|
41
40
|
self.task_queue = queue.Queue()
|
|
42
41
|
self.exit_event.bind_queue(self.task_queue)
|
|
@@ -334,7 +334,7 @@ StartCard\x01\x03\x00\x00\x00\x08N\
|
|
|
334
334
|
*\x89\xe6S\xd1Vh\x08\x00\x00\x00\x00\x06\x00\x00\x00\
|
|
335
335
|
\x0dTrigger Tasks\x07\x00\
|
|
336
336
|
\x00\x00\x09StartCard\x01\x03\x00\x00\
|
|
337
|
-
\x00\
|
|
337
|
+
\x00\x10p\xb9Q\xfb\x90\x09b\xe9N\xfbR\xa1_\x00\
|
|
338
338
|
Y\xcb\x08\x00\x00\x00\x00\x06\x00\x00\x00\x1eWait\
|
|
339
339
|
ing for task to \
|
|
340
340
|
be enabled\x07\x00\x00\x00\x09S\
|
|
@@ -1160,7 +1160,7 @@ qt_resource_struct = b"\
|
|
|
1160
1160
|
\x00\x00\x00>\x00\x01\x00\x00\x00\x01\x00\x00\x1a\x85\
|
|
1161
1161
|
\x00\x00\x01\x8e2\xed>\xd3\
|
|
1162
1162
|
\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
|
1163
|
-
\x00\x00\x01\x8f\
|
|
1163
|
+
\x00\x00\x01\x8f\xcf\xc5~\xab\
|
|
1164
1164
|
\x00\x00\x00T\x00\x02\x00\x00\x00\x05\x00\x00\x00\x0d\
|
|
1165
1165
|
\x00\x00\x00\x00\x00\x00\x00\x00\
|
|
1166
1166
|
\x00\x00\x00b\x00\x02\x00\x00\x00\x05\x00\x00\x00\x08\
|
|
@@ -9,20 +9,18 @@ class SelectCaptureListView(ListWidget):
|
|
|
9
9
|
|
|
10
10
|
def update_for_device(self, device, hwnd, capture):
|
|
11
11
|
if self.count() == 0:
|
|
12
|
-
item = QListWidgetItem(self.tr(f"Game Window
|
|
13
|
-
|
|
14
|
-
# Add the QListWidgetItem to the QListWidget
|
|
12
|
+
item = QListWidgetItem(self.tr(f"Game Window"))
|
|
15
13
|
self.addItem(item)
|
|
16
|
-
tips = hwnd or
|
|
14
|
+
tips = hwnd or ""
|
|
17
15
|
if device == "windows":
|
|
18
16
|
title = self.tr("Game Window")
|
|
19
17
|
if self.count() == 2:
|
|
20
18
|
self.takeItem(1)
|
|
21
19
|
else:
|
|
22
|
-
title = self.tr("Emulator Window")
|
|
20
|
+
title = self.tr("Emulator Window(Supports Background, Fast, Low Latency)")
|
|
23
21
|
if self.count() == 1:
|
|
24
|
-
item = QListWidgetItem(self.tr("ADB
|
|
22
|
+
item = QListWidgetItem(self.tr("ADB(Supports Background, Slow, High Compatibility, High Latency)"))
|
|
25
23
|
self.addItem(item)
|
|
26
|
-
self.item(0).setText(f"{title}
|
|
24
|
+
self.item(0).setText(f"{title} - {tips}")
|
|
27
25
|
selected = 0 if capture == "windows" else 1
|
|
28
26
|
self.setCurrentRow(selected)
|
|
@@ -143,16 +143,21 @@ class StartCard(SettingCard):
|
|
|
143
143
|
if not ok.gui.executor.connected():
|
|
144
144
|
self.status_bar.setTitle(self.tr("Game Window Disconnected"))
|
|
145
145
|
self.status_bar.setState(True)
|
|
146
|
-
elif not ok.gui.executor.can_capture():
|
|
147
|
-
self.status_bar.setTitle(self.tr('Paused: PC Game Window Must Be in Front!'))
|
|
148
|
-
self.status_bar.setState(True)
|
|
149
146
|
elif active_trigger_task_count := ok.gui.executor.active_trigger_task_count():
|
|
150
|
-
|
|
151
|
-
self.tr(
|
|
152
|
-
|
|
147
|
+
if not ok.gui.executor.can_capture():
|
|
148
|
+
self.status_bar.setTitle(self.tr('Paused: PC Game Window Must Be in Front!'))
|
|
149
|
+
self.status_bar.setState(True)
|
|
150
|
+
else:
|
|
151
|
+
self.status_bar.setTitle(
|
|
152
|
+
self.tr("Running") + ": " + str(active_trigger_task_count) + ' ' + self.tr("Trigger Tasks"))
|
|
153
|
+
self.status_bar.setState(False)
|
|
153
154
|
elif task := ok.gui.executor.current_task:
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
if not ok.gui.executor.can_capture():
|
|
156
|
+
self.status_bar.setTitle(self.tr('Paused: PC Game Window Must Be in Front!'))
|
|
157
|
+
self.status_bar.setState(True)
|
|
158
|
+
else:
|
|
159
|
+
self.status_bar.setTitle(self.tr("Running") + ": " + task.name)
|
|
160
|
+
self.status_bar.setState(False)
|
|
156
161
|
else:
|
|
157
162
|
self.status_bar.setTitle(self.tr("Waiting for task to be enabled"))
|
|
158
163
|
self.status_bar.setState(False)
|
|
@@ -29,9 +29,13 @@ class Tab(ScrollArea):
|
|
|
29
29
|
|
|
30
30
|
def addCard(self, title, widget, stretch=0, parent=None):
|
|
31
31
|
container = Card(title, widget)
|
|
32
|
-
self.
|
|
32
|
+
self.addWidget(container, stretch)
|
|
33
33
|
return container
|
|
34
34
|
|
|
35
|
-
def addWidget(self, widget, stretch=0):
|
|
36
|
-
self.vBoxLayout.addWidget(widget, stretch,
|
|
35
|
+
def addWidget(self, widget, stretch=0, align=Qt.AlignTop):
|
|
36
|
+
self.vBoxLayout.addWidget(widget, stretch, align)
|
|
37
37
|
return widget
|
|
38
|
+
|
|
39
|
+
def addLayout(self, layout, stretch=0):
|
|
40
|
+
self.vBoxLayout.addLayout(layout, stretch)
|
|
41
|
+
return layout
|
|
@@ -3,6 +3,7 @@ import time
|
|
|
3
3
|
import traceback
|
|
4
4
|
|
|
5
5
|
from ok.capture.BaseCaptureMethod import CaptureException
|
|
6
|
+
from ok.capture.adb.ADBCaptureMethod import ADBCaptureMethod
|
|
6
7
|
from ok.capture.adb.DeviceManager import DeviceManager
|
|
7
8
|
from ok.gui.Communicate import communicate
|
|
8
9
|
from ok.logging.Logger import get_logger
|
|
@@ -73,6 +74,7 @@ class TaskExecutor:
|
|
|
73
74
|
return self._frame
|
|
74
75
|
|
|
75
76
|
def supports_screen_ratio(self, supported_ratio):
|
|
77
|
+
frame = self.method.get_frame() if not isinstance(self.method, ADBCaptureMethod) else None
|
|
76
78
|
if supported_ratio is None:
|
|
77
79
|
return True, None
|
|
78
80
|
width = self.method.width
|
|
@@ -88,9 +90,13 @@ class TaskExecutor:
|
|
|
88
90
|
|
|
89
91
|
# Calculate the difference between the actual and supported ratios
|
|
90
92
|
difference = abs(actual_ratio - supported_ratio)
|
|
91
|
-
|
|
93
|
+
support = difference <= 0.01 * supported_ratio
|
|
94
|
+
if not support:
|
|
95
|
+
logger.error(f'resolution error {width}x{height} {frame is None}')
|
|
96
|
+
if not support and frame:
|
|
97
|
+
communicate.screenshot.emit(frame, "resolution_error")
|
|
92
98
|
# Check if the difference is within 1%
|
|
93
|
-
return
|
|
99
|
+
return support, f"{width}x{height}"
|
|
94
100
|
|
|
95
101
|
def can_capture(self):
|
|
96
102
|
return self.method is not None and self.interaction is not None and self.interaction.should_capture()
|