Perf(maaend): 清理代码并修改日志导出 - #545
Conversation
- 清理了一下MaaEnd的没啥用的死代码 - 移除导出日志包的限制
审查者指南本 PR 重构 MaaEnd AutoProxy 的配置与任务执行流程,集中处理任务结果、更新重试、进程清理及本地运行时元数据保留;同时以自定义逐条写盘的 ZIP writer 替换 AdmZip,取消问题报告的固定大小限制并降低大型日志归档的内存占用。 流式导出问题报告 ZIP 的时序图sequenceDiagram
participant Service as IssueReportService
participant Core as issueReportCore
participant Writer as StreamingZipWriter
participant Disk as ZIPFile
Service->>Core: createCollector(zipPath)
Core->>Writer: new StreamingZipWriter(zipPath)
Service->>Core: addDirectory / addDiagnosticFile
Core->>Writer: addBuffer(archivePath, content)
Core->>Writer: addFile(archivePath, sourcePath)
Writer->>Disk: write ZIP entry immediately
Service->>Writer: finalize()
Writer->>Disk: write central directory and close
MaaEnd AutoProxy 任务重试与结果跟踪的时序图sequenceDiagram
participant AutoProxyTask
participant MaaEnd
participant LogMonitor
participant ProcessManager
AutoProxyTask->>AutoProxyTask: set_maaend(device_info)
AutoProxyTask->>MaaEnd: asyncio.create_subprocess_exec(--autostart, --instance, AUTO-MAS)
MaaEnd-->>LogMonitor: task start / complete / failure logs
LogMonitor->>AutoProxyTask: check_log(log)
AutoProxyTask->>AutoProxyTask: parse_task_result()
alt MaaEnd 正在更新
AutoProxyTask->>AutoProxyTask: kill_maaend_process()
AutoProxyTask->>MaaEnd: restart current user once
else Success!
AutoProxyTask->>AutoProxyTask: kill_maaend_process()
else task failure
AutoProxyTask->>ProcessManager: kill_managed_process()
end
保留 MaaEnd 运行时元数据的流程图flowchart LR
Local["本机 MaaEnd 配置"] --> Merge["读取并继承 version、interfaceTaskSnapshot、welcomeShownHash"]
User["用户自动化配置"] --> Merge
Merge --> Validate["验证 MaaEnd 实例与任务配置"]
Validate --> Write["写入运行配置"]
Write --> Run["使用 AUTO-MAS 启动"]
文件级变更
可能关联的问题
提示与命令与 Sourcery 交互
自定义使用体验访问你的控制面板以:
获取帮助Original review guide in EnglishReviewer's Guide本 PR 重构 MaaEnd AutoProxy 的配置与任务执行流程,集中处理任务结果、更新重试、进程清理及本地运行时元数据保留;同时以自定义逐条写盘的 ZIP writer 替换 AdmZip,取消问题报告的固定大小限制并降低大型日志归档的内存占用。 Sequence diagram for streaming issue-report ZIP exportsequenceDiagram
participant Service as IssueReportService
participant Core as issueReportCore
participant Writer as StreamingZipWriter
participant Disk as ZIPFile
Service->>Core: createCollector(zipPath)
Core->>Writer: new StreamingZipWriter(zipPath)
Service->>Core: addDirectory / addDiagnosticFile
Core->>Writer: addBuffer(archivePath, content)
Core->>Writer: addFile(archivePath, sourcePath)
Writer->>Disk: write ZIP entry immediately
Service->>Writer: finalize()
Writer->>Disk: write central directory and close
Sequence diagram for MaaEnd AutoProxy task retry and result trackingsequenceDiagram
participant AutoProxyTask
participant MaaEnd
participant LogMonitor
participant ProcessManager
AutoProxyTask->>AutoProxyTask: set_maaend(device_info)
AutoProxyTask->>MaaEnd: asyncio.create_subprocess_exec(--autostart, --instance, AUTO-MAS)
MaaEnd-->>LogMonitor: task start / complete / failure logs
LogMonitor->>AutoProxyTask: check_log(log)
AutoProxyTask->>AutoProxyTask: parse_task_result()
alt MaaEnd 正在更新
AutoProxyTask->>AutoProxyTask: kill_maaend_process()
AutoProxyTask->>MaaEnd: restart current user once
else Success!
AutoProxyTask->>AutoProxyTask: kill_maaend_process()
else task failure
AutoProxyTask->>ProcessManager: kill_managed_process()
end
Flow diagram for preserving MaaEnd runtime metadataflowchart LR
Local["本机 MaaEnd 配置"] --> Merge["读取并继承 version、interfaceTaskSnapshot、welcomeShownHash"]
User["用户自动化配置"] --> Merge
Merge --> Validate["验证 MaaEnd 实例与任务配置"]
Validate --> Write["写入运行配置"]
Write --> Run["使用 AUTO-MAS 启动"]
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
你好——我发现了 4 个问题
AI Agent 提示词
请处理本次代码审查中的评论:
## 单独评论
### 评论 1
<location path="app/task/MaaEnd/AutoProxy.py" line_range="149-151" />
<code_context>
- self.script_config.get("Run", "AccountSwitchMethod") == "MAAEND"
- and account_id
+ if self.account_id and (
+ len(self.account_id) < 4 or not self.account_id[-4:].isdigit()
):
- if len(account_id) < 4 or not account_id[-4:].isdigit():
- self.cur_user_item.status = "异常"
- return (
- "MAAEND 内置账号切换需要账号末四位为数字,"
- "请检查账号ID或改用 MAS 自建账号切换"
- )
+ self.cur_user_item.status = "异常"
+ return "账号切换需要账号末四位为数字,请检查账号ID"
- config_user_id = (
</code_context>
<issue_to_address>
**issue (bug_risk):** 账号末四位校验现在对所有账户切换方式生效,即使 `AccountSwitchMethod` 是 `MAS` 也会拒绝非数字结尾的账号 ID;MAS 登录本身不要求账号 ID 末四位为数字。
**Triggers:** 当使用 MAS 自建账号切换且账号 ID 不是四位数字结尾时。
**Suggested fix:** 将校验恢复为仅在 `AccountSwitchMethod == "MAAEND"` 时执行。
```suggestion
if (
self.script_config.get("Run", "AccountSwitchMethod") == "MAAEND"
and self.account_id
and (
len(self.account_id) < 4 or not self.account_id[-4:].isdigit()
)
):
```
</issue_to_address>
### 评论 2
<location path="app/task/MaaEnd/AutoProxy.py" line_range="484" />
<code_context>
- or "AUTO-MAS"
- )
+ maaend_instance = instances[0]
if device_info is not None:
from app.core import MaaFWManager
</code_context>
<issue_to_address>
**issue (bug_risk):** 配置包含多个 MaaEnd 实例时,代码始终修改 `instances[0]`,但启动参数固定使用实例名 `AUTO-MAS`;当 AUTO-MAS 不是第一个实例时,任务配置写入了错误实例,实际启动的实例仍使用未配置的任务。
**Triggers:** 当 MaaEnd 配置中的 AUTO-MAS 实例不是 `instances[0]` 时。
**Suggested fix:** 按实例 ID `automas` 或名称 `AUTO-MAS` 查找目标实例,并在找不到时明确报错。
</issue_to_address>
### 评论 3
<location path="app/task/MaaEnd/AutoProxy.py" line_range="464" />
<code_context>
)
+ # 版本号、任务快照与欢迎页标记跟随本机 MaaEnd, 不沿用用户配置快照
+ maaend_local_set = read_file(self.maaend_set_path / "mxu-MaaEnd.json")
shutil.rmtree(self.maaend_set_path, ignore_errors=True)
- shutil.copytree(maaend_config_path, self.maaend_set_path)
</code_context>
<issue_to_address>
**issue (bug_risk):** `set_maaend` 在清理并复制配置目录前无条件读取本机的 `config/mxu-MaaEnd.json`;该文件不存在时直接抛出文件读取异常,导致 MaaEnd 配置无法初始化,而旧逻辑允许本机配置文件缺失并继续复制用户配置。
**Triggers:** 当 MaaEnd 安装目录尚未生成本机 `config/mxu-MaaEnd.json` 时。
**Suggested fix:** 先检查本机配置文件是否存在;不存在时使用空配置或跳过本机字段继承。
```suggestion
maaend_local_set = (
read_file(self.maaend_set_path / "mxu-MaaEnd.json")
if (self.maaend_set_path / "mxu-MaaEnd.json").exists()
else {}
)
```
</issue_to_address>
### 评论 4
<location path="frontend/electron/services/issueReportCore.ts" line_range="218" />
<code_context>
- 'truncated',
- `原始文件超过 ${MAX_ENTRY_BYTES} 字节`
- )
+ addEntry(state, archivePath, stat.size, content)
return
} catch (error) {
</code_context>
<issue_to_address>
**issue (performance):** 诊断文件导出删除了单文件和压缩包总大小限制,并直接用 `readFileSync` 将每个文本、二进制和脱敏 JSON 文件完整读入内存后加入 AdmZip;包含超大日志或大量大文件的诊断目录会同时占用原文件 Buffer、ZIP 内存和压缩输出内存,最终导致 Electron 主进程内存耗尽或导出崩溃。
**Triggers:** 当诊断目录包含数百 MB 或 GB 级日志/二进制文件时。
**Suggested fix:** 改用流式 ZIP 写入或保留可配置的单文件/总包大小上限,并在超限时记录跳过原因。
</issue_to_address>Sourcery 评估
需要人工审查。 有 4 个发现需要优先处理;此外,移除单文件和压缩包总大小限制会使诊断导出保留任意大小的日志和文件,可能耗尽内存或磁盘空间,并可能暴露敏感内容。仅回滚只能防止未来的导出,无法撤销已经创建的软件包或已经泄露的数据。此次 PR 还改变了整个自动化流程中的 MaaEnd 任务选择、重试和结果解析,因此除了简单清理之外,还增加了运行时行为不正确的可能性。
阻塞性发现:app/task/MaaEnd/AutoProxy.py:151、app/task/MaaEnd/AutoProxy.py:484、app/task/MaaEnd/AutoProxy.py:464、frontend/electron/services/issueReportCore.ts:218
帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会利用反馈来改进审查结果。
Original comment in English
Hey - I've found 4 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="app/task/MaaEnd/AutoProxy.py" line_range="149-151" />
<code_context>
- self.script_config.get("Run", "AccountSwitchMethod") == "MAAEND"
- and account_id
+ if self.account_id and (
+ len(self.account_id) < 4 or not self.account_id[-4:].isdigit()
):
- if len(account_id) < 4 or not account_id[-4:].isdigit():
- self.cur_user_item.status = "异常"
- return (
- "MAAEND 内置账号切换需要账号末四位为数字,"
- "请检查账号ID或改用 MAS 自建账号切换"
- )
+ self.cur_user_item.status = "异常"
+ return "账号切换需要账号末四位为数字,请检查账号ID"
- config_user_id = (
</code_context>
<issue_to_address>
**issue (bug_risk):** 账号末四位校验现在对所有账户切换方式生效,即使 `AccountSwitchMethod` 是 `MAS` 也会拒绝非数字结尾的账号 ID;MAS 登录本身不要求账号 ID 末四位为数字。
**Triggers:** 当使用 MAS 自建账号切换且账号 ID 不是四位数字结尾时。
**Suggested fix:** 将校验恢复为仅在 `AccountSwitchMethod == "MAAEND"` 时执行。
```suggestion
if (
self.script_config.get("Run", "AccountSwitchMethod") == "MAAEND"
and self.account_id
and (
len(self.account_id) < 4 or not self.account_id[-4:].isdigit()
)
):
```
</issue_to_address>
### Comment 2
<location path="app/task/MaaEnd/AutoProxy.py" line_range="484" />
<code_context>
- or "AUTO-MAS"
- )
+ maaend_instance = instances[0]
if device_info is not None:
from app.core import MaaFWManager
</code_context>
<issue_to_address>
**issue (bug_risk):** 配置包含多个 MaaEnd 实例时,代码始终修改 `instances[0]`,但启动参数固定使用实例名 `AUTO-MAS`;当 AUTO-MAS 不是第一个实例时,任务配置写入了错误实例,实际启动的实例仍使用未配置的任务。
**Triggers:** 当 MaaEnd 配置中的 AUTO-MAS 实例不是 `instances[0]` 时。
**Suggested fix:** 按实例 ID `automas` 或名称 `AUTO-MAS` 查找目标实例,并在找不到时明确报错。
</issue_to_address>
### Comment 3
<location path="app/task/MaaEnd/AutoProxy.py" line_range="464" />
<code_context>
)
+ # 版本号、任务快照与欢迎页标记跟随本机 MaaEnd, 不沿用用户配置快照
+ maaend_local_set = read_file(self.maaend_set_path / "mxu-MaaEnd.json")
shutil.rmtree(self.maaend_set_path, ignore_errors=True)
- shutil.copytree(maaend_config_path, self.maaend_set_path)
</code_context>
<issue_to_address>
**issue (bug_risk):** `set_maaend` 在清理并复制配置目录前无条件读取本机的 `config/mxu-MaaEnd.json`;该文件不存在时直接抛出文件读取异常,导致 MaaEnd 配置无法初始化,而旧逻辑允许本机配置文件缺失并继续复制用户配置。
**Triggers:** 当 MaaEnd 安装目录尚未生成本机 `config/mxu-MaaEnd.json` 时。
**Suggested fix:** 先检查本机配置文件是否存在;不存在时使用空配置或跳过本机字段继承。
```suggestion
maaend_local_set = (
read_file(self.maaend_set_path / "mxu-MaaEnd.json")
if (self.maaend_set_path / "mxu-MaaEnd.json").exists()
else {}
)
```
</issue_to_address>
### Comment 4
<location path="frontend/electron/services/issueReportCore.ts" line_range="218" />
<code_context>
- 'truncated',
- `原始文件超过 ${MAX_ENTRY_BYTES} 字节`
- )
+ addEntry(state, archivePath, stat.size, content)
return
} catch (error) {
</code_context>
<issue_to_address>
**issue (performance):** 诊断文件导出删除了单文件和压缩包总大小限制,并直接用 `readFileSync` 将每个文本、二进制和脱敏 JSON 文件完整读入内存后加入 AdmZip;包含超大日志或大量大文件的诊断目录会同时占用原文件 Buffer、ZIP 内存和压缩输出内存,最终导致 Electron 主进程内存耗尽或导出崩溃。
**Triggers:** 当诊断目录包含数百 MB 或 GB 级日志/二进制文件时。
**Suggested fix:** 改用流式 ZIP 写入或保留可配置的单文件/总包大小上限,并在超限时记录跳过原因。
</issue_to_address>Sourcery assessment
Needs a human reviewer. 4 findings to address first, and removing the per-file and total archive limits makes diagnostic exports retain arbitrary-sized logs and files, which can exhaust memory or disk and may expose sensitive contents; reverting only prevents future exports and cannot undo packages already created or data already disclosed. The PR also changes MaaEnd task selection, retry, and result parsing across the automation flow, increasing the chance of incorrect runtime behavior beyond a simple cleanup.
Blocking findings: app/task/MaaEnd/AutoProxy.py:151, app/task/MaaEnd/AutoProxy.py:484, app/task/MaaEnd/AutoProxy.py:464, frontend/electron/services/issueReportCore.ts:218
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
@sourcery-ai review |
There was a problem hiding this comment.
嘿——我发现了 5 个问题
面向 AI Agent 的提示
请处理本次代码审查中的评论:
## 个别评论
### 评论 1
<location path="frontend/electron/services/streamingZip.ts" line_range="57-58" />
<code_context>
+ private entries: ZipEntry[] = []
+
+ constructor(filePath: string) {
+ fs.mkdirSync(fs.realpathSync(filePath + '/..'), { recursive: true })
+ this.fd = fs.openSync(filePath, 'w')
+ }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** `fs.realpathSync(filePath + '/..')` 会尝试通过尚未创建的 ZIP 文件解析路径,因此对于普通的新归档路径,构造过程会抛出 `ENOENT` 或 `ENOTDIR`。结果是每次问题报告导出都会在写入任何条目之前失败。
**触发条件:** 当 `zipPath` 尚不存在时,这也是生成新报告时的正常情况。
**建议修复:** 创建路径后直接使用 `path.dirname(filePath)`,而不是解析 `filePath + '/..'`。
</issue_to_address>
### 评论 2
<location path="app/task/MaaEnd/AutoProxy.py" line_range="464" />
<code_context>
"未找到 MaaEnd 配置文件, 请先完成「MaaEnd 配置」步骤"
)
+ # 版本号、任务快照与欢迎页标记跟随本机 MaaEnd, 不沿用用户配置快照
+ maaend_local_set = read_file(self.maaend_set_path / "mxu-MaaEnd.json")
shutil.rmtree(self.maaend_set_path, ignore_errors=True)
- shutil.copytree(maaend_config_path, self.maaend_set_path)
+ shutil.copytree(self.maaend_config_path, self.maaend_set_path)
</code_context>
<issue_to_address>
**issue (bug_risk):** `read_file(self.maaend_set_path / "mxu-MaaEnd.json")` 现在是无条件执行的,因此当本地运行时配置缺失时,会在复制用户配置之前抛出异常。之前的代码明确支持本地配置缺失的情况,即不保留任何本地字段。
**触发条件:** 当 MaaEnd 安装尚未生成 `config/mxu-MaaEnd.json`,或本地配置已被删除时。
**建议修复:** 检查本地文件是否存在;如果不存在,则使用空的本地配置。
```suggestion
maaend_local_set = (
read_file(self.maaend_set_path / "mxu-MaaEnd.json")
if (self.maaend_set_path / "mxu-MaaEnd.json").exists()
else {}
)
```
</issue_to_address>
### 评论 3
<location path="app/task/MaaEnd/AutoProxy.py" line_range="483" />
<code_context>
- maaend_instance = instance
- break
- if maaend_instance is None:
- maaend_instance = instances[0]
- self.maaend_instance_name = (
- maaend_instance.get("name")
</code_context>
<issue_to_address>
**issue (bug_risk):** 配置始终应用于 `instances[0]`,但进程启动时使用的是硬编码的实例名称 `AUTO-MAS`。当第一个已配置实例不是 `AUTO-MAS` 实例时,被编辑的任务和设备并不是 MaaEnd 实际启动的实例。
**触发条件:** 当 MaaEnd 配置包含多个实例,且 `AUTO-MAS` 不是第一个实例时。
**建议修复:** 在修改实例前先选择 `AUTO-MAS` 实例,或者使用实际选定的实例名称启动进程。
</issue_to_address>
### 评论 4
<location path="app/task/MaaEnd/AutoProxy.py" line_range="150-151" />
<code_context>
- self.script_config.get("Run", "AccountSwitchMethod") == "MAAEND"
- and account_id
+ if self.account_id and (
+ len(self.account_id) < 4 or not self.account_id[-4:].isdigit()
):
- if len(account_id) < 4 or not account_id[-4:].isdigit():
- self.cur_user_item.status = "异常"
</code_context>
<issue_to_address>
**issue (broader_impact):** 账户 ID 格式检查现在会对所有账户切换方式执行,而之前的代码只会对 `MAAEND` 内置切换器执行检查。用户选择 MAS 切换器并使用非数字账户 ID 时,即使 MaaEnd 在内置账户切换过程中不会使用该 ID,仍会被 `check()` 拒绝。
**触发条件:** 当 `AccountSwitchMethod` 为 `MAS`,且配置的账户 ID 非空但末尾不是四位数字时。
**建议修复:** 像之前的实现一样,仅在 `AccountSwitchMethod == "MAAEND"` 时进行验证。
</issue_to_address>
### 评论 5
<location path="frontend/electron/services/streamingZip.ts" line_range="84-87" />
<code_context>
+ header.writeUInt16LE(8, 8)
+ header.writeUInt16LE(time, 10)
+ header.writeUInt16LE(date, 12)
+ header.writeUInt32LE(crc, 14)
+ header.writeUInt32LE(compressed.byteLength, 18)
+ header.writeUInt32LE(data.byteLength, 22)
+ header.writeUInt16LE(name.byteLength, 26)
+ header.writeUInt16LE(0, 28)
+
</code_context>
<issue_to_address>
**issue (bug_risk):** 自定义写入器生成的是经典 ZIP 标头,并使用 32 位写入存储大小和偏移量,同时没有 ZIP64 记录。文件、归档或中央目录超过 4 GiB 时,这些字段会溢出;尽管旧的大小限制已被移除,最终仍会生成无法读取或解压不正确的归档。
**触发条件:** 当源文件或生成的归档超过经典 ZIP 的 4 GiB 限制时。
**建议修复:** 实现 ZIP64 标头和 ZIP64 中央目录结束记录,或者保留一个低于经典 ZIP 限制的明确上限。
</issue_to_address>Sourcery 评估
需要人工审查。 请先处理 5 个发现的问题。此外,问题报告相关改动移除了单文件和整个归档的大小限制,因此大型日志或二进制文件可能会被写入报告并消耗大量磁盘空间或内存;生成的归档在回滚后仍会保留,并且可能已经被分享。MaaEnd 任务和进程管理的重构还引入了若干运行时行为变化,但这些问题通常可以通过回滚并重新运行来恢复。
阻塞性问题:frontend/electron/services/streamingZip.ts:58、app/task/MaaEnd/AutoProxy.py:464、app/task/MaaEnd/AutoProxy.py:483、app/task/MaaEnd/AutoProxy.py:151、frontend/electron/services/streamingZip.ts:87
Original comment in English
Hey - I've found 5 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="frontend/electron/services/streamingZip.ts" line_range="57-58" />
<code_context>
+ private entries: ZipEntry[] = []
+
+ constructor(filePath: string) {
+ fs.mkdirSync(fs.realpathSync(filePath + '/..'), { recursive: true })
+ this.fd = fs.openSync(filePath, 'w')
+ }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** `fs.realpathSync(filePath + '/..')` resolves a path through the not-yet-created ZIP file, so construction raises `ENOENT` or `ENOTDIR` for a normal new archive path. Consequently every issue-report export fails before any entries are written.
**Triggers:** When `zipPath` does not already exist, which is the normal case for generating a new report.
**Suggested fix:** Use `path.dirname(filePath)` directly after creating it, rather than resolving `filePath + '/..'`.
</issue_to_address>
### Comment 2
<location path="app/task/MaaEnd/AutoProxy.py" line_range="464" />
<code_context>
"未找到 MaaEnd 配置文件, 请先完成「MaaEnd 配置」步骤"
)
+ # 版本号、任务快照与欢迎页标记跟随本机 MaaEnd, 不沿用用户配置快照
+ maaend_local_set = read_file(self.maaend_set_path / "mxu-MaaEnd.json")
shutil.rmtree(self.maaend_set_path, ignore_errors=True)
- shutil.copytree(maaend_config_path, self.maaend_set_path)
+ shutil.copytree(self.maaend_config_path, self.maaend_set_path)
</code_context>
<issue_to_address>
**issue (bug_risk):** `read_file(self.maaend_set_path / "mxu-MaaEnd.json")` is now unconditional, so a missing local runtime configuration raises before the user configuration can be copied. The previous code explicitly supported a missing local configuration by preserving no local fields.
**Triggers:** When the MaaEnd installation has not yet generated `config/mxu-MaaEnd.json` or the local configuration was removed.
**Suggested fix:** Check whether the local file exists and use an empty local configuration when it does not.
```suggestion
maaend_local_set = (
read_file(self.maaend_set_path / "mxu-MaaEnd.json")
if (self.maaend_set_path / "mxu-MaaEnd.json").exists()
else {}
)
```
</issue_to_address>
### Comment 3
<location path="app/task/MaaEnd/AutoProxy.py" line_range="483" />
<code_context>
- maaend_instance = instance
- break
- if maaend_instance is None:
- maaend_instance = instances[0]
- self.maaend_instance_name = (
- maaend_instance.get("name")
</code_context>
<issue_to_address>
**issue (bug_risk):** Configuration is always applied to `instances[0]`, but the process is launched with the hard-coded instance name `AUTO-MAS`. When the first configured instance is not the `AUTO-MAS` instance, the edited tasks and device are not the instance that MaaEnd starts.
**Triggers:** When a MaaEnd configuration contains multiple instances and `AUTO-MAS` is not the first instance.
**Suggested fix:** Select the `AUTO-MAS` instance before modifying it, or launch the exact selected instance name.
</issue_to_address>
### Comment 4
<location path="app/task/MaaEnd/AutoProxy.py" line_range="150-151" />
<code_context>
- self.script_config.get("Run", "AccountSwitchMethod") == "MAAEND"
- and account_id
+ if self.account_id and (
+ len(self.account_id) < 4 or not self.account_id[-4:].isdigit()
):
- if len(account_id) < 4 or not account_id[-4:].isdigit():
- self.cur_user_item.status = "异常"
</code_context>
<issue_to_address>
**issue (broader_impact):** The account-ID format check now runs for every account-switch method, whereas the previous code applied it only to the `MAAEND` built-in switcher. A user selecting the MAS switcher with a nonnumeric account ID is rejected by `check()` even though MaaEnd does not consume that ID for built-in account switching.
**Triggers:** When `AccountSwitchMethod` is `MAS` and the configured account ID is nonempty but does not end in four digits.
**Suggested fix:** Keep the validation conditional on `AccountSwitchMethod == "MAAEND"`, as in the previous implementation.
</issue_to_address>
### Comment 5
<location path="frontend/electron/services/streamingZip.ts" line_range="84-87" />
<code_context>
+ header.writeUInt16LE(8, 8)
+ header.writeUInt16LE(time, 10)
+ header.writeUInt16LE(date, 12)
+ header.writeUInt32LE(crc, 14)
+ header.writeUInt32LE(compressed.byteLength, 18)
+ header.writeUInt32LE(data.byteLength, 22)
+ header.writeUInt16LE(name.byteLength, 26)
+ header.writeUInt16LE(0, 28)
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The custom writer emits classic ZIP headers and stores sizes and offsets with 32-bit writes, without ZIP64 records. Files, archives, or central directories exceeding 4 GiB overflow these fields and produce an unreadable or incorrectly extracted archive despite the removal of the old size limits.
**Triggers:** When a source file or the resulting archive crosses the classic ZIP 4 GiB limit.
**Suggested fix:** Implement ZIP64 headers and an ZIP64 end-of-central-directory record, or retain an explicit limit below the classic ZIP limits.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 5 findings to address first, and the issue-report change removes per-file and total archive size limits, so a large log or binary can be persisted into the report and consume substantial disk space or memory; generated archives also remain after a revert and may already have been shared. The MaaEnd task and process-management refactors add several runtime behavior changes, but their failures are generally recoverable by reverting and rerunning.
Blocking findings: frontend/electron/services/streamingZip.ts:58, app/task/MaaEnd/AutoProxy.py:464, app/task/MaaEnd/AutoProxy.py:483, app/task/MaaEnd/AutoProxy.py:151, frontend/electron/services/streamingZip.ts:87
| fs.mkdirSync(fs.realpathSync(filePath + '/..'), { recursive: true }) | ||
| this.fd = fs.openSync(filePath, 'w') |
There was a problem hiding this comment.
issue (bug_risk): fs.realpathSync(filePath + '/..') 会尝试通过尚未创建的 ZIP 文件解析路径,因此对于普通的新归档路径,构造过程会抛出 ENOENT 或 ENOTDIR。结果是每次问题报告导出都会在写入任何条目之前失败。
触发条件: 当 zipPath 尚不存在时,这也是生成新报告时的正常情况。
建议修复: 创建路径后直接使用 path.dirname(filePath),而不是解析 filePath + '/..'。
Original comment in English
issue (bug_risk): fs.realpathSync(filePath + '/..') resolves a path through the not-yet-created ZIP file, so construction raises ENOENT or ENOTDIR for a normal new archive path. Consequently every issue-report export fails before any entries are written.
Triggers: When zipPath does not already exist, which is the normal case for generating a new report.
Suggested fix: Use path.dirname(filePath) directly after creating it, rather than resolving filePath + '/..'.
| ) | ||
|
|
||
| # 版本号、任务快照与欢迎页标记跟随本机 MaaEnd, 不沿用用户配置快照 | ||
| maaend_local_set = read_file(self.maaend_set_path / "mxu-MaaEnd.json") |
There was a problem hiding this comment.
issue (bug_risk): read_file(self.maaend_set_path / "mxu-MaaEnd.json") 现在是无条件执行的,因此当本地运行时配置缺失时,会在复制用户配置之前抛出异常。之前的代码明确支持本地配置缺失的情况,即不保留任何本地字段。
触发条件: 当 MaaEnd 安装尚未生成 config/mxu-MaaEnd.json,或本地配置已被删除时。
建议修复: 检查本地文件是否存在;如果不存在,则使用空的本地配置。
| maaend_local_set = read_file(self.maaend_set_path / "mxu-MaaEnd.json") | |
| maaend_local_set = ( | |
| read_file(self.maaend_set_path / "mxu-MaaEnd.json") | |
| if (self.maaend_set_path / "mxu-MaaEnd.json").exists() | |
| else {} | |
| ) |
Original comment in English
issue (bug_risk): read_file(self.maaend_set_path / "mxu-MaaEnd.json") is now unconditional, so a missing local runtime configuration raises before the user configuration can be copied. The previous code explicitly supported a missing local configuration by preserving no local fields.
Triggers: When the MaaEnd installation has not yet generated config/mxu-MaaEnd.json or the local configuration was removed.
Suggested fix: Check whether the local file exists and use an empty local configuration when it does not.
| maaend_local_set = read_file(self.maaend_set_path / "mxu-MaaEnd.json") | |
| maaend_local_set = ( | |
| read_file(self.maaend_set_path / "mxu-MaaEnd.json") | |
| if (self.maaend_set_path / "mxu-MaaEnd.json").exists() | |
| else {} | |
| ) |
| or maaend_instance.get("customName") | ||
| or "AUTO-MAS" | ||
| ) | ||
| maaend_instance = instances[0] |
There was a problem hiding this comment.
issue (bug_risk): 配置始终应用于 instances[0],但进程启动时使用的是硬编码的实例名称 AUTO-MAS。当第一个已配置实例不是 AUTO-MAS 实例时,被编辑的任务和设备并不是 MaaEnd 实际启动的实例。
触发条件: 当 MaaEnd 配置包含多个实例,且 AUTO-MAS 不是第一个实例时。
建议修复: 在修改实例前先选择 AUTO-MAS 实例,或者使用实际选定的实例名称启动进程。
Original comment in English
issue (bug_risk): Configuration is always applied to instances[0], but the process is launched with the hard-coded instance name AUTO-MAS. When the first configured instance is not the AUTO-MAS instance, the edited tasks and device are not the instance that MaaEnd starts.
Triggers: When a MaaEnd configuration contains multiple instances and AUTO-MAS is not the first instance.
Suggested fix: Select the AUTO-MAS instance before modifying it, or launch the exact selected instance name.
| len(self.account_id) < 4 or not self.account_id[-4:].isdigit() | ||
| ): |
There was a problem hiding this comment.
issue (broader_impact): 账户 ID 格式检查现在会对所有账户切换方式执行,而之前的代码只会对 MAAEND 内置切换器执行检查。用户选择 MAS 切换器并使用非数字账户 ID 时,即使 MaaEnd 在内置账户切换过程中不会使用该 ID,仍会被 check() 拒绝。
触发条件: 当 AccountSwitchMethod 为 MAS,且配置的账户 ID 非空但末尾不是四位数字时。
建议修复: 像之前的实现一样,仅在 AccountSwitchMethod == "MAAEND" 时进行验证。
Original comment in English
issue (broader_impact): The account-ID format check now runs for every account-switch method, whereas the previous code applied it only to the MAAEND built-in switcher. A user selecting the MAS switcher with a nonnumeric account ID is rejected by check() even though MaaEnd does not consume that ID for built-in account switching.
Triggers: When AccountSwitchMethod is MAS and the configured account ID is nonempty but does not end in four digits.
Suggested fix: Keep the validation conditional on AccountSwitchMethod == "MAAEND", as in the previous implementation.
| header.writeUInt32LE(crc, 14) | ||
| header.writeUInt32LE(compressed.byteLength, 18) | ||
| header.writeUInt32LE(data.byteLength, 22) | ||
| header.writeUInt16LE(name.byteLength, 26) |
There was a problem hiding this comment.
issue (bug_risk): 自定义写入器生成的是经典 ZIP 标头,并使用 32 位写入存储大小和偏移量,同时没有 ZIP64 记录。文件、归档或中央目录超过 4 GiB 时,这些字段会溢出;尽管旧的大小限制已被移除,最终仍会生成无法读取或解压不正确的归档。
触发条件: 当源文件或生成的归档超过经典 ZIP 的 4 GiB 限制时。
建议修复: 实现 ZIP64 标头和 ZIP64 中央目录结束记录,或者保留一个低于经典 ZIP 限制的明确上限。
Original comment in English
issue (bug_risk): The custom writer emits classic ZIP headers and stores sizes and offsets with 32-bit writes, without ZIP64 records. Files, archives, or central directories exceeding 4 GiB overflow these fields and produce an unreadable or incorrectly extracted archive despite the removal of the old size limits.
Triggers: When a source file or the resulting archive crosses the classic ZIP 4 GiB limit.
Suggested fix: Implement ZIP64 headers and an ZIP64 end-of-central-directory record, or retain an explicit limit below the classic ZIP limits.
清理了MaaEnd Autoproxy代码逻辑,删掉一些没意义的分支
修改导出日志逻辑,现在允许大文件导出
Sourcery 总结
优化 MaaEnd AutoProxy 执行流程,并将问题报告生成切换为流式归档,以更可靠地导出大型日志。
新功能:
错误修复:
增强功能:
杂项:
Original summary in English
Sourcery 总结
优化 MaaEnd 自动代理的执行可靠性,并改进问题报告生成以支持大型日志导出。
新功能:
错误修复:
增强功能:
日常维护:
Original summary in English
Summary by Sourcery
优化 MaaEnd 自动代理的执行可靠性,并改进问题报告生成以支持大型日志导出。
New Features:
Bug Fixes:
Enhancements:
Chores:
Original summary in English