feat: publish workphone SDK deployment and API docs

This commit is contained in:
Manus AI
2026-07-14 18:10:52 +08:00
commit 021d633cc1
534 changed files with 122391 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
"""
触摸加固层 — 将机器精确操作伪装为真人触摸
功能:
1. 坐标随机偏移 (+-3~8px)
2. 点击时长随机化 (50~150ms)
3. 贝塞尔曲线轨迹滑动 (替代直线滑动)
4. 按压-微移-抬起时序模拟
5. 可配置的「手抖」程度
"""
import logging
import math
import random
import time
from typing import List, Optional, Tuple
logger = logging.getLogger(__name__)
Point = Tuple[float, float]
class TouchHardener:
"""触摸事件加固 — 让自动化操作看起来像人"""
def __init__(self, device=None, tremor_level: float = 1.0):
"""
Args:
device: uiautomator2 设备对象
tremor_level: 手抖程度倍数 (0.5=稳手, 1.0=普通, 2.0=抖得厉害)
"""
self.d = device
self.tremor = max(0.1, tremor_level)
def humanized_click(self, x: int, y: int) -> Tuple[int, int]:
"""
带随机偏移的点击。返回实际点击坐标。
"""
offset_x = random.gauss(0, 3 * self.tremor)
offset_y = random.gauss(0, 3 * self.tremor)
actual_x = max(0, int(x + offset_x))
actual_y = max(0, int(y + offset_y))
duration_ms = random.randint(50, 150)
if self.d:
self.d.click(actual_x, actual_y)
settle_ms = random.uniform(30, 80)
time.sleep(settle_ms / 1000)
logger.debug(f"click ({x},{y}) → ({actual_x},{actual_y}) dur={duration_ms}ms")
return actual_x, actual_y
def humanized_swipe(self, x1: int, y1: int, x2: int, y2: int,
duration: float = 0.5, steps: int = 0) -> List[Point]:
"""
贝塞尔曲线滑动。返回轨迹点序列。
"""
sx = x1 + random.gauss(0, 2 * self.tremor)
sy = y1 + random.gauss(0, 2 * self.tremor)
ex = x2 + random.gauss(0, 2 * self.tremor)
ey = y2 + random.gauss(0, 2 * self.tremor)
ctrl_points = self._random_bezier_controls(sx, sy, ex, ey)
if steps <= 0:
dist = math.hypot(ex - sx, ey - sy)
steps = max(8, int(dist / 15))
trajectory = self._bezier_curve(sx, sy, ex, ey, ctrl_points, steps)
if self.d:
self.d.swipe(int(sx), int(sy), int(ex), int(ey), duration=duration, steps=steps)
logger.debug(f"swipe ({x1},{y1})→({x2},{y2}) pts={len(trajectory)}")
return trajectory
def humanized_long_press(self, x: int, y: int, duration_ms: int = 800):
"""长按 — 带起始微抖"""
actual_x = int(x + random.gauss(0, 2 * self.tremor))
actual_y = int(y + random.gauss(0, 2 * self.tremor))
actual_dur = duration_ms + random.randint(-100, 150)
actual_dur = max(300, actual_dur)
if self.d:
self.d.long_click(actual_x, actual_y, duration=actual_dur / 1000)
logger.debug(f"long_press ({x},{y})→({actual_x},{actual_y}) dur={actual_dur}ms")
def humanized_type(self, text: str, char_delay_range: Tuple[float, float] = (0.03, 0.12)):
"""
逐字输入 — 每个字符间隔随机延迟,模拟打字节奏。
"""
for i, char in enumerate(text):
if self.d:
self.d.send_keys(char)
delay = random.uniform(*char_delay_range)
if char in (' ', ',', '.', '', ''):
delay *= random.uniform(1.5, 3.0)
time.sleep(delay)
logger.debug(f"typed {len(text)} chars")
def pre_action_pause(self):
"""操作前的微停顿 — 模拟人的反应时间"""
pause = random.uniform(0.2, 0.8) * self.tremor
time.sleep(pause)
def post_action_pause(self):
"""操作后的短暂停顿 — 模拟人看结果"""
pause = random.uniform(0.3, 1.2) * self.tremor
time.sleep(pause)
# ---- 内部方法 ----
@staticmethod
def _random_bezier_controls(x1: float, y1: float,
x2: float, y2: float) -> List[Point]:
"""生成 1~2 个随机控制点,使路径弯曲"""
mx = (x1 + x2) / 2
my = (y1 + y2) / 2
dist = math.hypot(x2 - x1, y2 - y1)
spread = dist * random.uniform(0.1, 0.35)
c1 = (mx + random.gauss(0, spread), my + random.gauss(0, spread))
if random.random() > 0.5:
c2 = (mx + random.gauss(0, spread * 0.6), my + random.gauss(0, spread * 0.6))
return [c1, c2]
return [c1]
@staticmethod
def _bezier_curve(x1: float, y1: float, x2: float, y2: float,
controls: List[Point], steps: int) -> List[Point]:
"""计算贝塞尔曲线点"""
points: List[Point] = []
if len(controls) == 1:
cx, cy = controls[0]
for i in range(steps + 1):
t = i / steps
bx = (1 - t) ** 2 * x1 + 2 * (1 - t) * t * cx + t ** 2 * x2
by = (1 - t) ** 2 * y1 + 2 * (1 - t) * t * cy + t ** 2 * y2
points.append((bx, by))
elif len(controls) >= 2:
c1x, c1y = controls[0]
c2x, c2y = controls[1]
for i in range(steps + 1):
t = i / steps
bx = ((1 - t) ** 3 * x1 + 3 * (1 - t) ** 2 * t * c1x +
3 * (1 - t) * t ** 2 * c2x + t ** 3 * x2)
by = ((1 - t) ** 3 * y1 + 3 * (1 - t) ** 2 * t * c1y +
3 * (1 - t) * t ** 2 * c2y + t ** 3 * y2)
points.append((bx, by))
else:
for i in range(steps + 1):
t = i / steps
points.append((x1 + (x2 - x1) * t, y1 + (y2 - y1) * t))
return points