Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

### 破坏性变更

- 森空岛获取凭据改为扫码登录,完善游戏社区签到、云游戏时长判断与日常便笺展示
- 森空岛获取凭据改为扫码登录,完善游戏社区签到、云游戏时长判断与日常便笺展示 by [@qiyinxi](https://github.com/qiyinxi)
- MFW 项目新增了自动更新时机设置,升级后**已有脚本一律默认为「运行前更新」**;不需要的话在项目配置里改成「不更新」 by [@qiyinxi](https://github.com/qiyinxi)
- HSR 专项脚本页的「游戏启动参数」已移除,**旧配置中的该项会在下次保存时自动清除**;窗口大小改由「1920×1080 窗口模式」开关控制 by [@qiyinxi](https://github.com/qiyinxi)
- MAA 专项代理接管配置时**会强制开启「开始唤醒」的账号切换开关**,以确保按用户配置的账号切号;用户未填写账号时仍不会切号 by [@qiyinxi](https://github.com/qiyinxi)
Expand Down Expand Up @@ -69,6 +69,7 @@
### 变更

- 启动界面 启动与初始化时的等待画面重做,只显示当前在做什么和一条进度条,首次安装或更新时才展示步骤进度,出错时给出一句话原因和一个主要操作、日志收进「详细信息」,并取消失败后的 60 秒自动重试 by [@qiyinxi](https://github.com/qiyinxi)
- 配置分享 通用脚本的模板浏览与分享改用新的 AUTO-MAS 配置中心,分享前需在浏览器完成一次登录授权,分享者身份由登录账号确定、不再手填作者
- OK-WW专项 清理无效的游戏启动选项与空配置项,避免脚本配置中出现无效设置 by [@1w1w11w1](https://github.com/1w1w11w1) by [@qiyinxi](https://github.com/qiyinxi)
- 后端更新自动在后台下载并于下次启动生效,启动失败时可修复依赖后重试 by [@ClozyA](https://github.com/ClozyA) by [@qiyinxi](https://github.com/qiyinxi)
- 配置来源 MAA、SRC、MaaEnd 与 OK-NTE 用户页的「简洁/详细」配置模式更名为「脚本/用户」,含义不变,旧配置自动迁移 by [@1w1w11w1](https://github.com/1w1w11w1) by [@qiyinxi](https://github.com/qiyinxi)
Expand Down Expand Up @@ -157,7 +158,7 @@
- MFW专项 修复脚本侧强制停止任务(如 MaaEnd 分辨率不达标时的强停)被记成「任务完成」的问题:现在被强停的任务按失败记录,本轮剩余任务不再投递,不会再出现整轮一件事没做却报成全部成功 by [@qiyinxi](https://github.com/qiyinxi)
- MAA专项 修复 MAA 卡死后不会被判定为超时、任务一直挂着的问题:MAA 每隔一段时间输出的日志停滞提示被当成任务仍在推进,把超时计时反复重置,剿灭等超时阈值长于提示间隔的模式永远等不到超时;现已识别新旧两版 MAA 的该提示,MAA 的五种界面语言均生效 by [@qiyinxi](https://github.com/qiyinxi)
- MAA专项 修复关闭理智作战后活动关优先任务一并从任务队列中消失的问题 by [@1w1w11w1](https://github.com/1w1w11w1) by [@qiyinxi](https://github.com/qiyinxi)
- BetterGI专项、ZZZ-OD专项 修复任务出错时提示送不到前端、用户看到的报错与实际出错原因无关的问题
- BetterGI专项、ZZZ-OD专项 修复任务出错时提示送不到前端、用户看到的报错与实际出错原因无关的问题 by [@qiyinxi](https://github.com/qiyinxi)

### 开发流程

Expand Down
2 changes: 2 additions & 0 deletions app/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from .queue import router as queue_router
from .scripts import router as scripts_router
from .setting import router as setting_router
from .share import router as share_router
from .skland_qr import router as skland_qr_router
from .tools import router as tools_router
from .update import router as update_router
Expand All @@ -51,6 +52,7 @@
"history_router",
"tools_router",
"setting_router",
"share_router",
"update_router",
"ocr_router",
"openclaw_qq_router",
Expand Down
18 changes: 0 additions & 18 deletions app/api/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,24 +231,6 @@ async def confirm_notice() -> OutBase:
# return InfoOut(data=data)


@router.post(
"/webconfig",
tags=["Get"],
summary="获取配置分享中心的配置信息",
response_model=InfoOut,
status_code=200,
)
async def get_web_config() -> InfoOut:

try:
data = await Config.get_web_config()
except Exception as e:
return InfoOut(
code=500, status="error", message=f"{type(e).__name__}: {str(e)}", data={}
)
return InfoOut(data={"WebConfig": data})


@router.post(
"/get/overview",
tags=["Get"],
Expand Down
44 changes: 38 additions & 6 deletions app/api/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from app.models.config import MaaFWConfig as RuntimeMaaFWConfig
from app.models.config import OkNteConfig as RuntimeOkNteConfig
from app.models.schema import *
from app.services import ConfigCenterError
from app.task.MaaFW.tools.core.automas_maafw_interface.loader import (
MaaFWInterfaceLoadError,
load_interface_model_cached,
Expand Down Expand Up @@ -396,34 +397,65 @@ async def export_script_to_file(script: ScriptFileIn = Body(...)) -> OutBase:
@router.post(
"/import/web",
tags=["Update"],
summary="从网络加载脚本配置",
summary="从配置中心导入脚本配置",
response_model=OutBase,
status_code=200,
)
async def import_script_from_web(script: ScriptUrlIn = Body(...)) -> OutBase:
async def import_script_from_web(script: ScriptTemplateImportIn = Body(...)) -> OutBase:

try:
await Config.import_script_from_web(script.scriptId, script.url)
await Config.import_script_from_share(
script.scriptId, config_key=script.configKey, version_no=script.versionNo
)
except ConfigCenterError as e:
return OutBase(code=500, status="error", message=str(e))
except Exception as e:
return OutBase(
code=500, status="error", message=f"{type(e).__name__}: {str(e)}"
)
return OutBase()


@router.post(
"/share/inspect",
tags=["Get"],
summary="分享前检查脚本配置中的隐私风险",
response_model=ShareInspectOut,
status_code=200,
)
async def inspect_script_share(
script: ScriptShareInspectIn = Body(...),
) -> ShareInspectOut:

try:
_, risks = await Config.build_share_config(
script.scriptId, config_name=script.config_name
)
except Exception as e:
return ShareInspectOut(
code=500, status="error", message=f"{type(e).__name__}: {str(e)}"
)
return ShareInspectOut(risks=[ShareRiskItem(**_) for _ in risks])


@router.post(
"/Upload/web",
tags=["Action"],
summary="上传脚本配置到网络",
summary="分享脚本配置到配置中心",
response_model=OutBase,
status_code=200,
)
async def upload_script_to_web(script: ScriptUploadIn = Body(...)) -> OutBase:

try:
await Config.upload_script_to_web(
script.scriptId, script.config_name, script.author, script.description
await Config.upload_script_to_share(
script.scriptId,
config_name=script.config_name,
description=script.description,
acknowledged=script.acknowledged,
)
except ConfigCenterError as e:
return OutBase(code=500, status="error", message=str(e))
except Exception as e:
return OutBase(
code=500, status="error", message=f"{type(e).__name__}: {str(e)}"
Expand Down
158 changes: 158 additions & 0 deletions app/api/share.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# AUTO-MAS: A Multi-Script, Multi-Config Management and Automation Software
# Copyright © 2024-2025 DLmaster361
# Copyright © 2025-2026 AUTO-MAS Team

# This file is part of AUTO-MAS.

# AUTO-MAS is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.

# AUTO-MAS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with AUTO-MAS. If not, see <https://www.gnu.org/licenses/>.

# Contact: DLmaster_361@163.com


from typing import Any, Dict

from fastapi import APIRouter, Body

from app.models.schema import (
ShareAuthStatusOut,
ShareTemplateItem,
ShareTemplateListIn,
ShareTemplateListOut,
)
from app.services import ConfigCenter, ConfigCenterError

router = APIRouter(prefix="/api/share", tags=["配置中心"])


def _build_auth_status(status: Dict[str, Any]) -> ShareAuthStatusOut:
"""把配置中心客户端的状态字典映射成响应模型"""

return ShareAuthStatusOut(
message=status.get("message", "操作成功"),
authStatus=status.get("status", "idle"),
username=status.get("username", ""),
displayName=status.get("displayName", ""),
userCode=status.get("userCode", ""),
verificationUri=status.get("verificationUri", ""),
expiresIn=status.get("expiresIn", 0),
interval=status.get("interval", 5),
)


@router.post(
"/templates",
tags=["Get"],
summary="获取配置中心已发布的通用脚本配置",
response_model=ShareTemplateListOut,
status_code=200,
)
async def list_share_templates(
query: ShareTemplateListIn = Body(...),
) -> ShareTemplateListOut:

try:
items, pagination = await ConfigCenter.list_templates(
query.page, query.pageSize, query.keyword
)
except ConfigCenterError as e:
return ShareTemplateListOut(code=500, status="error", message=str(e))
except Exception as e:
return ShareTemplateListOut(
code=500, status="error", message=f"{type(e).__name__}: {str(e)}"
)

return ShareTemplateListOut(
items=[ShareTemplateItem(**_) for _ in items],
page=pagination["page"],
pageSize=pagination["pageSize"],
total=pagination["total"],
hasNext=pagination["hasNext"],
)


@router.post(
"/auth/status",
tags=["Get"],
summary="获取配置中心授权状态",
response_model=ShareAuthStatusOut,
status_code=200,
)
async def get_share_auth_status() -> ShareAuthStatusOut:

return _build_auth_status(ConfigCenter.get_status())


@router.post(
"/auth/start",
tags=["Action"],
summary="发起配置中心浏览器授权",
response_model=ShareAuthStatusOut,
status_code=200,
)
async def start_share_auth() -> ShareAuthStatusOut:

try:
data = await ConfigCenter.start_authorization()
except ConfigCenterError as e:
return ShareAuthStatusOut(
code=500, status="error", message=str(e), authStatus="idle"
)
except Exception as e:
return ShareAuthStatusOut(
code=500,
status="error",
message=f"{type(e).__name__}: {str(e)}",
authStatus="idle",
)

return _build_auth_status({"status": "pending", **data})


@router.post(
"/auth/poll",
tags=["Get"],
summary="轮询配置中心授权结果",
response_model=ShareAuthStatusOut,
status_code=200,
)
async def poll_share_auth() -> ShareAuthStatusOut:

try:
status = await ConfigCenter.poll_authorization()
except ConfigCenterError as e:
return ShareAuthStatusOut(
code=500, status="error", message=str(e), authStatus="idle"
)
except Exception as e:
return ShareAuthStatusOut(
code=500,
status="error",
message=f"{type(e).__name__}: {str(e)}",
authStatus="idle",
)

return _build_auth_status(status)


@router.post(
"/auth/cancel",
tags=["Action"],
summary="取消等待中的配置中心授权",
response_model=ShareAuthStatusOut,
status_code=200,
)
async def cancel_share_auth() -> ShareAuthStatusOut:

await ConfigCenter.cancel_authorization()
return _build_auth_status(ConfigCenter.get_status())
Loading