zhmiscellany 6.0.8__py3-none-any.whl → 6.1.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.
- zhmiscellany/_misc_supportfuncs.py +99 -52
- zhmiscellany/_processing_supportfuncs.py +0 -2
- {zhmiscellany-6.0.8.dist-info → zhmiscellany-6.1.0.dist-info}/METADATA +1 -1
- {zhmiscellany-6.0.8.dist-info → zhmiscellany-6.1.0.dist-info}/RECORD +6 -6
- {zhmiscellany-6.0.8.dist-info → zhmiscellany-6.1.0.dist-info}/WHEEL +0 -0
- {zhmiscellany-6.0.8.dist-info → zhmiscellany-6.1.0.dist-info}/top_level.txt +0 -0
|
@@ -92,41 +92,54 @@ def patch_cpp():
|
|
|
92
92
|
if WIN32_AVAILABLE:
|
|
93
93
|
patch_cpp()
|
|
94
94
|
|
|
95
|
+
# Linux specific imports
|
|
96
|
+
if not WIN32_AVAILABLE:
|
|
97
|
+
try:
|
|
98
|
+
import pyautogui
|
|
99
|
+
|
|
100
|
+
# Optimize PyAutoGUI for speed to match ctypes performance
|
|
101
|
+
pyautogui.FAILSAFE = False
|
|
102
|
+
pyautogui.PAUSE = 0
|
|
103
|
+
pyautogui.MINIMUM_DURATION = 0
|
|
104
|
+
except ImportError:
|
|
105
|
+
raise ImportError("Linux support requires pyautogui. Install it via: pip install pyautogui")
|
|
106
|
+
|
|
107
|
+
# Windows specific imports and Structs
|
|
108
|
+
if WIN32_AVAILABLE:
|
|
109
|
+
class POINT(Structure):
|
|
110
|
+
_fields_ = [("x", c_long),
|
|
111
|
+
("y", c_long)]
|
|
95
112
|
|
|
96
|
-
class POINT(Structure):
|
|
97
|
-
_fields_ = [("x", c_long),
|
|
98
|
-
("y", c_long)]
|
|
99
113
|
|
|
114
|
+
class MOUSEINPUT(Structure):
|
|
115
|
+
_fields_ = [("dx", c_long),
|
|
116
|
+
("dy", c_long),
|
|
117
|
+
("mouseData", c_uint),
|
|
118
|
+
("dwFlags", c_uint),
|
|
119
|
+
("time", c_uint),
|
|
120
|
+
("dwExtraInfo", POINTER(c_uint))]
|
|
100
121
|
|
|
101
|
-
class MOUSEINPUT(Structure):
|
|
102
|
-
_fields_ = [("dx", c_long),
|
|
103
|
-
("dy", c_long),
|
|
104
|
-
("mouseData", c_uint),
|
|
105
|
-
("dwFlags", c_uint),
|
|
106
|
-
("time", c_uint),
|
|
107
|
-
("dwExtraInfo", POINTER(c_uint))]
|
|
108
122
|
|
|
123
|
+
class INPUT_UNION(ctypes.Union):
|
|
124
|
+
_fields_ = [("mi", MOUSEINPUT)]
|
|
109
125
|
|
|
110
|
-
class INPUT_UNION(ctypes.Union):
|
|
111
|
-
_fields_ = [("mi", MOUSEINPUT)]
|
|
112
126
|
|
|
127
|
+
class INPUT(Structure):
|
|
128
|
+
_fields_ = [("type", c_int),
|
|
129
|
+
("union", INPUT_UNION)]
|
|
113
130
|
|
|
114
|
-
class INPUT(Structure):
|
|
115
|
-
_fields_ = [("type", c_int),
|
|
116
|
-
("union", INPUT_UNION)]
|
|
117
131
|
|
|
132
|
+
# Constants
|
|
133
|
+
MOUSEEVENTF_ABSOLUTE = 0x8000
|
|
134
|
+
MOUSEEVENTF_MOVE = 0x0001
|
|
135
|
+
MOUSEEVENTF_LEFTDOWN = 0x0002
|
|
136
|
+
MOUSEEVENTF_LEFTUP = 0x0004
|
|
137
|
+
MOUSEEVENTF_RIGHTDOWN = 0x0008
|
|
138
|
+
MOUSEEVENTF_RIGHTUP = 0x0010
|
|
139
|
+
MOUSEEVENTF_MIDDLEDOWN = 0x0020
|
|
140
|
+
MOUSEEVENTF_MIDDLEUP = 0x0040
|
|
118
141
|
|
|
119
|
-
# Constants
|
|
120
|
-
MOUSEEVENTF_ABSOLUTE = 0x8000
|
|
121
|
-
MOUSEEVENTF_MOVE = 0x0001
|
|
122
|
-
MOUSEEVENTF_LEFTDOWN = 0x0002
|
|
123
|
-
MOUSEEVENTF_LEFTUP = 0x0004
|
|
124
|
-
MOUSEEVENTF_RIGHTDOWN = 0x0008
|
|
125
|
-
MOUSEEVENTF_RIGHTUP = 0x0010
|
|
126
|
-
MOUSEEVENTF_MIDDLEDOWN = 0x0020
|
|
127
|
-
MOUSEEVENTF_MIDDLEUP = 0x0040
|
|
128
142
|
|
|
129
|
-
# Screen metrics
|
|
130
143
|
def get_actual_screen_resolution():
|
|
131
144
|
if WIN32_AVAILABLE:
|
|
132
145
|
hdc = windll.user32.GetDC(0)
|
|
@@ -135,19 +148,33 @@ def get_actual_screen_resolution():
|
|
|
135
148
|
windll.user32.ReleaseDC(0, hdc)
|
|
136
149
|
return width, height
|
|
137
150
|
else:
|
|
138
|
-
|
|
139
|
-
|
|
151
|
+
# Linux implementation using pyautogui
|
|
152
|
+
try:
|
|
153
|
+
return pyautogui.size()
|
|
154
|
+
except Exception:
|
|
155
|
+
print("Could not determine screen resolution on Linux, defaulting to 1920x1080")
|
|
156
|
+
return 1920, 1080
|
|
140
157
|
|
|
141
|
-
SCREEN_WIDTH, SCREEN_HEIGHT = (1920, 1080) if not WIN32_AVAILABLE else get_actual_screen_resolution()
|
|
142
158
|
|
|
159
|
+
# Initialize Globals
|
|
160
|
+
SCREEN_WIDTH, SCREEN_HEIGHT = get_actual_screen_resolution()
|
|
143
161
|
calibrated = False
|
|
144
162
|
calipass = False
|
|
163
|
+
calibration_multiplier_x = 1.0
|
|
164
|
+
calibration_multiplier_y = 1.0
|
|
165
|
+
|
|
145
166
|
|
|
146
167
|
def move_mouse(x: int, y: int, relative=False):
|
|
168
|
+
# --- LINUX IMPLEMENTATION ---
|
|
147
169
|
if not WIN32_AVAILABLE:
|
|
148
|
-
|
|
170
|
+
# PyAutoGUI handles relative/absolute logic natively
|
|
171
|
+
if relative:
|
|
172
|
+
pyautogui.move(x, y)
|
|
173
|
+
else:
|
|
174
|
+
pyautogui.moveTo(x, y)
|
|
149
175
|
return
|
|
150
|
-
|
|
176
|
+
|
|
177
|
+
# --- WINDOWS IMPLEMENTATION ---
|
|
151
178
|
if not relative:
|
|
152
179
|
# Convert coordinates to normalized coordinates (0-65535)
|
|
153
180
|
normalized_x = int(x * (65535 / SCREEN_WIDTH))
|
|
@@ -182,53 +209,70 @@ def move_mouse(x: int, y: int, relative=False):
|
|
|
182
209
|
|
|
183
210
|
windll.user32.SendInput(1, ctypes.byref(input_struct), sizeof(INPUT))
|
|
184
211
|
|
|
212
|
+
|
|
185
213
|
def get_mouse_xy():
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
214
|
+
# --- LINUX IMPLEMENTATION ---
|
|
215
|
+
if not WIN32_AVAILABLE:
|
|
216
|
+
return pyautogui.position()
|
|
217
|
+
|
|
218
|
+
# --- WINDOWS IMPLEMENTATION ---
|
|
219
|
+
x, y = win32api.GetCursorPos()
|
|
220
|
+
return x, y
|
|
221
|
+
|
|
192
222
|
|
|
193
223
|
def calibrate():
|
|
224
|
+
"""
|
|
225
|
+
Windows-specific calibration for relative movement scaling.
|
|
226
|
+
On Linux, libraries handle this abstraction automatically, so we skip it.
|
|
227
|
+
"""
|
|
194
228
|
if not WIN32_AVAILABLE:
|
|
195
|
-
print("calibrate() only supports Windows! Functionality disabled")
|
|
196
229
|
return
|
|
197
|
-
|
|
230
|
+
|
|
198
231
|
global calibration_multiplier_x, calibration_multiplier_y, calibrated, calipass
|
|
199
232
|
if calibrated:
|
|
200
233
|
return
|
|
201
234
|
if calipass:
|
|
202
235
|
return
|
|
203
236
|
calipass = True
|
|
237
|
+
|
|
204
238
|
# calibrate relative movement, required because windows is weird
|
|
205
239
|
original_mouse_point = get_mouse_xy()
|
|
206
240
|
calibration_distance = 128
|
|
207
241
|
moved_pos = (0, 0)
|
|
208
242
|
lim = 64
|
|
209
243
|
i = 0
|
|
244
|
+
|
|
245
|
+
# Note: logic below calls move_mouse, which calls calibrate,
|
|
246
|
+
# but calipass=True prevents recursion loop
|
|
210
247
|
while ((not moved_pos[0]) or (not moved_pos[1])) and i < lim:
|
|
211
248
|
i += 1
|
|
212
|
-
move_mouse(0,0)
|
|
249
|
+
move_mouse(0, 0) # Reset to 0,0
|
|
213
250
|
move_mouse(calibration_distance, calibration_distance, relative=True)
|
|
214
251
|
moved_pos = get_mouse_xy()
|
|
252
|
+
|
|
215
253
|
if not i < lim:
|
|
216
|
-
raise Exception('Relative mouse movement could not be calibrated
|
|
217
|
-
|
|
218
|
-
|
|
254
|
+
raise Exception('Relative mouse movement could not be calibrated.')
|
|
255
|
+
|
|
256
|
+
calibration_multiplier_x = calibration_distance / moved_pos[0]
|
|
257
|
+
calibration_multiplier_y = calibration_distance / moved_pos[1]
|
|
219
258
|
calibrated = True
|
|
220
|
-
|
|
259
|
+
|
|
260
|
+
# Return mouse to original position
|
|
261
|
+
move_mouse(original_mouse_point[0], original_mouse_point[1])
|
|
221
262
|
|
|
222
263
|
|
|
223
264
|
def mouse_down(button: int):
|
|
224
265
|
"""Press mouse button down. button: 1=left, 2=right, 3=middle"""
|
|
225
|
-
if not WIN32_AVAILABLE:
|
|
226
|
-
print("mouse_down() only supports Windows! Functionality disabled")
|
|
227
|
-
return
|
|
228
|
-
|
|
229
266
|
if button not in [1, 2, 3]:
|
|
230
267
|
raise ValueError("Button must be 1 (left), 2 (right), or 3 (middle)")
|
|
231
268
|
|
|
269
|
+
# --- LINUX IMPLEMENTATION ---
|
|
270
|
+
if not WIN32_AVAILABLE:
|
|
271
|
+
btn_map = {1: 'left', 2: 'right', 3: 'middle'}
|
|
272
|
+
pyautogui.mouseDown(button=btn_map[button])
|
|
273
|
+
return
|
|
274
|
+
|
|
275
|
+
# --- WINDOWS IMPLEMENTATION ---
|
|
232
276
|
flags = {
|
|
233
277
|
1: MOUSEEVENTF_LEFTDOWN,
|
|
234
278
|
2: MOUSEEVENTF_RIGHTDOWN,
|
|
@@ -254,13 +298,16 @@ def mouse_down(button: int):
|
|
|
254
298
|
|
|
255
299
|
def mouse_up(button: int):
|
|
256
300
|
"""Release mouse button. button: 1=left, 2=right, 3=middle"""
|
|
257
|
-
if not WIN32_AVAILABLE:
|
|
258
|
-
print("mouse_up() only supports Windows! Functionality disabled")
|
|
259
|
-
return
|
|
260
|
-
|
|
261
301
|
if button not in [1, 2, 3]:
|
|
262
302
|
raise ValueError("Button must be 1 (left), 2 (right), or 3 (middle)")
|
|
263
303
|
|
|
304
|
+
# --- LINUX IMPLEMENTATION ---
|
|
305
|
+
if not WIN32_AVAILABLE:
|
|
306
|
+
btn_map = {1: 'left', 2: 'right', 3: 'middle'}
|
|
307
|
+
pyautogui.mouseUp(button=btn_map[button])
|
|
308
|
+
return
|
|
309
|
+
|
|
310
|
+
# --- WINDOWS IMPLEMENTATION ---
|
|
264
311
|
flags = {
|
|
265
312
|
1: MOUSEEVENTF_LEFTUP,
|
|
266
313
|
2: MOUSEEVENTF_RIGHTUP,
|
|
@@ -281,4 +328,4 @@ def mouse_up(button: int):
|
|
|
281
328
|
)
|
|
282
329
|
)
|
|
283
330
|
|
|
284
|
-
windll.user32.SendInput(1, ctypes.byref(input_struct), sizeof(INPUT))
|
|
331
|
+
windll.user32.SendInput(1, ctypes.byref(input_struct), sizeof(INPUT))
|
|
@@ -14,10 +14,8 @@ if sys.platform == "win32":
|
|
|
14
14
|
RAY_AVAILABLE = True
|
|
15
15
|
except ImportError:
|
|
16
16
|
RAY_AVAILABLE = False
|
|
17
|
-
print("Warning: Ray not available - multiprocessing functionality disabled")
|
|
18
17
|
else:
|
|
19
18
|
RAY_AVAILABLE = False
|
|
20
|
-
print("Ray is only supported on Windows - multiprocessing functionality disabled")
|
|
21
19
|
|
|
22
20
|
|
|
23
21
|
def clear_logs():
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
zhmiscellany/__init__.py,sha256=Oh3gAJRWq2aUEgkolmQyiZOQ3iey5OC4NA2XaTHuVv4,1139
|
|
2
2
|
zhmiscellany/_discord_supportfuncs.py,sha256=RotSpurqFtL5q6v_ST1e2Y_1qJMaHp1CDsF5i-gR4ec,6524
|
|
3
3
|
zhmiscellany/_fileio_supportfuncs.py,sha256=soibLv9nOR79sHQ2MGQH2O6MhnqdXqI7ybxHSN2Tfac,434
|
|
4
|
-
zhmiscellany/_misc_supportfuncs.py,sha256=
|
|
5
|
-
zhmiscellany/_processing_supportfuncs.py,sha256=
|
|
4
|
+
zhmiscellany/_misc_supportfuncs.py,sha256=pMd7Y4hzstn5BFFlBQbkZYQetvy5WCx8hFb-hL3FO0s,9799
|
|
5
|
+
zhmiscellany/_processing_supportfuncs.py,sha256=u5dzW-2OtyViC74r5fhqd5_2uQ92ZhieRJRTJMevqbg,11071
|
|
6
6
|
zhmiscellany/_py_resources.py,sha256=HqJs5aRLymLZ2J5Io8g6bY58pGWhN9b8vCktC2DW4KQ,229009
|
|
7
7
|
zhmiscellany/_resource_files_lookup.py,sha256=hsgPW0dngokgqWrAVAv5rUo-eobzJPjvWHt4xrOG5l0,856
|
|
8
8
|
zhmiscellany/cpp.py,sha256=XEUEoIKCDCdY5VgwNWE5oXrGjtsmGdz_MnaVwQmi2dk,179
|
|
@@ -21,7 +21,7 @@ zhmiscellany/pipes.py,sha256=zETvWP4PF-PuSzYwR1UCodY4ftNAgmCChb9DUMofXok,4657
|
|
|
21
21
|
zhmiscellany/processing.py,sha256=sDKIbzG9TNFyT6yJ4TJL59taG-59_v3CBLekVSLrwgE,10899
|
|
22
22
|
zhmiscellany/rust.py,sha256=znN6DYNoa_p-braTuDZKvUnXX8reWLFu_dG4fv2vLR0,442
|
|
23
23
|
zhmiscellany/string.py,sha256=xyqE6V5YF2nieZDcg5ZrXTIrH2D9oDRbZ5vQGz8rPys,4787
|
|
24
|
-
zhmiscellany-6.0.
|
|
25
|
-
zhmiscellany-6.0.
|
|
26
|
-
zhmiscellany-6.0.
|
|
27
|
-
zhmiscellany-6.0.
|
|
24
|
+
zhmiscellany-6.1.0.dist-info/METADATA,sha256=IzKNJvKrOuFNwLX6d3-3alPiedJn7KmupqYwQhZgQZI,43560
|
|
25
|
+
zhmiscellany-6.1.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
26
|
+
zhmiscellany-6.1.0.dist-info/top_level.txt,sha256=ioDtsrevCI52rTxZntMPljRIBsZs73tD0hI00HektiE,13
|
|
27
|
+
zhmiscellany-6.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|