修复脚本。拔出设备,重新插回脚本可以继续执行。
This commit is contained in:
@@ -2,6 +2,7 @@ import random
|
|||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from collections import defaultdict
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import wda
|
import wda
|
||||||
@@ -34,6 +35,7 @@ class ScriptManager():
|
|||||||
# return cls._instance
|
# return cls._instance
|
||||||
_device_cache = {}
|
_device_cache = {}
|
||||||
_cache_lock = threading.Lock() # 线程安全锁(可选,如果你有多线程)
|
_cache_lock = threading.Lock() # 线程安全锁(可选,如果你有多线程)
|
||||||
|
_udid_locks = defaultdict(threading.Lock)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_screen_info(cls, udid: str):
|
def get_screen_info(cls, udid: str):
|
||||||
@@ -146,19 +148,31 @@ class ScriptManager():
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
session.tap(100, 100)
|
session.tap(100, 100)
|
||||||
|
|
||||||
|
# 养号
|
||||||
# 养号
|
# 养号
|
||||||
def growAccount(self, udid, isComment, event, is_monitoring=False):
|
def growAccount(self, udid, isComment, event, is_monitoring=False):
|
||||||
LogManager.method_info(f"调用刷视频", "养号", udid)
|
LogManager.method_info("调用刷视频", "养号", udid)
|
||||||
|
|
||||||
# ========= 初始化 =========
|
# ✅ 同一台设备同一时间只允许一个脚本跑,防止WDA并发爆炸(call depth exceed)
|
||||||
client = wda.USBClient(udid, ev.wdaFunctionPort)
|
lock = self._udid_locks[udid]
|
||||||
session = client.session()
|
if not lock.acquire(blocking=False):
|
||||||
|
LogManager.method_error("同一UDID已有任务在运行,拒绝重复启动", "养号", udid=udid)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
AiUtils.makeUdidDir(udid)
|
AiUtils.makeUdidDir(udid)
|
||||||
|
|
||||||
|
# 外层重启循环:任何异常都会回到这里重新建 session
|
||||||
while not event.is_set():
|
while not event.is_set():
|
||||||
|
client = None
|
||||||
|
session = None
|
||||||
try:
|
try:
|
||||||
|
# ========= 初始化(每次重启都重新创建)=========
|
||||||
|
client = wda.USBClient(udid, ev.wdaFunctionPort)
|
||||||
|
session = client.session()
|
||||||
|
|
||||||
if not is_monitoring:
|
if not is_monitoring:
|
||||||
LogManager.method_info(f"开始养号,重启tiktok", "养号", udid)
|
LogManager.method_info("开始养号,重启tiktok", "养号", udid)
|
||||||
ControlUtils.closeTikTok(session, udid)
|
ControlUtils.closeTikTok(session, udid)
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
ControlUtils.openTikTok(session, udid)
|
ControlUtils.openTikTok(session, udid)
|
||||||
@@ -166,23 +180,24 @@ class ScriptManager():
|
|||||||
|
|
||||||
recomend_cx = 0
|
recomend_cx = 0
|
||||||
recomend_cy = 0
|
recomend_cy = 0
|
||||||
|
|
||||||
# ========= 主循环 =========
|
# ========= 主循环 =========
|
||||||
while not event.is_set():
|
while not event.is_set():
|
||||||
# 设置手机的节点深度为15,判断该页面是否正确
|
# 设置手机的节点深度为15,判断该页面是否正确
|
||||||
session.appium_settings({"snapshotMaxDepth": 15})
|
session.appium_settings({"snapshotMaxDepth": 15})
|
||||||
|
|
||||||
el = session.xpath(
|
el = session.xpath(
|
||||||
'//XCUIElementTypeButton[@name="top_tabs_recomend" or @name="推荐" or @label="推荐"]'
|
'//XCUIElementTypeButton[@name="top_tabs_recomend" or @name="推荐" or @label="推荐"]'
|
||||||
)
|
)
|
||||||
|
|
||||||
# 获取推荐按钮所在的坐标
|
# 获取推荐按钮所在的坐标
|
||||||
if el.exists:
|
if el.exists:
|
||||||
bounds = el.bounds # 返回 [x, y, width, height]
|
bounds = el.bounds # [x, y, width, height]
|
||||||
recomend_cx = bounds[0] + bounds[2] // 2
|
recomend_cx = bounds[0] + bounds[2] // 2
|
||||||
recomend_cy = bounds[1] + bounds[3] // 2
|
recomend_cy = bounds[1] + bounds[3] // 2
|
||||||
|
|
||||||
if not el.exists:
|
if not el.exists:
|
||||||
# 记录日志
|
|
||||||
LogManager.method_error("找不到推荐按钮,养号出现问题,重启养号功能", "养号", udid=udid)
|
LogManager.method_error("找不到推荐按钮,养号出现问题,重启养号功能", "养号", udid=udid)
|
||||||
# 手动的抛出异常 重启流程
|
|
||||||
raise Exception("找不到推荐按钮,养号出现问题,重启养号功能")
|
raise Exception("找不到推荐按钮,养号出现问题,重启养号功能")
|
||||||
|
|
||||||
if el.value != "1":
|
if el.value != "1":
|
||||||
@@ -190,7 +205,8 @@ class ScriptManager():
|
|||||||
raise Exception("当前页面不是推荐页面,养号出现问题,重启养号功能")
|
raise Exception("当前页面不是推荐页面,养号出现问题,重启养号功能")
|
||||||
|
|
||||||
LogManager.method_info("当前页面是推荐页面,开始养号", "养号", udid=udid)
|
LogManager.method_info("当前页面是推荐页面,开始养号", "养号", udid=udid)
|
||||||
# 重新设置节点的深度,防止手机进行卡顿
|
|
||||||
|
# 重新设置节点深度,防止手机卡顿
|
||||||
session.appium_settings({"snapshotMaxDepth": 0})
|
session.appium_settings({"snapshotMaxDepth": 0})
|
||||||
|
|
||||||
# ---- 截图保存 ----
|
# ---- 截图保存 ----
|
||||||
@@ -202,7 +218,6 @@ class ScriptManager():
|
|||||||
filePath = os.path.join(resource_dir, "bgv.png")
|
filePath = os.path.join(resource_dir, "bgv.png")
|
||||||
img.save(filePath)
|
img.save(filePath)
|
||||||
LogManager.method_info(f"保存屏幕图像成功 -> {filePath}", "养号", udid)
|
LogManager.method_info(f"保存屏幕图像成功 -> {filePath}", "养号", udid)
|
||||||
print("保存了背景图:", filePath)
|
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LogManager.method_info(f"截图或保存失败,失败原因:{e}", "养号", udid)
|
LogManager.method_info(f"截图或保存失败,失败原因:{e}", "养号", udid)
|
||||||
@@ -211,13 +226,14 @@ class ScriptManager():
|
|||||||
# ---- 视频逻辑 ----
|
# ---- 视频逻辑 ----
|
||||||
try:
|
try:
|
||||||
width, height, scale = self.get_screen_info(udid)
|
width, height, scale = self.get_screen_info(udid)
|
||||||
|
|
||||||
if scale == 3.0:
|
if scale == 3.0:
|
||||||
addX, addY = AiUtils.findImageInScreen("add", udid)
|
addX, addY = AiUtils.findImageInScreen("add", udid)
|
||||||
else:
|
else:
|
||||||
addX, addY = AiUtils.findImageInScreen("like1", udid)
|
addX, addY = AiUtils.findImageInScreen("like1", udid)
|
||||||
|
|
||||||
isSame = False
|
isSame = False
|
||||||
for i in range(2):
|
for _ in range(2):
|
||||||
if scale == 3.0:
|
if scale == 3.0:
|
||||||
tx, ty = AiUtils.findImageInScreen("add", udid)
|
tx, ty = AiUtils.findImageInScreen("add", udid)
|
||||||
else:
|
else:
|
||||||
@@ -228,7 +244,6 @@ class ScriptManager():
|
|||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
else:
|
else:
|
||||||
isSame = False
|
isSame = False
|
||||||
# break
|
|
||||||
|
|
||||||
if addX > 0 and isSame:
|
if addX > 0 and isSame:
|
||||||
needLike = random.randint(0, 100)
|
needLike = random.randint(0, 100)
|
||||||
@@ -236,20 +251,21 @@ class ScriptManager():
|
|||||||
if homeButton:
|
if homeButton:
|
||||||
LogManager.method_info("有首页按钮,查看视频", "养号", udid)
|
LogManager.method_info("有首页按钮,查看视频", "养号", udid)
|
||||||
videoTime = random.randint(5, 15)
|
videoTime = random.randint(5, 15)
|
||||||
|
|
||||||
LogManager.method_info("准备停止脚本", method="task")
|
LogManager.method_info("准备停止脚本", method="task")
|
||||||
for _ in range(videoTime): # 0.2 秒一片
|
for _ in range(videoTime):
|
||||||
if event.is_set():
|
if event.is_set():
|
||||||
LogManager.method_info("停止脚本中", method="task")
|
LogManager.method_info("停止脚本中", method="task")
|
||||||
break
|
break
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
LogManager.method_info("停止脚本成功", method="task")
|
LogManager.method_info("停止脚本成功", method="task")
|
||||||
|
|
||||||
# 重置 session
|
|
||||||
session.appium_settings({"snapshotMaxDepth": 0})
|
session.appium_settings({"snapshotMaxDepth": 0})
|
||||||
|
|
||||||
if needLike < 25:
|
if needLike < 25:
|
||||||
LogManager.method_info("进行点赞", "养号", udid)
|
LogManager.method_info("进行点赞", "养号", udid)
|
||||||
ControlUtils.clickLike(session, udid)
|
ControlUtils.clickLike(session, udid)
|
||||||
|
|
||||||
LogManager.method_info("继续观看视频", "养号", udid)
|
LogManager.method_info("继续观看视频", "养号", udid)
|
||||||
LogManager.method_info("准备划到下一个视频", "养号", udid)
|
LogManager.method_info("准备划到下一个视频", "养号", udid)
|
||||||
else:
|
else:
|
||||||
@@ -271,9 +287,8 @@ class ScriptManager():
|
|||||||
|
|
||||||
ControlUtils.swipe_up(client)
|
ControlUtils.swipe_up(client)
|
||||||
|
|
||||||
# 如果is_monitoring 为False 则说明和监控消息没有联动,反正 则证明和监控消息进行联动
|
# 如果is_monitoring 为True:检测收件箱消息
|
||||||
if is_monitoring:
|
if is_monitoring:
|
||||||
# 监控消息按钮,判断是否有消息
|
|
||||||
el = session.xpath(
|
el = session.xpath(
|
||||||
'//XCUIElementTypeButton[@name="a11y_vo_inbox"]'
|
'//XCUIElementTypeButton[@name="a11y_vo_inbox"]'
|
||||||
' | '
|
' | '
|
||||||
@@ -281,10 +296,11 @@ class ScriptManager():
|
|||||||
' | '
|
' | '
|
||||||
'//XCUIElementTypeButton[.//XCUIElementTypeStaticText[@value="收件箱"]]'
|
'//XCUIElementTypeButton[.//XCUIElementTypeStaticText[@value="收件箱"]]'
|
||||||
)
|
)
|
||||||
# 判断收件箱是否有消息
|
|
||||||
if el.exists:
|
if el.exists:
|
||||||
|
m = None
|
||||||
try:
|
try:
|
||||||
m = re.search(r'(\d+)', el.label) # 抓到的第一个数字串
|
m = re.search(r"(\d+)", (el.label or ""))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LogManager.method_error(f"解析收件箱数量异常: {e}", "检测消息", udid)
|
LogManager.method_error(f"解析收件箱数量异常: {e}", "检测消息", udid)
|
||||||
|
|
||||||
@@ -296,131 +312,160 @@ class ScriptManager():
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("刷视频脚本有错误:错误内容:", e)
|
print("刷视频脚本有错误:错误内容:", e)
|
||||||
LogManager.method_error(f"刷视频过程出现错误,重试", "养号", udid)
|
LogManager.method_error("刷视频过程出现错误,重试", "养号", udid)
|
||||||
raise e # 抛出给上层,触发重生机制
|
# 抛出给上层,触发重启(外层 while 会重建 session)
|
||||||
|
raise
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("刷视频遇到错误了。错误内容:", e)
|
print("刷视频遇到错误了。错误内容:", e)
|
||||||
LogManager.method_error(f"[{udid}] 养号出现异常,将重启流程: {e}", "养号", udid)
|
LogManager.method_error(f"[{udid}] 养号出现异常,将重启流程: {e}", "养号", udid)
|
||||||
|
|
||||||
|
# ✅ 关键:这里等待后回到外层 while,重新创建client/session
|
||||||
event.wait(timeout=3)
|
event.wait(timeout=3)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# 尽量释放 session(不同wda版本不一定有close)
|
||||||
|
try:
|
||||||
|
if session is not None:
|
||||||
|
session.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
finally:
|
||||||
|
lock.release()
|
||||||
|
|
||||||
# 观看直播
|
# 观看直播
|
||||||
def watchLiveForGrowth(self, udid, event, max_retries=None):
|
def watchLiveForGrowth(self, udid, event, max_retries=None):
|
||||||
import random, wda
|
import random, wda
|
||||||
|
|
||||||
retry_count = 0
|
retry_count = 0
|
||||||
backoff_sec = 10
|
backoff_sec = 10
|
||||||
|
|
||||||
|
# ✅ 同一台设备同一时间只允许一个任务跑
|
||||||
|
lock = self._udid_locks[udid]
|
||||||
|
if not lock.acquire(blocking=False):
|
||||||
|
LogManager.method_error("同一UDID已有任务在运行,拒绝重复启动", "直播养号", udid=udid)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 外层重启循环:任何异常都会回到这里重新建 client/session
|
||||||
|
while not event.is_set():
|
||||||
|
|
||||||
|
client = None
|
||||||
|
session = None
|
||||||
|
try:
|
||||||
# —— 每次重启都新建 client/session ——
|
# —— 每次重启都新建 client/session ——
|
||||||
client = wda.USBClient(udid, ev.wdaFunctionPort)
|
client = wda.USBClient(udid, ev.wdaFunctionPort)
|
||||||
session = client.session()
|
session = client.session()
|
||||||
|
|
||||||
while not event.is_set():
|
|
||||||
try:
|
|
||||||
|
|
||||||
# 1) 先关再开
|
# 1) 先关再开
|
||||||
ControlUtils.closeTikTok(session, udid)
|
ControlUtils.closeTikTok(session, udid)
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
ControlUtils.openTikTok(session, udid)
|
ControlUtils.openTikTok(session, udid)
|
||||||
event.wait(timeout=3)
|
event.wait(timeout=3)
|
||||||
|
|
||||||
|
# 2) 进入直播按钮(中英文都匹配)
|
||||||
session.appium_settings({"snapshotMaxDepth": 15})
|
session.appium_settings({"snapshotMaxDepth": 15})
|
||||||
# 2) 进入直播 (使用英文)
|
|
||||||
live_button = session(
|
live_button = session.xpath(
|
||||||
xpath='//XCUIElementTypeButton[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"] '
|
'//XCUIElementTypeButton[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"]'
|
||||||
'| //XCUIElementTypeOther[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"]'
|
' | '
|
||||||
|
'//XCUIElementTypeOther[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"]'
|
||||||
)
|
)
|
||||||
|
|
||||||
if live_button.exists:
|
if live_button.exists:
|
||||||
live_button.click()
|
live_button.click()
|
||||||
else:
|
else:
|
||||||
LogManager.method_error("无法找到直播间按钮 抛出异常 重新启动", "直播养号", udid)
|
LogManager.method_error("无法找到直播间按钮,重启流程", "直播养号", udid=udid)
|
||||||
# 抛出异常
|
raise Exception("找不到直播按钮")
|
||||||
raise Exception(f"找不到直播按钮,抛出异常 重新启动")
|
|
||||||
waitTime = random.randint(15, 20)
|
# 进入后稍等
|
||||||
for _ in range(waitTime): # 0.2 秒一片
|
wait_time = random.randint(15, 20)
|
||||||
|
for _ in range(wait_time):
|
||||||
if event.is_set():
|
if event.is_set():
|
||||||
break
|
break
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
|
|
||||||
# live_button = session(xpath='//XCUIElementTypeButton[@name="直播"]')
|
# ✅ 恢复深度(避免一直高深度导致卡顿/递归)
|
||||||
live_button = session(
|
session.appium_settings({"snapshotMaxDepth": 0})
|
||||||
xpath='//XCUIElementTypeButton[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"] '
|
|
||||||
'| //XCUIElementTypeOther[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"]'
|
|
||||||
)
|
|
||||||
|
|
||||||
if live_button.exists:
|
# 如果还在直播入口页(说明没进去),继续主流程重来
|
||||||
|
live_button2 = session.xpath(
|
||||||
|
'//XCUIElementTypeButton[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"]'
|
||||||
|
' | '
|
||||||
|
'//XCUIElementTypeOther[@name="LIVE" or @label="LIVE" or @name="直播" or @label="直播"]'
|
||||||
|
)
|
||||||
|
if live_button2.exists:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 下滑一下
|
# 下滑一下进入直播流
|
||||||
ControlUtils.swipe_up(client)
|
ControlUtils.swipe_up(client)
|
||||||
|
|
||||||
# 3) 取分辨率;可选重建 session 规避句柄陈旧
|
# 取分辨率
|
||||||
size = session.window_size()
|
size = session.window_size()
|
||||||
width, height = size.width, size.height
|
width, height = size.width, size.height
|
||||||
|
|
||||||
# 4) 主循环:刷直播
|
# 4) 主循环:刷直播
|
||||||
while not event.is_set():
|
while not event.is_set():
|
||||||
|
|
||||||
|
# 小停顿
|
||||||
event.wait(timeout=3)
|
event.wait(timeout=3)
|
||||||
|
|
||||||
# 找到一个看直播的时候肯定有的元素,当这个元素没有的时候,就代表当前的页面出现了问题
|
# 找一个直播间必存在的元素,用来判断是否还在直播间
|
||||||
# 需要抛出异常,重启这个流程
|
|
||||||
el1 = session.xpath('//XCUIElementTypeOther[@name="GBLFeedRootViewComponent"]')
|
el1 = session.xpath('//XCUIElementTypeOther[@name="GBLFeedRootViewComponent"]')
|
||||||
el2 = session.xpath('//XCUIElementTypeOther[@value="0%"]')
|
el2 = session.xpath('//XCUIElementTypeOther[@value="0%"]')
|
||||||
|
|
||||||
if not (el1.exists or el2.exists):
|
if not (el1.exists or el2.exists):
|
||||||
print("当前页面不是直播间,重启刷直播")
|
LogManager.method_error("当前页面不是直播间,重启刷直播", "直播养号", udid=udid)
|
||||||
LogManager.method_error("当前页面不是直播间,重启刷直播", "直播养号", udid=udid)
|
|
||||||
raise Exception("当前页面不是直播间")
|
raise Exception("当前页面不是直播间")
|
||||||
else:
|
else:
|
||||||
print("当前页面是直播间,继续刷直播")
|
LogManager.method_info("当前页面是直播间,继续刷直播", "直播养号", udid=udid)
|
||||||
LogManager.method_info("当前页面是直播间,继续刷直播", "直播养号", udid=udid)
|
|
||||||
|
|
||||||
# PK 直接划走
|
# PK 直接划走
|
||||||
if session(xpath='//XCUIElementTypeOther[@name="kGBLInteractionViewMatchScoreBar"]').exists:
|
if session.xpath('//XCUIElementTypeOther[@name="kGBLInteractionViewMatchScoreBar"]').exists:
|
||||||
print("✅ 当前是 PK,跳过")
|
|
||||||
LogManager.method_info("✅ 当前是 PK,跳过", "直播养号", udid=udid)
|
LogManager.method_info("✅ 当前是 PK,跳过", "直播养号", udid=udid)
|
||||||
ControlUtils.swipe_up(client)
|
ControlUtils.swipe_up(client)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 计算直播显示窗口数量(主画面+连麦小窗)
|
# 计算直播显示窗口数量(主画面+连麦小窗)
|
||||||
count = AiUtils.count_add_by_xml(session)
|
count = AiUtils.count_add_by_xml(session)
|
||||||
print(f"检测到直播显示区域窗口数:{count}")
|
LogManager.method_info(f"检测到直播显示区域窗口数:{count}", "直播养号", udid=udid)
|
||||||
|
|
||||||
if count > 1:
|
if count > 1:
|
||||||
print("❌ 多窗口(有人连麦/分屏),划走")
|
|
||||||
LogManager.method_info("❌ 多窗口(有人连麦/分屏),划走", "直播养号", udid=udid)
|
LogManager.method_info("❌ 多窗口(有人连麦/分屏),划走", "直播养号", udid=udid)
|
||||||
ControlUtils.swipe_up(client)
|
ControlUtils.swipe_up(client)
|
||||||
continue
|
continue
|
||||||
else:
|
|
||||||
print("✅ 单窗口,(10%概率)开始点赞")
|
|
||||||
LogManager.method_info("✅ 单窗口,(3%概率)开始点赞", "直播养号", udid=udid)
|
|
||||||
|
|
||||||
# 随机点赞(仍保留中途保护)
|
# 随机点赞:约 3% 概率触发
|
||||||
if random.random() >= 0.97:
|
if random.random() >= 0.97:
|
||||||
print("开始点赞")
|
LogManager.method_info("✅ 单窗口,开始随机点赞", "直播养号", udid=udid)
|
||||||
LogManager.method_info("开始点赞", "直播养号", udid=udid)
|
like_times = random.randint(10, 30)
|
||||||
for _ in range(random.randint(10, 30)):
|
for _ in range(like_times):
|
||||||
|
if event.is_set():
|
||||||
|
break
|
||||||
|
|
||||||
# 中途转PK/连麦立即跳过
|
# 中途转PK/连麦立即跳过
|
||||||
if session(xpath='//XCUIElementTypeOther[@name="kGBLInteractionViewMatchScoreBar"]').exists \
|
is_pk = session.xpath(
|
||||||
or AiUtils.count_add_by_xml(session) > 1:
|
'//XCUIElementTypeOther[@name="kGBLInteractionViewMatchScoreBar"]').exists
|
||||||
print("❗ 中途发生 PK/连麦,跳过")
|
multi = AiUtils.count_add_by_xml(session) > 1
|
||||||
|
if is_pk or multi:
|
||||||
LogManager.method_info("❗ 中途发生 PK/连麦,跳过", "直播养号", udid=udid)
|
LogManager.method_info("❗ 中途发生 PK/连麦,跳过", "直播养号", udid=udid)
|
||||||
ControlUtils.swipe_up(client)
|
ControlUtils.swipe_up(client)
|
||||||
break
|
break
|
||||||
|
|
||||||
x = width // 3 + random.randint(-10, 10)
|
x = width // 3 + random.randint(-10, 10)
|
||||||
y = height // 3 + random.randint(10, 20)
|
y = height // 3 + random.randint(10, 20)
|
||||||
print("双击坐标:", x, y)
|
|
||||||
|
|
||||||
session.double_tap(x, y)
|
session.double_tap(x, y)
|
||||||
|
event.wait(timeout=random.uniform(0.3, 0.8))
|
||||||
|
|
||||||
print("--------------------------------------------")
|
# 停留观看 5~10 分钟
|
||||||
# 换成
|
|
||||||
total_seconds = random.randint(300, 600)
|
total_seconds = random.randint(300, 600)
|
||||||
for _ in range(total_seconds): # 0.2 秒一片
|
for _ in range(total_seconds):
|
||||||
if event.is_set():
|
if event.is_set():
|
||||||
break
|
break
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
|
|
||||||
|
# 下一场
|
||||||
ControlUtils.swipe_up(client)
|
ControlUtils.swipe_up(client)
|
||||||
|
|
||||||
# 正常退出(外部 event 触发)
|
# 正常退出(外部 event 触发)
|
||||||
@@ -428,20 +473,35 @@ class ScriptManager():
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
retry_count += 1
|
retry_count += 1
|
||||||
LogManager.method_error(f"watchLiveForGrowth 异常(第{retry_count}次):{repr(e)}", "直播养号", udid)
|
LogManager.method_error(
|
||||||
# 尝试轻量恢复一次,避免一些短暂性 session 失效
|
f"watchLiveForGrowth 异常(第{retry_count}次):{repr(e)}",
|
||||||
try:
|
"直播养号",
|
||||||
client = wda.USBClient(udid, ev.wdaFunctionPort)
|
udid
|
||||||
_ = client.session()
|
)
|
||||||
except Exception:
|
|
||||||
pass
|
# 达到最大重试次数则退出(如果你传了 max_retries)
|
||||||
# 冷却后整段流程重来
|
if max_retries is not None and retry_count >= max_retries:
|
||||||
for _ in range(backoff_sec): # 0.2 秒一片
|
LogManager.method_error("达到最大重试次数,结束直播养号", "直播养号", udid)
|
||||||
|
break
|
||||||
|
|
||||||
|
# 冷却后整段流程重来(外层 while 会重建 session)
|
||||||
|
for _ in range(backoff_sec):
|
||||||
if event.is_set():
|
if event.is_set():
|
||||||
break
|
break
|
||||||
event.wait(timeout=1)
|
event.wait(timeout=1)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# 尽量释放 session(不同wda版本不一定有close)
|
||||||
|
try:
|
||||||
|
if session is not None:
|
||||||
|
session.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
finally:
|
||||||
|
lock.release()
|
||||||
|
|
||||||
"""
|
"""
|
||||||
外层包装,出现异常自动重试、
|
外层包装,出现异常自动重试、
|
||||||
关注打招呼以及回复主播消息
|
关注打招呼以及回复主播消息
|
||||||
|
|||||||
Reference in New Issue
Block a user