kotonebot 0.4.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kotonebot/backend/context/context.py +1002 -1002
- kotonebot/backend/core.py +6 -49
- kotonebot/backend/image.py +36 -5
- kotonebot/backend/loop.py +222 -208
- kotonebot/backend/ocr.py +7 -1
- kotonebot/client/device.py +108 -243
- kotonebot/client/host/__init__.py +34 -3
- kotonebot/client/host/adb_common.py +7 -9
- kotonebot/client/host/custom.py +6 -2
- kotonebot/client/host/leidian_host.py +2 -7
- kotonebot/client/host/mumu12_host.py +2 -7
- kotonebot/client/host/protocol.py +4 -3
- kotonebot/client/implements/__init__.py +62 -11
- kotonebot/client/implements/adb.py +5 -1
- kotonebot/client/implements/nemu_ipc/__init__.py +4 -0
- kotonebot/client/implements/uiautomator2.py +6 -2
- kotonebot/client/implements/windows.py +7 -3
- kotonebot/client/registration.py +1 -1
- kotonebot/client/scaler.py +467 -0
- kotonebot/config/base_config.py +1 -1
- kotonebot/config/config.py +61 -0
- kotonebot/core/__init__.py +13 -0
- kotonebot/core/entities/base.py +182 -0
- kotonebot/core/entities/compound.py +75 -0
- kotonebot/core/entities/ocr.py +117 -0
- kotonebot/core/entities/template_match.py +198 -0
- kotonebot/devtools/__init__.py +42 -0
- kotonebot/devtools/cli/__init__.py +6 -0
- kotonebot/devtools/cli/main.py +53 -0
- kotonebot/devtools/project/project.py +41 -0
- kotonebot/devtools/project/scanner.py +202 -0
- kotonebot/devtools/project/schema.py +99 -0
- kotonebot/devtools/resgen/__init__.py +42 -0
- kotonebot/devtools/resgen/codegen.py +331 -0
- kotonebot/devtools/resgen/core.py +94 -0
- kotonebot/devtools/resgen/parsers.py +360 -0
- kotonebot/devtools/resgen/utils.py +158 -0
- kotonebot/devtools/resgen/validation.py +115 -0
- kotonebot/devtools/web/dist/assets/bootstrap-icons-BOrJxbIo.woff +0 -0
- kotonebot/devtools/web/dist/assets/bootstrap-icons-BtvjY1KL.woff2 +0 -0
- kotonebot/devtools/web/dist/assets/ext-language_tools-CD021WJ2.js +2577 -0
- kotonebot/devtools/web/dist/assets/index-B_m5f2LF.js +2836 -0
- kotonebot/devtools/web/dist/assets/index-BlEDyGGa.css +9 -0
- kotonebot/devtools/web/dist/assets/language-client-C9muzqaq.js +128 -0
- kotonebot/devtools/web/dist/assets/mode-python-CtHp76XS.js +476 -0
- kotonebot/devtools/web/dist/icons/symbol-class.svg +3 -0
- kotonebot/devtools/web/dist/icons/symbol-file.svg +3 -0
- kotonebot/devtools/web/dist/icons/symbol-method.svg +3 -0
- kotonebot/devtools/web/dist/index.html +25 -0
- kotonebot/devtools/web/server/__init__.py +0 -0
- kotonebot/devtools/web/server/rest_api.py +217 -0
- kotonebot/devtools/web/server/server.py +85 -0
- kotonebot/errors.py +7 -2
- kotonebot/interop/win/__init__.py +10 -1
- kotonebot/interop/win/_mouse.py +311 -0
- kotonebot/interop/win/shake_mouse.py +224 -0
- kotonebot/primitives/__init__.py +3 -1
- kotonebot/primitives/geometry.py +817 -40
- kotonebot/primitives/visual.py +81 -1
- kotonebot/ui/pushkit/image_host.py +2 -1
- kotonebot/ui/pushkit/wxpusher.py +2 -1
- {kotonebot-0.4.0.dist-info → kotonebot-0.6.0.dist-info}/METADATA +4 -1
- kotonebot-0.6.0.dist-info/RECORD +105 -0
- kotonebot-0.6.0.dist-info/entry_points.txt +2 -0
- kotonebot/client/implements/adb_raw.py +0 -159
- kotonebot-0.4.0.dist-info/RECORD +0 -70
- /kotonebot/{tools → devtools}/mirror.py +0 -0
- /kotonebot/{tools → devtools/project}/__init__.py +0 -0
- {kotonebot-0.4.0.dist-info → kotonebot-0.6.0.dist-info}/WHEEL +0 -0
- {kotonebot-0.4.0.dist-info → kotonebot-0.6.0.dist-info}/licenses/LICENSE +0 -0
- {kotonebot-0.4.0.dist-info → kotonebot-0.6.0.dist-info}/top_level.txt +0 -0
kotonebot/primitives/visual.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import warnings
|
|
3
|
+
from functools import cache
|
|
2
4
|
|
|
5
|
+
import cv2
|
|
3
6
|
from cv2.typing import MatLike
|
|
4
7
|
|
|
5
|
-
from .geometry import Size
|
|
8
|
+
from .geometry import Size, Rect
|
|
6
9
|
from kotonebot.util import cv2_imread
|
|
7
10
|
|
|
8
11
|
logger = logging.getLogger(__name__)
|
|
@@ -57,6 +60,83 @@ class Image:
|
|
|
57
60
|
def size(self) -> Size:
|
|
58
61
|
return Size(self.pixels.shape[1], self.pixels.shape[0])
|
|
59
62
|
|
|
63
|
+
# Compatibility with older API (deprecated)
|
|
64
|
+
def __compat_warn(self, name: str) -> None:
|
|
65
|
+
warnings.warn(
|
|
66
|
+
f'`Image.{name}` is deprecated — use `kotonebot.primitives.Image` API instead.',
|
|
67
|
+
DeprecationWarning,
|
|
68
|
+
stacklevel=3,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def path(self) -> str | None:
|
|
73
|
+
"""Deprecated alias for `file_path`."""
|
|
74
|
+
self.__compat_warn('path')
|
|
75
|
+
return self.file_path
|
|
76
|
+
|
|
77
|
+
@path.setter
|
|
78
|
+
def path(self, value: str | None) -> None:
|
|
79
|
+
self.__compat_warn('path')
|
|
80
|
+
self.file_path = value
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def data(self) -> MatLike:
|
|
84
|
+
"""Deprecated alias for `pixels`."""
|
|
85
|
+
self.__compat_warn('data')
|
|
86
|
+
return self.pixels
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def data_with_alpha(self) -> MatLike:
|
|
90
|
+
"""Deprecated: return image including alpha channel when available."""
|
|
91
|
+
self.__compat_warn('data_with_alpha')
|
|
92
|
+
# If current pixels already contain alpha, return them
|
|
93
|
+
try:
|
|
94
|
+
if self.__pixels is not None and getattr(self.__pixels, 'shape', None) and len(self.__pixels.shape) >= 3 and self.__pixels.shape[2] == 4:
|
|
95
|
+
return self.__pixels
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
98
|
+
if not self.file_path:
|
|
99
|
+
raise ValueError('Either pixels or file_path must be provided.')
|
|
100
|
+
arr = cv2_imread(self.file_path, cv2.IMREAD_UNCHANGED)
|
|
101
|
+
return arr
|
|
102
|
+
|
|
103
|
+
@cache
|
|
104
|
+
def binary(self) -> 'Image':
|
|
105
|
+
"""Deprecated: return a grayscale copy of the image."""
|
|
106
|
+
self.__compat_warn('binary')
|
|
107
|
+
gray = cv2.cvtColor(self.pixels, cv2.COLOR_BGR2GRAY)
|
|
108
|
+
return Image(pixels=gray, name=self.name)
|
|
109
|
+
|
|
110
|
+
def __repr__(self) -> str:
|
|
111
|
+
class_name = self.__class__.__name__
|
|
112
|
+
if self.file_path is None:
|
|
113
|
+
return f'<{class_name}: memory>'
|
|
114
|
+
else:
|
|
115
|
+
return f'<{class_name}: "{self.name or "untitled"}" at {self.file_path}>'
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class ImageSlice(Image):
|
|
119
|
+
def __init__(
|
|
120
|
+
self,
|
|
121
|
+
pixels: MatLike | None = None,
|
|
122
|
+
file_path: str | None = None,
|
|
123
|
+
lazy_load: bool = False,
|
|
124
|
+
name: str | None = None,
|
|
125
|
+
description: str | None = None,
|
|
126
|
+
*,
|
|
127
|
+
slice_rect: Rect | None
|
|
128
|
+
):
|
|
129
|
+
super().__init__(
|
|
130
|
+
pixels=pixels,
|
|
131
|
+
file_path=file_path,
|
|
132
|
+
lazy_load=lazy_load,
|
|
133
|
+
name=name,
|
|
134
|
+
description=description
|
|
135
|
+
)
|
|
136
|
+
self.slice_rect = slice_rect
|
|
137
|
+
"""图像切片的矩形区域。"""
|
|
138
|
+
|
|
139
|
+
|
|
60
140
|
class Template(Image):
|
|
61
141
|
"""
|
|
62
142
|
模板图像类。
|
|
@@ -4,7 +4,6 @@ from pathlib import Path
|
|
|
4
4
|
from typing import Sequence
|
|
5
5
|
|
|
6
6
|
import cv2
|
|
7
|
-
import requests
|
|
8
7
|
import numpy as np
|
|
9
8
|
from cv2.typing import MatLike
|
|
10
9
|
from dotenv import load_dotenv
|
|
@@ -23,6 +22,8 @@ def _upload_single(image: MatLike | str) -> str:
|
|
|
23
22
|
|
|
24
23
|
:param image: OpenCV MatLike 或本地图片文件路径
|
|
25
24
|
"""
|
|
25
|
+
import requests
|
|
26
|
+
|
|
26
27
|
api_url = 'https://freeimage.host/api/1/upload'
|
|
27
28
|
api_key = os.getenv('FREEIMAGEHOST_KEY')
|
|
28
29
|
|
kotonebot/ui/pushkit/wxpusher.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
3
|
from typing import Sequence
|
|
4
|
-
import requests
|
|
5
4
|
from cv2.typing import MatLike
|
|
6
5
|
from dotenv import dotenv_values
|
|
7
6
|
|
|
@@ -16,6 +15,8 @@ class Wxpusher(PushkitProtocol):
|
|
|
16
15
|
self.uid = uid or config["WXPUSHER_UID"]
|
|
17
16
|
|
|
18
17
|
def push(self, title: str, message: str, *, images: Sequence[str | MatLike] | None = None) -> None:
|
|
18
|
+
import requests
|
|
19
|
+
|
|
19
20
|
summary = title
|
|
20
21
|
content = message
|
|
21
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kotonebot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Kotonebot is game automation library based on computer vision technology, works for Windows and Android.
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -15,6 +15,7 @@ Requires-Dist: typing-extensions~=4.12
|
|
|
15
15
|
Requires-Dist: python-dotenv~=1.0
|
|
16
16
|
Requires-Dist: onnxruntime~=1.14
|
|
17
17
|
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: mouse>=0.7.1
|
|
18
19
|
Provides-Extra: android
|
|
19
20
|
Requires-Dist: adbutils>=2.8; extra == "android"
|
|
20
21
|
Requires-Dist: uiautomator2>=3.2; extra == "android"
|
|
@@ -32,6 +33,8 @@ Requires-Dist: psutil~=6.1; extra == "dev"
|
|
|
32
33
|
Requires-Dist: twine~=6.1; extra == "dev"
|
|
33
34
|
Requires-Dist: build; extra == "dev"
|
|
34
35
|
Requires-Dist: snakeviz; extra == "dev"
|
|
36
|
+
Requires-Dist: tomli; python_version < "3.11" and extra == "dev"
|
|
37
|
+
Requires-Dist: dataclass-wizard; extra == "dev"
|
|
35
38
|
Requires-Dist: jinja2~=3.1; extra == "dev"
|
|
36
39
|
Requires-Dist: tqdm~=4.67; extra == "dev"
|
|
37
40
|
Provides-Extra: all
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
kotonebot/__init__.py,sha256=DWS8zZAWH-MQZxk6bDm9uNAfY9UVmtd7Q928suujpiQ,636
|
|
2
|
+
kotonebot/errors.py,sha256=yllcOJxBdqcXadFLGcxIGzLEfoGkx8eaNK-R_SkFFro,2585
|
|
3
|
+
kotonebot/util.py,sha256=ftWhlnZ3qJ80x2wVCHYr2wW299JQkYDOREP1mA-n1vg,14370
|
|
4
|
+
kotonebot/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
kotonebot/backend/bot.py,sha256=Ph0pfAubr_TV4MmqkyYL0P0hLbXdFEkzlQ0V2B1niZI,11870
|
|
6
|
+
kotonebot/backend/color.py,sha256=KqFISc6puMNbsyB5diu5PcqNjdkLwUeryVsMmeAJG4Q,20125
|
|
7
|
+
kotonebot/backend/core.py,sha256=RjJE586tNGkx8H_6Zo_gUrQsdHbexjKVUhMHdACBLX4,2454
|
|
8
|
+
kotonebot/backend/dispatch.py,sha256=t3eqkOVNNrdaeXSMLxDbReYhVRoAlSRNxb7oO2clRsQ,7423
|
|
9
|
+
kotonebot/backend/flow_controller.py,sha256=sbr6JiuYXErevY_BPrzw7hUCfxLGVrz0W_KNbXIxe9Q,6228
|
|
10
|
+
kotonebot/backend/image.py,sha256=GKXRwNR-fDwciNVluT6Da47BUn-KWZ3ELVdmM1qVI-s,29438
|
|
11
|
+
kotonebot/backend/loop.py,sha256=1Bz9YwK-2IrePKwRam6yg_inlUComK7H6luRFaBmVXk,7286
|
|
12
|
+
kotonebot/backend/ocr.py,sha256=8pkNBwLz0W3QseKMfr_BxDvJAPuRMfh3h4MbHzk3cBU,18379
|
|
13
|
+
kotonebot/backend/preprocessor.py,sha256=YmAbLa-XXES2AchMJtsBpPZwIIGHuYapwpXpw0YSpbA,3423
|
|
14
|
+
kotonebot/backend/context/__init__.py,sha256=0X9jzM0ftGQUgjoXCk98xf1inoCqHqaUwT0wcHn9P5s,168
|
|
15
|
+
kotonebot/backend/context/context.py,sha256=TDi9F8vaNYhCPCZv2A_Vz8guyyp1WRGmtjAufgfWI0I,34782
|
|
16
|
+
kotonebot/backend/context/task_action.py,sha256=LdxyeW-1ie71ludnAN36ltlcAw4AX3Lb9ua7I5xK4yY,6444
|
|
17
|
+
kotonebot/backend/debug/__init__.py,sha256=pcSpwzU2YwGrogOoHmsI035nkA_-kDLfm-lfBxHuQ-c,43
|
|
18
|
+
kotonebot/backend/debug/entry.py,sha256=_sIGi9_LegbaM2DCcDTvGJhrkyUqF6W2Al4nYmkb9rM,2833
|
|
19
|
+
kotonebot/backend/debug/mock.py,sha256=0fTiJeqVTanQv6L3TPbldgbJRBPmunZOjlzKtVicJ_M,2118
|
|
20
|
+
kotonebot/backend/debug/server.py,sha256=9PEpczIrwCnD4c_FAtiojwk27aKkkzTtRySCsdho4Rs,7517
|
|
21
|
+
kotonebot/backend/debug/vars.py,sha256=3wtbkH2WFNXyT2ZNu-8en3S0pAb40h-SefYyScRMLnM,10912
|
|
22
|
+
kotonebot/client/__init__.py,sha256=1eXyGopBFpYoucNTNkTo-7nIeDyasyETfHJ8DWuaNTo,192
|
|
23
|
+
kotonebot/client/device.py,sha256=Wiiy5djmxQk0nQXn69TOy73e6_ubo7idSb_0f4rJ0PI,14699
|
|
24
|
+
kotonebot/client/fast_screenshot.py,sha256=q69AX15VXRuB0U2qFJKfoTOBgG4nVBCUcaN1CX0VsUc,13647
|
|
25
|
+
kotonebot/client/protocol.py,sha256=x05llULFI3MddbvBX_c0sYWlSzCyWa3hped24ktq2Ko,2300
|
|
26
|
+
kotonebot/client/registration.py,sha256=e1mTvuoSqfCZtvZmkmL1GmjAGnfcH_biPDTTDRihuDA,837
|
|
27
|
+
kotonebot/client/scaler.py,sha256=9UHwLYNphIQFgAXnzsp6d6CJ_sq0Z_ZyZ1bsfZa-F6g,17491
|
|
28
|
+
kotonebot/client/host/__init__.py,sha256=qbjja1FoovIer4NMDcAQkDXxbOMSaV6z27VWb7iE5fk,1580
|
|
29
|
+
kotonebot/client/host/adb_common.py,sha256=xorKEiVEohFHdMU259fHZHhpbBI1-WVUMlDZCbYZ3yI,3628
|
|
30
|
+
kotonebot/client/host/custom.py,sha256=zYI4tZl5xGxdUTvF2li7c315252_hijdwMXwGMCXRpQ,4211
|
|
31
|
+
kotonebot/client/host/leidian_host.py,sha256=O8BUx61HDJs3lsdhoJcuYKEYImG9jWM6mqrOec0oSlc,7538
|
|
32
|
+
kotonebot/client/host/mumu12_host.py,sha256=CB-O7z3B-dWGVxiI78eK78hhyqileswa1DYXAftvjU8,14253
|
|
33
|
+
kotonebot/client/host/protocol.py,sha256=fnb9EqlTnSEfPlJ37HMYU6We4_YemX8mQFxcy2gsP8U,8173
|
|
34
|
+
kotonebot/client/host/windows_common.py,sha256=_Hf4CvHKNgiMIVY3ZPr3wF71r6nMErNi84Y_fswUjBc,2431
|
|
35
|
+
kotonebot/client/implements/__init__.py,sha256=OaSvmYTwxasdnYCS0kKrrcmmWPHjfMpYdmZ9siP03m8,2137
|
|
36
|
+
kotonebot/client/implements/adb.py,sha256=0Xs5o014SG9dNDIJYgI2_QyOMcZghuscolfK8eQnA40,3288
|
|
37
|
+
kotonebot/client/implements/remote_windows.py,sha256=SRq97cuXdUVvFIhsazZt4djMeGSLfYS88IUyzmlpaww,6756
|
|
38
|
+
kotonebot/client/implements/uiautomator2.py,sha256=Hal_DDWRCoLjL854xqDRq1X4Gm6O_SCBCUhqM2p1ykw,2722
|
|
39
|
+
kotonebot/client/implements/windows.py,sha256=bnASXFE8xHzY9Ue90r0ppYNnIVezhfMHAA0X9deXTNM,6889
|
|
40
|
+
kotonebot/client/implements/nemu_ipc/__init__.py,sha256=atIZjwnxhKEOndikoHDYhPrkvb7iC3zscBC457MQPz4,321
|
|
41
|
+
kotonebot/client/implements/nemu_ipc/external_renderer_ipc.py,sha256=YsfKf0-qorfAf2YvNuxpLb9af-HJFsu97bnXABshhbA,10643
|
|
42
|
+
kotonebot/client/implements/nemu_ipc/nemu_ipc.py,sha256=LhUUyfB28MDnRg8z2FyGah1hTeOMFiX7w8LZLAAjLF8,12082
|
|
43
|
+
kotonebot/config/__init__.py,sha256=-jATUOdrpUrBRT9RiTRQho2-2zeet50qQggsVMVpqNE,35
|
|
44
|
+
kotonebot/config/base_config.py,sha256=oJMoCEDUU15S7iO8WJg_qqL4YbXSr9qZqlYE82KJSl0,3427
|
|
45
|
+
kotonebot/config/config.py,sha256=0MeumpADN8PneyeqVGutByL-39jZdJioJWL8DM5xtdU,1951
|
|
46
|
+
kotonebot/config/manager.py,sha256=XBtriAU9eo-wv2iKOwyDqu8tzhbKqFCuy0jsAM9T9uU,1061
|
|
47
|
+
kotonebot/core/__init__.py,sha256=r2d-3TLGKvr3H8q3sfDZRtRaq0xPE9gUN4aHnqa7Ofs,410
|
|
48
|
+
kotonebot/core/entities/base.py,sha256=ROvY1LgrAdLISBnpEnJs-NafmZMeuuZcgevGsmn5glE,7116
|
|
49
|
+
kotonebot/core/entities/compound.py,sha256=cl6FJsMMhrvn_5KuLolkzWQKxqyIvfcPYIgkN2Fdeio,2928
|
|
50
|
+
kotonebot/core/entities/ocr.py,sha256=Z_N_sEFcuh0MZ0ZrvIaOxeF3V0_NqF02FDBmv9RqhcM,4633
|
|
51
|
+
kotonebot/core/entities/template_match.py,sha256=qBR-Qsd9rV32YMexZuyz7nhKyWtmeulka1CcDTccOJc,8348
|
|
52
|
+
kotonebot/devtools/__init__.py,sha256=d3S1dd3_ydmXatAeuBLBTfo0Z_w9I-48WzEolM9F8uk,702
|
|
53
|
+
kotonebot/devtools/mirror.py,sha256=jlGpeX_WkFpcZxojxDzT5QqVeIpd_UIDzSMR2K31VJ0,13820
|
|
54
|
+
kotonebot/devtools/cli/__init__.py,sha256=T9OOD1_m9ByRumCtBgtI_4whhY4SdrqzBMBaViugBKU,137
|
|
55
|
+
kotonebot/devtools/cli/main.py,sha256=EFLpCW5JZ-bSPUTUOIsLgZvvMO8lPmNUeB4Qoo2qRXs,1300
|
|
56
|
+
kotonebot/devtools/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
+
kotonebot/devtools/project/project.py,sha256=cyj4bMf0SweijpYEHlRUkZWm7vabuQLn7W2qz8dTKUA,1314
|
|
58
|
+
kotonebot/devtools/project/scanner.py,sha256=IGQbalqlpCwkB_dRtb4_2C_LwjI2GR_Zfx2zqvse9mk,8043
|
|
59
|
+
kotonebot/devtools/project/schema.py,sha256=HPyCEmIbCXB0mTjoW3VvmAS1FMwWlj7IeoF1xipJ3-k,2723
|
|
60
|
+
kotonebot/devtools/resgen/__init__.py,sha256=apaE2yf1n4Cn9MTxLBZaamfB6M83f6LHRgkoUPsUvCo,692
|
|
61
|
+
kotonebot/devtools/resgen/codegen.py,sha256=HWzx2V2R9J6P6N1tfILO5GR9iXJG_ivJafEWjnA9Cs4,14063
|
|
62
|
+
kotonebot/devtools/resgen/core.py,sha256=mLGqwQ85ucOL2qKFTK29SJTCZrCplAEhSuP7GDMfoss,2607
|
|
63
|
+
kotonebot/devtools/resgen/parsers.py,sha256=cnmaCYZaHovj5_DPzcAbYme3Z87-K01AwQL9Fvc3Qts,15146
|
|
64
|
+
kotonebot/devtools/resgen/utils.py,sha256=13mLQ4ozQEt04GAuK5VFTxtGOk2FM5O7XhdEZ-BMdKU,5593
|
|
65
|
+
kotonebot/devtools/resgen/validation.py,sha256=7yen17JtNU_OoV40fD6xfSx5l054RRFpK4xoJ51lnDA,4284
|
|
66
|
+
kotonebot/devtools/web/dist/index.html,sha256=88mzflP34NfrgFD1lC8n7xP0lkOCTcuXeilQqXiC1EY,736
|
|
67
|
+
kotonebot/devtools/web/dist/assets/bootstrap-icons-BOrJxbIo.woff,sha256=ux3pibg5cPb05U3hzZdMXLpVtzWC2l4bIlptDt8ClIM,176032
|
|
68
|
+
kotonebot/devtools/web/dist/assets/bootstrap-icons-BtvjY1KL.woff2,sha256=R2rfQrQDJQmPz6izarPnaRhrtPbOaiSXU-LhqcIr-Z4,130396
|
|
69
|
+
kotonebot/devtools/web/dist/assets/ext-language_tools-CD021WJ2.js,sha256=reG0R93ZT7Ig_m_7w2fprBrBWW8A4fnj5Ebj9cQ2FIM,107959
|
|
70
|
+
kotonebot/devtools/web/dist/assets/index-B_m5f2LF.js,sha256=xwiem8jQxMujvdhBXKpIOkpPcCjj1l5GcRZjW4c3l78,1380535
|
|
71
|
+
kotonebot/devtools/web/dist/assets/index-BlEDyGGa.css,sha256=LWUTFbG5yb-_Cu5jkz6mgCj2SKCvdQKq0ndbokf1bBU,311806
|
|
72
|
+
kotonebot/devtools/web/dist/assets/language-client-C9muzqaq.js,sha256=X3Kb1EYQOIzMkdxGGSaYt4CBDFZwpBpWshFj8xNu8bI,265765
|
|
73
|
+
kotonebot/devtools/web/dist/assets/mode-python-CtHp76XS.js,sha256=t_YFLderRSd06Q7-1sBcsPPkZN3Cty7BgblBEkV7mcw,16876
|
|
74
|
+
kotonebot/devtools/web/dist/icons/symbol-class.svg,sha256=7FmIdU7IU34qYW521_wX0TligscsmiCttLZdr064JrE,737
|
|
75
|
+
kotonebot/devtools/web/dist/icons/symbol-file.svg,sha256=yOROcG5HGkXDopwQZUjoDH6NGlSBy_kg6gossqkTrvk,331
|
|
76
|
+
kotonebot/devtools/web/dist/icons/symbol-method.svg,sha256=KGS0YF4X4jyzU9PB0NHe6txcEoTZlHMa72kI8dDkDjc,482
|
|
77
|
+
kotonebot/devtools/web/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
|
+
kotonebot/devtools/web/server/rest_api.py,sha256=Kk_bc3T3Qz_8okxOWd4url3ImXJh-V5x9t3vir3muKA,8249
|
|
79
|
+
kotonebot/devtools/web/server/server.py,sha256=e4M99fDAR3lWGG7k3FBzWDye2O8yTDjYt6A-tXug5wQ,2694
|
|
80
|
+
kotonebot/interop/win/__init__.py,sha256=20_Oxkv9h6tqfw59CFLaCMCbRL-k-82kv-tY6KtivxQ,234
|
|
81
|
+
kotonebot/interop/win/_mouse.py,sha256=SdkgVyxRnZQbR47yQWqmWzSQw3lcG9eNN1hITgiSu2c,10441
|
|
82
|
+
kotonebot/interop/win/message_box.py,sha256=R06GSu936Bx_Wg7ddn6LOvazD9_Gt3mhz4_oUuIoYO0,8635
|
|
83
|
+
kotonebot/interop/win/reg.py,sha256=xw35d1xl8ucITT4bOMFgHmMkAUhak7x3lzegR3g3S48,1347
|
|
84
|
+
kotonebot/interop/win/shake_mouse.py,sha256=SdJ94NyScAgF_IDr7E4DPDE1DVpo_vyFLaAf0SQCgG0,7266
|
|
85
|
+
kotonebot/interop/win/shortcut.py,sha256=f1u6IWvpw6Kxt014wnHz5Z94rVK1qf4kLtRsI9bJYnk,1764
|
|
86
|
+
kotonebot/interop/win/task_dialog.py,sha256=Ezi1CsjFSbnKccvYfIRaJoCGHUsJnnIpHb0gtKR603E,20191
|
|
87
|
+
kotonebot/logging/__init__.py,sha256=r0q4z59yYy_bQnHTwJYsiPGwOGIgEOrcXH1mNs1h_N0,142
|
|
88
|
+
kotonebot/logging/log.py,sha256=PLb6r_hlW1mvqU_kx6_89zaQ1IpamgHWG3sQ0ZnlrCI,555
|
|
89
|
+
kotonebot/primitives/__init__.py,sha256=Gsuo5NSTo81aDi3HDkAj2gFqSTWtY-k2PSJ4fc8w5FA,392
|
|
90
|
+
kotonebot/primitives/geometry.py,sha256=B5uabs6xDVy0vYuTJDphLb1X5913BAzlPZpitKeLRFA,34199
|
|
91
|
+
kotonebot/primitives/visual.py,sha256=K2-kJ36D6jtxhpQps6c0hNPjIt7P5HdVEhgAsjqk78Q,4653
|
|
92
|
+
kotonebot/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
93
|
+
kotonebot/ui/user.py,sha256=aP6Va3iHaVA0-AHViNa04a3HDpLLiovZjV5_AMGY4cI,4485
|
|
94
|
+
kotonebot/ui/file_host/sensio.py,sha256=QyH8DpyO3sf2Hz4NuOW9oDt1V3G06XMO7yKfgLwq1oE,914
|
|
95
|
+
kotonebot/ui/file_host/tmp_send.py,sha256=SwzTUGIjZXaP1_H86qahuLwUd8VeHGWW86XKaC__WKI,1802
|
|
96
|
+
kotonebot/ui/pushkit/__init__.py,sha256=xDUctRUL3euvge-yl8IhFYMlxIxQXsjxcyGN5tUwPtE,73
|
|
97
|
+
kotonebot/ui/pushkit/image_host.py,sha256=4ZEptuowUJJ-b9WwXaEfbVes2b-aJBK-JDI4bP8A9VM,2591
|
|
98
|
+
kotonebot/ui/pushkit/protocol.py,sha256=KVZ-xr0sMdiuri7AiYqugpZRRtefBsosXm6zouScUR4,266
|
|
99
|
+
kotonebot/ui/pushkit/wxpusher.py,sha256=Px-7pUvUMsgJLKzJXRJBVv8rPZMnELTYrTBhhllR8tM,1750
|
|
100
|
+
kotonebot-0.6.0.dist-info/licenses/LICENSE,sha256=gcuuhKKc5-dwvyvHsXjlC9oM6N5gZ6umYbC8ewW1Yvg,35821
|
|
101
|
+
kotonebot-0.6.0.dist-info/METADATA,sha256=03B-8qSqwe0SbRoxdRtRYrQjQxtjz3PwRxNFPSz0UOU,3351
|
|
102
|
+
kotonebot-0.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
103
|
+
kotonebot-0.6.0.dist-info/entry_points.txt,sha256=0TRRHk88fKrlrGGuxTMfa80P618wK3kLspjTrRAVoy0,53
|
|
104
|
+
kotonebot-0.6.0.dist-info/top_level.txt,sha256=QUWAZdbBndoojkrs6RcNytLAn7a0ns4YNF4tLx2Nc4s,10
|
|
105
|
+
kotonebot-0.6.0.dist-info/RECORD,,
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import time
|
|
3
|
-
import subprocess
|
|
4
|
-
import struct
|
|
5
|
-
from threading import Thread, Lock
|
|
6
|
-
from functools import cached_property
|
|
7
|
-
from typing_extensions import override
|
|
8
|
-
|
|
9
|
-
import cv2
|
|
10
|
-
import numpy as np
|
|
11
|
-
from cv2.typing import MatLike
|
|
12
|
-
from adbutils._utils import adb_path
|
|
13
|
-
|
|
14
|
-
from .adb import AdbImpl
|
|
15
|
-
from adbutils._device import AdbDevice as AdbUtilsDevice
|
|
16
|
-
from kotonebot import logging
|
|
17
|
-
|
|
18
|
-
logger = logging.getLogger(__name__)
|
|
19
|
-
|
|
20
|
-
WAIT_TIMEOUT = 10
|
|
21
|
-
MAX_RETRY_COUNT = 5
|
|
22
|
-
SCRIPT: str = """#!/bin/sh
|
|
23
|
-
while true; do
|
|
24
|
-
screencap
|
|
25
|
-
sleep 0.3
|
|
26
|
-
done
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
class AdbRawImpl(AdbImpl):
|
|
30
|
-
def __init__(self, adb_connection: AdbUtilsDevice):
|
|
31
|
-
super().__init__(adb_connection)
|
|
32
|
-
self.__worker: Thread | None = None
|
|
33
|
-
self.__process: subprocess.Popen | None = None
|
|
34
|
-
self.__data: MatLike | None = None
|
|
35
|
-
self.__retry_count = 0
|
|
36
|
-
self.__lock = Lock()
|
|
37
|
-
self.__stopping = False
|
|
38
|
-
|
|
39
|
-
def __cleanup_worker(self) -> None:
|
|
40
|
-
if self.__process:
|
|
41
|
-
try:
|
|
42
|
-
self.__process.kill()
|
|
43
|
-
except:
|
|
44
|
-
pass
|
|
45
|
-
self.__process = None
|
|
46
|
-
if self.__worker:
|
|
47
|
-
try:
|
|
48
|
-
self.__worker.join()
|
|
49
|
-
except:
|
|
50
|
-
pass
|
|
51
|
-
self.__worker = None
|
|
52
|
-
self.__data = None
|
|
53
|
-
|
|
54
|
-
def __start_worker(self) -> None:
|
|
55
|
-
self.__stopping = True
|
|
56
|
-
self.__cleanup_worker()
|
|
57
|
-
self.__stopping = False
|
|
58
|
-
self.__worker = Thread(target=self.__worker_thread_with_retry, daemon=True)
|
|
59
|
-
self.__worker.start()
|
|
60
|
-
|
|
61
|
-
def __worker_thread_with_retry(self) -> None:
|
|
62
|
-
try:
|
|
63
|
-
self.__worker_thread()
|
|
64
|
-
except Exception as e:
|
|
65
|
-
logger.error(f"Worker thread failed: {e}")
|
|
66
|
-
with self.__lock:
|
|
67
|
-
self.__retry_count += 1
|
|
68
|
-
raise
|
|
69
|
-
|
|
70
|
-
def __worker_thread(self) -> None:
|
|
71
|
-
with open('screenshot.sh', 'w', encoding='utf-8', newline='\n') as f:
|
|
72
|
-
f.write(SCRIPT)
|
|
73
|
-
self.adb.push('screenshot.sh', '/data/local/tmp/screenshot.sh')
|
|
74
|
-
self.adb.shell(f'chmod 755 /data/local/tmp/screenshot.sh')
|
|
75
|
-
os.remove('screenshot.sh')
|
|
76
|
-
|
|
77
|
-
cmd = fr'{adb_path()} -s {self.adb.serial} exec-out "sh /data/local/tmp/screenshot.sh"'
|
|
78
|
-
self.__process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
|
|
79
|
-
|
|
80
|
-
while not self.__stopping and self.__process.poll() is None:
|
|
81
|
-
if self.__process.stdout is None:
|
|
82
|
-
logger.error("Failed to get stdout from process")
|
|
83
|
-
continue
|
|
84
|
-
|
|
85
|
-
# 解析 header
|
|
86
|
-
# https://stackoverflow.com/questions/22034959/what-format-does-adb-screencap-sdcard-screenshot-raw-produce-without-p-f
|
|
87
|
-
if self.__api_level >= 26:
|
|
88
|
-
metadata = self.__process.stdout.read(16)
|
|
89
|
-
w, h, p, c = struct.unpack('<IIII', metadata)
|
|
90
|
-
# w=width, h=height, p=pixel_format, c=color_space
|
|
91
|
-
# 详见:https://android.googlesource.com/platform/frameworks/base/+/26a2b97dbe48ee45e9ae70110714048f2f360f97/cmds/screencap/screencap.cpp#209
|
|
92
|
-
else:
|
|
93
|
-
metadata = self.__process.stdout.read(12)
|
|
94
|
-
w, h, p = struct.unpack('<III', metadata)
|
|
95
|
-
if p == 1: # PixelFormat.RGBA_8888
|
|
96
|
-
channel = 4
|
|
97
|
-
else:
|
|
98
|
-
raise ValueError(f"Unsupported pixel format: {p}")
|
|
99
|
-
data_size = w * h * channel
|
|
100
|
-
|
|
101
|
-
if (data_size < 100 * 100 * 4) or (data_size > 3000 * 3000 * 4):
|
|
102
|
-
raise ValueError(f"Invaild data_size: {w}x{h}.")
|
|
103
|
-
|
|
104
|
-
# 读取图像数据
|
|
105
|
-
# logger.verbose(f"receiving image data: {w}x{h} {data_size} bytes")
|
|
106
|
-
image_data = self.__process.stdout.read(data_size)
|
|
107
|
-
if not isinstance(image_data, bytes) or len(image_data) != data_size:
|
|
108
|
-
logger.error(f"Failed to read image data, expected {data_size} bytes but got {len(image_data) if isinstance(image_data, bytes) else 'non-bytes'}")
|
|
109
|
-
raise RuntimeError("Failed to read image data")
|
|
110
|
-
|
|
111
|
-
np_data = np.frombuffer(image_data, np.uint8)
|
|
112
|
-
np_data = np_data.reshape(h, w, channel)
|
|
113
|
-
self.__data = cv2.cvtColor(np_data, cv2.COLOR_RGBA2BGR)
|
|
114
|
-
|
|
115
|
-
@cached_property
|
|
116
|
-
def __api_level(self) -> int:
|
|
117
|
-
try:
|
|
118
|
-
output = self.adb.shell("getprop ro.build.version.sdk")
|
|
119
|
-
assert isinstance(output, str)
|
|
120
|
-
return int(output.strip())
|
|
121
|
-
except Exception as e:
|
|
122
|
-
logger.error(f"Failed to get API level: {e}")
|
|
123
|
-
return 0
|
|
124
|
-
|
|
125
|
-
@override
|
|
126
|
-
def screenshot(self) -> MatLike:
|
|
127
|
-
with self.__lock:
|
|
128
|
-
if self.__retry_count >= MAX_RETRY_COUNT:
|
|
129
|
-
raise RuntimeError(f"Maximum retry count ({MAX_RETRY_COUNT}) exceeded")
|
|
130
|
-
|
|
131
|
-
if not self.__worker or (self.__worker and not self.__worker.is_alive()):
|
|
132
|
-
self.__start_worker()
|
|
133
|
-
|
|
134
|
-
start_time = time.time()
|
|
135
|
-
while self.__data is None:
|
|
136
|
-
time.sleep(0.01)
|
|
137
|
-
if time.time() - start_time > WAIT_TIMEOUT:
|
|
138
|
-
logger.warning("Screenshot timeout, cleaning up and restarting worker...")
|
|
139
|
-
with self.__lock:
|
|
140
|
-
if self.__retry_count < MAX_RETRY_COUNT:
|
|
141
|
-
self.__start_worker()
|
|
142
|
-
start_time = time.time() # 重置超时计时器
|
|
143
|
-
continue
|
|
144
|
-
else:
|
|
145
|
-
raise RuntimeError(f"Maximum retry count ({MAX_RETRY_COUNT}) exceeded")
|
|
146
|
-
|
|
147
|
-
# 检查 worker 是否还活着
|
|
148
|
-
if self.__worker and not self.__worker.is_alive():
|
|
149
|
-
with self.__lock:
|
|
150
|
-
if self.__retry_count < MAX_RETRY_COUNT:
|
|
151
|
-
logger.warning("Worker thread died, restarting...")
|
|
152
|
-
self.__start_worker()
|
|
153
|
-
else:
|
|
154
|
-
raise RuntimeError(f"Maximum retry count ({MAX_RETRY_COUNT}) exceeded")
|
|
155
|
-
|
|
156
|
-
logger.verbose(f"adb raw screenshot wait time: {time.time() - start_time:.4f}s")
|
|
157
|
-
data = self.__data
|
|
158
|
-
self.__data = None
|
|
159
|
-
return data
|
kotonebot-0.4.0.dist-info/RECORD
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
kotonebot/__init__.py,sha256=DWS8zZAWH-MQZxk6bDm9uNAfY9UVmtd7Q928suujpiQ,636
|
|
2
|
-
kotonebot/errors.py,sha256=1mZLFhNNxtRkm66y80rPzOeFjCgR0TgxgCDGo9ByZek,2294
|
|
3
|
-
kotonebot/util.py,sha256=ftWhlnZ3qJ80x2wVCHYr2wW299JQkYDOREP1mA-n1vg,14370
|
|
4
|
-
kotonebot/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
kotonebot/backend/bot.py,sha256=Ph0pfAubr_TV4MmqkyYL0P0hLbXdFEkzlQ0V2B1niZI,11870
|
|
6
|
-
kotonebot/backend/color.py,sha256=KqFISc6puMNbsyB5diu5PcqNjdkLwUeryVsMmeAJG4Q,20125
|
|
7
|
-
kotonebot/backend/core.py,sha256=A0f2i1KO9PXn4ndRDOBbADtB_beVxD1P0g4FYioxUY0,4026
|
|
8
|
-
kotonebot/backend/dispatch.py,sha256=t3eqkOVNNrdaeXSMLxDbReYhVRoAlSRNxb7oO2clRsQ,7423
|
|
9
|
-
kotonebot/backend/flow_controller.py,sha256=sbr6JiuYXErevY_BPrzw7hUCfxLGVrz0W_KNbXIxe9Q,6228
|
|
10
|
-
kotonebot/backend/image.py,sha256=jXYGVXa9K1zBCJBG1Btsf2AG5XI9A0DMy5uYy6KOusk,28111
|
|
11
|
-
kotonebot/backend/loop.py,sha256=e4STYQ6sbUp53xcYJXyhz4vOyEzXds1MKR0xebqU228,6638
|
|
12
|
-
kotonebot/backend/ocr.py,sha256=IE_LUCdD4i00a02xgLkSRPcYYo3R2MBfZKKQHjOFfgM,18058
|
|
13
|
-
kotonebot/backend/preprocessor.py,sha256=YmAbLa-XXES2AchMJtsBpPZwIIGHuYapwpXpw0YSpbA,3423
|
|
14
|
-
kotonebot/backend/context/__init__.py,sha256=0X9jzM0ftGQUgjoXCk98xf1inoCqHqaUwT0wcHn9P5s,168
|
|
15
|
-
kotonebot/backend/context/context.py,sha256=R91knq7Ry5MSWaFhOj3HIF13u8bomOOsGk59yPOG4aw,33780
|
|
16
|
-
kotonebot/backend/context/task_action.py,sha256=LdxyeW-1ie71ludnAN36ltlcAw4AX3Lb9ua7I5xK4yY,6444
|
|
17
|
-
kotonebot/backend/debug/__init__.py,sha256=pcSpwzU2YwGrogOoHmsI035nkA_-kDLfm-lfBxHuQ-c,43
|
|
18
|
-
kotonebot/backend/debug/entry.py,sha256=_sIGi9_LegbaM2DCcDTvGJhrkyUqF6W2Al4nYmkb9rM,2833
|
|
19
|
-
kotonebot/backend/debug/mock.py,sha256=0fTiJeqVTanQv6L3TPbldgbJRBPmunZOjlzKtVicJ_M,2118
|
|
20
|
-
kotonebot/backend/debug/server.py,sha256=9PEpczIrwCnD4c_FAtiojwk27aKkkzTtRySCsdho4Rs,7517
|
|
21
|
-
kotonebot/backend/debug/vars.py,sha256=3wtbkH2WFNXyT2ZNu-8en3S0pAb40h-SefYyScRMLnM,10912
|
|
22
|
-
kotonebot/client/__init__.py,sha256=1eXyGopBFpYoucNTNkTo-7nIeDyasyETfHJ8DWuaNTo,192
|
|
23
|
-
kotonebot/client/device.py,sha256=bb49Gbo-zcF1SaeBbRljxkuKGMp5e9umPiguAbV1kok,19405
|
|
24
|
-
kotonebot/client/fast_screenshot.py,sha256=q69AX15VXRuB0U2qFJKfoTOBgG4nVBCUcaN1CX0VsUc,13647
|
|
25
|
-
kotonebot/client/protocol.py,sha256=x05llULFI3MddbvBX_c0sYWlSzCyWa3hped24ktq2Ko,2300
|
|
26
|
-
kotonebot/client/registration.py,sha256=XK424QEWbJKfNdkiDoIJUh_JIy8ryk4I4I3hrWUXCX8,848
|
|
27
|
-
kotonebot/client/host/__init__.py,sha256=WsDNAugbr4k1fMCHBdaYZmrifrq6WmSQByp1qOFbV_I,579
|
|
28
|
-
kotonebot/client/host/adb_common.py,sha256=_S2LKpsNnRUREUpzO71OfMIB8Dt0pmxKdSbcmpqss-4,3750
|
|
29
|
-
kotonebot/client/host/custom.py,sha256=_r2GAtJ20CoEx8JO7wVa4jr6KT8YgO5wzrFHLFtOgZE,4079
|
|
30
|
-
kotonebot/client/host/leidian_host.py,sha256=H1yNhKRBdjzyY8_UjqohuJwjj-gVvN1s3dnQfKgFdW8,7729
|
|
31
|
-
kotonebot/client/host/mumu12_host.py,sha256=cWlbZiV0HdN2S42L1Nd5Jcv3bw-b1oxjX4_3y5JE-tI,14444
|
|
32
|
-
kotonebot/client/host/protocol.py,sha256=x2TbnDELDQpqxSKWUHLT3Pez8Qx6IzL4wyUfgf9mFyk,8051
|
|
33
|
-
kotonebot/client/host/windows_common.py,sha256=_Hf4CvHKNgiMIVY3ZPr3wF71r6nMErNi84Y_fswUjBc,2431
|
|
34
|
-
kotonebot/client/implements/__init__.py,sha256=_qZNM-2wEr4Q-_2kWisyuc4AUoqpRB_gAC_hr8_RkSY,511
|
|
35
|
-
kotonebot/client/implements/adb.py,sha256=OcATiRGj84KMM9mEuQLzLoNyDBaZRJugR-BFrlWjB-c,3145
|
|
36
|
-
kotonebot/client/implements/adb_raw.py,sha256=zUTI9QscmdN031tbBbInUN8G-LrgQv-cTc_Yl0zaZQU,6307
|
|
37
|
-
kotonebot/client/implements/remote_windows.py,sha256=SRq97cuXdUVvFIhsazZt4djMeGSLfYS88IUyzmlpaww,6756
|
|
38
|
-
kotonebot/client/implements/uiautomator2.py,sha256=ER4cNLI_cCpIGKWIXeuaUPmVtz50JuFO5Kx-ZwCGI1s,2575
|
|
39
|
-
kotonebot/client/implements/windows.py,sha256=-P5nFiUbCxz9qMM-WZPtw-Q2xYc3Tmym5MNK3gBwoB4,6738
|
|
40
|
-
kotonebot/client/implements/nemu_ipc/__init__.py,sha256=vSZzv75bn38Wch86PYs5UDOCLwxxoDGm2v1jrwff_S8,200
|
|
41
|
-
kotonebot/client/implements/nemu_ipc/external_renderer_ipc.py,sha256=YsfKf0-qorfAf2YvNuxpLb9af-HJFsu97bnXABshhbA,10643
|
|
42
|
-
kotonebot/client/implements/nemu_ipc/nemu_ipc.py,sha256=LhUUyfB28MDnRg8z2FyGah1hTeOMFiX7w8LZLAAjLF8,12082
|
|
43
|
-
kotonebot/config/__init__.py,sha256=-jATUOdrpUrBRT9RiTRQho2-2zeet50qQggsVMVpqNE,35
|
|
44
|
-
kotonebot/config/base_config.py,sha256=NpJuUmzgjUHelzm55bbVvk9x9MdwuKwfxwpaJFp-9iw,3438
|
|
45
|
-
kotonebot/config/manager.py,sha256=XBtriAU9eo-wv2iKOwyDqu8tzhbKqFCuy0jsAM9T9uU,1061
|
|
46
|
-
kotonebot/interop/win/__init__.py,sha256=jH8E0iqT1lOs4C_i5yl4bJ7z7iZh2ieGOF1lu8raJ30,111
|
|
47
|
-
kotonebot/interop/win/message_box.py,sha256=R06GSu936Bx_Wg7ddn6LOvazD9_Gt3mhz4_oUuIoYO0,8635
|
|
48
|
-
kotonebot/interop/win/reg.py,sha256=xw35d1xl8ucITT4bOMFgHmMkAUhak7x3lzegR3g3S48,1347
|
|
49
|
-
kotonebot/interop/win/shortcut.py,sha256=f1u6IWvpw6Kxt014wnHz5Z94rVK1qf4kLtRsI9bJYnk,1764
|
|
50
|
-
kotonebot/interop/win/task_dialog.py,sha256=Ezi1CsjFSbnKccvYfIRaJoCGHUsJnnIpHb0gtKR603E,20191
|
|
51
|
-
kotonebot/logging/__init__.py,sha256=r0q4z59yYy_bQnHTwJYsiPGwOGIgEOrcXH1mNs1h_N0,142
|
|
52
|
-
kotonebot/logging/log.py,sha256=PLb6r_hlW1mvqU_kx6_89zaQ1IpamgHWG3sQ0ZnlrCI,555
|
|
53
|
-
kotonebot/primitives/__init__.py,sha256=R11AoTQQU6ql86oaVjZJkH2-kkxf5kr9xY8gnqPjLgM,355
|
|
54
|
-
kotonebot/primitives/geometry.py,sha256=L2-mqhfSXSNyt9Qvjo5T27WZc9cso2v9oWeRVnz6-1k,7973
|
|
55
|
-
kotonebot/primitives/visual.py,sha256=fZbNgaM03wCaR1Rb0QgeAQIfNsBBXPoUp2-E2IYFsLA,2028
|
|
56
|
-
kotonebot/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
-
kotonebot/tools/mirror.py,sha256=jlGpeX_WkFpcZxojxDzT5QqVeIpd_UIDzSMR2K31VJ0,13820
|
|
58
|
-
kotonebot/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
|
-
kotonebot/ui/user.py,sha256=aP6Va3iHaVA0-AHViNa04a3HDpLLiovZjV5_AMGY4cI,4485
|
|
60
|
-
kotonebot/ui/file_host/sensio.py,sha256=QyH8DpyO3sf2Hz4NuOW9oDt1V3G06XMO7yKfgLwq1oE,914
|
|
61
|
-
kotonebot/ui/file_host/tmp_send.py,sha256=SwzTUGIjZXaP1_H86qahuLwUd8VeHGWW86XKaC__WKI,1802
|
|
62
|
-
kotonebot/ui/pushkit/__init__.py,sha256=xDUctRUL3euvge-yl8IhFYMlxIxQXsjxcyGN5tUwPtE,73
|
|
63
|
-
kotonebot/ui/pushkit/image_host.py,sha256=nB6BCOA5ZgSGi-ntgqQp49H1UZDk8qC41O_PTLPzZ-E,2581
|
|
64
|
-
kotonebot/ui/pushkit/protocol.py,sha256=KVZ-xr0sMdiuri7AiYqugpZRRtefBsosXm6zouScUR4,266
|
|
65
|
-
kotonebot/ui/pushkit/wxpusher.py,sha256=U7WKxyf9pVgGvppmBxwMRuBuFkQG3NC3tkdRh7_-IOw,1732
|
|
66
|
-
kotonebot-0.4.0.dist-info/licenses/LICENSE,sha256=gcuuhKKc5-dwvyvHsXjlC9oM6N5gZ6umYbC8ewW1Yvg,35821
|
|
67
|
-
kotonebot-0.4.0.dist-info/METADATA,sha256=4P-5GBc-v3VEtDlQqx0F3pUJXC7D9p2b0cmPbVZ91NE,3207
|
|
68
|
-
kotonebot-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
69
|
-
kotonebot-0.4.0.dist-info/top_level.txt,sha256=QUWAZdbBndoojkrs6RcNytLAn7a0ns4YNF4tLx2Nc4s,10
|
|
70
|
-
kotonebot-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|