Merge branch 'main' of https://git.zhaozuohong.vip/mower-ng/mower-ng
This commit is contained in:
commit
20e8a59b62
9 changed files with 146 additions and 67 deletions
|
@ -346,6 +346,12 @@ class EmulatorPart(ConfModel):
|
||||||
rotate: bool = False
|
rotate: bool = False
|
||||||
"将截图旋转180度"
|
"将截图旋转180度"
|
||||||
|
|
||||||
|
class DroidCastRawConf(ConfModel):
|
||||||
|
orientation: Literal["portrait", "landscape"] = "landscape"
|
||||||
|
"屏幕方向"
|
||||||
|
rotate: Literal[0, 90, 180, 270] = 0
|
||||||
|
"截图旋转角度"
|
||||||
|
|
||||||
adb: str = "127.0.0.1:16384"
|
adb: str = "127.0.0.1:16384"
|
||||||
"ADB连接地址"
|
"ADB连接地址"
|
||||||
emulator: EmulatorConf
|
emulator: EmulatorConf
|
||||||
|
@ -356,6 +362,8 @@ class EmulatorPart(ConfModel):
|
||||||
"游戏服务器"
|
"游戏服务器"
|
||||||
droidcast: DroidCastConf
|
droidcast: DroidCastConf
|
||||||
"DroidCast截图设置"
|
"DroidCast截图设置"
|
||||||
|
droidcast_raw: DroidCastRawConf
|
||||||
|
"DroidCast截图设置"
|
||||||
custom_screenshot: CustomScreenshotConf
|
custom_screenshot: CustomScreenshotConf
|
||||||
"自定义截图"
|
"自定义截图"
|
||||||
tap_to_launch_game: TapToLaunchGameConf
|
tap_to_launch_game: TapToLaunchGameConf
|
||||||
|
@ -369,10 +377,11 @@ class EmulatorPart(ConfModel):
|
||||||
screencap_strategy: Literal[
|
screencap_strategy: Literal[
|
||||||
"adb",
|
"adb",
|
||||||
"droidcast",
|
"droidcast",
|
||||||
|
"droidcast_raw",
|
||||||
"mumuipc",
|
"mumuipc",
|
||||||
"diy",
|
"diy",
|
||||||
"scrcpy",
|
"scrcpy",
|
||||||
] = "droidcast"
|
] = "droidcast_raw"
|
||||||
"截图方案"
|
"截图方案"
|
||||||
control_strategy: Literal["scrcpy", "mumuipc"] = "scrcpy"
|
control_strategy: Literal["scrcpy", "mumuipc"] = "scrcpy"
|
||||||
"触控方案"
|
"触控方案"
|
||||||
|
|
|
@ -12,6 +12,7 @@ from mower.utils.log import logger, save_screenshot
|
||||||
method_map = {
|
method_map = {
|
||||||
"adb": "mower.utils.device.method.adb.ADB",
|
"adb": "mower.utils.device.method.adb.ADB",
|
||||||
"droidcast": "mower.utils.device.method.droidcast.DroidCast",
|
"droidcast": "mower.utils.device.method.droidcast.DroidCast",
|
||||||
|
"droidcast_raw": "mower.utils.device.method.droidcast.DroidCast_raw",
|
||||||
"scrcpy": "mower.utils.device.method.scrcpy.Scrcpy",
|
"scrcpy": "mower.utils.device.method.scrcpy.Scrcpy",
|
||||||
"mumuipc": "mower.utils.device.method.mumu_ipc.MuMu12IPC",
|
"mumuipc": "mower.utils.device.method.mumu_ipc.MuMu12IPC",
|
||||||
"diy": "mower.utils.device.method.adb.DIY",
|
"diy": "mower.utils.device.method.adb.DIY",
|
||||||
|
|
|
@ -285,7 +285,7 @@ class ADB:
|
||||||
dpi = (override_dpi or physical_dpi).partition("density:")[2].strip()
|
dpi = (override_dpi or physical_dpi).partition("density:")[2].strip()
|
||||||
if (
|
if (
|
||||||
config.conf.emulator.name == "MuMu12"
|
config.conf.emulator.name == "MuMu12"
|
||||||
and config.conf.screencap_strategy == "droidcast"
|
and config.conf.screencap_strategy.startswith("droidcast")
|
||||||
):
|
):
|
||||||
from mower.utils.device.method.mumumanager import MuMuManager
|
from mower.utils.device.method.mumumanager import MuMuManager
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,16 @@ import time
|
||||||
from functools import cached_property, wraps
|
from functools import cached_property, wraps
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
|
import numpy as np
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from mower import __rootdir__
|
|
||||||
from mower.utils import config
|
from mower.utils import config
|
||||||
from mower.utils.csleep import MowerExit
|
from mower.utils.csleep import MowerExit
|
||||||
from mower.utils.device.method.adb import ADB
|
from mower.utils.device.method.adb import ADB
|
||||||
from mower.utils.image import bytes2img
|
from mower.utils.image import bytes2img
|
||||||
from mower.utils.log import logger
|
from mower.utils.log import logger
|
||||||
from mower.utils.network import get_new_port, is_port_in_use
|
from mower.utils.network import get_new_port, is_port_in_use
|
||||||
|
from mower.utils.path import get_path
|
||||||
|
|
||||||
|
|
||||||
def retry_droidcast(func):
|
def retry_droidcast(func):
|
||||||
|
@ -29,6 +30,10 @@ def retry_droidcast(func):
|
||||||
|
|
||||||
|
|
||||||
class DroidCast:
|
class DroidCast:
|
||||||
|
display_name = "DroidCast"
|
||||||
|
package_name = "com.rayworks.droidcast"
|
||||||
|
apk_file = "DroidCast-debug-1.2.1.apk"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.session = requests.Session()
|
self.session = requests.Session()
|
||||||
self.port = 0
|
self.port = 0
|
||||||
|
@ -40,7 +45,7 @@ class DroidCast:
|
||||||
|
|
||||||
def get_droidcast_classpath(self) -> str | None:
|
def get_droidcast_classpath(self) -> str | None:
|
||||||
# TODO: 退出时(并非结束mower线程时)关闭DroidCast进程、取消ADB转发
|
# TODO: 退出时(并非结束mower线程时)关闭DroidCast进程、取消ADB转发
|
||||||
out = self.adb.adb_shell("pm path com.rayworks.droidcast")
|
out = self.adb.adb_shell(f"pm path {self.package_name}")
|
||||||
if out is None:
|
if out is None:
|
||||||
logger.exception("无法获取CLASSPATH")
|
logger.exception("无法获取CLASSPATH")
|
||||||
return None
|
return None
|
||||||
|
@ -54,15 +59,18 @@ class DroidCast:
|
||||||
return class_path
|
return class_path
|
||||||
|
|
||||||
def start_droidcast(self) -> bool:
|
def start_droidcast(self) -> bool:
|
||||||
class_path = self.get_droidcast_classpath()
|
try:
|
||||||
|
class_path = self.get_droidcast_classpath()
|
||||||
|
except Exception:
|
||||||
|
class_path = None
|
||||||
if not class_path:
|
if not class_path:
|
||||||
logger.info("安装DroidCast")
|
logger.info(f"安装{self.display_name}")
|
||||||
apk_path = f"{__rootdir__}/vendor/DroidCast-debug-1.2.1.apk"
|
|
||||||
try:
|
try:
|
||||||
self.adb.adb.install(apk_path)
|
apk_path = get_path(f"@install/mower/vendor/{self.apk_file}")
|
||||||
logger.info("DroidCast安装完成,获取CLASSPATH")
|
self.adb.adb.install(str(apk_path))
|
||||||
|
logger.info(f"{self.display_name}安装完成,获取CLASSPATH")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"DroidCast安装失败: {e}")
|
logger.error(f"{self.display_name}安装失败: {e}")
|
||||||
return False
|
return False
|
||||||
class_path = self.get_droidcast_classpath()
|
class_path = self.get_droidcast_classpath()
|
||||||
if not class_path:
|
if not class_path:
|
||||||
|
@ -83,24 +91,68 @@ class DroidCast:
|
||||||
if port == 0:
|
if port == 0:
|
||||||
port = get_new_port()
|
port = get_new_port()
|
||||||
self.port = port
|
self.port = port
|
||||||
logger.info(f"更新DroidCast端口为{port}")
|
logger.info(f"更新{self.display_name}端口为{port}")
|
||||||
else:
|
else:
|
||||||
logger.info(f"保持DroidCast端口为{port}")
|
logger.info(f"保持{self.display_name}端口为{port}")
|
||||||
self.adb.adb.forward(f"tcp:{port}", f"tcp:{port}")
|
self.adb.adb.forward(f"tcp:{port}", f"tcp:{port}")
|
||||||
logger.info("ADB端口转发成功,启动DroidCast")
|
logger.info("ADB端口转发成功,启动{self.display_name}")
|
||||||
cmd = f"{class_path} app_process / com.rayworks.droidcast.Main --port={port}"
|
cmd = f"{class_path} app_process / {self.package_name}.Main --port={port}"
|
||||||
self.socket = self.adb.adb_shell(cmd, True)
|
self.socket = self.adb.adb_shell(cmd, True)
|
||||||
time.sleep(1) # TODO: 更好地等待DroidCast启动
|
time.sleep(1) # TODO: 更好地等待DroidCast启动
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@retry_droidcast
|
def decode(self, data):
|
||||||
def capture_display(self):
|
img = bytes2img(data)
|
||||||
if self.port == 0:
|
|
||||||
raise Exception("DroidCast未启动")
|
|
||||||
url = f"http://127.0.0.1:{self.port}/screenshot"
|
|
||||||
logger.debug(f"GET {url}")
|
|
||||||
r = self.session.get(url)
|
|
||||||
img = bytes2img(r.content)
|
|
||||||
if config.conf.droidcast.rotate:
|
if config.conf.droidcast.rotate:
|
||||||
img = cv2.rotate(img, cv2.ROTATE_180)
|
img = cv2.rotate(img, cv2.ROTATE_180)
|
||||||
return img
|
return img
|
||||||
|
|
||||||
|
@retry_droidcast
|
||||||
|
def capture_display(self):
|
||||||
|
if self.port == 0:
|
||||||
|
raise Exception(f"{self.display_name}未启动")
|
||||||
|
url = f"http://127.0.0.1:{self.port}/screenshot"
|
||||||
|
logger.debug(f"GET {url}")
|
||||||
|
r = self.session.get(url)
|
||||||
|
return self.decode(r.content)
|
||||||
|
|
||||||
|
|
||||||
|
class DroidCast_raw(DroidCast):
|
||||||
|
display_name = "DroidCast_raw"
|
||||||
|
package_name = "ink.mol.droidcast_raw"
|
||||||
|
apk_file = "DroidCast_raw-release-1.1.apk"
|
||||||
|
|
||||||
|
def decode(self, data):
|
||||||
|
# https://github.com/LmeSzinc/StarRailCopilot/blob/bf62eccaaa6f46ea9796a83175df0ab7882dd137/module/device/method/droidcast.py#L226
|
||||||
|
arr = np.frombuffer(data, dtype=np.uint16)
|
||||||
|
if config.conf.droidcast_raw.orientation == "portrait":
|
||||||
|
shape = (1080, 1920)
|
||||||
|
else:
|
||||||
|
shape = (1920, 1080)
|
||||||
|
arr = arr.reshape(shape)
|
||||||
|
|
||||||
|
r = cv2.bitwise_and(arr, 0b1111100000000000)
|
||||||
|
r = cv2.convertScaleAbs(r, alpha=0.00390625)
|
||||||
|
m = cv2.convertScaleAbs(r, alpha=0.03125)
|
||||||
|
cv2.add(r, m, dst=r)
|
||||||
|
|
||||||
|
g = cv2.bitwise_and(arr, 0b0000011111100000)
|
||||||
|
g = cv2.convertScaleAbs(g, alpha=0.125)
|
||||||
|
m = cv2.convertScaleAbs(g, alpha=0.015625, dst=m)
|
||||||
|
cv2.add(g, m, dst=g)
|
||||||
|
|
||||||
|
b = cv2.bitwise_and(arr, 0b0000000000011111)
|
||||||
|
b = cv2.convertScaleAbs(b, alpha=8)
|
||||||
|
m = cv2.convertScaleAbs(b, alpha=0.03125, dst=m)
|
||||||
|
cv2.add(b, m, dst=b)
|
||||||
|
|
||||||
|
img = cv2.merge([r, g, b])
|
||||||
|
|
||||||
|
if config.conf.droidcast_raw.rotate == 90:
|
||||||
|
img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
|
||||||
|
elif config.conf.droidcast_raw.rotate == 180:
|
||||||
|
img = cv2.rotate(img, cv2.ROTATE_180)
|
||||||
|
elif config.conf.droidcast_raw.rotate == 270:
|
||||||
|
img = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
||||||
|
|
||||||
|
return img
|
||||||
|
|
|
@ -145,7 +145,10 @@ class MuMuManager:
|
||||||
width = int(float(self.get_field_value(data, "resolution_width.custom")))
|
width = int(float(self.get_field_value(data, "resolution_width.custom")))
|
||||||
height = int(float(self.get_field_value(data, "resolution_height.custom")))
|
height = int(float(self.get_field_value(data, "resolution_height.custom")))
|
||||||
dpi = int(float(self.get_field_value(data, "resolution_dpi.custom")))
|
dpi = int(float(self.get_field_value(data, "resolution_dpi.custom")))
|
||||||
if config.conf.screencap_strategy == "droidcast" and self.app_kept_alive():
|
if (
|
||||||
|
config.conf.screencap_strategy.startswith("droidcast")
|
||||||
|
and self.app_kept_alive()
|
||||||
|
):
|
||||||
logger.error("MuMu12的droidcast截图策略下,需要关闭应用后台保活")
|
logger.error("MuMu12的droidcast截图策略下,需要关闭应用后台保活")
|
||||||
try:
|
try:
|
||||||
self.set_app_kept_alive_false()
|
self.set_app_kept_alive_false()
|
||||||
|
|
BIN
mower/vendor/DroidCast_raw-release-1.1.apk
vendored
Normal file
BIN
mower/vendor/DroidCast_raw-release-1.1.apk
vendored
Normal file
Binary file not shown.
2
ui/dist/assets/Settings.css
vendored
2
ui/dist/assets/Settings.css
vendored
|
@ -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-43df5096]{display:flex;align-items:center;gap:14px;width:100%}.mower-basic[data-v-43df5096]{width:100%}.mower-basic td[data-v-43df5096]:nth-child(1){width:120px}.mower-basic td[data-v-43df5096]:nth-child(3){padding-left:6px;width:40px}.riic-conf[data-v-43df5096]{width:100%}.riic-conf td[data-v-43df5096]:nth-child(1){width:130px}.riic-conf td[data-v-43df5096]:nth-child(3){padding-left:12px;width:120px}.coord td[data-v-43df5096]{width:120px}.coord td[data-v-43df5096]:nth-child(1),.coord td[data-v-43df5096]:nth-child(3){width:30px}.coord td[data-v-43df5096]:nth-child(2){padding-right:30px}.coord-label[data-v-43df5096]{width:40px;padding-left:8px}p[data-v-43df5096]{margin:0 0 8px}h4[data-v-43df5096]{margin:12px 0 10px}.time-table[data-v-43df5096]{width:100%;margin-bottom:12px}.time-table td[data-v-43df5096]:nth-child(1){width:40px}.scale[data-v-43df5096]{width:60px;text-align:right}.scale-apply[data-v-43df5096]{margin-left:24px}.waiting-table th[data-v-43df5096],.waiting-table td[data-v-43df5096]{padding:4px;min-width:70px;width:100px}.waiting-table th[data-v-43df5096]:first-child,.waiting-table td[data-v-43df5096]: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-58034e1c]{display:flex;align-items:center;gap:14px;width:100%}.mower-basic[data-v-58034e1c]{width:100%}.mower-basic td[data-v-58034e1c]:nth-child(1){width:120px}.mower-basic td[data-v-58034e1c]:nth-child(3){padding-left:6px;width:40px}.riic-conf[data-v-58034e1c]{width:100%}.riic-conf td[data-v-58034e1c]:nth-child(1){width:130px}.riic-conf td[data-v-58034e1c]:nth-child(3){padding-left:12px;width:120px}.coord td[data-v-58034e1c]{width:120px}.coord td[data-v-58034e1c]:nth-child(1),.coord td[data-v-58034e1c]:nth-child(3){width:30px}.coord td[data-v-58034e1c]:nth-child(2){padding-right:30px}.coord-label[data-v-58034e1c]{width:40px;padding-left:8px}p[data-v-58034e1c]{margin:0 0 8px}h4[data-v-58034e1c]{margin:12px 0 10px}.time-table[data-v-58034e1c]{width:100%;margin-bottom:12px}.time-table td[data-v-58034e1c]:nth-child(1){width:40px}.scale[data-v-58034e1c]{width:60px;text-align:right}.scale-apply[data-v-58034e1c]{margin-left:24px}.waiting-table th[data-v-58034e1c],.waiting-table td[data-v-58034e1c]{padding:4px;min-width:70px;width:100px}.waiting-table th[data-v-58034e1c]:first-child,.waiting-table td[data-v-58034e1c]: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}
|
||||||
|
|
58
ui/dist/assets/Settings.js
vendored
58
ui/dist/assets/Settings.js
vendored
File diff suppressed because one or more lines are too long
|
@ -70,9 +70,10 @@ async function select_maa_adb_path() {
|
||||||
|
|
||||||
const screencap_options = computed(() => {
|
const screencap_options = computed(() => {
|
||||||
const result = [
|
const result = [
|
||||||
{ label: 'ADB+Gzip(主动截图,无损压缩,兼容性好,速度慢)', value: 'adb' },
|
{ label: 'DroidCast_raw(主动,无损,较快)', value: 'droidcast_raw' },
|
||||||
{ label: 'DroidCast(主动截图,有损压缩,速度较快)', value: 'droidcast' },
|
{ label: 'ADB+Gzip(主动,无损,很慢)', value: 'adb' },
|
||||||
{ label: 'scrcpy(被动截图,有损压缩,视频流,特殊)', value: 'scrcpy' },
|
{ label: 'DroidCast(主动,有损,较快)', value: 'droidcast' },
|
||||||
|
{ label: 'scrcpy(被动,有损,特殊)', value: 'scrcpy' },
|
||||||
{ label: '自定义(以下命令需要向STDOUT打印截图文件)', value: 'diy' }
|
{ label: '自定义(以下命令需要向STDOUT打印截图文件)', value: 'diy' }
|
||||||
]
|
]
|
||||||
if (conf.value.emulator.name == 'MuMu12') {
|
if (conf.value.emulator.name == 'MuMu12') {
|
||||||
|
@ -275,15 +276,6 @@ const message = useMessage()
|
||||||
>
|
>
|
||||||
通过共享内存的方式直接获取无损截图,避免了编码、解码、跨进程传输等环节的开销,截图速度远高于通用截图方案。
|
通过共享内存的方式直接获取无损截图,避免了编码、解码、跨进程传输等环节的开销,截图速度远高于通用截图方案。
|
||||||
</n-alert>
|
</n-alert>
|
||||||
<n-alert
|
|
||||||
title="请关闭MuMu模拟器12的后台保活"
|
|
||||||
closable
|
|
||||||
style="margin: 8px 0"
|
|
||||||
type="warning"
|
|
||||||
v-if="conf.emulator.name == 'MuMu12' && conf.screencap_strategy == 'droidcast'"
|
|
||||||
>
|
|
||||||
在MuMu模拟器12上使用DroidCast截图方式,需关闭后台保活,或换用ADB+Gzip截图方式。
|
|
||||||
</n-alert>
|
|
||||||
<n-form-item label="触控方案">
|
<n-form-item label="触控方案">
|
||||||
<n-select v-model:value="conf.control_strategy" :options="touch_options" />
|
<n-select v-model:value="conf.control_strategy" :options="touch_options" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
@ -298,6 +290,26 @@ const message = useMessage()
|
||||||
</n-flex>
|
</n-flex>
|
||||||
</n-radio-group>
|
</n-radio-group>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
<template v-if="conf.screencap_strategy == 'droidcast_raw'">
|
||||||
|
<n-form-item label="屏幕朝向">
|
||||||
|
<n-radio-group v-model:value="conf.droidcast_raw.orientation">
|
||||||
|
<n-flex>
|
||||||
|
<n-radio value="portrait">竖屏</n-radio>
|
||||||
|
<n-radio value="landscape">横屏</n-radio>
|
||||||
|
</n-flex>
|
||||||
|
</n-radio-group>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="旋转截图" v-if="conf.screencap_strategy == 'droidcast_raw'">
|
||||||
|
<n-radio-group v-model:value="conf.droidcast_raw.rotate">
|
||||||
|
<n-flex>
|
||||||
|
<n-radio :value="0">不旋转</n-radio>
|
||||||
|
<n-radio :value="90">旋转90度</n-radio>
|
||||||
|
<n-radio :value="180">旋转180度</n-radio>
|
||||||
|
<n-radio :value="270">旋转270度</n-radio>
|
||||||
|
</n-flex>
|
||||||
|
</n-radio-group>
|
||||||
|
</n-form-item>
|
||||||
|
</template>
|
||||||
<n-form-item label="截图命令" v-if="conf.screencap_strategy == 'diy'">
|
<n-form-item label="截图命令" v-if="conf.screencap_strategy == 'diy'">
|
||||||
<n-input
|
<n-input
|
||||||
v-model:value="conf.custom_screenshot.command"
|
v-model:value="conf.custom_screenshot.command"
|
||||||
|
@ -313,8 +325,10 @@ const message = useMessage()
|
||||||
<div v-if="screenshot_success">
|
<div v-if="screenshot_success">
|
||||||
截图用时:<n-text strong :type="screenshot_type">{{ elapsed }}ms</n-text>
|
截图用时:<n-text strong :type="screenshot_type">{{ elapsed }}ms</n-text>
|
||||||
</div>
|
</div>
|
||||||
<n-text type="error" v-else>截图失败!</n-text>
|
<template v-else>
|
||||||
<div>{{ reason }}</div>
|
<n-text type="error">截图失败!</n-text>
|
||||||
|
<div>{{ reason }}</div>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</n-flex>
|
</n-flex>
|
||||||
<n-image
|
<n-image
|
||||||
|
|
Loading…
Add table
Reference in a new issue