Compare commits

...

31 commits

Author SHA1 Message Date
e64295fa22 Merge branch 'main' of https://git.zhaozuohong.vip/mower-ng/mower-ng
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-08 00:39:24 +08:00
0e853f68a5 减慢填free的滑动速度 2024-12-08 00:39:09 +08:00
0dd1c28a2a 减少多余back回主页的发生 2024-12-08 00:33:28 +08:00
d7a949ad54 保全自动代理 2024-12-07 23:46:23 +08:00
ee7eda936a number匹配优化 2024-12-07 23:16:07 +08:00
c517e512a8 scrcpy kill_server
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 22:43:16 +08:00
36ed947ee4 add:保全代理元素与场景 2024-12-07 21:12:08 +08:00
bd3d83851e requirements.txt
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 20:15:08 +08:00
183898e5ea 修改swipe_update参数
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 20:11:39 +08:00
85c40dd426 允许不保存截图
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 19:43:15 +08:00
3c5c02e441 scrcpy启动应用
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 19:25:53 +08:00
ffc36ec2d2 av依赖 2024-12-07 19:18:06 +08:00
228270d9c5 前端收到截图前显示黑屏
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 19:03:41 +08:00
d07fb4f865 scrcpy virtual display 2024-12-07 19:00:44 +08:00
97b66d57ef 头像同名trap_去重
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 16:13:05 +08:00
7ec0694151 fix:第一段滑动参数写错
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 15:22:13 +08:00
7a06e924bc 读取作业适配旧type
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 15:09:03 +08:00
fe79e9ac1d rapidocr修正结果 2024-12-07 15:07:54 +08:00
7924e339ef skill_ready增加横向范围 2024-12-07 15:06:55 +08:00
429184dda7 get_pos限制范围 2024-12-07 15:06:06 +08:00
570bc19381 识别保全关卡改为ocr 2024-12-07 15:04:59 +08:00
904153b2ad 作业方向小写转大写 2024-12-07 15:04:24 +08:00
bbfdd005d5 保全战斗前增调装置适配新ui,去掉不必要的sleep 2024-12-07 15:03:34 +08:00
389c1834b4 前端显示截图
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-07 10:27:10 +08:00
28243b0e1f 读取conf时修正不对的Literal类型
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-06 22:01:57 +08:00
b27187cc57 swipe_update改进
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-06 19:08:27 +08:00
f59277a4ee mumuipc触控优化(选人不行,别用)
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-06 18:58:07 +08:00
30afa2f919 scrcpy内置0.1s延时
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-06 18:49:26 +08:00
0f36631d86 swipe_update修复
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-06 17:11:04 +08:00
d63942efa2 fix:判断战斗选人s滑动是否停下
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-06 01:39:40 +08:00
381a133a5a 右滑最后向上滑一下&fix:判断滑动是否结束
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
2024-12-06 00:52:58 +08:00
57 changed files with 605 additions and 704 deletions

View file

