feat: 后端添加电源操作逻辑
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
|
||||
from fastapi import APIRouter, Body
|
||||
|
||||
from app.core import TaskManager
|
||||
from app.core import Config, TaskManager
|
||||
from app.services import System
|
||||
from app.models.schema import *
|
||||
|
||||
@@ -58,11 +58,27 @@ async def stop_task(task: DispatchIn = Body(...)) -> OutBase:
|
||||
return OutBase()
|
||||
|
||||
|
||||
@router.post("/power", summary="电源操作", response_model=OutBase, status_code=200)
|
||||
async def power_task(task: PowerIn = Body(...)) -> OutBase:
|
||||
@router.post(
|
||||
"/set/power", summary="设置电源标志", response_model=OutBase, status_code=200
|
||||
)
|
||||
async def set_power(task: PowerIn = Body(...)) -> OutBase:
|
||||
|
||||
try:
|
||||
await System.set_power(task.signal)
|
||||
Config.power_sign = task.signal
|
||||
except Exception as e:
|
||||
return OutBase(
|
||||
code=500, status="error", message=f"{type(e).__name__}: {str(e)}"
|
||||
)
|
||||
return OutBase()
|
||||
|
||||
|
||||
@router.post(
|
||||
"/cancel/power", summary="取消电源任务", response_model=OutBase, status_code=200
|
||||
)
|
||||
async def cancel_power_task() -> OutBase:
|
||||
|
||||
try:
|
||||
await System.cancel_power_task()
|
||||
except Exception as e:
|
||||
return OutBase(
|
||||
code=500, status="error", message=f"{type(e).__name__}: {str(e)}"
|
||||
|
||||
@@ -659,6 +659,9 @@ class AppConfig(GlobalConfig):
|
||||
|
||||
self.server: Optional[uvicorn.Server] = None
|
||||
self.websocket: Optional[WebSocket] = None
|
||||
self.power_sign: Literal[
|
||||
"NoAction", "Shutdown", "ShutdownForce", "Hibernate", "Sleep", "KillSelf"
|
||||
] = "NoAction"
|
||||
self.silence_dict: Dict[Path, datetime] = {}
|
||||
self.if_ignore_silence: List[uuid.UUID] = []
|
||||
self.temp_task: List[asyncio.Task] = []
|
||||
@@ -1924,7 +1927,7 @@ class AppConfig(GlobalConfig):
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://download.auto-mas.top/d/AUTO_MAA/Server/notice.json",
|
||||
"https://download.auto-mas.top/d/AUTO_MAS/Server/notice.json",
|
||||
timeout=10,
|
||||
proxies=self.get_proxies(),
|
||||
)
|
||||
|
||||
@@ -25,9 +25,11 @@ from functools import partial
|
||||
from typing import Dict, Optional, Literal
|
||||
|
||||
from .config import Config, MaaConfig, GeneralConfig, QueueConfig
|
||||
from app.services import System
|
||||
from app.models.schema import WebSocketMessage
|
||||
from app.utils import get_logger
|
||||
from app.task import *
|
||||
from app.utils.constants import POWER_SIGN_MAP
|
||||
|
||||
|
||||
logger = get_logger("业务调度")
|
||||
@@ -321,17 +323,25 @@ class _TaskManager:
|
||||
|
||||
if mode == "自动代理" and task_id in Config.QueueConfig:
|
||||
|
||||
await Config.send_json(
|
||||
WebSocketMessage(
|
||||
id=str(task_id),
|
||||
type="Signal",
|
||||
data={
|
||||
"power": Config.QueueConfig[task_id].get(
|
||||
"Info", "AfterAccomplish"
|
||||
)
|
||||
},
|
||||
).model_dump()
|
||||
)
|
||||
if Config.power_sign != "NoAction":
|
||||
Config.power_sign = Config.QueueConfig[task_id].get(
|
||||
"Info", "AfterAccomplish"
|
||||
)
|
||||
|
||||
if len(self.task_dict) == 0 and Config.power_sign != "NoAction":
|
||||
logger.info(f"所有任务已结束,准备执行电源操作: {Config.power_sign}")
|
||||
await Config.send_json(
|
||||
WebSocketMessage(
|
||||
id="Main",
|
||||
type="Message",
|
||||
data={
|
||||
"type": "Countdown",
|
||||
"title": f"{POWER_SIGN_MAP[Config.power_sign]}倒计时",
|
||||
"message": f"程序将在倒计时结束后执行 {POWER_SIGN_MAP[Config.power_sign]} 操作",
|
||||
},
|
||||
).model_dump()
|
||||
)
|
||||
await System.start_power_task()
|
||||
|
||||
async def start_startup_queue(self):
|
||||
"""开始运行启动时运行的调度队列"""
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
import sys
|
||||
import ctypes
|
||||
import asyncio
|
||||
import win32gui
|
||||
import win32process
|
||||
import psutil
|
||||
@@ -29,9 +30,10 @@ import tempfile
|
||||
import getpass
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
from typing import Literal, Optional
|
||||
|
||||
from app.core import Config
|
||||
from app.models.schema import WebSocketMessage
|
||||
from app.utils.logger import get_logger
|
||||
|
||||
logger = get_logger("系统服务")
|
||||
@@ -41,6 +43,10 @@ class _SystemHandler:
|
||||
|
||||
ES_CONTINUOUS = 0x80000000
|
||||
ES_SYSTEM_REQUIRED = 0x00000001
|
||||
countdown = 60
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.power_task: Optional[asyncio.Task] = None
|
||||
|
||||
async def set_Sleep(self) -> None:
|
||||
"""同步系统休眠状态"""
|
||||
@@ -245,6 +251,47 @@ class _SystemHandler:
|
||||
logger.info("执行退出主程序操作")
|
||||
Config.server.should_exit = True
|
||||
|
||||
async def _power_task(
|
||||
self,
|
||||
power_sign: Literal[
|
||||
"NoAction", "Shutdown", "ShutdownForce", "Hibernate", "Sleep", "KillSelf"
|
||||
],
|
||||
) -> None:
|
||||
"""电源任务"""
|
||||
|
||||
await asyncio.sleep(self.countdown)
|
||||
if power_sign == "KillSelf":
|
||||
await Config.send_json(
|
||||
WebSocketMessage(
|
||||
id="Main", type="Signal", data={"RequestClose": "请求前端关闭"}
|
||||
).model_dump()
|
||||
)
|
||||
await self.set_power(power_sign)
|
||||
|
||||
async def start_power_task(self):
|
||||
"""开始电源任务"""
|
||||
|
||||
if self.power_task is None or self.power_task.done():
|
||||
self.power_task = asyncio.create_task(self._power_task(Config.power_sign))
|
||||
logger.info(
|
||||
f"电源任务已启动, {self.countdown}秒后执行: {Config.power_sign}"
|
||||
)
|
||||
else:
|
||||
logger.warning("已有电源任务在运行, 请勿重复启动")
|
||||
|
||||
async def cancel_power_task(self):
|
||||
"""取消电源任务"""
|
||||
|
||||
if self.power_task is not None and not self.power_task.done():
|
||||
self.power_task.cancel()
|
||||
try:
|
||||
await self.power_task
|
||||
except asyncio.CancelledError:
|
||||
logger.info("电源任务已取消")
|
||||
else:
|
||||
logger.warning("当前无电源任务在运行")
|
||||
raise RuntimeError("当前无电源任务在运行")
|
||||
|
||||
async def kill_emulator_processes(self):
|
||||
"""这里暂时仅支持 MuMu 模拟器"""
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ class _UpdateHandler:
|
||||
await Config.send_json(
|
||||
WebSocketMessage(
|
||||
id="Update",
|
||||
type="Message",
|
||||
type="Info",
|
||||
data={"Error": f"解压失败, {type(e).__name__}: {e}"},
|
||||
).model_dump()
|
||||
)
|
||||
|
||||
@@ -1093,7 +1093,7 @@ class MaaManager:
|
||||
return result_text
|
||||
|
||||
async def get_message(self, message_id: str):
|
||||
"""获取当前任务的属性值"""
|
||||
"""获取客户端回应消息"""
|
||||
|
||||
logger.info(f"等待客户端回应消息: {message_id}")
|
||||
|
||||
|
||||
@@ -102,28 +102,28 @@ RESOURCE_STAGE_DROP_INFO = {
|
||||
"Display": "PR-A",
|
||||
"Value": "PR-A",
|
||||
"Drop": "PR-A",
|
||||
"DropName": "医疗/重装芯片",
|
||||
"DropName": "奶/盾芯片",
|
||||
"Activity": {"Tip": "一四五日", "StageName": "资源关卡"},
|
||||
},
|
||||
"PR-B-1": {
|
||||
"Display": "PR-B",
|
||||
"Value": "PR-B",
|
||||
"Drop": "PR-B",
|
||||
"DropName": "术师/狙击芯片",
|
||||
"DropName": "术/狙芯片",
|
||||
"Activity": {"Tip": "一二五六", "StageName": "资源关卡"},
|
||||
},
|
||||
"PR-C-1": {
|
||||
"Display": "PR-C",
|
||||
"Value": "PR-C",
|
||||
"Drop": "PR-C",
|
||||
"DropName": "先锋/辅助芯片",
|
||||
"DropName": "先/辅芯片",
|
||||
"Activity": {"Tip": "三四六日", "StageName": "资源关卡"},
|
||||
},
|
||||
"PR-D-1": {
|
||||
"Display": "PR-D",
|
||||
"Value": "PR-D",
|
||||
"Drop": "PR-D",
|
||||
"DropName": "近卫/特种芯片",
|
||||
"DropName": "近/特芯片",
|
||||
"Activity": {"Tip": "二三六日", "StageName": "资源关卡"},
|
||||
},
|
||||
}
|
||||
@@ -229,6 +229,16 @@ MATERIALS_MAP = {
|
||||
}
|
||||
"""掉落物索引表"""
|
||||
|
||||
POWER_SIGN_MAP = {
|
||||
"NoAction": "无动作",
|
||||
"Shutdown": "关机",
|
||||
"ShutdownForce": "强制关机",
|
||||
"Hibernate": "休眠",
|
||||
"Sleep": "睡眠",
|
||||
"KillSelf": "退出程序",
|
||||
}
|
||||
"""电源操作类型索引表"""
|
||||
|
||||
RESERVED_NAMES = {
|
||||
"CON",
|
||||
"PRN",
|
||||
|
||||
Reference in New Issue
Block a user