@ -508,7 +508,10 @@ class Arknights数据处理器:
mask = full.copy()
name_list = []
i = 0
trap_list = []
for filename in file_list:
if filename == "char_017_huang2.png":
continue
x = (i % col) * w
y = (i // col) * h
mx, my = sa(scope, (x, y))
@ -517,6 +520,10 @@ class Arknights数据处理器:
# j: char_285_medic2
# k: Lancet-2
if filename.startswith(j):
if filename.startswith("trap_"):
if k in trap_list:
break
trap_list.append(k)
img = loadimg(os.path.join(data_path, filename), True)
if img.shape != (h, w):
img = cv2.resize(img, (w, h))

View file

@ -615,6 +615,10 @@
"label": "SSS_CHOOSE_EC",
"comment": "选择定向元件"
},
"1019": {
"label": "SSS_ELIMI_AGENCY",
"comment": "保全扫荡确认"
},
"1101": {
"label": "SF_ENTRANCE",
"comment": "隐秘战线入口"

BIN
mower/resources/sss/ope/elimi_agency_on.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
mower/resources/sss/ope/prts.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
mower/resources/sss/ope/use.png (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -831,9 +831,9 @@ class BaseSchedulerSolver(SceneGraphSolver, BaseMixin):
if error_count > 3:
raise e
error_count += 1
self.back()
self.cback(3)
continue
self.back()
self.cback(3)
plan = self.op_data.plan
fix_plan = {}
for key in plan:
@ -1946,7 +1946,9 @@ class BaseSchedulerSolver(SceneGraphSolver, BaseMixin):
else:
st = ret[-2][1][0] # 起点
ed = ret[0][1][0] # 终点
self.swipe_noinertia(st, (ed[0] - st[0], 0), interval=1)
self.swipe_noinertia(
st, (ed[0] - st[0], 0), duration=400, interval=1
)
while self.find("confirm_blue"):
self.tap("confirm_blue")

View file

@ -62,7 +62,7 @@ class BattleAgentChooseSolver(SceneGraphSolver):
f"tmp_swipe:{self.tmp_swipe[-1][1][0][0]}, {agents[-1][1][0][0]}"
)
if self.tmp_swipe[-1][0] == agents[-1][0]:
if abs(self.tmp_swipe[-1][1][0][0] - agents[-1][1][0][0]) > 30:
if self.tmp_swipe[-1][1][0][0] != agents[-1][1][0][0]:
self.tmp_swipe = agents
return
self.tmp_swipe = None
@ -121,13 +121,14 @@ class BattleAgentChooseSolver(SceneGraphSolver):
# 右滑
self.before_swipe = agents
self.tmp_swipe = self.swipe_update(
self.swipe_update(
[(1000, 540), (-2500, 0)],
[600],
self.interval,
interval=self.interval,
func=operator_team_select,
)
self.tmp_swipe = operator_team_select(config.recog.img)
logger.debug(f"右滑 {self.before_swipe},{self.tmp_swipe}")
if self.tmp_swipe:
if self.tmp_swipe[-1][0] == self.before_swipe[-1][0]:

View file

@ -148,7 +148,7 @@ class FightMixin:
def toggle_speed(self):
target = 1 if self.speed == 2 else 2
logger.info(f"切换至{target}倍速")
config.device.tap((1650, 80))
self.tap((1650, 80))
self.speed = target
self.complete_action()
@ -243,7 +243,7 @@ class FightMixin:
"选中干员"
pos = self.calc.get_character_screen_pos(x, y, False, False)
pos = int(pos.x), int(pos.y)
config.device.tap(pos)
self.tap(pos)
def withdraw(self):
"撤下干员"
@ -261,7 +261,7 @@ class FightMixin:
self.Bullet_Time = False
pos = self.calc.get_with_draw_screen_pos(x, y)
pos = int(pos.x), int(pos.y)
config.device.tap(pos)
self.tap(pos)
self.sleep(0.5)
self.clear_op()
self.complete_action()
@ -360,7 +360,7 @@ class FightMixin:
width = right - left
height = bottom - top
logger.debug(f"{width=} {height=}")
return width < 900 and height < 850
return width < 950 and height < 850
except Exception as e:
logger.exception(e)
return False
@ -400,7 +400,7 @@ class FightMixin:
skill_ready = loadres("fight/skill_ready", True)
pos = self.calc.get_character_screen_pos(x, y, False, False)
pos = int(pos.x), int(pos.y)
img = cropimg(config.recog.gray, sa(((-15, -168), (20, -118)), pos))
img = cropimg(config.recog.gray, sa(((-25, -168), (25, -118)), pos))
mask = np.ones_like(skill_ready, dtype=np.float32)
mask[8:17, :] = 0.3
result = cv2.matchTemplate(
@ -457,7 +457,7 @@ class FightMixin:
else:
dir = (0, 400)
dir = va(pos, dir)
self.swipe_ext([start, pos], [config.conf.first_swipe_duration], 100, 0)
self.swipe_ext([start, pos], [config.conf.first_swipe_duration], 100, 0.05)
if direction == "None":
self.clear_op()
self.location[(x, y)] = name

View file

@ -10,7 +10,7 @@ from mower.solvers.infra.riic_tag_choose import RIICTagChoose
from mower.utils import config
from mower.utils.character_recognize import operator_room_select
from mower.utils.graph.utils import SceneGraphSolver
from mower.utils.image import cropimg
from mower.utils.image import cropimg, diff_ratio
from mower.utils.log import logger
from mower.utils.scene import Scene
@ -25,6 +25,7 @@ class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
agents (list): 选人名单
wait_time (float, optional): 选人完成到按确定的时间
"""
logger.info(f"安排干员:{agents}")
self.agents = agents
self.room = room
self.wait_time = wait_time
@ -40,6 +41,9 @@ class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
self.tap_time = datetime.now()
self.tmp_swipe = None
self.recog_agents = None
self.before = None
self.solver_update_before_transition = True
self.choosed = []
logger.debug(f"待选名单:{self.agents}")
@ -60,38 +64,39 @@ class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
"""
self.agent = [self.agents_copy.pop(0), False, False]
logger.info(f"开始选择干员:{self.agent[0]}")
else:
if self.wait_time > 0:
self.sleep(self.check_wait_time())
self.success = True
self.tap("confirm_blue")
return
if self.before is not None:
self.sleep(0.1)
if diff_ratio(self.before, config.recog.gray):
logger.debug("滑动还在继续")
self.before = config.recog.gray
self.recog_agents = None
return
self.before = None
agents = operator_room_select(config.recog.img)
agents_dict = dict(agents)
if self.recog_agents is None:
self.recog_agents = dict(operator_room_select(config.recog.img))
if len(self.agents) > 1:
for i in agents_dict:
if self.is_choosed(agents_dict[i]) and agents_dict[i][0][0] < 1600:
for i in self.recog_agents:
if (
self.is_choosed(self.recog_agents[i])
and self.recog_agents[i][0][0] < 1600
):
if i not in self.agents and i not in self.choosed:
logger.info(f"存在错选 {i}")
self.tap("choose_agent/clear", interval=self.interval)
self.agents_copy = deepcopy(self.agents)
self.choosed = []
self.recog_agents = None
self.agent = None
return
if self.tmp_swipe:
logger.debug(
f"tmp_swipe:{self.tmp_swipe[-1][1][0][0]}, {agents[-1][1][0][0]}"
)
if self.tmp_swipe[-1][0] == agents[-1][0]:
if abs(self.tmp_swipe[-1][1][0][0] - agents[-1][1][0][0]) > 30:
self.tmp_swipe = agents
return
self.tmp_swipe = None
agent_name = self.agent[0]
if agent_name == "Free":
@ -99,20 +104,28 @@ class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
self.agent = None
return
if agent_name in agents_dict.keys():
is_choosed = self.is_choosed(agents_dict[agent_name])
logger.debug(f"{agent_name} 是否被选上:{is_choosed}")
if agent_name in self.recog_agents.keys():
is_choosed = self.is_choosed(self.recog_agents[agent_name])
if is_choosed:
logger.info(f"{agent_name}选择完成")
self.recog_agents = None
self.choosed.append(agent_name)
self.agent = None
else:
if agents_dict[agent_name][0][0] > 1650:
self.swipe_noinertia((1000, 540), (-500, 0), interval=0.5)
if self.recog_agents[agent_name][0][0] > 1650:
logger.debug(f"滑动调整位置 {self.recog_agents[agent_name]}")
self.swipe_update(
[(700, 770), (400, 770), (400, 500)],
[200, 200],
up_wait=200,
interval=0.2,
)
self.recog_agents = None
return
logger.debug(f"tap {agent_name} ")
self.ctap(agents_dict[agent_name], 2, self.interval, agent_name)
self.ctap(self.recog_agents[agent_name], 5, self.interval, agent_name)
self.recog_agents = None
return
logger.debug(f"选tag和左滑 {self.agent}")
@ -123,39 +136,42 @@ class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
if RIICTagChoose().run(tag):
self.agent[1] = True
self.recog_agents = None
return
if self.agent[2] is False:
if self.tmp_left is None:
self.tmp_left = list(agents_dict.keys())[0]
self.swipe_noinertia((1000, 540), (300, 0), interval=0.5)
return
elif self.tmp_left != list(agents_dict.keys())[0]:
self.swipe_noinertia((1000, 540), (1000, 0), interval=0.5)
self.tmp_left = list(agents_dict.keys())[0]
return
self.agent[2] = True
tmp_recog = self.swipe_update(
[(700, 770), (1600, 770), (1600, 500)],
[200, 200],
up_wait=200,
interval=0.2,
func=operator_room_select,
)
if tmp_recog[0][0] == list(self.recog_agents.keys())[0]:
self.agent[2] = True
self.recog_agents = None
return
# 右滑
self.before_swipe = agents
self.tmp_swipe = self.swipe_update(
[(1000, 540), (-2500, 0)],
[600],
self.interval,
interval=self.interval,
func=operator_room_select,
self.recog_agents = dict(
self.swipe_update(
[(1600, 770), (600, 770), (600, 900)],
[300, 500],
up_wait=200,
interval=0.2,
func=operator_room_select,
)
)
logger.debug(f"右滑 {self.before_swipe},{self.tmp_swipe}")
if self.tmp_swipe:
if self.tmp_swipe[-1][0] == self.before_swipe[-1][0]:
if self.tmp_swipe[-1][1][0][0] == self.before_swipe[-1][1][0][0]:
logger.error(RuntimeError("滑动失败"))
return True
else:
self.tmp_swipe[-1][1][0][0] != self.before_swipe[-1][1][0][0]
raise RuntimeError(f"缺少干员 {self.agent[0]}")
tmp_img = config.recog.gray
config.recog.update()
if diff_ratio(tmp_img, config.recog.gray):
if agent_name not in self.recog_agents.keys():
logger.info(f"缺少:{agent_name}")
return True
self.before = config.recog.gray
def is_choosed(self, scope) -> bool:
# logger.info(scope)
up_pt = cropimg(
config.recog.img,
[
@ -171,8 +187,9 @@ class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
[scope[0][0] + 1, scope[1][1] + 213],
],
)[0][0][0]
logger.debug(f"is_choosed: {up_pt}{down_pt}")
if (up_pt < 50) and down_pt < 50:
logger.debug(f"is_choosed: {up_pt},{down_pt}")
if up_pt < 50 and down_pt < 50:
return True
return False

View file

@ -102,7 +102,7 @@ class EnterRoomSolver(SceneGraphSolver, BaseMixin):
super().run()
def timeout(self) -> bool:
return datetime.now() > self.start_time + timedelta(seconds=3)
return datetime.now() > self.start_time + timedelta(seconds=5)
def bug_timeout(self) -> bool:
return datetime.now() > self.avoid_bug_start_time + timedelta(seconds=60)
@ -147,8 +147,8 @@ class EnterRoomSolver(SceneGraphSolver, BaseMixin):
elif scene in [Scene.CTRLCENTER_ASSISTANT, Scene.INFRA_DETAILS]:
if self.detect_room() == self.room:
if not self.detail:
self.tap((960, 540), interval=0)
if not self.detail and self.find("arrange_check_in_on"):
self.tap((960, 540))
return True
if self.find("room_detail"):
return True

View file

@ -65,9 +65,8 @@ class GetAgentFromRoomSolver(SceneGraphSolver, BaseMixin):
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
img = cv2.bitwise_not(img)
return (
config.recog.num.number_int("riic_base", img=img, target_range=range(1, 6))
+ 1
return config.recog.num.number_int(
"riic_base", img=img, target_range=range(1, 6)
)
@staticmethod

View file

@ -83,7 +83,7 @@ class ReclamationAlgorithm(SceneGraphSolver):
def tap_loop(self, pos):
while not self.event.is_set():
config.device.tap(pos)
self.tap(pos)
def fast_tap(self, pos):
self.event.clear()

View file

@ -1,18 +1,17 @@
from datetime import datetime, timedelta
import cv2
from mower.utils import config
from mower.utils.email import send_message
from mower.utils.generate_image import generate_image
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg
from mower.utils.log import logger
from mower.utils.rapidocr import ocr_rec
from mower.utils.recognize import Scene
from .sss_choose import SSSChooseSolver
from .sss_fight import SSSFightSolver
from .sss_navi import SSSNaviSolver
from .sss_ope import SSSOpeSolver
from .utils import is_full
@ -41,16 +40,9 @@ class SSSSolver(SceneGraphSolver):
self.stages[stage_name] = stage
def detect_stage(self):
for stage in self.stages:
stage_name_size = 40 if len(stage) < 6 else 34
res = generate_image(stage, stage_name_size)
img = cropimg(config.recog.gray, ((180, 400), (420, 480)))
result = cv2.matchTemplate(img, res, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
logger.debug(f"stage:{stage},max_val:{max_val}")
if max_val > 0.85:
return stage
return None
img = cropimg(config.recog.img, ((180, 400), (420, 480)))
res = ocr_rec(img)
return res
def transition(self):
if self.deadline and self.deadline < datetime.now():
@ -76,7 +68,13 @@ class SSSSolver(SceneGraphSolver):
send_message("保全模组条与仪已刷满", level="WARNING")
self.full = True
return True
elif (
scene == Scene.SSS_START
and config.conf.sss.finish_while_full
and self.find("sss/ope/prts")
):
self.full = SSSOpeSolver().run()
return self.full
elif scene == Scene.SSS_DROP_AGENT_BEFORE_FIGHT:
self.scene_graph_step(Scene.SSS_DEPLOY)

View file

@ -10,6 +10,7 @@ from mower.utils.generate_image import generate_image
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, loadres, thres2
from mower.utils.log import logger
from mower.utils.rapidocr import ocr_rec
from mower.utils.recognize import Scene
from mower.utils.vector import ss, va
@ -109,12 +110,10 @@ class SSSDROPSolver(SceneGraphSolver):
for drop in self.drops:
if drop in opers:
self.tap(opers[drop])
self.sleep(0.5)
self.choose = True
return
if len(opers):
self.tap(opers.popitem()[1])
self.sleep(0.5)
self.choose = True
return
@ -123,13 +122,11 @@ class SSSDROPSolver(SceneGraphSolver):
if drop not in agent:
if pos := self.find_EC(drop, 29, ((510, 700), (1480, 770))):
self.tap(pos)
self.sleep(0.5)
self.tap((1750, 550))
return
else:
if pos := self.find_PR_in_fight(drop, ((468, 735), (1321, 797))):
self.tap(pos)
self.sleep(0.5)
self.tap((1750, 550))
return
self.tap("sss/abandon")
@ -142,13 +139,15 @@ class SSSDROPSolver(SceneGraphSolver):
self.tap((1794, 900))
return
else:
ec_pos = [((470, 400), (800, 450)), ((1200, 400), (1530, 450))]
res = {}
for pos in ec_pos:
img = cropimg(config.recog.img, pos)
res[ocr_rec(img)] = pos
for drop in self.drops:
if drop not in agent:
if pos := self.find_EC(drop, 30, ((640, 630), (1280, 700))):
self.tap(pos)
self.sleep(0.5)
self.choose = True
return
if drop in res:
self.tap(res[drop])
self.choose = True
elif scene == Scene.SSS_ABANDON_DROP_IN_FIGHT:
self.scene_graph_step(Scene.OPERATOR_FIGHT)

View file

@ -77,6 +77,9 @@ class SSSNaviSolver(SceneGraphSolver):
elif self.mode == "ex" and self.find("sss/switch_to_ex"):
self.tap("sss/switch_to_ex")
return
if config.conf.sss.finish_while_full and self.find("sss/ope/prts"):
return True
self.tap((1555, 966))
elif scene == Scene.SSS_CHOOSE_EC:
for scope in ec_pos:

View file

@ -0,0 +1,48 @@
from mower.utils import config
from mower.utils.graph import SceneGraphSolver
from mower.utils.recognize import Scene
from .utils import is_full
class SSSOpeSolver(SceneGraphSolver):
solver_name = "保全代理"
def run(self) -> bool:
self.success = False # 是否刷满
self.check = False # 是否可代理层数小于设置要求
super().run()
return self.success
def transition(self):
if (scene := self.scene()) == Scene.SSS_START:
if self.find("sss/ope/prts") and not self.check:
self.tap("sss/ope/prts")
return
elif self.find("sss/ope/elimi_agency_on") and self.check:
self.tap("sss/ope/elimi_agency_on")
return
self.tap((1555, 966))
elif scene in [Scene.SSS_EC, Scene.SSS_EC_EX] and self.check:
return True
elif scene == Scene.SSS_ELIMI_AGENCY:
if is_full():
self.success = True
return True
if (
config.recog.num.number_int(
"riic_base",
((1750, 50), (1850, 150)),
50,
120,
target_range=range(1, 7),
)
< config.conf.sss.ope_limit_stage
):
self.scene_graph_step(Scene.SSS_START)
self.check = True
return
self.tap("sss/ope/use")
else:
self.scene_graph_step(Scene.SSS_START)

View file

@ -9,8 +9,8 @@ def number(scope: tp.Scope, height: int, thres: int) -> int:
def is_full() -> bool:
"判断模块增补仪和条是否刷满"
if number(((150, 975), (300, 1030)), 50, 120) != 60:
if number(((150, 975), (300, 1030)), 50, 100) != 60:
return False
if number(((530, 975), (680, 1030)), 50, 120) != 24:
if number(((530, 975), (680, 1030)), 50, 100) != 24:
return False
return True

BIN
mower/static/avatar.pkl (Stored with Git LFS)

Binary file not shown.

View file

@ -110,7 +110,7 @@ operators = {}
# 日志
log_queue = Queue()
wh = None
sc_queue = Queue()
screenshot_time: datetime = datetime.now() - timedelta(
milliseconds=conf.screenshot_interval

View file

@ -1,4 +1,4 @@
from typing import Literal
from typing import Literal, get_args, get_origin
from pydantic import BaseModel, model_validator
from pydantic_core import PydanticUndefined
@ -14,6 +14,30 @@ class ConfModel(BaseModel):
data[name] = field.annotation()
else:
data[name] = field.default
else:
value = data[name]
expected_type = field.annotation
# 处理嵌套的 BaseModel
if isinstance(field.annotation, type) and issubclass(
field.annotation, BaseModel
):
if not isinstance(value, dict): # 确保嵌套类型为字典
value = {}
# 递归调用嵌套模型的验证器
data[name] = field.annotation(**value)
# 检查 Literal 类型并修正
elif get_origin(expected_type) is Literal:
valid_literals = get_args(expected_type)
if value not in valid_literals:
# 修正为默认值
data[name] = (
field.default
if field.default is not PydanticUndefined
else None
)
return data
@ -197,10 +221,12 @@ class LongTaskPart(ConfModel):
class SSSConf(ConfModel):
choose_agent: bool = True
"自动编队"
mode: str = "normal"
mode: Literal["normal", "ex"] = "normal"
"难度:正常为normal,应急为ex"
finish_while_full: bool = True
"模组刷满时直接结束"
ope_limit_stage: int = 6
"使用代理卡最低层数要求"
maa_rg_enable: int = 0
"大型任务"
@ -385,7 +411,7 @@ class EmulatorPart(ConfModel):
"截图方案"
control_strategy: Literal["scrcpy", "mumuipc"] = "scrcpy"
"触控方案"
app_control_strategy: Literal["adb", "mumumanager"] = "adb"
app_control_strategy: Literal["adb", "mumumanager", "scrcpy"] = "adb"
"应用控制方案"

View file

@ -46,6 +46,7 @@ class Action(BaseModel):
"MoveCamera",
"调配干员",
"CheckIfStartOver",
"GetDrops",
] = "Deploy"
name: Optional[str] = None
costs: Optional[int] = None

View file

@ -69,11 +69,6 @@ class Device:
logger.debug(keycode)
self.control.send_keyevent(keycode)
def send_text(self, text: str) -> None:
"""send a text"""
logger.debug(repr(text))
self.app_control.send_text(text)
def screencap(self) -> bytes:
start_time = datetime.now()
if config.conf.screencap_strategy != "scrcpy":
@ -105,14 +100,6 @@ class Device:
save_screenshot(img)
return img
def current_focus(self) -> str:
"""detect current focus app"""
return self.app_control.current_focus()
def display_frames(self) -> tuple[int, int, int]:
"""get display frames if in compatibility mode"""
return self.app_control.display_frames()
def tap(self, point: tuple[int, int]) -> None:
"""tap"""
logger.debug(point)
@ -150,7 +137,7 @@ class Device:
Any: func的返回值
"""
logger.debug(f"{points=} {durations=} {update=} {interval=} {func=}")
self.control.swipe_ext(points, durations, update, interval, func)
return self.control.swipe_ext(points, durations, update, interval, func)
def check_current_focus(self) -> bool:
"""check if the application is in the foreground"""

View file

@ -221,29 +221,12 @@ class ADB:
"am start -a android.intent.action.MAIN -c android.intent.category.HOME"
)
def send_text(self, text: str) -> None:
"""send a text"""
text = text.replace('"', '\\"')
command = f'input text "{text}"'
self.adb_shell(command)
def current_focus(self) -> str:
"""detect current focus app"""
command = "dumpsys window | grep mCurrentFocus"
line = self.adb_shell(command)
return line.strip()[:-1].split(" ")[-1]
def display_frames(self) -> tuple[int, int, int]:
"""get display frames if in compatibility mode"""
if not config.MNT_COMPATIBILITY_MODE:
return None
command = "dumpsys window | grep DisplayFrames"
line = self.adb_shell(command)
""" eg. DisplayFrames w=1920 h=1080 r=3 """
res = line.strip().replace("=", " ").split(" ")
return int(res[2]), int(res[4]), int(res[6])
def check_current_focus(self) -> bool:
"""check if the application is in the foreground"""
update = False

View file

@ -10,10 +10,12 @@ import numpy as np
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.csleep import MowerExit
from mower.utils.device import swipe_update
from mower.utils.device.emulator import restart_emulator
from mower.utils.device.exception import EmulatorError, GameError
from mower.utils.device.method.mumumanager import MuMuManager
from mower.utils.log import logger
from mower.utils.vector import sm, va
class NemuIpcIncompatible(Exception):
@ -234,7 +236,7 @@ class MuMu12IPC:
def finger_touch_down(self, finger_id: int, x: int, y: int):
self.check_status()
result = self.external_renderer.nemu_input_event_finger_touch_down(
self.connection, self.display_id, finger_id, x, y
self.connection, self.display_id, finger_id, int(1080 - y), int(x)
)
if result != 0:
self.connection = 0
@ -300,42 +302,36 @@ class MuMu12IPC:
interval (float): 滑动完成后的等待时间单位为秒默认 0
func (Callable[[np.ndarray], Any]): 截图后处理的函数默认空函数
"""
frame_time = 1 / 30 # 模拟帧率为 30 FPS
steps = max(int(duration / frame_time), 1) # 计算滑动的总步数
time_per_step = duration / steps # 每步所需时间
frame_time = 1 / 30
# 可选截图功能
if update:
initial_image = self.capture_display() # 截图
thread = threading.Thread(target=func, args=(initial_image,))
start_time = time.perf_counter()
fall and self.touch_down(x0, y0)
if update and config.recog:
thread = threading.Thread(target=swipe_update.start, args=(func,))
thread.start()
# 按下起点
if fall:
self.touch_down(x0, y0)
if (down_time := time.perf_counter()) < start_time + frame_time:
time.sleep(start_time + frame_time - down_time)
down_time = start_time + frame_time
# 滑动过程
for step in range(steps):
progress = (step + 1) / steps
x = int(x0 + (x1 - x0) * progress)
y = int(y0 + (y1 - y0) * progress)
# 确保每步保持固定帧时间
step_start = time.perf_counter()
while (progress := (time.perf_counter() - down_time) / duration) <= 1:
x, y = va(sm(1 - progress, (x0, y0)), sm(progress, (x1, y1)))
start_time = time.perf_counter()
self.touch_down(x, y)
elapsed = time.perf_counter() - step_start
if elapsed < time_per_step:
time.sleep(time_per_step - elapsed)
if (move_time := time.perf_counter() - start_time) < frame_time:
time.sleep(frame_time - move_time)
self.touch_down(x1, y1)
# 到达终点
if lift:
self.touch_up()
lift and self.touch_up()
# 等待截图线程完成
if update:
if update and config.recog:
start_time = time.perf_counter()
thread.join()
if (stop_time := time.perf_counter()) < start_time + interval:
time.sleep(start_time + interval - stop_time)
return swipe_update.result
# 滑动完成后的等待时间
if interval > 0:
time.sleep(interval)

View file

@ -1,329 +1,12 @@
"""
This module includes all consts used in this project
"""
# Action
ACTION_DOWN = 0
ACTION_UP = 1
ACTION_MOVE = 2
# KeyCode
KEYCODE_UNKNOWN = 0
KEYCODE_SOFT_LEFT = 1
KEYCODE_SOFT_RIGHT = 2
KEYCODE_HOME = 3
KEYCODE_BACK = 4
KEYCODE_CALL = 5
KEYCODE_ENDCALL = 6
KEYCODE_0 = 7
KEYCODE_1 = 8
KEYCODE_2 = 9
KEYCODE_3 = 10
KEYCODE_4 = 11
KEYCODE_5 = 12
KEYCODE_6 = 13
KEYCODE_7 = 14
KEYCODE_8 = 15
KEYCODE_9 = 16
KEYCODE_STAR = 17
KEYCODE_POUND = 18
KEYCODE_DPAD_UP = 19
KEYCODE_DPAD_DOWN = 20
KEYCODE_DPAD_LEFT = 21
KEYCODE_DPAD_RIGHT = 22
KEYCODE_DPAD_CENTER = 23
KEYCODE_VOLUME_UP = 24
KEYCODE_VOLUME_DOWN = 25
KEYCODE_POWER = 26
KEYCODE_CAMERA = 27
KEYCODE_CLEAR = 28
KEYCODE_A = 29
KEYCODE_B = 30
KEYCODE_C = 31
KEYCODE_D = 32
KEYCODE_E = 33
KEYCODE_F = 34
KEYCODE_G = 35
KEYCODE_H = 36
KEYCODE_I = 37
KEYCODE_J = 38
KEYCODE_K = 39
KEYCODE_L = 40
KEYCODE_M = 41
KEYCODE_N = 42
KEYCODE_O = 43
KEYCODE_P = 44
KEYCODE_Q = 45
KEYCODE_R = 46
KEYCODE_S = 47
KEYCODE_T = 48
KEYCODE_U = 49
KEYCODE_V = 50
KEYCODE_W = 51
KEYCODE_X = 52
KEYCODE_Y = 53
KEYCODE_Z = 54
KEYCODE_COMMA = 55
KEYCODE_PERIOD = 56
KEYCODE_ALT_LEFT = 57
KEYCODE_ALT_RIGHT = 58
KEYCODE_SHIFT_LEFT = 59
KEYCODE_SHIFT_RIGHT = 60
KEYCODE_TAB = 61
KEYCODE_SPACE = 62
KEYCODE_SYM = 63
KEYCODE_EXPLORER = 64
KEYCODE_ENVELOPE = 65
KEYCODE_ENTER = 66
KEYCODE_DEL = 67
KEYCODE_GRAVE = 68
KEYCODE_MINUS = 69
KEYCODE_EQUALS = 70
KEYCODE_LEFT_BRACKET = 71
KEYCODE_RIGHT_BRACKET = 72
KEYCODE_BACKSLASH = 73
KEYCODE_SEMICOLON = 74
KEYCODE_APOSTROPHE = 75
KEYCODE_SLASH = 76
KEYCODE_AT = 77
KEYCODE_NUM = 78
KEYCODE_HEADSETHOOK = 79
KEYCODE_PLUS = 81
KEYCODE_MENU = 82
KEYCODE_NOTIFICATION = 83
KEYCODE_SEARCH = 84
KEYCODE_MEDIA_PLAY_PAUSE = 85
KEYCODE_MEDIA_STOP = 86
KEYCODE_MEDIA_NEXT = 87
KEYCODE_MEDIA_PREVIOUS = 88
KEYCODE_MEDIA_REWIND = 89
KEYCODE_MEDIA_FAST_FORWARD = 90
KEYCODE_MUTE = 91
KEYCODE_PAGE_UP = 92
KEYCODE_PAGE_DOWN = 93
KEYCODE_BUTTON_A = 96
KEYCODE_BUTTON_B = 97
KEYCODE_BUTTON_C = 98
KEYCODE_BUTTON_X = 99
KEYCODE_BUTTON_Y = 100
KEYCODE_BUTTON_Z = 101
KEYCODE_BUTTON_L1 = 102
KEYCODE_BUTTON_R1 = 103
KEYCODE_BUTTON_L2 = 104
KEYCODE_BUTTON_R2 = 105
KEYCODE_BUTTON_THUMBL = 106
KEYCODE_BUTTON_THUMBR = 107
KEYCODE_BUTTON_START = 108
KEYCODE_BUTTON_SELECT = 109
KEYCODE_BUTTON_MODE = 110
KEYCODE_ESCAPE = 111
KEYCODE_FORWARD_DEL = 112
KEYCODE_CTRL_LEFT = 113
KEYCODE_CTRL_RIGHT = 114
KEYCODE_CAPS_LOCK = 115
KEYCODE_SCROLL_LOCK = 116
KEYCODE_META_LEFT = 117
KEYCODE_META_RIGHT = 118
KEYCODE_FUNCTION = 119
KEYCODE_SYSRQ = 120
KEYCODE_BREAK = 121
KEYCODE_MOVE_HOME = 122
KEYCODE_MOVE_END = 123
KEYCODE_INSERT = 124
KEYCODE_FORWARD = 125
KEYCODE_MEDIA_PLAY = 126
KEYCODE_MEDIA_PAUSE = 127
KEYCODE_MEDIA_CLOSE = 128
KEYCODE_MEDIA_EJECT = 129
KEYCODE_MEDIA_RECORD = 130
KEYCODE_F1 = 131
KEYCODE_F2 = 132
KEYCODE_F3 = 133
KEYCODE_F4 = 134
KEYCODE_F5 = 135
KEYCODE_F6 = 136
KEYCODE_F7 = 137
KEYCODE_F8 = 138
KEYCODE_F9 = 139
KEYCODE_F10 = 140
KEYCODE_F11 = 141
KEYCODE_F12 = 142
KEYCODE_NUM_LOCK = 143
KEYCODE_NUMPAD_0 = 144
KEYCODE_NUMPAD_1 = 145
KEYCODE_NUMPAD_2 = 146
KEYCODE_NUMPAD_3 = 147
KEYCODE_NUMPAD_4 = 148
KEYCODE_NUMPAD_5 = 149
KEYCODE_NUMPAD_6 = 150
KEYCODE_NUMPAD_7 = 151
KEYCODE_NUMPAD_8 = 152
KEYCODE_NUMPAD_9 = 153
KEYCODE_NUMPAD_DIVIDE = 154
KEYCODE_NUMPAD_MULTIPLY = 155
KEYCODE_NUMPAD_SUBTRACT = 156
KEYCODE_NUMPAD_ADD = 157
KEYCODE_NUMPAD_DOT = 158
KEYCODE_NUMPAD_COMMA = 159
KEYCODE_NUMPAD_ENTER = 160
KEYCODE_NUMPAD_EQUALS = 161
KEYCODE_NUMPAD_LEFT_PAREN = 162
KEYCODE_NUMPAD_RIGHT_PAREN = 163
KEYCODE_VOLUME_MUTE = 164
KEYCODE_INFO = 165
KEYCODE_CHANNEL_UP = 166
KEYCODE_CHANNEL_DOWN = 167
KEYCODE_ZOOM_IN = 168
KEYCODE_ZOOM_OUT = 169
KEYCODE_TV = 170
KEYCODE_WINDOW = 171
KEYCODE_GUIDE = 172
KEYCODE_DVR = 173
KEYCODE_BOOKMARK = 174
KEYCODE_CAPTIONS = 175
KEYCODE_SETTINGS = 176
KEYCODE_TV_POWER = 177
KEYCODE_TV_INPUT = 178
KEYCODE_STB_POWER = 179
KEYCODE_STB_INPUT = 180
KEYCODE_AVR_POWER = 181
KEYCODE_AVR_INPUT = 182
KEYCODE_PROG_RED = 183
KEYCODE_PROG_GREEN = 184
KEYCODE_PROG_YELLOW = 185
KEYCODE_PROG_BLUE = 186
KEYCODE_APP_SWITCH = 187
KEYCODE_BUTTON_1 = 188
KEYCODE_BUTTON_2 = 189
KEYCODE_BUTTON_3 = 190
KEYCODE_BUTTON_4 = 191
KEYCODE_BUTTON_5 = 192
KEYCODE_BUTTON_6 = 193
KEYCODE_BUTTON_7 = 194
KEYCODE_BUTTON_8 = 195
KEYCODE_BUTTON_9 = 196
KEYCODE_BUTTON_10 = 197
KEYCODE_BUTTON_11 = 198
KEYCODE_BUTTON_12 = 199
KEYCODE_BUTTON_13 = 200
KEYCODE_BUTTON_14 = 201
KEYCODE_BUTTON_15 = 202
KEYCODE_BUTTON_16 = 203
KEYCODE_LANGUAGE_SWITCH = 204
KEYCODE_MANNER_MODE = 205
KEYCODE_3D_MODE = 206
KEYCODE_CONTACTS = 207
KEYCODE_CALENDAR = 208
KEYCODE_MUSIC = 209
KEYCODE_CALCULATOR = 210
KEYCODE_ZENKAKU_HANKAKU = 211
KEYCODE_EISU = 212
KEYCODE_MUHENKAN = 213
KEYCODE_HENKAN = 214
KEYCODE_KATAKANA_HIRAGANA = 215
KEYCODE_YEN = 216
KEYCODE_RO = 217
KEYCODE_KANA = 218
KEYCODE_ASSIST = 219
KEYCODE_BRIGHTNESS_DOWN = 220
KEYCODE_BRIGHTNESS_UP = 221
KEYCODE_MEDIA_AUDIO_TRACK = 222
KEYCODE_SLEEP = 223
KEYCODE_WAKEUP = 224
KEYCODE_PAIRING = 225
KEYCODE_MEDIA_TOP_MENU = 226
KEYCODE_11 = 227
KEYCODE_12 = 228
KEYCODE_LAST_CHANNEL = 229
KEYCODE_TV_DATA_SERVICE = 230
KEYCODE_VOICE_ASSIST = 231
KEYCODE_TV_RADIO_SERVICE = 232
KEYCODE_TV_TELETEXT = 233
KEYCODE_TV_NUMBER_ENTRY = 234
KEYCODE_TV_TERRESTRIAL_ANALOG = 235
KEYCODE_TV_TERRESTRIAL_DIGITAL = 236
KEYCODE_TV_SATELLITE = 237
KEYCODE_TV_SATELLITE_BS = 238
KEYCODE_TV_SATELLITE_CS = 239
KEYCODE_TV_SATELLITE_SERVICE = 240
KEYCODE_TV_NETWORK = 241
KEYCODE_TV_ANTENNA_CABLE = 242
KEYCODE_TV_INPUT_HDMI_1 = 243
KEYCODE_TV_INPUT_HDMI_2 = 244
KEYCODE_TV_INPUT_HDMI_3 = 245
KEYCODE_TV_INPUT_HDMI_4 = 246
KEYCODE_TV_INPUT_COMPOSITE_1 = 247
KEYCODE_TV_INPUT_COMPOSITE_2 = 248
KEYCODE_TV_INPUT_COMPONENT_1 = 249
KEYCODE_TV_INPUT_COMPONENT_2 = 250
KEYCODE_TV_INPUT_VGA_1 = 251
KEYCODE_TV_AUDIO_DESCRIPTION = 252
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254
KEYCODE_TV_ZOOM_MODE = 255
KEYCODE_TV_CONTENTS_MENU = 256
KEYCODE_TV_MEDIA_CONTEXT_MENU = 257
KEYCODE_TV_TIMER_PROGRAMMING = 258
KEYCODE_HELP = 259
KEYCODE_NAVIGATE_PREVIOUS = 260
KEYCODE_NAVIGATE_NEXT = 261
KEYCODE_NAVIGATE_IN = 262
KEYCODE_NAVIGATE_OUT = 263
KEYCODE_STEM_PRIMARY = 264
KEYCODE_STEM_1 = 265
KEYCODE_STEM_2 = 266
KEYCODE_STEM_3 = 267
KEYCODE_DPAD_UP_LEFT = 268
KEYCODE_DPAD_DOWN_LEFT = 269
KEYCODE_DPAD_UP_RIGHT = 270
KEYCODE_DPAD_DOWN_RIGHT = 271
KEYCODE_MEDIA_SKIP_FORWARD = 272
KEYCODE_MEDIA_SKIP_BACKWARD = 273
KEYCODE_MEDIA_STEP_FORWARD = 274
KEYCODE_MEDIA_STEP_BACKWARD = 275
KEYCODE_SOFT_SLEEP = 276
KEYCODE_CUT = 277
KEYCODE_COPY = 278
KEYCODE_PASTE = 279
KEYCODE_SYSTEM_NAVIGATION_UP = 280
KEYCODE_SYSTEM_NAVIGATION_DOWN = 281
KEYCODE_SYSTEM_NAVIGATION_LEFT = 282
KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283
KEYCODE_KEYCODE_ALL_APPS = 284
KEYCODE_KEYCODE_REFRESH = 285
KEYCODE_KEYCODE_THUMBS_UP = 286
KEYCODE_KEYCODE_THUMBS_DOWN = 287
# Event
EVENT_INIT = "init"
EVENT_FRAME = "frame"
# Type
TYPE_INJECT_KEYCODE = 0
TYPE_INJECT_TEXT = 1
TYPE_INJECT_TOUCH_EVENT = 2
TYPE_INJECT_SCROLL_EVENT = 3
TYPE_BACK_OR_SCREEN_ON = 4
TYPE_EXPAND_NOTIFICATION_PANEL = 5
TYPE_EXPAND_SETTINGS_PANEL = 6
TYPE_COLLAPSE_PANELS = 7
TYPE_GET_CLIPBOARD = 8
TYPE_SET_CLIPBOARD = 9
TYPE_SET_SCREEN_POWER_MODE = 10
TYPE_ROTATE_DEVICE = 11
COPY_KEY_NONE = 0
COPY_KEY_COPY = 1
COPY_KEY_CUT = 2
# Lock screen orientation
LOCK_SCREEN_ORIENTATION_UNLOCKED = -1
LOCK_SCREEN_ORIENTATION_INITIAL = -2
LOCK_SCREEN_ORIENTATION_0 = 0
LOCK_SCREEN_ORIENTATION_1 = 1
LOCK_SCREEN_ORIENTATION_2 = 2
LOCK_SCREEN_ORIENTATION_3 = 3
# Screen power mode
POWER_MODE_OFF = 0
POWER_MODE_NORMAL = 2
TYPE_START_APP = 16

View file

@ -3,6 +3,8 @@ import struct
from time import sleep
from typing import TYPE_CHECKING
from mower.utils import config
from . import const
if TYPE_CHECKING:
@ -83,6 +85,12 @@ class ControlSender:
buttons,
)
@inject(const.TYPE_START_APP)
def start_app(self):
app_name = config.conf.APPNAME.encode("utf-8")
length = len(app_name)
return struct.pack(f"!B{length}s", length, app_name)
def tap(self, x, y, hold_time: float = 0.07) -> None:
"""
Tap on screen

View file

@ -1,9 +1,8 @@
from __future__ import annotations
import socket
import struct
import threading
import time
from datetime import datetime
from functools import cached_property, wraps
from queue import Queue
from typing import Any, Callable, Optional
@ -13,7 +12,8 @@ from adbutils import AdbConnection, Network
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.csleep import MowerExit
from mower.utils.csleep import MowerExit, csleep
from mower.utils.device import swipe_update
from mower.utils.device.method.adb import ADB
from mower.utils.device.method.adb.const import KeyCode
from mower.utils.log import logger
@ -27,16 +27,6 @@ SCR_PATH = "/data/local/tmp/scrcpy-server.jar"
SCR_VER = "3.0.2"
swipe_update_result = None
def recog_start(func: Callable[[tp.Image], Any] = lambda _: None):
time.sleep(0.1)
config.recog.update()
global swipe_update_result
swipe_update_result = func(config.recog.img)
def retry_scrcpy(func):
@wraps(func)
def retry_wrapper(self, *args, **kwargs):
@ -55,15 +45,12 @@ def retry_scrcpy(func):
class Client:
def __init__(self, displayid: Optional[int] = None):
def __init__(self):
# User accessible
self.last_frame: Optional[np.ndarray] = None
self.resolution = (1920, 1080)
self.control = ControlSender(self)
# Params
self.displayid = displayid
# Need to destroy
self.__server_stream: Optional[AdbConnection] = None
self.control_socket: Optional[socket.socket] = None
@ -114,13 +101,13 @@ class Client:
cmdline = f"CLASSPATH={SCR_PATH} app_process /"
cmdline += f" com.genymobile.scrcpy.Server {SCR_VER} audio=false"
cmdline += " control=true tunnel_forward=true send_device_meta=false"
if config.conf.screencap_strategy != "scrcpy":
cmdline += " video=false"
else:
if config.conf.screencap_strategy == "scrcpy":
cmdline += f" send_codec_meta=false max_fps={1000 / config.conf.screenshot_interval}"
cmdline += " video_bit_rate=128000000 video_codec=h264"
if self.displayid:
cmdline += f" display_id={self.displayid}"
if config.conf.app_control_strategy == "scrcpy":
cmdline += " new_display=1920x1080/280 vd_system_decorations=false"
else:
cmdline += " video=false"
self.__server_stream: AdbConnection = self.adb.adb_shell(cmdline, True)
# Wait for server to start
self.__server_stream.conn.settimeout(3)
@ -164,6 +151,9 @@ class Client:
else:
self.control_socket = first_socket
if config.conf.app_control_strategy == "scrcpy":
self.launch()
except socket.timeout:
raise ConnectionError("Failed to connect scrcpy-server")
@ -238,7 +228,7 @@ class Client:
fall and self.control.touch(x0, y0, const.ACTION_DOWN)
if update and config.recog:
thread = threading.Thread(target=recog_start, args=(func,))
thread = threading.Thread(target=swipe_update.start, args=(func,))
thread.start()
if (down_time := time.perf_counter()) < start_time + frame_time:
@ -260,7 +250,7 @@ class Client:
thread.join()
if (stop_time := time.perf_counter()) < start_time + interval:
time.sleep(start_time + interval - stop_time)
return swipe_update_result
return swipe_update.result
if interval > 0:
time.sleep(interval)
@ -297,3 +287,49 @@ class Client:
"""send a key event"""
logger.debug(keycode)
self.control.send_keyevent(keycode)
@retry_scrcpy
def launch(self):
self.control.start_app()
@retry_scrcpy
def exit(self):
self.adb.exit()
@retry_scrcpy
def home(self):
self.adb.exit()
@retry_scrcpy
def check_device_screen(self):
return True
@retry_scrcpy
def check_current_focus(self) -> bool:
"""check if the application is in the foreground"""
update = False
start_time = datetime.now()
while True:
try:
focus = self.adb.adb_shell("dumpsys window | grep Window")
if (
f"{config.conf.APPNAME}/{config.APP_ACTIVITY_NAME}" not in focus
and "com.hypergryph.arknights.bilibili/com.gsc.welcome.WelcomeActivity"
not in focus
):
if (datetime.now() - start_time).total_seconds() > 40:
self.exit() # 应用卡死
start_time = datetime.now()
self.launch()
update = True
csleep(1)
continue
return update
except MowerExit:
raise
except Exception as e:
logger.exception(e)
update = True
def kill_server(self):
self.adb.kill_server()

View file

@ -0,0 +1,17 @@
import time
from typing import Any, Callable
from mower.utils import config
from mower.utils import typealias as tp
result = None
def start(func: Callable[[tp.Image], Any] = lambda _: None):
if config.conf.screencap_strategy == "scrcpy":
time.sleep(config.conf.screenshot_interval / 500)
else:
time.sleep(0.1)
config.recog.update()
global result
result = func(config.recog.img)

View file

@ -24,15 +24,25 @@ def enter_sss(solver: BaseSolver):
@edge(Scene.SSS_DEPLOY, Scene.SSS_MAIN)
@edge(Scene.SSS_REDEPLOY, Scene.SSS_MAIN)
@edge(Scene.SSS_CHOOSE_EC, Scene.SSS_MAIN)
@edge(Scene.SSS_ELIMI_AGENCY, Scene.SSS_MAIN)
@edge(Scene.SSS_EC, Scene.SSS_EXIT_CONFIRM)
@edge(Scene.SSS_DEVICE, Scene.SSS_EXIT_CONFIRM)
@edge(Scene.SSS_OPERATION_COMPLETE, Scene.SSS_DEPLOY)
@edge(Scene.SSS_SQUAD, Scene.SSS_EXIT_CONFIRM)
@edge(Scene.SSS_TERMINATED, Scene.SSS_START)
def sss_back(solver: BaseSolver):
solver.back()
@edge(Scene.SSS_TERMINATED, Scene.SSS_START)
def sss_terminated(solver: BaseSolver):
solver.tap((960, 540))
@edge(Scene.SSS_ELIMI_AGENCY, Scene.SSS_START)
def sss_elimi_agency(solver: BaseSolver):
solver.tap((1500, 1000))
@edge(Scene.SSS_ABANDON_DROP_IN_FIGHT, Scene.OPERATOR_FIGHT)
@edge(Scene.SSS_EXIT_CONFIRM, Scene.SSS_TERMINATED)
def sss_exit(solver: BaseSolver):

View file

@ -136,4 +136,6 @@ Thread(target=screenshot_worker, daemon=True).start()
def save_screenshot(img: tp.Image) -> None:
filename = f"{time.time_ns()}.jpg"
logger.debug(filename)
screenshot_queue.put((img, filename))
if config.conf.screenshot > 0:
screenshot_queue.put((img, filename))
config.sc_queue.put(img)

View file

@ -63,13 +63,13 @@ class NumberRecognizer:
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
score = {}
for i in target_range:
im = templates[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value += str(score.index(min(score)))
score[min_val] = i
value += str(score[(min(score))])
return value

View file

@ -8,9 +8,12 @@ engine = RapidOCR(text_score=0.3)
logger.info("OCR加载完成")
replacement = {"酪酊之旅": "酩酊之旅"}
def ocr_rec(img: tp.Image | tp.GrayImage) -> str | None:
result, elapse = engine(img, use_det=False, use_cls=False, use_rec=True)
elapse = round(elapse[0] * 1000)
text = result[0][0].strip()
logger.debug(f"{elapse}ms {text}")
return text
return text if text not in replacement else replacement[text]

View file

@ -311,6 +311,8 @@ class Recognizer:
self.scene = Scene.SSS_ACTION
elif self.find("sss/accomplished"):
self.scene = Scene.SSS_ACCOMPLISHED
elif self.find("sss/ope/use"):
self.scene = Scene.SSS_ELIMI_AGENCY
elif self.find("login_captcha"):
self.scene = Scene.LOGIN_CAPTCHA
elif self.find("sign_in/banner"):

View file

@ -150,6 +150,9 @@ color = {
"sss/loading_ex": (1647, 524),
"sss/main": (1569, 256),
"sss/no_drop_check": (1669, 865),
"sss/ope/elimi_agency_on": (1653, 857),
"sss/ope/prts": (1369, 857),
"sss/ope/use": (1627, 965),
"sss/redeploy": (1644, 970),
"sss/redeploy_ex": (1642, 968),
"sss/settlement_commission": (1593, 31),

View file

@ -307,6 +307,8 @@ class Scene:
"应急模式额外元件"
SSS_CHOOSE_EC = 1018
"选择定向元件"
SSS_ELIMI_AGENCY = 1019
"保全扫荡确认"
SF_ENTRANCE = 1101
"隐秘战线入口"
SF_EXIT = 1102
@ -520,6 +522,7 @@ SceneComment = {
1016: "保全作战完成或终止",
1017: "应急模式额外元件",
1018: "选择定向元件",
1019: "保全扫荡确认",
1101: "隐秘战线入口",
1102: "暂离行动",
1103: "选择小队",

View file

@ -1,5 +1,4 @@
import random
import time
from abc import abstractmethod
from datetime import datetime, timedelta
from typing import Any, Callable, Literal, Optional, Tuple
@ -134,6 +133,8 @@ class BaseSolver:
else:
# tp.Coordinate
x, y = poly
x = max(0, min(x, 1920))
y = max(0, min(y, 1080))
return (int(x), int(y))
def sleep(self, interval: float = 1) -> None:
@ -141,16 +142,6 @@ class BaseSolver:
csleep(interval)
config.recog.update()
def input(self, referent: str, input_area: tp.Scope, text: str = None) -> None:
"""input text"""
logger.debug(f"{referent=} {input_area=}")
config.device.tap(self.get_pos(input_area))
time.sleep(0.5)
if text is None:
text = input(referent).strip()
config.device.send_text(str(text))
config.device.tap((0, 0))
def find(
self,
res: tp.Res,

View file

@ -34,6 +34,11 @@ direction_translation = {
"": "Left",
"": "Right",
"": "None",
"up": "Up",
"down": "Down",
"left": "Left",
"right": "Right",
"none": "None",
}

View file

@ -496,6 +496,9 @@ Res = Literal[
"sss/loading_ex",
"sss/main",
"sss/no_drop_check",
"sss/ope/elimi_agency_on",
"sss/ope/prts",
"sss/ope/use",
"sss/operation_complete",
"sss/redeploy",
"sss/redeploy_ex",

View file

@ -63,4 +63,7 @@ cryptography==43.0.1
SQLAlchemy==2.0.35
# ADB
adbutils==2.8.0
adbutils==2.8.0
# scrcpy截图
av==14.0.1

View file

@ -11,6 +11,8 @@ annotated-types==0.7.0
# via pydantic
apkutils2==1.0.0
# via adbutils
av==14.0.1
# via -r requirements.in
base45==0.4.4
# via -r requirements.in
blinker==1.8.2

View file

@ -1,4 +1,5 @@
#!/usr/bin/env python3
import base64
import json
import mimetypes
import os
@ -41,6 +42,8 @@ def read_log():
msg = config.log_queue.get()
log_lines.append(msg)
log_lines = log_lines[-100:]
if not ws_connections:
continue
data = json.dumps({"type": "log", "data": msg})
for ws in ws_connections:
ws.send(data)
@ -49,6 +52,8 @@ def read_log():
def push_config():
while True:
config.push_conf.wait()
if not ws_connections:
continue
data = json.dumps(
{
"type": "conf",
@ -61,8 +66,27 @@ def push_config():
config.push_conf.clear()
def push_sc():
import cv2
from mower.utils.image import img2bytes
while True:
img = config.sc_queue.get()
if not ws_connections:
continue
img = cv2.resize(img, (480, 270))
img = img2bytes(img)
img = base64.b64encode(img).decode("utf-8")
img = f"data:image/jpeg;base64,{img}"
data = json.dumps({"type": "sc", "data": img})
for ws in ws_connections:
ws.send(data)
Thread(target=read_log, daemon=True).start()
Thread(target=push_config, daemon=True).start()
Thread(target=push_sc, daemon=True).start()
@sock.route("/ws")

View file

@ -1,4 +1,4 @@
import{_ as U,a as X}from"./IosArrowForward.js";import{ar as z,as as v,av as C,au as p,a_ as q,bT as A,ay as S,B as O,ax as G,b0 as J,D as Q,b as W,j as L,aC as Y,H as b,z as Z,c as F,bH as ee,r as k,s as oe,w as re,bu as V,bv as i,bt as _,bw as s,bC as H,bD as M,bo as r,F as T,by as N,bE as I,bx as te,i as le,aX as ne,b3 as se,k as ie}from"./_plugin-vue_export-helper.js";import{ak as ae}from"./main.js";import{S as de,_ as ce}from"./Scrollbar.js";import{_ as ue}from"./Flex.js";import{_ as me}from"./Image.js";import{_ as ve}from"./Slider.js";import"./get-slot.js";import"./utils.js";import"./use-locale.js";import"./download.js";const pe=z([v("list",`
import{_ as U,a as X}from"./IosArrowForward.js";import{ar as z,as as v,av as C,au as b,a_ as q,bT as A,ay as S,B as O,ax as G,b0 as J,D as Q,b as W,j as L,aC as Y,H as p,z as Z,c as F,bH as ee,r as k,s as oe,w as re,bu as V,bv as i,bt as _,bw as s,bC as H,bD as M,bo as r,F as T,by as N,bE as I,bx as te,i as le,aX as ne,b3 as se,k as ie}from"./_plugin-vue_export-helper.js";import{ak as ae}from"./main.js";import{S as de,_ as ce,a as ue}from"./Scrollbar.js";import{_ as me}from"./Flex.js";import{_ as ve}from"./Slider.js";import"./utils.js";import"./use-locale.js";import"./download.js";import"./get-slot.js";const be=z([v("list",`
--n-merged-border-color: var(--n-border-color);
--n-merged-color: var(--n-color);
--n-merged-color-hover: var(--n-color-hover);
@ -12,7 +12,7 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as z,as as v,av as C,a
list-style-type: none;
color: var(--n-text-color);
background-color: var(--n-merged-color);
`,[C("show-divider",[v("list-item",[z("&:not(:last-child)",[p("divider",`
`,[C("show-divider",[v("list-item",[z("&:not(:last-child)",[b("divider",`
background-color: var(--n-merged-border-color);
`)])])]),C("clickable",[v("list-item",`
cursor: pointer;
@ -23,13 +23,13 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as z,as as v,av as C,a
border-radius: var(--n-border-radius);
`,[z("&:hover",`
background-color: var(--n-merged-color-hover);
`,[p("divider",`
`,[b("divider",`
background-color: transparent;
`)])])]),C("bordered, hoverable",[v("list-item",`
padding: 12px 20px;
`),p("header, footer",`
`),b("header, footer",`
padding: 12px 20px;
`)]),p("header, footer",`
`)]),b("header, footer",`
padding: 12px 0;
box-sizing: border-box;
transition: border-color .3s var(--n-bezier);
@ -45,15 +45,15 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as z,as as v,av as C,a
transition:
background-color .3s var(--n-bezier),
border-color .3s var(--n-bezier);
`,[p("prefix",`
`,[b("prefix",`
margin-right: 20px;
flex: 0;
`),p("suffix",`
`),b("suffix",`
margin-left: 20px;
flex: 0;
`),p("main",`
`),b("main",`
flex: 1;
`),p("divider",`
`),b("divider",`
height: 1px;
position: absolute;
bottom: 0;
@ -70,4 +70,4 @@ import{_ as U,a as X}from"./IosArrowForward.js";import{ar as z,as as v,av as C,a
--n-merged-color-hover: var(--n-color-hover-popover);
--n-merged-color: var(--n-color-popover);
--n-merged-border-color: var(--n-border-color-popover);
`))]),be=Object.assign(Object.assign({},S.props),{size:{type:String,default:"medium"},bordered:Boolean,clickable:Boolean,hoverable:Boolean,showDivider:{type:Boolean,default:!0}}),K=Z("n-list"),_e=O({name:"List",props:be,setup(e){const{mergedClsPrefixRef:o,inlineThemeDisabled:t,mergedRtlRef:m}=G(e),c=J("List",m,o),l=S("List","-list",pe,ae,e,o);Q(K,{showDividerRef:W(e,"showDivider"),mergedClsPrefixRef:o});const f=L(()=>{const{common:{cubicBezierEaseInOut:g},self:{fontSize:R,textColor:n,color:d,colorModal:B,colorPopover:D,borderColor:w,borderColorModal:P,borderColorPopover:j,borderRadius:y,colorHover:$,colorHoverModal:E,colorHoverPopover:h}}=l.value;return{"--n-font-size":R,"--n-bezier":g,"--n-text-color":n,"--n-color":d,"--n-border-radius":y,"--n-border-color":w,"--n-border-color-modal":P,"--n-border-color-popover":j,"--n-color-modal":B,"--n-color-popover":D,"--n-color-hover":$,"--n-color-hover-modal":E,"--n-color-hover-popover":h}}),u=t?Y("list",void 0,f,e):void 0;return{mergedClsPrefix:o,rtlEnabled:c,cssVars:t?void 0:f,themeClass:u==null?void 0:u.themeClass,onRender:u==null?void 0:u.onRender}},render(){var e;const{$slots:o,mergedClsPrefix:t,onRender:m}=this;return m==null||m(),b("ul",{class:[`${t}-list`,this.rtlEnabled&&`${t}-list--rtl`,this.bordered&&`${t}-list--bordered`,this.showDivider&&`${t}-list--show-divider`,this.hoverable&&`${t}-list--hoverable`,this.clickable&&`${t}-list--clickable`,this.themeClass],style:this.cssVars},o.header?b("div",{class:`${t}-list__header`},o.header()):null,(e=o.default)===null||e===void 0?void 0:e.call(o),o.footer?b("div",{class:`${t}-list__footer`},o.footer()):null)}}),fe=O({name:"ListItem",setup(){const e=F(K,null);return e||ee("list-item","`n-list-item` must be placed in `n-list`."),{showDivider:e.showDividerRef,mergedClsPrefix:e.mergedClsPrefixRef}},render(){const{$slots:e,mergedClsPrefix:o}=this;return b("li",{class:`${o}-list-item`},e.prefix?b("div",{class:`${o}-list-item__prefix`},e.prefix()):null,e.default?b("div",{class:`${o}-list-item__main`},e):null,e.suffix?b("div",{class:`${o}-list-item__suffix`},e.suffix()):null,this.showDivider&&b("div",{class:`${o}-list-item__divider`}))}}),ge={style:{"text-align":"center",margin:"0"}},Pe={__name:"DebugConsole",setup(e){const o=F("axios"),t=k([]),m=k(""),c=k([]),l=k(0),f=k(null);oe(()=>{o.get("/debug/log").then(({data:n})=>{t.value=n}),u("runtime.log")});function u(n){m.value=n,o.get(`/debug/log/${n}`).then(({data:d})=>{l.value=0,c.value=d,l.value=c.value.length-1})}const g=L(()=>{var n;return(n=c.value[l.value])==null?void 0:n.screenshot}),R=L(()=>`/debug/screenshot/${g.value}`);return re(l,()=>{var n;(n=f.value)==null||n.scrollTo({top:0})}),(n,d)=>{const B=fe,D=_e,w=de,P=me,j=ve,y=ne,$=se,E=ce,h=ue;return _(),V(h,{style:{width:"100%",height:"100%",gap:"0","overflow-y":"hidden"}},{default:i(()=>[s(w,{style:{width:"220px"}},{default:i(()=>[s(D,{hoverable:"",clickable:"",bordered:""},{default:i(()=>[(_(!0),H(T,null,M(r(t),a=>(_(),V(B,{onClick:x=>u(a)},{default:i(()=>[ie(I(a),1)]),_:2},1032,["onClick"]))),256))]),_:1})]),_:1}),s(h,{vertical:"",style:{flex:"1",height:"100%",overflow:"hidden"}},{default:i(()=>[N("h2",ge,I(r(m)),1),r(g)?(_(),V(P,{key:0,src:r(R),alt:r(g),width:"100%",style:{"max-height":"50%"},"object-fit":"scale-down"},null,8,["src","alt"])):te("",!0),s(w,{ref_key:"log_scroll",ref:f,style:{width:"100%"},"content-style":"font-size: 16px; user-select: text; padding: 0 12px"},{default:i(()=>{var a;return[(_(!0),H(T,null,M((a=r(c)[r(l)])==null?void 0:a.log,x=>(_(),H("div",null,[N("code",null,I(x),1)]))),256))]}),_:1},512),s(h,{align:"center",style:{padding:"0 12px 6px"}},{default:i(()=>[s(j,{style:{flex:"1"},"show-tooltip":"",value:r(l),"onUpdate:value":d[0]||(d[0]=a=>le(l)?l.value=a:null),min:0,max:r(c).length-1,"format-tooltip":a=>{var x;return(x=r(c)[a])==null?void 0:x.time}},null,8,["value","max","format-tooltip"]),s(E,null,{default:i(()=>[s($,{disabled:r(l)==0,onClick:d[1]||(d[1]=a=>l.value--)},{icon:i(()=>[s(y,null,{default:i(()=>[s(r(U))]),_:1})]),_:1},8,["disabled"]),s($,{disabled:r(l)==r(c).length-1,onClick:d[2]||(d[2]=a=>l.value++)},{icon:i(()=>[s(y,null,{default:i(()=>[s(r(X))]),_:1})]),_:1},8,["disabled"])]),_:1})]),_:1})]),_:1})]),_:1})}}};export{Pe as default};
`))]),pe=Object.assign(Object.assign({},S.props),{size:{type:String,default:"medium"},bordered:Boolean,clickable:Boolean,hoverable:Boolean,showDivider:{type:Boolean,default:!0}}),K=Z("n-list"),_e=O({name:"List",props:pe,setup(e){const{mergedClsPrefixRef:o,inlineThemeDisabled:t,mergedRtlRef:m}=G(e),c=J("List",m,o),l=S("List","-list",be,ae,e,o);Q(K,{showDividerRef:W(e,"showDivider"),mergedClsPrefixRef:o});const f=L(()=>{const{common:{cubicBezierEaseInOut:g},self:{fontSize:R,textColor:n,color:d,colorModal:B,colorPopover:D,borderColor:w,borderColorModal:P,borderColorPopover:j,borderRadius:y,colorHover:$,colorHoverModal:E,colorHoverPopover:h}}=l.value;return{"--n-font-size":R,"--n-bezier":g,"--n-text-color":n,"--n-color":d,"--n-border-radius":y,"--n-border-color":w,"--n-border-color-modal":P,"--n-border-color-popover":j,"--n-color-modal":B,"--n-color-popover":D,"--n-color-hover":$,"--n-color-hover-modal":E,"--n-color-hover-popover":h}}),u=t?Y("list",void 0,f,e):void 0;return{mergedClsPrefix:o,rtlEnabled:c,cssVars:t?void 0:f,themeClass:u==null?void 0:u.themeClass,onRender:u==null?void 0:u.onRender}},render(){var e;const{$slots:o,mergedClsPrefix:t,onRender:m}=this;return m==null||m(),p("ul",{class:[`${t}-list`,this.rtlEnabled&&`${t}-list--rtl`,this.bordered&&`${t}-list--bordered`,this.showDivider&&`${t}-list--show-divider`,this.hoverable&&`${t}-list--hoverable`,this.clickable&&`${t}-list--clickable`,this.themeClass],style:this.cssVars},o.header?p("div",{class:`${t}-list__header`},o.header()):null,(e=o.default)===null||e===void 0?void 0:e.call(o),o.footer?p("div",{class:`${t}-list__footer`},o.footer()):null)}}),fe=O({name:"ListItem",setup(){const e=F(K,null);return e||ee("list-item","`n-list-item` must be placed in `n-list`."),{showDivider:e.showDividerRef,mergedClsPrefix:e.mergedClsPrefixRef}},render(){const{$slots:e,mergedClsPrefix:o}=this;return p("li",{class:`${o}-list-item`},e.prefix?p("div",{class:`${o}-list-item__prefix`},e.prefix()):null,e.default?p("div",{class:`${o}-list-item__main`},e):null,e.suffix?p("div",{class:`${o}-list-item__suffix`},e.suffix()):null,this.showDivider&&p("div",{class:`${o}-list-item__divider`}))}}),ge={style:{"text-align":"center",margin:"0"}},De={__name:"DebugConsole",setup(e){const o=F("axios"),t=k([]),m=k(""),c=k([]),l=k(0),f=k(null);oe(()=>{o.get("/debug/log").then(({data:n})=>{t.value=n}),u("runtime.log")});function u(n){m.value=n,o.get(`/debug/log/${n}`).then(({data:d})=>{l.value=0,c.value=d,l.value=c.value.length-1})}const g=L(()=>{var n;return(n=c.value[l.value])==null?void 0:n.screenshot}),R=L(()=>`/debug/screenshot/${g.value}`);return re(l,()=>{var n;(n=f.value)==null||n.scrollTo({top:0})}),(n,d)=>{const B=fe,D=_e,w=de,P=ce,j=ve,y=ne,$=se,E=ue,h=me;return _(),V(h,{style:{width:"100%",height:"100%",gap:"0","overflow-y":"hidden"}},{default:i(()=>[s(w,{style:{width:"220px"}},{default:i(()=>[s(D,{hoverable:"",clickable:"",bordered:""},{default:i(()=>[(_(!0),H(T,null,M(r(t),a=>(_(),V(B,{onClick:x=>u(a)},{default:i(()=>[ie(I(a),1)]),_:2},1032,["onClick"]))),256))]),_:1})]),_:1}),s(h,{vertical:"",style:{flex:"1",height:"100%",overflow:"hidden"}},{default:i(()=>[N("h2",ge,I(r(m)),1),r(g)?(_(),V(P,{key:0,src:r(R),alt:r(g),width:"100%",style:{"max-height":"50%"},"object-fit":"scale-down"},null,8,["src","alt"])):te("",!0),s(w,{ref_key:"log_scroll",ref:f,style:{width:"100%"},"content-style":"font-size: 16px; user-select: text; padding: 0 12px"},{default:i(()=>{var a;return[(_(!0),H(T,null,M((a=r(c)[r(l)])==null?void 0:a.log,x=>(_(),H("div",null,[N("code",null,I(x),1)]))),256))]}),_:1},512),s(h,{align:"center",style:{padding:"0 12px 6px"}},{default:i(()=>[s(j,{style:{flex:"1"},"show-tooltip":"",value:r(l),"onUpdate:value":d[0]||(d[0]=a=>le(l)?l.value=a:null),min:0,max:r(c).length-1,"format-tooltip":a=>{var x;return(x=r(c)[a])==null?void 0:x.time}},null,8,["value","max","format-tooltip"]),s(E,null,{default:i(()=>[s($,{disabled:r(l)==0,onClick:d[1]||(d[1]=a=>l.value--)},{icon:i(()=>[s(y,null,{default:i(()=>[s(r(U))]),_:1})]),_:1},8,["disabled"]),s($,{disabled:r(l)==r(c).length-1,onClick:d[2]||(d[2]=a=>l.value++)},{icon:i(()=>[s(y,null,{default:i(()=>[s(r(X))]),_:1})]),_:1},8,["disabled"])]),_:1})]),_:1})]),_:1})]),_:1})}}};export{De as default};

View file

@ -1,4 +1,4 @@
import{_ as fn}from"./HelpText.js";import{m as mn,n as pn,o as gn,B as At,V as Vt,h as Mt,i as jt,f as yn,b as it,p as bn,q as _t,r as Cn,A as _n,j as kn,s as kt,u as wn,k as Dn,v as Sn,_ as Rn,w as xn}from"./main.js";import{c as zt,g as wt,d as Dt,e as St,f as ne,h as ot,m as st,y as dt,q as ut,i as $n,j as Fe,k as qe,l as D,n as me,o as oe,t as ie,u as Ee,v as za,w as Rt,x as xt,z as be,A as Bt,B as Qe,C as On,D as ct,E as Et,F as It,G as Ut,H as Yt,I as ht,J as ra,K as Tn,a as Pn,p as $t,r as rt,L as Fn,b as An}from"./op_select.js";import{c as ea,j as y,aR as Vn,ai as Nt,H as t,an as Lt,ar as P,as as K,av as H,au as fe,B as Ie,ax as mt,r as R,s as pt,w as Ae,b as Ce,ay as va,aC as Ea,z as Mn,n as qt,bL as Ge,bM as _e,b3 as pe,b8 as oa,aD as Ht,E as Kt,M as Wt,b4 as W,K as Qt,at as Ra,bF as Jt,aI as vt,az as jn,l as zn,D as Bn,aY as Ot,J as En,b2 as Ba,aL as Pe,ap as In,aO as Un,aV as Yn,br as Gt,bt as xe,bu as Je,bv as re,bo as Y,bC as xa,bw as te,i as ia,bx as Xe,by as ae,k as Te,F as Tt,bE as Pt,b9 as Nn,bm as Zt,bG as Ln,aX as qn}from"./_plugin-vue_export-helper.js";import{F as fa,_ as Hn,a as Kn}from"./Select.js";import{u as Ia}from"./use-locale.js";import{V as ft}from"./VirtualList.js";import{F as sa,B as da,a as ua,b as ca,s as Wn}from"./Forward.js";import{_ as aa}from"./Input.js";import{t as Qn,c as Jn,_ as Gn}from"./Tag.js";import{S as Zn,_ as Xn}from"./Scrollbar.js";function el(e,l){const u=ea(Vn,null);return y(()=>e.hljs||(u==null?void 0:u.mergedHljsRef.value))}const Ft=Nt("date",t("svg",{width:"28px",height:"28px",viewBox:"0 0 28 28",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},t("g",{stroke:"none","stroke-width":"1","fill-rule":"evenodd"},t("g",{"fill-rule":"nonzero"},t("path",{d:"M21.75,3 C23.5449254,3 25,4.45507456 25,6.25 L25,21.75 C25,23.5449254 23.5449254,25 21.75,25 L6.25,25 C4.45507456,25 3,23.5449254 3,21.75 L3,6.25 C3,4.45507456 4.45507456,3 6.25,3 L21.75,3 Z M23.5,9.503 L4.5,9.503 L4.5,21.75 C4.5,22.7164983 5.28350169,23.5 6.25,23.5 L21.75,23.5 C22.7164983,23.5 23.5,22.7164983 23.5,21.75 L23.5,9.503 Z M21.75,4.5 L6.25,4.5 C5.28350169,4.5 4.5,5.28350169 4.5,6.25 L4.5,8.003 L23.5,8.003 L23.5,6.25 C23.5,5.28350169 22.7164983,4.5 21.75,4.5 Z"}))))),al=Nt("to",t("svg",{viewBox:"0 0 20 20",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},t("g",{stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},t("g",{fill:"currentColor","fill-rule":"nonzero"},t("path",{d:"M11.2654,3.20511 C10.9644,2.92049 10.4897,2.93371 10.2051,3.23464 C9.92049,3.53558 9.93371,4.01027 10.2346,4.29489 L15.4737,9.25 L2.75,9.25 C2.33579,9.25 2,9.58579 2,10.0000012 C2,10.4142 2.33579,10.75 2.75,10.75 L15.476,10.75 L10.2346,15.7073 C9.93371,15.9919 9.92049,16.4666 10.2051,16.7675 C10.4897,17.0684 10.9644,17.0817 11.2654,16.797 L17.6826,10.7276 C17.8489,10.5703 17.9489,10.3702 17.9826,10.1614 C17.994,10.1094 18,10.0554 18,10.0000012 C18,9.94241 17.9935,9.88633 17.9812,9.83246 C17.9462,9.62667 17.8467,9.42976 17.6826,9.27455 L11.2654,3.20511 Z"})))));function tl(e,l){const u=mn(e),a=Math.trunc(u.getMonth()/3)+1,i=l-a;return zt(u,u.getMonth()+i*3)}function nl(e){const{textColor2:l,fontSize:u,fontWeightStrong:a,textColor3:i}=e;return{textColor:l,fontSize:u,fontWeightStrong:a,"mono-3":"#a0a1a7","hue-1":"#0184bb","hue-2":"#4078f2","hue-3":"#a626a4","hue-4":"#50a14f","hue-5":"#e45649","hue-5-2":"#c91243","hue-6":"#986801","hue-6-2":"#c18401",lineNumberTextColor:i}}const ll={name:"Code",common:Lt,self:nl},rl=P([K("code",`
import{_ as fn}from"./HelpText.js";import{m as mn,n as pn,o as gn,B as At,V as Vt,h as Mt,i as jt,f as yn,b as it,p as bn,q as _t,r as Cn,A as _n,j as kn,s as kt,u as wn,k as Dn,v as Sn,_ as Rn,w as xn}from"./main.js";import{c as zt,g as wt,d as Dt,e as St,f as ne,h as ot,m as st,y as dt,q as ut,i as $n,j as Fe,k as qe,l as D,n as me,o as oe,t as ie,u as Ee,v as za,w as Rt,x as xt,z as be,A as Bt,B as Qe,C as On,D as ct,E as Et,F as It,G as Ut,H as Yt,I as ht,J as ra,K as Tn,a as Pn,p as $t,r as rt,L as Fn,b as An}from"./op_select.js";import{c as ea,j as y,aR as Vn,ai as Nt,H as t,an as Lt,ar as P,as as K,av as H,au as fe,B as Ie,ax as mt,r as R,s as pt,w as Ae,b as Ce,ay as va,aC as Ea,z as Mn,n as qt,bL as Ge,bM as _e,b3 as pe,b8 as oa,aD as Ht,E as Kt,M as Wt,b4 as W,K as Qt,at as Ra,bF as Jt,aI as vt,az as jn,l as zn,D as Bn,aY as Ot,J as En,b2 as Ba,aL as Pe,ap as In,aO as Un,aV as Yn,br as Gt,bt as xe,bu as Je,bv as re,bo as Y,bC as xa,bw as te,i as ia,bx as Xe,by as ae,k as Te,F as Tt,bE as Pt,b9 as Nn,bm as Zt,bG as Ln,aX as qn}from"./_plugin-vue_export-helper.js";import{F as fa,_ as Hn,a as Kn}from"./Select.js";import{u as Ia}from"./use-locale.js";import{V as ft}from"./VirtualList.js";import{F as sa,B as da,a as ua,b as ca,s as Wn}from"./Forward.js";import{_ as aa}from"./Input.js";import{t as Qn,c as Jn,_ as Gn}from"./Tag.js";import{S as Zn,a as Xn}from"./Scrollbar.js";function el(e,l){const u=ea(Vn,null);return y(()=>e.hljs||(u==null?void 0:u.mergedHljsRef.value))}const Ft=Nt("date",t("svg",{width:"28px",height:"28px",viewBox:"0 0 28 28",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},t("g",{stroke:"none","stroke-width":"1","fill-rule":"evenodd"},t("g",{"fill-rule":"nonzero"},t("path",{d:"M21.75,3 C23.5449254,3 25,4.45507456 25,6.25 L25,21.75 C25,23.5449254 23.5449254,25 21.75,25 L6.25,25 C4.45507456,25 3,23.5449254 3,21.75 L3,6.25 C3,4.45507456 4.45507456,3 6.25,3 L21.75,3 Z M23.5,9.503 L4.5,9.503 L4.5,21.75 C4.5,22.7164983 5.28350169,23.5 6.25,23.5 L21.75,23.5 C22.7164983,23.5 23.5,22.7164983 23.5,21.75 L23.5,9.503 Z M21.75,4.5 L6.25,4.5 C5.28350169,4.5 4.5,5.28350169 4.5,6.25 L4.5,8.003 L23.5,8.003 L23.5,6.25 C23.5,5.28350169 22.7164983,4.5 21.75,4.5 Z"}))))),al=Nt("to",t("svg",{viewBox:"0 0 20 20",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},t("g",{stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},t("g",{fill:"currentColor","fill-rule":"nonzero"},t("path",{d:"M11.2654,3.20511 C10.9644,2.92049 10.4897,2.93371 10.2051,3.23464 C9.92049,3.53558 9.93371,4.01027 10.2346,4.29489 L15.4737,9.25 L2.75,9.25 C2.33579,9.25 2,9.58579 2,10.0000012 C2,10.4142 2.33579,10.75 2.75,10.75 L15.476,10.75 L10.2346,15.7073 C9.93371,15.9919 9.92049,16.4666 10.2051,16.7675 C10.4897,17.0684 10.9644,17.0817 11.2654,16.797 L17.6826,10.7276 C17.8489,10.5703 17.9489,10.3702 17.9826,10.1614 C17.994,10.1094 18,10.0554 18,10.0000012 C18,9.94241 17.9935,9.88633 17.9812,9.83246 C17.9462,9.62667 17.8467,9.42976 17.6826,9.27455 L11.2654,3.20511 Z"})))));function tl(e,l){const u=mn(e),a=Math.trunc(u.getMonth()/3)+1,i=l-a;return zt(u,u.getMonth()+i*3)}function nl(e){const{textColor2:l,fontSize:u,fontWeightStrong:a,textColor3:i}=e;return{textColor:l,fontSize:u,fontWeightStrong:a,"mono-3":"#a0a1a7","hue-1":"#0184bb","hue-2":"#4078f2","hue-3":"#a626a4","hue-4":"#50a14f","hue-5":"#e45649","hue-5-2":"#c91243","hue-6":"#986801","hue-6-2":"#c18401",lineNumberTextColor:i}}const ll={name:"Code",common:Lt,self:nl},rl=P([K("code",`
font-size: var(--n-font-size);
font-family: var(--n-font-family);
`,[H("show-line-numbers",`

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
.log[data-v-b6949d6f]{overflow:hidden;flex:1}.task-table[data-v-b6949d6f]{max-width:600px}.task-table th[data-v-b6949d6f]{padding:2px 16px}.task-table td[data-v-b6949d6f]{height:24px;padding:2px 8px}.task-table td[data-v-b6949d6f]:last-child{width:100%}.action-container[data-v-b6949d6f]{display:flex;align-items:center;gap:12px}.scroll-container[data-v-b6949d6f]{display:flex;align-items:center;gap:4px}.expand[data-v-b6949d6f]{flex-grow:1}.toggle-table-collapse-btn[data-v-b6949d6f]{position:absolute;top:12px;right:12px}.toggle-fullscreen-btn[data-v-b6949d6f]{position:absolute;top:12px;right:50px}.log-bg[data-v-b6949d6f]{content:"";width:100%;height:100%;position:absolute;top:0;left:0;opacity:var(--15833a31);background-image:url(/bg.webp);background-repeat:no-repeat;background-size:cover;background-position:65% 50%;pointer-events:none}.hljs-date{color:#f0a020!important;font-weight:700}.hljs-time{color:#2080f0!important;font-weight:700}.hljs-room{color:#18a058!important;font-weight:700}.hljs-operator{color:#d03050!important}.hljs-info{font-weight:700}.hljs-warning{color:#f0a020!important;font-weight:700}.hljs-error{color:#d03050!important;font-weight:700}.hljs-scene{font-style:italic}
.log[data-v-c4feeca6]{overflow:hidden;flex:1}.task-table[data-v-c4feeca6]{position:relative;max-width:600px}.task-table th[data-v-c4feeca6]{padding:2px 16px}.task-table td[data-v-c4feeca6]{height:24px;padding:2px 8px}.task-table td[data-v-c4feeca6]:last-child{width:100%}.action-container[data-v-c4feeca6]{display:flex;align-items:center;gap:12px}.scroll-container[data-v-c4feeca6]{display:flex;align-items:center;gap:4px}.expand[data-v-c4feeca6]{flex-grow:1}.toggle-table-collapse-btn[data-v-c4feeca6]{position:absolute;top:0;right:0}.toggle-fullscreen-btn[data-v-c4feeca6]{position:absolute;top:0;right:38px}.log-bg[data-v-c4feeca6]{content:"";width:100%;height:100%;position:absolute;top:0;left:0;opacity:var(--55f59a8a);background-image:url(/bg.webp);background-repeat:no-repeat;background-size:cover;background-position:65% 50%;pointer-events:none;z-index:14}.sc[data-v-c4feeca6]{max-width:480px;max-height:270px;border-radius:6px;z-index:15}.hljs-date{color:#f0a020!important;font-weight:700}.hljs-time{color:#2080f0!important;font-weight:700}.hljs-room{color:#18a058!important;font-weight:700}.hljs-operator{color:#d03050!important}.hljs-info{font-weight:700}.hljs-warning{color:#f0a020!important;font-weight:700}.hljs-error{color:#d03050!important;font-weight:700}.hljs-scene{font-style:italic}

42
ui/dist/assets/Log.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
.sss-container[data-v-2dffb781]{display:flex;width:100%;gap:8px}.wrapper[data-v-2dffb781]{white-space:pre-wrap;-webkit-user-select:text;user-select:text}.title[data-v-2dffb781]{font-size:18px;font-weight:500;margin-bottom:6px}p[data-v-d479d5bf]{margin:0 0 10px}.misc-container[data-v-d479d5bf]{display:flex;align-items:center;gap:12px}.header[data-v-d479d5bf]{margin:12px 0}.tasktable[data-v-6e42e723]{margin-top:4px;width:100%;overflow:scroll}.tasktable table[data-v-6e42e723]{border-collapse:collapse;width:100%}.btn-clear[data-v-6e42e723]{margin:4px}@media screen and (max-width: 1399px){.tasktable[data-v-6e42e723]{max-height:300px}.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{position:sticky;top:0;background-color:#7ea5b4;z-index:1}}@media screen and (min-width: 1400px){.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{background-color:#7ea5b4}}.class1[data-v-6e42e723]{background-color:var(--06f96d6a);text-align:center;vertical-align:middle}.class2[data-v-6e42e723]{background-color:var(--292d8683);text-align:center;vertical-align:middle}.custom-tag[data-v-6e42e723]{width:100%;height:100%;justify-content:space-between}.today[data-v-6e42e723]{font-weight:400;font-size:12px}.activity[data-v-6e42e723]{align-items:center;gap:4px!important}.card-title[data-v-6e42e723]{transition:.3s}.disabled[data-v-6e42e723]{color:var(--6d545694)}.form-item[data-v-6e42e723]{margin:0 0 4px}p[data-v-748f667d]{margin:2px 0}h4[data-v-748f667d]{margin:12px 0 8px}table[data-v-748f667d]{width:100%}td[data-v-748f667d]:nth-child(1){width:80px}.ignore-blacklist[data-v-748f667d]{margin-bottom:10px;display:flex;gap:12px}.h4[data-v-748f667d]{font-size:16px;font-weight:500}.maa-shop[data-v-748f667d]{margin:8px 0}.item[data-v-748f667d]{font-weight:500;font-size:16px}p[data-v-707c6f48]{margin:0 0 8px}h4[data-v-707c6f48]{margin:12px 0 10px}.big-table[data-v-707c6f48]{margin-top:10px;max-width:320px}.big-table th[data-v-707c6f48]{text-align:center}.big-table tr[data-v-707c6f48]{width:70px}.big-table td[data-v-707c6f48]{height:24px}.big-table td[data-v-707c6f48]:nth-child(1){width:70px;text-align:center}.big-table td[data-v-707c6f48]:nth-child(2){width:420px}.final[data-v-707c6f48]{margin:16px 0 0}.item[data-v-e95953da]{font-weight:500;font-size:16px}.n-divider[data-v-e95953da]:not(.n-divider--vertical){margin:6px 0}.subtitle[data-v-31c5d919]{margin:12px 0 6px}.misc-container{margin-top:12px;display:flex;align-items:center;gap:12px}.email-title[data-v-7cbc22ce]{width:100%}.expand[data-v-7cbc22ce]{flex-grow:1}.email-table[data-v-7cbc22ce]{width:100%;margin-bottom:12px}.email-test[data-v-7cbc22ce]{display:flex;align-items:center;gap:16px}.email-mode[data-v-7cbc22ce]{margin-left:20px}.email-label[data-v-7cbc22ce]{width:68px}p[data-v-7cbc22ce]{margin:0 0 10px}.mt-16[data-v-7cbc22ce]{margin-top:16px}.threshold[data-v-7e026566]{display:flex;align-items:center;gap:14px;width:100%}.mower-basic[data-v-7e026566]{width:100%}.mower-basic td[data-v-7e026566]:nth-child(1){width:120px}.mower-basic td[data-v-7e026566]:nth-child(3){padding-left:6px;width:40px}.riic-conf[data-v-7e026566]{width:100%}.riic-conf td[data-v-7e026566]:nth-child(1){width:130px}.riic-conf td[data-v-7e026566]:nth-child(3){padding-left:12px;width:120px}.coord td[data-v-7e026566]{width:120px}.coord td[data-v-7e026566]:nth-child(1),.coord td[data-v-7e026566]:nth-child(3){width:30px}.coord td[data-v-7e026566]:nth-child(2){padding-right:30px}.coord-label[data-v-7e026566]{width:40px;padding-left:8px}p[data-v-7e026566]{margin:0 0 8px}h4[data-v-7e026566]{margin:12px 0 10px}.time-table[data-v-7e026566]{width:100%;margin-bottom:12px}.time-table td[data-v-7e026566]:nth-child(1){width:40px}.scale[data-v-7e026566]{width:60px;text-align:right}.scale-apply[data-v-7e026566]{margin-left:24px}.waiting-table th[data-v-7e026566],.waiting-table td[data-v-7e026566]{padding:4px;min-width:70px;width:100px}.waiting-table th[data-v-7e026566]:first-child,.waiting-table td[data-v-7e026566]:first-child{width:auto;padding:4px 8px}@media (max-width: 1399px){.grid-two{margin:0 0 -10px;width:100%;max-width:600px}.grid-left{display:grid;row-gap:10px;grid-template-columns:100%}.grid-right{display:grid;row-gap:10px;grid-template-columns:100%;margin-top:10px}}@media (min-width: 1400px){.grid-two{display:grid;grid-template-columns:minmax(0px,1fr) minmax(0px,1fr);align-items:flex-start;gap:5px}.grid-left,.grid-right{display:grid;gap:5px;grid-template-columns:100%;max-width:600px}}.n-divider:not(.n-divider--vertical){margin:14px 0 8px}
.sss-container[data-v-2dffb781]{display:flex;width:100%;gap:8px}.wrapper[data-v-2dffb781]{white-space:pre-wrap;-webkit-user-select:text;user-select:text}.title[data-v-2dffb781]{font-size:18px;font-weight:500;margin-bottom:6px}p[data-v-d479d5bf]{margin:0 0 10px}.misc-container[data-v-d479d5bf]{display:flex;align-items:center;gap:12px}.header[data-v-d479d5bf]{margin:12px 0}.tasktable[data-v-6e42e723]{margin-top:4px;width:100%;overflow:scroll}.tasktable table[data-v-6e42e723]{border-collapse:collapse;width:100%}.btn-clear[data-v-6e42e723]{margin:4px}@media screen and (max-width: 1399px){.tasktable[data-v-6e42e723]{max-height:300px}.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{position:sticky;top:0;background-color:#7ea5b4;z-index:1}}@media screen and (min-width: 1400px){.tasktable td[data-v-6e42e723]{width:10.2857142857%}.tasktable td[data-v-6e42e723]:first-child{width:10%}.tasktable td[data-v-6e42e723]:nth-child(2){width:18%}.tasktable thead[data-v-6e42e723]{background-color:#7ea5b4}}.class1[data-v-6e42e723]{background-color:var(--06f96d6a);text-align:center;vertical-align:middle}.class2[data-v-6e42e723]{background-color:var(--292d8683);text-align:center;vertical-align:middle}.custom-tag[data-v-6e42e723]{width:100%;height:100%;justify-content:space-between}.today[data-v-6e42e723]{font-weight:400;font-size:12px}.activity[data-v-6e42e723]{align-items:center;gap:4px!important}.card-title[data-v-6e42e723]{transition:.3s}.disabled[data-v-6e42e723]{color:var(--6d545694)}.form-item[data-v-6e42e723]{margin:0 0 4px}p[data-v-748f667d]{margin:2px 0}h4[data-v-748f667d]{margin:12px 0 8px}table[data-v-748f667d]{width:100%}td[data-v-748f667d]:nth-child(1){width:80px}.ignore-blacklist[data-v-748f667d]{margin-bottom:10px;display:flex;gap:12px}.h4[data-v-748f667d]{font-size:16px;font-weight:500}.maa-shop[data-v-748f667d]{margin:8px 0}.item[data-v-748f667d]{font-weight:500;font-size:16px}p[data-v-707c6f48]{margin:0 0 8px}h4[data-v-707c6f48]{margin:12px 0 10px}.big-table[data-v-707c6f48]{margin-top:10px;max-width:320px}.big-table th[data-v-707c6f48]{text-align:center}.big-table tr[data-v-707c6f48]{width:70px}.big-table td[data-v-707c6f48]{height:24px}.big-table td[data-v-707c6f48]:nth-child(1){width:70px;text-align:center}.big-table td[data-v-707c6f48]:nth-child(2){width:420px}.final[data-v-707c6f48]{margin:16px 0 0}.item[data-v-e95953da]{font-weight:500;font-size:16px}.n-divider[data-v-e95953da]:not(.n-divider--vertical){margin:6px 0}.subtitle[data-v-31c5d919]{margin:12px 0 6px}.misc-container{margin-top:12px;display:flex;align-items:center;gap:12px}.email-title[data-v-7cbc22ce]{width:100%}.expand[data-v-7cbc22ce]{flex-grow:1}.email-table[data-v-7cbc22ce]{width:100%;margin-bottom:12px}.email-test[data-v-7cbc22ce]{display:flex;align-items:center;gap:16px}.email-mode[data-v-7cbc22ce]{margin-left:20px}.email-label[data-v-7cbc22ce]{width:68px}p[data-v-7cbc22ce]{margin:0 0 10px}.mt-16[data-v-7cbc22ce]{margin-top:16px}.threshold[data-v-32cd0fe1]{display:flex;align-items:center;gap:14px;width:100%}.mower-basic[data-v-32cd0fe1]{width:100%}.mower-basic td[data-v-32cd0fe1]:nth-child(1){width:120px}.mower-basic td[data-v-32cd0fe1]:nth-child(3){padding-left:6px;width:40px}.riic-conf[data-v-32cd0fe1]{width:100%}.riic-conf td[data-v-32cd0fe1]:nth-child(1){width:130px}.riic-conf td[data-v-32cd0fe1]:nth-child(3){padding-left:12px;width:120px}.coord td[data-v-32cd0fe1]{width:120px}.coord td[data-v-32cd0fe1]:nth-child(1),.coord td[data-v-32cd0fe1]:nth-child(3){width:30px}.coord td[data-v-32cd0fe1]:nth-child(2){padding-right:30px}.coord-label[data-v-32cd0fe1]{width:40px;padding-left:8px}p[data-v-32cd0fe1]{margin:0 0 8px}h4[data-v-32cd0fe1]{margin:12px 0 10px}.time-table[data-v-32cd0fe1]{width:100%;margin-bottom:12px}.time-table td[data-v-32cd0fe1]:nth-child(1){width:40px}.scale[data-v-32cd0fe1]{width:60px;text-align:right}.scale-apply[data-v-32cd0fe1]{margin-left:24px}.waiting-table th[data-v-32cd0fe1],.waiting-table td[data-v-32cd0fe1]{padding:4px;min-width:70px;width:100px}.waiting-table th[data-v-32cd0fe1]:first-child,.waiting-table td[data-v-32cd0fe1]:first-child{width:auto;padding:4px 8px}@media (max-width: 1399px){.grid-two{margin:0 0 -10px;width:100%;max-width:600px}.grid-left{display:grid;row-gap:10px;grid-template-columns:100%}.grid-right{display:grid;row-gap:10px;grid-template-columns:100%;margin-top:10px}}@media (min-width: 1400px){.grid-two{display:grid;grid-template-columns:minmax(0px,1fr) minmax(0px,1fr);align-items:flex-start;gap:5px}.grid-left,.grid-right{display:grid;gap:5px;grid-template-columns:100%;max-width:600px}}.n-divider:not(.n-divider--vertical){margin:14px 0 8px}

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
import{c as Q,q as kt,w as lt,u as Ct,ai as qe,H as c,as as b,av as O,ar as E,z as Ue,ay as le,B as Z,ax as Te,r as K,D as Oe,aZ as Ie,j as _,aB as ne,ak as St,au as G,b as D,L as Be,bN as Pt,s as $t,aY as re,aC as Ve,aD as _t,aG as Ft,l as Le,bH as be,b2 as J,N as Ot,bO as We,b4 as Bt,be as st,A as qt,az as Tt,b3 as Se,bh as zt,bg as It,bF as Lt,aI as jt,T as At,F as Dt,aL as He,n as Et,br as Mt,bP as Nt,bQ as Ut,bt as Vt,bu as Wt,bv as Ht,bw as Gt,bo as Pe}from"./_plugin-vue_export-helper.js";import{F as dt,G as ut,H as Xt,S as ct,I as ft,W as gt,J as ht,K as Yt,A as Kt,L as Ge,M as Zt,s as Jt,j as Qt,N as er,O as tr}from"./main.js";import{_ as rr,D as nr,N as ir}from"./Image.js";import{E as ar}from"./Input.js";import{d as or}from"./download.js";import{m as lr}from"./index.js";import{r as sr,M as dr}from"./op_select.js";import{_ as ur}from"./Select.js";function cr(t,e,r){var n;const i=Q(t,null);if(i===null)return;const a=(n=kt())===null||n===void 0?void 0:n.proxy;lt(r,o),o(r.value),Ct(()=>{o(void 0,r.value)});function o(u,s){if(!i)return;const f=i[e];s!==void 0&&l(f,s),u!==void 0&&d(f,u)}function l(u,s){u[s]||(u[s]=[]),u[s].splice(u[s].findIndex(f=>f===a),1)}function d(u,s){u[s]||(u[s]=[]),~u[s].findIndex(f=>f===a)||u[s].push(a)}}const fr=qe("attach",c("svg",{viewBox:"0 0 16 16",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},c("g",{stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},c("g",{fill:"currentColor","fill-rule":"nonzero"},c("path",{d:"M3.25735931,8.70710678 L7.85355339,4.1109127 C8.82986412,3.13460197 10.4127766,3.13460197 11.3890873,4.1109127 C12.365398,5.08722343 12.365398,6.67013588 11.3890873,7.64644661 L6.08578644,12.9497475 C5.69526215,13.3402718 5.06209717,13.3402718 4.67157288,12.9497475 C4.28104858,12.5592232 4.28104858,11.9260582 4.67157288,11.5355339 L9.97487373,6.23223305 C10.1701359,6.0369709 10.1701359,5.72038841 9.97487373,5.52512627 C9.77961159,5.32986412 9.4630291,5.32986412 9.26776695,5.52512627 L3.96446609,10.8284271 C3.18341751,11.6094757 3.18341751,12.8758057 3.96446609,13.6568542 C4.74551468,14.4379028 6.01184464,14.4379028 6.79289322,13.6568542 L12.0961941,8.35355339 C13.4630291,6.98671837 13.4630291,4.77064094 12.0961941,3.40380592 C10.7293591,2.0369709 8.51328163,2.0369709 7.14644661,3.40380592 L2.55025253,8 C2.35499039,8.19526215 2.35499039,8.51184464 2.55025253,8.70710678 C2.74551468,8.90236893 3.06209717,8.90236893 3.25735931,8.70710678 Z"}))))),gr=qe("trash",c("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},c("path",{d:"M432,144,403.33,419.74A32,32,0,0,1,371.55,448H140.46a32,32,0,0,1-31.78-28.26L80,144",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}),c("rect",{x:"32",y:"64",width:"448",height:"80",rx:"16",ry:"16",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}),c("line",{x1:"312",y1:"240",x2:"200",y2:"352",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}),c("line",{x1:"312",y1:"352",x2:"200",y2:"240",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}))),hr=qe("cancel",c("svg",{viewBox:"0 0 16 16",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},c("g",{stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},c("g",{fill:"currentColor","fill-rule":"nonzero"},c("path",{d:"M2.58859116,2.7156945 L2.64644661,2.64644661 C2.82001296,2.47288026 3.08943736,2.45359511 3.2843055,2.58859116 L3.35355339,2.64644661 L8,7.293 L12.6464466,2.64644661 C12.8417088,2.45118446 13.1582912,2.45118446 13.3535534,2.64644661 C13.5488155,2.84170876 13.5488155,3.15829124 13.3535534,3.35355339 L8.707,8 L13.3535534,12.6464466 C13.5271197,12.820013 13.5464049,13.0894374 13.4114088,13.2843055 L13.3535534,13.3535534 C13.179987,13.5271197 12.9105626,13.5464049 12.7156945,13.4114088 L12.6464466,13.3535534 L8,8.707 L3.35355339,13.3535534 C3.15829124,13.5488155 2.84170876,13.5488155 2.64644661,13.3535534 C2.45118446,13.1582912 2.45118446,12.8417088 2.64644661,12.6464466 L7.293,8 L2.64644661,3.35355339 C2.47288026,3.17998704 2.45359511,2.91056264 2.58859116,2.7156945 L2.64644661,2.64644661 L2.58859116,2.7156945 Z"}))))),pr=qe("retry",c("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},c("path",{d:"M320,146s24.36-12-64-12A160,160,0,1,0,416,294",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-miterlimit: 10; stroke-width: 32px;"}),c("polyline",{points:"256 58 336 138 256 218",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}))),mr=b("form",[O("inline",`
import{c as Q,q as kt,w as lt,u as Ct,ai as qe,H as c,as as b,av as O,ar as E,z as Ue,ay as le,B as Z,ax as Te,r as K,D as Oe,aZ as Ie,j as _,aB as ne,ak as St,au as G,b as D,L as Be,bN as Pt,s as $t,aY as re,aC as Ve,aD as _t,aG as Ft,l as Le,bH as be,b2 as J,N as Ot,bO as We,b4 as Bt,be as st,A as qt,az as Tt,b3 as Se,bh as zt,bg as It,bF as Lt,aI as jt,T as At,F as Dt,aL as He,n as Et,br as Mt,bP as Nt,bQ as Ut,bt as Vt,bu as Wt,bv as Ht,bw as Gt,bo as Pe}from"./_plugin-vue_export-helper.js";import{F as dt,G as ut,H as Xt,S as ct,I as ft,W as gt,J as ht,K as Yt,A as Kt,L as Ge,M as Zt,s as Jt,j as Qt,N as er,O as tr}from"./main.js";import{_ as rr,D as nr,N as ir}from"./Scrollbar.js";import{E as ar}from"./Input.js";import{d as or}from"./download.js";import{m as lr}from"./index.js";import{r as sr,M as dr}from"./op_select.js";import{_ as ur}from"./Select.js";function cr(t,e,r){var n;const i=Q(t,null);if(i===null)return;const a=(n=kt())===null||n===void 0?void 0:n.proxy;lt(r,o),o(r.value),Ct(()=>{o(void 0,r.value)});function o(u,s){if(!i)return;const f=i[e];s!==void 0&&l(f,s),u!==void 0&&d(f,u)}function l(u,s){u[s]||(u[s]=[]),u[s].splice(u[s].findIndex(f=>f===a),1)}function d(u,s){u[s]||(u[s]=[]),~u[s].findIndex(f=>f===a)||u[s].push(a)}}const fr=qe("attach",c("svg",{viewBox:"0 0 16 16",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},c("g",{stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},c("g",{fill:"currentColor","fill-rule":"nonzero"},c("path",{d:"M3.25735931,8.70710678 L7.85355339,4.1109127 C8.82986412,3.13460197 10.4127766,3.13460197 11.3890873,4.1109127 C12.365398,5.08722343 12.365398,6.67013588 11.3890873,7.64644661 L6.08578644,12.9497475 C5.69526215,13.3402718 5.06209717,13.3402718 4.67157288,12.9497475 C4.28104858,12.5592232 4.28104858,11.9260582 4.67157288,11.5355339 L9.97487373,6.23223305 C10.1701359,6.0369709 10.1701359,5.72038841 9.97487373,5.52512627 C9.77961159,5.32986412 9.4630291,5.32986412 9.26776695,5.52512627 L3.96446609,10.8284271 C3.18341751,11.6094757 3.18341751,12.8758057 3.96446609,13.6568542 C4.74551468,14.4379028 6.01184464,14.4379028 6.79289322,13.6568542 L12.0961941,8.35355339 C13.4630291,6.98671837 13.4630291,4.77064094 12.0961941,3.40380592 C10.7293591,2.0369709 8.51328163,2.0369709 7.14644661,3.40380592 L2.55025253,8 C2.35499039,8.19526215 2.35499039,8.51184464 2.55025253,8.70710678 C2.74551468,8.90236893 3.06209717,8.90236893 3.25735931,8.70710678 Z"}))))),gr=qe("trash",c("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},c("path",{d:"M432,144,403.33,419.74A32,32,0,0,1,371.55,448H140.46a32,32,0,0,1-31.78-28.26L80,144",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}),c("rect",{x:"32",y:"64",width:"448",height:"80",rx:"16",ry:"16",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}),c("line",{x1:"312",y1:"240",x2:"200",y2:"352",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}),c("line",{x1:"312",y1:"352",x2:"200",y2:"240",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}))),hr=qe("cancel",c("svg",{viewBox:"0 0 16 16",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},c("g",{stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},c("g",{fill:"currentColor","fill-rule":"nonzero"},c("path",{d:"M2.58859116,2.7156945 L2.64644661,2.64644661 C2.82001296,2.47288026 3.08943736,2.45359511 3.2843055,2.58859116 L3.35355339,2.64644661 L8,7.293 L12.6464466,2.64644661 C12.8417088,2.45118446 13.1582912,2.45118446 13.3535534,2.64644661 C13.5488155,2.84170876 13.5488155,3.15829124 13.3535534,3.35355339 L8.707,8 L13.3535534,12.6464466 C13.5271197,12.820013 13.5464049,13.0894374 13.4114088,13.2843055 L13.3535534,13.3535534 C13.179987,13.5271197 12.9105626,13.5464049 12.7156945,13.4114088 L12.6464466,13.3535534 L8,8.707 L3.35355339,13.3535534 C3.15829124,13.5488155 2.84170876,13.5488155 2.64644661,13.3535534 C2.45118446,13.1582912 2.45118446,12.8417088 2.64644661,12.6464466 L7.293,8 L2.64644661,3.35355339 C2.47288026,3.17998704 2.45359511,2.91056264 2.58859116,2.7156945 L2.64644661,2.64644661 L2.58859116,2.7156945 Z"}))))),pr=qe("retry",c("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},c("path",{d:"M320,146s24.36-12-64-12A160,160,0,1,0,416,294",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-miterlimit: 10; stroke-width: 32px;"}),c("polyline",{points:"256 58 336 138 256 218",style:"fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"}))),mr=b("form",[O("inline",`
width: 100%;
display: inline-flex;
align-items: flex-start;

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
var _r=Object.defineProperty;var Fr=(t,n,e)=>n in t?_r(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var h=(t,n,e)=>Fr(t,typeof n!="symbol"?n+"":n,e);import{B as le,H as u,ai as Rr,bH as Vr,z as En,c as bt,j as F,r as te,b3 as De,b8 as at,ar as V,as as K,av as se,au as Ye,at as An,ay as fe,ax as Je,bF as $n,w as lt,b as Be,aI as Xt,n as ut,D as zn,aC as dt,J as Yr,b2 as ke,aD as Hr,E as Sr,aL as Z,M as Br,ap as Un,an as Ln,aO as qn,aV as Wn,bN as Er,b0 as vt,b4 as ft,bM as dn,bR as Nt,t as _t,L as Ar,N as $r,aY as ct,bS as zr,bj as fn,C as Ur,A as Pe,aj as Lr,aG as mn,v as hn,bL as gn,a_ as qr,bT as Wr}from"./_plugin-vue_export-helper.js";import{m as k,o as Te,P as et,Q as jr,f as Qr,b as qt,R as Gr,n as Xr,B as Zr,V as Kr,h as Jr,i as ea,q as pn,r as ta,T as na,A as Wt,U as ra,X as aa,Y as oa}from"./main.js";import{e as jn,u as Zt}from"./use-locale.js";import{F as ia,A as sa}from"./Select.js";import{_ as Ze}from"./Input.js";import{_ as la}from"./Scrollbar.js";import{g as ua}from"./get-slot.js";import{m as ca}from"./index.js";import{_ as Qn}from"./Avatar.js";import{_ as da}from"./Tag.js";const fa=le({name:"ArrowUp",render(){return u("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20"},u("g",{fill:"none"},u("path",{d:"M3.13 9.163a.5.5 0 1 0 .74.674L9.5 3.67V17.5a.5.5 0 0 0 1 0V3.672l5.63 6.165a.5.5 0 0 0 .738-.674l-6.315-6.916a.746.746 0 0 0-.632-.24a.746.746 0 0 0-.476.24L3.131 9.163z",fill:"currentColor"})))}}),Gn=le({name:"Remove",render(){return u("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},u("line",{x1:"400",y1:"256",x2:"112",y2:"256",style:`
var _r=Object.defineProperty;var Fr=(t,n,e)=>n in t?_r(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var h=(t,n,e)=>Fr(t,typeof n!="symbol"?n+"":n,e);import{B as le,H as u,ai as Rr,bH as Vr,z as En,c as bt,j as F,r as te,b3 as De,b8 as at,ar as V,as as K,av as se,au as Ye,at as An,ay as fe,ax as Je,bF as $n,w as lt,b as Be,aI as Xt,n as ut,D as zn,aC as dt,J as Yr,b2 as ke,aD as Hr,E as Sr,aL as Z,M as Br,ap as Un,an as Ln,aO as qn,aV as Wn,bN as Er,b0 as vt,b4 as ft,bM as dn,bR as Nt,t as _t,L as Ar,N as $r,aY as ct,bS as zr,bj as fn,C as Ur,A as Pe,aj as Lr,aG as mn,v as hn,bL as gn,a_ as qr,bT as Wr}from"./_plugin-vue_export-helper.js";import{m as k,o as Te,P as et,Q as jr,f as Qr,b as qt,R as Gr,n as Xr,B as Zr,V as Kr,h as Jr,i as ea,q as pn,r as ta,T as na,A as Wt,U as ra,X as aa,Y as oa}from"./main.js";import{e as jn,u as Zt}from"./use-locale.js";import{F as ia,A as sa}from"./Select.js";import{_ as Ze}from"./Input.js";import{a as la}from"./Scrollbar.js";import{g as ua}from"./get-slot.js";import{m as ca}from"./index.js";import{_ as Qn}from"./Avatar.js";import{_ as da}from"./Tag.js";const fa=le({name:"ArrowUp",render(){return u("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20"},u("g",{fill:"none"},u("path",{d:"M3.13 9.163a.5.5 0 1 0 .74.674L9.5 3.67V17.5a.5.5 0 0 0 1 0V3.672l5.63 6.165a.5.5 0 0 0 .738-.674l-6.315-6.916a.746.746 0 0 0-.632-.24a.746.746 0 0 0-.476.24L3.131 9.163z",fill:"currentColor"})))}}),Gn=le({name:"Remove",render(){return u("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},u("line",{x1:"400",y1:"256",x2:"112",y2:"256",style:`
fill: none;
stroke: currentColor;
stroke-linecap: round;

BIN
ui/public/black.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -3,7 +3,7 @@ import { storeToRefs } from 'pinia'
import { useMowerStore } from '@/stores/mower'
const mower_store = useMowerStore()
const { log, log_mobile, running, log_lines, task_list, waiting, get_task_id } =
const { log, log_mobile, running, log_lines, task_list, waiting, get_task_id, sc_uri } =
storeToRefs(mower_store)
const { get_tasks } = mower_store
const axios = inject('axios')
@ -54,19 +54,19 @@ function stop() {
})
}
import PlayIcon from '@vicons/ionicons5/Play'
import StopIcon from '@vicons/ionicons5/Stop'
import AddIcon from '@vicons/ionicons5/Add'
import { useConfigStore } from '@/stores/config'
import FullscreenIcon from '@vicons/fluent/ArrowMaximize20Regular'
import CollapseIcon from '@vicons/fluent/PanelTopContract20Regular'
import ExpandIcon from '@vicons/fluent/PanelTopExpand20Regular'
import FullscreenIcon from '@vicons/fluent/ArrowMaximize20Regular'
import AddIcon from '@vicons/ionicons5/Add'
import PlayIcon from '@vicons/ionicons5/Play'
import StopIcon from '@vicons/ionicons5/Stop'
const show_task_table = ref(true)
const show_task = ref(false)
const add_task = ref(true)
provide('show_task', show_task)
provide('add_task', add_task)
import { useConfigStore } from '@/stores/config'
const config_store = useConfigStore()
const { conf } = storeToRefs(config_store)
@ -88,13 +88,23 @@ const stop_options = [
function fullscreen() {
document.documentElement.requestFullscreen()
}
const sc_preview = ref(true)
</script>
<template>
<div class="home-container">
<div class="log-bg"></div>
<n-image
v-if="sc_preview"
preview-disabled
width="100%"
class="sc"
:src="sc_uri == '' ? '/black.jpg' : sc_uri"
object-fit="scale-down"
/>
<n-table class="task-table" size="small" :single-line="false">
<thead>
<thead @click="sc_preview = !sc_preview">
<tr>
<th>时间</th>
<th :colspan="2">任务</th>
@ -121,6 +131,33 @@ function fullscreen() {
</tr>
</template>
</tbody>
<n-button
class="toggle-table-collapse-btn"
size="small"
@click="show_task_table = !show_task_table"
:focusable="false"
v-if="mobile"
>
<template #icon>
<n-icon>
<collapse-icon v-if="show_task_table" />
<expand-icon v-else />
</n-icon>
</template>
</n-button>
<n-button
class="toggle-fullscreen-btn"
size="small"
@click="fullscreen"
:focusable="false"
v-if="mobile"
>
<template #icon>
<n-icon>
<fullscreen-icon />
</n-icon>
</template>
</n-button>
</n-table>
<n-log
class="log"
@ -172,33 +209,6 @@ function fullscreen() {
<span class="scroll-label" v-if="!mobile">自动滚动</span>
</div>
</div>
<n-button
class="toggle-table-collapse-btn"
size="small"
@click="show_task_table = !show_task_table"
:focusable="false"
v-if="mobile"
>
<template #icon>
<n-icon>
<collapse-icon v-if="show_task_table" />
<expand-icon v-else />
</n-icon>
</template>
</n-button>
<n-button
class="toggle-fullscreen-btn"
size="small"
@click="fullscreen"
:focusable="false"
v-if="mobile"
>
<template #icon>
<n-icon>
<fullscreen-icon />
</n-icon>
</template>
</n-button>
</div>
</template>
@ -209,6 +219,7 @@ function fullscreen() {
}
.task-table {
position: relative;
max-width: 600px;
th {
@ -243,14 +254,14 @@ function fullscreen() {
.toggle-table-collapse-btn {
position: absolute;
top: 12px;
right: 12px;
top: 0;
right: 0;
}
.toggle-fullscreen-btn {
position: absolute;
top: 12px;
right: 50px;
top: 0;
right: 38px;
}
.log-bg {
@ -266,6 +277,14 @@ function fullscreen() {
background-size: cover;
background-position: 65% 50%;
pointer-events: none;
z-index: 14;
}
.sc {
max-width: 480px;
max-height: 270px;
border-radius: 6px;
z-index: 15;
}
</style>

View file

@ -95,6 +95,9 @@ const app_control_options = computed(() => {
if (conf.value.emulator.name == 'MuMu12') {
result.push({ label: 'MuMu模拟器12应用管理器', value: 'mumumanager' })
}
if (conf.value.screencap_strategy == 'scrcpy' && conf.value.control_strategy == 'scrcpy') {
result.push({ label: 'scrcpy virtual display', value: 'scrcpy' })
}
return result
})

View file

@ -36,6 +36,8 @@ export const useMowerStore = defineStore('mower', () => {
const { conf, timestamp, post_conf } = storeToRefs(config_store)
const { parse_config } = config_store
const sc_uri = ref('')
function listen_ws() {
let backend_url
if (import.meta.env.DEV) {
@ -55,6 +57,8 @@ export const useMowerStore = defineStore('mower', () => {
timestamp.value = data.time
conf.value = parse_config(data.data)
}
} else if (data.type == 'sc') {
sc_uri.value = data.data
}
}
}
@ -79,6 +83,7 @@ export const useMowerStore = defineStore('mower', () => {
log_mobile,
log_lines,
ws,
sc_uri,
running,
waiting,
listen_ws,