Compare commits

...

608 Commits

Author SHA1 Message Date
uye
8796112363 Release v5.28.4 (#14958)
## Summary by Sourcery

通过更新游戏内容数据,并打磨小游戏、肉鸽玩法、工具链和 CI 行为,为各端与各平台准备 v5.28.4 版本。

New Features:
- 基于所选游戏客户端类型,动态加载小游戏任务选项。
- 为最新活动和 UR 关卡新增关卡、任务与地块位置数据。

Bug Fixes:
- 当小游戏选择为空或未知时,显示专用提示,而不是静默失败。
- 将未知的“两位字母-数字”形式的关卡视作已过期活动关卡,而不是常驻关卡。
- 在包括 txwy 在内的所有客户端上允许幻影肉鸽难度 15。
- 通过放宽匹配模式,改进 MacGui 问题自动打标签的 issue 检查器配置。
- 避免在 lldb 中包装冒烟测试,从而使脚本能在没有调试器的环境中运行。

Enhancements:
- 扩展小游戏提示,覆盖更多小游戏变体,例如 HoneyFruit 对决频道。
- 调整资源、CLI 二进制文件与模板的优化设置,以匹配新版本内容。

Build:
- 调整冒烟测试工作流的权限,只请求对仓库内容的只读访问。

CI:
- 简化 CI 中调用冒烟测试脚本的方式,改为直接运行测试二进制文件,而不附加调试器。

Tests:
- 更新冒烟测试工具和日志,以便在新版本内容下运行面向各客户端的自动化检查。

Chores:
- 刷新多类游戏数据资源文件(战斗、基建、物品、关卡、任务以及本地化)以适配新版本。

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

Prepare v5.28.4 by updating game content data and polishing minigame,
roguelike, tooling, and CI behavior across clients and platforms.

New Features:
- Load minigame task options dynamically based on the selected game
client type.
- Add new stage, task, and tile-position data for the latest activities
and UR stages.

Bug Fixes:
- Handle unknown or empty minigame selections by showing a dedicated tip
instead of failing silently.
- Treat unknown two-letter dash numeric stages as expired activity
stages instead of permanent ones.
- Allow Phantom roguelike difficulty 15 on all clients, including txwy.
- Improve MacGui issue auto-labeling by broadening the matching patterns
in the issue checker configuration.
- Avoid wrapping smoke tests in lldb so the script can run in
environments without the debugger.

Enhancements:
- Extend minigame tips to cover additional minigame variants such as
HoneyFruit duel channel.
- Refine resources, CLI binary, and template optimization settings to
align with the new release content.

Build:
- Adjust smoke testing workflow permissions to only request read access
to repository contents.

CI:
- Simplify the smoke testing script invocation in CI to run the test
binary directly without debugger attachment.

Tests:
- Update smoke testing tooling and logs for running client-specific
automated checks with the new release content.

Chores:
- Refresh multiple game data resource files (battle, infrastructure,
items, stages, tasks, and localization) for the new release.

</details>

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

通过更新游戏内容数据,并打磨小游戏、肉鸽玩法、工具链和 CI 行为,为各端与各平台准备 v5.28.4 版本。

New Features:
- 基于所选游戏客户端类型,动态加载小游戏任务选项。
- 为最新活动和 UR 关卡新增关卡、任务与地块位置数据。

Bug Fixes:
- 当小游戏选择为空或未知时,显示专用提示,而不是静默失败。
- 将未知的“两位字母-数字”形式的关卡视作已过期活动关卡,而不是常驻关卡。
- 在包括 txwy 在内的所有客户端上允许幻影肉鸽难度 15。
- 通过放宽匹配模式,改进 MacGui 问题自动打标签的 issue 检查器配置。
- 避免在 lldb 中包装冒烟测试,从而使脚本能在没有调试器的环境中运行。

Enhancements:
- 扩展小游戏提示,覆盖更多小游戏变体,例如 HoneyFruit 对决频道。
- 调整资源、CLI 二进制文件与模板的优化设置,以匹配新版本内容。

Build:
- 调整冒烟测试工作流的权限,只请求对仓库内容的只读访问。

CI:
- 简化 CI 中调用冒烟测试脚本的方式,改为直接运行测试二进制文件,而不附加调试器。

Tests:
- 更新冒烟测试工具和日志,以便在新版本内容下运行面向各客户端的自动化检查。

Chores:
- 刷新多类游戏数据资源文件(战斗、基建、物品、关卡、任务以及本地化)以适配新版本。

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

Prepare v5.28.4 by updating game content data and polishing minigame,
roguelike, tooling, and CI behavior across clients and platforms.

New Features:
- Load minigame task options dynamically based on the selected game
client type.
- Add new stage, task, and tile-position data for the latest activities
and UR stages.

Bug Fixes:
- Handle unknown or empty minigame selections by showing a dedicated tip
instead of failing silently.
- Treat unknown two-letter dash numeric stages as expired activity
stages instead of permanent ones.
- Allow Phantom roguelike difficulty 15 on all clients, including txwy.
- Improve MacGui issue auto-labeling by broadening the matching patterns
in the issue checker configuration.
- Avoid wrapping smoke tests in lldb so the script can run in
environments without the debugger.

Enhancements:
- Extend minigame tips to cover additional minigame variants such as
HoneyFruit duel channel.
- Refine resources, CLI binary, and template optimization settings to
align with the new release content.

Build:
- Adjust smoke testing workflow permissions to only request read access
to repository contents.

CI:
- Simplify the smoke testing script invocation in CI to run the test
binary directly without debugger attachment.

Tests:
- Update smoke testing tooling and logs for running client-specific
automated checks with the new release content.

Chores:
- Refresh multiple game data resource files (battle, infrastructure,
items, stages, tasks, and localization) for the new release.

</details>

</details>
2025-12-06 00:13:02 +08:00
github-actions[bot]
bd0681a437 docs: Auto Update Changelogs of v5.28.4 (#14959)
* docs: Auto Generate Changelog of Release v5.28.4

* docs: Auto Update Changelogs of v5.28.4 (#14960)

* Initial plan

* docs: Update CHANGELOG.md v5.28.4 per formatting guidelines

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Refine precommit template description

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Add separator and preserve v5.28.3 content

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Apply version merge rules for v5.28.4 patch release

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>
2025-12-06 00:10:34 +08:00
uye
4feb2f109b perf: 调整 UpdateMiniGameTaskList 2025-12-05 18:44:55 +08:00
HY
765b9acb1c feat: 當左上角進行中活動因太多被折疊時,增加展開領取的狀態判斷 (#14957)
* feat: 當左側進行中活動列表折疊時,增加展開領取的狀態判斷

* chore: 放個圖片

* chore: 加個保底任務 & 補充說明文字

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: 移除 "maxTimes"

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-12-05 18:22:27 +08:00
晓丶梦丶仁
bdeebe80e0 rft: Minigame ToolboxViewModel (#14951)
* rft: Minigame ToolboxViewModel

* fix: Invalid Task Name

* feat: Invalid Task Tip

* fix: key name
2025-12-05 17:07:46 +08:00
github-actions[bot]
df9f458a6f chore: Auto Update Game Resources - 2025-12-05
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19957243176

[skip changelog]
2025-12-05 08:30:31 +00:00
uye
ee7a61974b feat: 关卡选择验证输入,非当期活动的关卡名会当做未开放关卡 2025-12-05 16:11:11 +08:00
uye
b4887ae836 feat: UR 活动导航 2025-12-05 16:11:11 +08:00
github-actions[bot]
ca23e700c8 chore: Auto Update Game Resources - 2025-12-05
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19954805469

[skip changelog]
2025-12-05 06:31:21 +00:00
github-actions[bot]
2a4b9097c3 chore: Auto Update Game Resources - 2025-12-04
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19947291234

[skip changelog]
2025-12-04 23:29:22 +00:00
github-actions[bot]
97a45542f3 chore: Auto Update Game Resources - 2025-12-04
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19942256933

[skip changelog]
2025-12-04 20:03:59 +00:00
github-actions[bot]
226b21d32a feat: Update Submodules MaaMacGui, maa-cli
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19910040375
[skip changelog]
2025-12-03 21:52:50 +00:00
HY
5b49d406c9 chore: 調整繁中服傀影肉鴿能夠選擇的難度 (#14952) 2025-12-03 19:40:29 +01:00
HY
6dd412364b fix: 繁中服周年月卡領取及贈送單抽的處理錯誤 (#14953) 2025-12-04 01:37:08 +08:00
Rbqwow
55b9ce4c7d fix: issue-checker.yml 中 MacGui 正则不包含 MacGui 2025-12-04 01:13:00 +08:00
github-actions[bot]
0acdf51077 feat: Update Submodules MaaMacGui, maa-cli
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19874728857
[skip changelog]
2025-12-02 21:52:33 +00:00
Status102
a92d429ab3 ci: smoke_test remove lldb (#14942)
ci: fix unthrow smoke_test error
2025-12-03 01:11:38 +08:00
萨拉托加
7eccc8674b fix: 卫戍协议因网络问题卡在结算界面 2025-12-02 23:35:24 +08:00
uye
b61e04dcfc fix: 代理失败后等待动画结束后再点击任务失败
fix #14937
2025-12-02 17:55:04 +08:00
uye
dd7c6d0a85 fix: 自定义基建排班使用无人机加速未进驻干员的设施导致卡死
fix #14933
2025-12-02 17:38:58 +08:00
github-actions[bot]
79469f2047 feat: Update Submodules MaaMacGui, maa-cli
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19838737544
[skip changelog]
2025-12-01 21:52:29 +00:00
Drest
0ea6626435 fix: 干员识别异常(荒芜拉普兰德) (#14934) 2025-12-01 10:29:27 +00:00
AnnAngela
bde9b78a60 ci: Potential fix for code scanning alert no. 109: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-11-30 23:47:58 +08:00
Constrat
53498f0d54 fix: precommit
precommit is fucking useless. It pushes the optimized templates in the PR, but it still throws the stupid failed check.
2025-11-29 23:25:38 +01:00
HY
ccdc37dbc3 chore: 更新繁中服部分基建設施截圖 (#14923)
* chore: 更新繁中服部分基建設施截圖

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: HY <momomochi987@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-29 23:20:27 +01:00
uye
746e62226f Release v5.28.3 (#14920)
## Summary by Sourcery

调整异常日志的基址解析方式,精炼调试文件保留策略,在 CI 中打包 Windows 调试符号,并为新版本更新配置、模板和任务资源。

New Features:
- 在 `txwy` 资源命名空间下,为小游戏与关卡新增全局任务配置。

Enhancements:
- 更改异常基址查找逻辑,以解析当前模块,从而在各平台上提供更精确的栈追踪日志。
- 收紧调试日志默认清理阈值,以减少调试文件的数量和存活时间。
- 根据新版本内容更新资源配置、本地化文件、GUI 资源以及模板优化设置。

CI:
- 在上传为 CI 构建工件前,将 Windows PDB 调试符号压缩为带版本号的 ZIP 存档,并在之后从安装目录中清理这些符号文件。

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

Adjust exception logging base address resolution, refine debug file
retention defaults, package Windows debug symbols in CI, and update
configuration, templates, and task resources for the new release.

New Features:
- Add new global task configurations for minigames and stages under the
txwy resource namespace.

Enhancements:
- Change exception base address lookup to resolve the current module for
more accurate stacktrace logging across platforms.
- Tighten default debug log cleanup thresholds to reduce the number and
lifetime of debug files.
- Update resource configs, localization files, GUI assets, and template
optimization settings in line with the new release content.

CI:
- Compress Windows PDB debug symbols into versioned ZIP archives before
uploading them as CI artifacts and clean them from the install directory
afterward.

</details>
2025-11-29 21:39:03 +08:00
Status102
784baa5a2a perf: debug下非根路径文件限3日内 (#14919) 2025-11-29 19:05:23 +08:00
github-actions[bot]
849c34c7fe docs: Auto Update Changelogs of v5.28.3 (#14921)
* docs: Auto Generate Changelog of Release v5.28.3

* docs: Auto Update Changelogs of v5.28.3 (#14922)

* Initial plan

* docs: Update CHANGELOG.md for v5.28.3 following generation rules

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Improve changelog text capitalization and formatting

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Append v5.28.3 changelog to existing v5.28.x release notes

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Bump version to v5.28.3 and update highlights

Updated version number and highlighted bug fixes.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>
2025-11-29 18:57:05 +08:00
github-actions[bot]
008252f3c8 chore: Auto Templates Optimization
Triggered by d24bd20919

[skip changelog]
2025-11-29 10:12:16 +00:00
uye
d24bd20919 fix: yj 的小杯 UI 2025-11-29 18:11:37 +08:00
uye
34acc37961 perf: 调整小游戏描述 2025-11-29 17:42:24 +08:00
uye
b2111f7d8b feat: 支持 PV 小游戏从当前关卡开始 2025-11-29 17:24:17 +08:00
uye
ab9faff55b perf: 优化 PV 小游戏部分复杂背景关卡的识别 2025-11-29 17:06:54 +08:00
uye
aaa2cb8fd7 perf: 优化 卫戍协议 流程 2025-11-29 16:42:52 +08:00
uye
9336144892 perf: 优化 PV 小游戏识别范围,提高识别率 2025-11-29 16:42:15 +08:00
uye
131eda9dfb fix: PV 小游戏进入关卡时遇到网络连接会少选烟花样片 2025-11-29 16:11:01 +08:00
uye
f2a3f84180 chore: debug 截图默认保存最近 10 张 2025-11-29 16:00:16 +08:00
status102
629bb9e576 chore: format 2025-11-29 12:24:38 +08:00
HY
56d311ebdb chore: 繁中服「眾生行記」活動導航 (#14908)
Co-authored-by: HY <momomochi987@users.noreply.github.com>
2025-11-29 00:28:41 +08:00
HY
139d812c0b chore: 繁中服「爭鋒頻道:青草城」小遊戲 (#14906)
chore: 繁中服「爭鋒頻道:青草城」

Co-authored-by: HY <momomochi987@users.noreply.github.com>
2025-11-29 00:28:27 +08:00
status102
a373f7bf8e fix: 改漏了 2025-11-28 23:43:29 +08:00
status102
1bb6012cd8 fix: 压缩win平台的pdb文件 2025-11-28 23:37:48 +08:00
status102
426b785b21 fix: MaaCore Base Address 2025-11-28 23:23:38 +08:00
Hao Guan
8ec9023112 feat(mac): PV小游戏 2025-11-28 20:32:45 +08:00
uye
4edf912ecd Release v5.28.2 (#14901) 2025-11-28 18:59:50 +08:00
uye
07c01a6777 docs: 更新 CHANGELOG.md 2025-11-28 18:54:46 +08:00
github-actions[bot]
fbd2a6eb82 chore: Auto Templates Optimization
Triggered by f4f7a9d5a1

[skip changelog]
2025-11-28 10:51:58 +00:00
pre-commit-ci[bot]
f4f7a9d5a1 chore: Auto update by pre-commit hooks [skip changelog] 2025-11-28 10:51:38 +00:00
不留
d1cdd26176 fix: 裁剪 PV 小游戏 06-14 模板图以尽可能提高识别分数 (#14900)
* fix: 裁剪模板图以尽可能提高识别分数

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-28 18:43:24 +08:00
uye
f82ce2acad Release v5.28.1 (#14864)
Important [fix:
regex_error(error_badrepeat)](4861e96ddc)

<img width="1549" height="236" alt="image"
src="https://github.com/user-attachments/assets/0be3c81c-0281-4716-bae2-85a9fc5507db"
/>

My mistake a week ago.
Pushed a typo in the Sami I.S. regex

## Summary by Sourcery

为 v5.28.1 版本发布做准备,包括配置微调、自动化更新和资源刷新。

Bug Fixes:
- 在解析战斗编队前重置 support-unit 使用状态,以避免在多次运行之间出现陈旧状态。
- 在使用扁平化安装(flattened installs)时修正安装配置,确保库路径和安装目标位置设置一致。

Enhancements:
- 为新版本刷新游戏/资源任务定义、关卡元数据以及版本信息。
- 更新模板优化配置,以与当前的资源布局保持一致。

Build:
- 在使用扁平化安装布局时,调整 CMake 配置以设置运行库/链接库的安装目标以及 RPATH。

CI:
- 在 CI、发布、资源同步、网站和维护任务中,将所有 GitHub Actions 工作流更新为使用 actions/checkout v6。

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

Prepare the v5.28.1 release with configuration tweaks, automation
updates, and resource refreshes.

Bug Fixes:
- Reset support-unit usage state before parsing battle formations to
avoid stale state between runs.
- Correct installation configuration when using flattened installs so
library paths and install destinations are set consistently.

Enhancements:
- Refresh game/resource task definitions, stage metadata, and version
information for the new release.
- Update template optimization configuration to align with the current
resource layout.

Build:
- Adjust CMake configuration to set runtime/library install destinations
and RPATH when using a flattened install layout.

CI:
- Update all GitHub Actions workflows to use actions/checkout v6 across
CI, release, resource sync, website, and maintenance jobs.

</details>
2025-11-28 16:19:52 +08:00
Copilot
58d974184f Release v5.28.1 (#14897)
* Initial plan

* docs: add PV-烟花筹委会 mini-game highlight to v5.28.1 changelog

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: move PV-烟花筹委会 highlight to top section with v5.28.1+ note

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Bump version to 5.28.1 and update changelog

Updated version from 5.28.0 to 5.28.1 and added new features.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>
2025-11-28 16:11:23 +08:00
uye
eebdb0e9f0 docs: Update CHANGELOG for version 5.28.1 2025-11-28 16:02:19 +08:00
uye
18a65f3b39 feat: pv 小游戏 (#14885)
* feat: pv 小游戏架子

* chore: Auto update by pre-commit hooks [skip changelog]

* feat: 1-5 关

* chore: Auto update by pre-commit hooks [skip changelog]

* feat: PV 小游戏 06-15 (#14888)

* feat: 06-15

* fix: 15

* fix: templates and threshold

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: Auto update by pre-commit hooks [skip changelog]

* feat: 小游戏 16-20

* fix: 18-20 导航

* chore: Auto update by pre-commit hooks [skip changelog]

* feat: 添加 ui 入口

* fix: 全角数字

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: 不留 <weinibuliu@outlook.com>
2025-11-28 15:54:14 +08:00
status102
1d4a84dcca fix: 收集遗漏的MaaCore.pdb和MaaUtils/pdb 2025-11-28 14:36:11 +08:00
status102
69f3919b52 perf: wpf Debug压缩包切片增加时间前缀 2025-11-28 14:33:21 +08:00
github-actions[bot]
96d426f52c chore: Auto Update Game Resources - 2025-11-28
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19755551218

[skip changelog]
2025-11-28 06:04:54 +00:00
github-actions[bot]
b460703cdd chore: Auto Update Game Resources - 2025-11-28
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19754997403

[skip changelog]
2025-11-28 05:29:54 +00:00
uye
b7b010f97c fix: 基建换班卡死在无人机使用界面
fix #14751
2025-11-28 01:29:51 +08:00
github-actions[bot]
fdc1184ea0 chore: Auto Update Game Resources - 2025-11-27
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19740458310

[skip changelog]
2025-11-27 15:03:42 +00:00
DavidWang19
51c5fb44ee feat: 更新界园肉鸽商品列表 (#14882)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-27 12:27:00 +00:00
github-actions[bot]
ffbb46ba52 chore: Auto Update Game Resources - 2025-11-27
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19734077676

[skip changelog]
2025-11-27 11:03:19 +00:00
不留
d025969c82 refactor: 改进 ImageCropper (#14762)
* fix: 修复 ImageCropper 循环异常退出的问题

* feat: 允许 ADB 为空

* fix: 修复 input 为空时的异常

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: 规范变量命名

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-27 18:25:42 +08:00
github-actions[bot]
c9f3fb8053 chore: Auto Templates Optimization
Triggered by 9c2d6c3a30

[skip changelog]
2025-11-27 09:15:39 +00:00
uye
9c2d6c3a30 rft: 整理截图 2025-11-27 17:14:54 +08:00
github-actions[bot]
efda298a11 chore: Auto Templates Optimization
Triggered by fec5edd021

[skip changelog]
2025-11-27 08:11:27 +00:00
uye
fec5edd021 chore: 重命名文件夹 2025-11-27 16:08:57 +08:00
github-actions[bot]
ede4cd526e chore: Auto Update Game Resources - 2025-11-27
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19727964321

[skip changelog]
2025-11-27 07:04:13 +00:00
uye
8ac9610d66 chore: Update bug report template to simplify instructions
Removed redundant instruction about uploading error images from the debug directory.
2025-11-27 03:47:42 +08:00
uye
838790a6a1 chore: Refine descriptions in en-bug-report.yaml
Updated descriptions in the bug report template for clarity and formatting.
2025-11-27 03:46:50 +08:00
uye
cef398b417 chore: Update descriptions in cn-bug-report.yaml 2025-11-27 03:43:03 +08:00
github-actions[bot]
f09dbd2f49 docs: Auto Update Changelogs of v5.28.1 (#14879)
* docs: Auto Generate Changelog of Release v5.28.1

* [WIP] Update changelogs for version v5.28.1 (#14881)

* Initial plan

* docs: Update CHANGELOG.md following changelog generation guidelines

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Update CHANGELOG with recent fixes and improvements

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>
2025-11-27 03:37:46 +08:00
uye
46b8d41998 rft: 整理一下截图 (#14878)
* rft: 整理一下截图

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-27 02:59:56 +08:00
SherkeyXD
695ca69da6 chore: remove and sort usings (#14877) 2025-11-27 02:55:57 +08:00
DavidWang19
84fe358011 feat: 更新肉鸽协议文档和界园肉鸽商品列表 (#14873)
* feat: 更新肉鸽协议文档和界园肉鸽商品列表

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 将no修改为No

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-27 02:54:58 +08:00
uye
c4b363da3d feat: 刷理智失败次数达到上限时报错 2025-11-27 01:28:32 +08:00
uye
3177e2a51d fix: 功能入口 (#14872)
* fix: 功能入口

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: 调整任务

* chore: 重试时只检测对应主题

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-27 01:03:02 +08:00
travellerse
46cea84d7d fix: 避免通宝插件通过任务链作用到通宝以外的地方 (#14867) 2025-11-27 00:35:27 +08:00
Rbqwow
753637609d docs: issue模板修改25mb压缩包上传提示 (#14850)
* docs: 25mb

* i18n: add 25MB upload limit message to English bug report template (#14858)

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2025-11-27 00:34:20 +08:00
Constrat
4861e96ddc fix: regex_error(error_badrepeat) 2025-11-25 21:39:56 +01:00
status102
2003772ddf fix: 重置助战干员为未编入
link to #14859
2025-11-26 00:53:41 +08:00
github-actions[bot]
8c76a62230 chore: Auto Update Game Resources - 2025-11-25
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19677269535

[skip changelog]
2025-11-25 16:49:03 +00:00
uye
3511a426de chore: 调整 StartToVisit 阈值
fix #14853

相关工作项: #14
2025-11-25 16:01:25 +08:00
MistEO
9f8da17db1 build: set RPATH_LIBRARY_INSTALL_DIR (#14854) 2025-11-25 13:22:41 +08:00
github-actions[bot]
4eff74e5b1 chore: Auto Templates Optimization
Triggered by fdb89a6d4e

[skip changelog]
2025-11-24 16:43:56 +00:00
uye
fdb89a6d4e fix: 齐聚主题会在基建同时存在红蓝两个提示的时候无法进入
fix 14746
2025-11-25 00:43:27 +08:00
MistEO
8a73d922e0 feat: update meojson to v5.0.0 (#14849) 2025-11-25 00:29:46 +08:00
dependabot[bot]
36084974d1 ci: bump actions/checkout from 5 to 6 in /.github/workflows in the github-actions group (#14847)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 23:39:04 +08:00
uye
27027dbdfa Release v5.28.0 (#14833)
发正式版,先别进新东西

## Summary by Sourcery

Prepare battle processing, vision handling, roguelike copper management,
and CI smoke testing for the v5.28.0 release.

Bug Fixes:
- Allow skill usage actions to correctly handle drone deployments by
mapping tile locations to dynamically registered operator names.
- Prevent region-of-interest calculations from exceeding image bounds by
clamping rectangles safely and logging out-of-range inputs.
- Avoid smoke-test workflow failures when cache key generation fails by
making the step non-fatal and guarding cache restore on a valid key.

Enhancements:
- Centralize registration of deployed operators into a reusable helper
to keep battlefield state consistent.
- Standardize logging in the roguelike coppers task plugin to use the
project logging macros and clean up unused includes.
2025-11-24 16:55:52 +08:00
github-actions[bot]
d828cdb078 docs: Auto Update Changelogs of v5.28.0 (#14836)
* docs: Auto Generate Changelog of Release v5.28.0

* docs: Optimize changelog formatting and organization for v5.28.0 (#14837)

Reformatted changelog entries to follow project conventions: merged
related commits, fixed CJK/Latin number spacing, reordered sections by
language, clarified vague descriptions, and added Highlights section.

**Changes:**

* **Added Highlights section** - Created bilingual (Chinese/English)
highlights focusing on 5 key user-facing improvements:
  1. Task error log screenshot viewing on hover for intuitive debugging
2. Debug screenshot packaging with multi-volume support (20 MB per
volume) for flexible uploads
  3. Smart auto support unit borrowing when only one operator is missing
  4. Optimized auto-battle page layout
5. Integrated Strategies fixes (boss recognition, Tongbao parsing, event
recognition, task chains)
* **Merged duplicate entries** - Combined 3 "Release beta.2" PRs, 2
"Auto Update Changelogs", and related bug fixes (e.g., 通宝解析 fixes
#14802/#14820/#14829)
* **Fixed number spacing** - Added spaces around numbers in mixed
CJK/Latin text per convention (e.g., "第三层" → "第 3 层", "8识别成g" → "8 识别成
g")
* **Reordered sections** - Chinese entries first, English-only entries
last within each category
* **Improved clarity** - Replaced vague commit messages with descriptive
text (e.g., "投资入口不知道为啥没点进去" → "投资入口识别失败")
* **Fixed categorization** - Moved "修复 '入暂亭' 事件" from Improved to Fix
section

Removed uninformative entries like "擦屁股", "unused", "去掉勾选框" that don't
describe actual changes.

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

* feat: Revise changelog for version 5.28.0

Updated highlights and added new features for better debugging and auto-battle experience.

* doc: Update CHANGELOG.md for recent feature enhancements

* doc: Update CHANGELOG with recent fixes and optimizations

* docs: Revise CHANGELOG for clarity and detail

Updated the CHANGELOG with improved error handling descriptions and clarified features for 'Generate Support Payload' and 'Copilot'.

* docs: changelog

* docs: Update CHANGELOG with recent fixes and optimizations

* chore: EN issues address

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AnnAngela <naganjue@vip.qq.com>
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
Co-authored-by: Status102 <102887808+status102@users.noreply.github.com>
Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
2025-11-24 16:47:56 +08:00
Copilot
a778ff84d9 fix: propagate errors from parallel downloads in res-update-game workflow (#14794)
* Initial plan

* fix: properly handle errors in parallel downloads for stages.json

Co-authored-by: AnnAngela <9762652+AnnAngela@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AnnAngela <9762652+AnnAngela@users.noreply.github.com>
2025-11-24 09:30:03 +01:00
uye
95133cfeae fix: 部分名片无法进入线索交接
fix #14841
2025-11-24 14:40:26 +08:00
github-actions[bot]
4f7ba196c3 chore: Auto Update Game Resources - 2025-11-24
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19624349036

[skip changelog]
2025-11-24 05:29:59 +00:00
travellerse
e4644f7d2f fix: 修复放弃通宝的后续任务逻辑 (#14840) 2025-11-24 13:28:03 +08:00
uye
12846c9689 fix: 移除传入的 save_cnt 参数 2025-11-24 13:22:58 +08:00
github-actions[bot]
4fef683612 chore: Auto Templates Optimization
Triggered by a0547bee50

[skip changelog]
2025-11-24 05:11:49 +00:00
uye
a0547bee50 fix: 在未进入缩小的全局总览的时可能进错宿舍 2025-11-24 13:11:20 +08:00
pre-commit-ci[bot]
9f0e6e104c chore: Auto update by pre-commit hooks [skip changelog] 2025-11-24 05:00:32 +00:00
uye
e0b67b1523 fix: 大括号位置错误 2025-11-24 12:57:35 +08:00
uye
31520afb37 fix: image 长宽等于 0 时提前返回 2025-11-24 12:48:08 +08:00
uye
bf30c84b4f chore: 完全越界时报 error 2025-11-24 02:46:18 +08:00
uye
5c6f654762 fix: 避免输出空矩阵 2025-11-23 16:23:50 +08:00
uye
127d3a670c perf: 简化 ROI 修正逻辑 2025-11-23 16:15:10 +08:00
Status102
58d001744e feat(MaaCore): Copilot支持切换技能用法使用坐标 (#14818)
* feat: 支持切换技能用法使用坐标

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: usage

* fix: const ref

* perf: capture

* fix: case define

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-23 15:55:13 +08:00
status102
0d3a7ba48f fix: unused 2025-11-23 15:28:23 +08:00
status102
9b8686778d chore: 移除部分无需的include 2025-11-23 13:48:07 +08:00
晓丶梦丶仁
61489e4890 fix: KR 引航 2025-11-23 12:43:51 +08:00
uye
16bccd9876 fix: 擦屁股 2025-11-23 02:29:54 +08:00
uye
30fcea747b fix: StartUp 为什么要进终端 2025-11-23 01:54:52 +08:00
MistEO
44aec32649 ci: continue on bad cache key 2025-11-22 22:48:20 +08:00
uye
3cfcffbe16 Release v5.28.0-beta.2 (#14831)
一波三折!

## Summary by Sourcery

CI:
- Allow GitHub Actions cache steps to continue on error across multiple
workflows, preventing cache failures from breaking CI runs.
2025-11-22 22:42:58 +08:00
MistEO
3bec98b7ce ci: continue on error for all actions/cache 2025-11-22 22:23:36 +08:00
MistEO
889313fe36 ci: continue on cache maadeps error 2025-11-22 22:19:06 +08:00
uye
9db5f5a43b Release v5.28.0-beta.2 (#14827)
## Summary by Sourcery

Tighten roguelike copper exchange handling and improve debugging support
for copper recognition issues.

Bug Fixes:
- Ensure exactly one copper is detected in the left column during
exchange mode and fail fast otherwise.
- Fix the created copper’s position and logging to consistently use the
top-left slot coordinates.
- Stop silently continuing when copper creation fails by treating it as
a hard failure.

Enhancements:
- Add debug image capture for unexpected left-column copper counts and
for newly detected coppers.
- Always compile the copper detection debug drawing and image-saving
helpers regardless of debug flags.

Documentation:
- Update the documented path for saved debug images when unknown copper
names are encountered.
2025-11-22 21:42:40 +08:00
travellerse
d3f038b1ce fix: 修正通宝识别中的坐标 (#14829)
* fix: 修正通宝识别中的坐标

* fix: 添加Sarkaz关掉进入事件窗口的模板
2025-11-22 21:39:43 +08:00
travellerse
46d0fd2e5c fix: 处理左侧通宝解析失败的情况 (#14820)
* fix: 处理左侧通宝解析失败的情况

* fix: 更新调试图像保存路径至 debug/roguelike/coppers/unknown 目录

* fix: 优化通宝处理逻辑

* fix: 限制一下变量作用域

* fix: 移除ASST_DEBUG
2025-11-22 20:57:09 +08:00
github-actions[bot]
2503f2bc68 chore: Auto Update Game Resources - 2025-11-22
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19594191480

[skip changelog]
2025-11-22 10:28:05 +00:00
uye
de8634bf29 Release v5.28.0-beta.2 (#14800)
## Summary by Sourcery

Improve copilot configuration UX, extend roguelike (JieGarden)
automation with copper handling, and refine tooling, workflows, and
diagnostics for better stability and observability.

New Features:
- Add structured JSON-based configuration with popup editor for copilot
user additional operators, including optional skill and module fields.
- Introduce automated JieGarden copper pickup and exchange logic with
dedicated analyzers and config to optimize in-run decisions.
- Add UI theme task generation and image moving utilities to support
multi-theme homepage templates.

Bug Fixes:
- Ensure copilot log tooltips are closed and cleaned when clearing logs
to avoid lingering UI artifacts.
- Fix fight times unused warning trigger conditions so it only logs when
a finished run has remaining configured runs.
- Wait for reserve recruitment confirmation to disappear in JieGarden
recruit flow to prevent premature termination.
- Honor first-floor foldartal and start-with-elite-two flags correctly
so rerolling and early-exit behaviors are coordinated.
- Prevent GetImageFromROI cutter from crashing on unreadable images and
ensure crop regions are correctly resolved from base tasks.
- Handle GitHub API rate limiting and missing outputs more robustly in
the changelog generator and resource update workflows.

Enhancements:
- Refine copilot formation and support usage options, including a toggle
for support unit usage and updated formation index naming.
- Export operator box data including missing operators with default
metadata instead of only current user-stored entries.
- Warn users in logs when an outdated GPU driver is detected and include
localized messaging.
- Improve roguelike Bosky Passage routing by closing obstructive popups
before updating the map.
- Make InterfaceTask capture debug screenshots on failure to aid
troubleshooting.
- Simplify and harden changelog generation by restructuring commit
categorization, contributor resolution, and tree building logic.
- Modernize ROI-based image cutter to work off UiTheme task JSONs,
propagate shared crop docs, and respect per-template filenames.

Build:
- Adjust Windows nightly OTA CMake configuration to build with
RelWithDebInfo and publish PDB debug symbols for components.

CI:
- Tighten game resource download workflow with failing curl on HTTP
errors, coordinated job waiting, simpler artifact retries, and smarter
failure-comment management on the dev branch.

Documentation:
- Document JieGarden copper configuration schema and automatic
pickup/exchange behavior in the integrated strategy protocol docs.
- Clarify SECURITY policy to state that only the latest v5 stable
release receives security support.
2025-11-22 18:20:27 +08:00
github-actions[bot]
2e3fe293e6 docs: Auto Update Changelogs of v5.28.0-beta.2 (#14801)
* docs: Auto Generate Changelog of Release v5.28.0-beta.2

* docs: Optimize changelog formatting for v5.28.0-beta.2 (#14819)

* Initial plan

* docs: Optimize changelog formatting for v5.28.0-beta.2

- Merge similar commits (e.g., OCR replacement commits)
- Add spaces around numbers in Chinese/English mixed text (GPU, OCR, 20 MB)
- Sort entries: Chinese first, then English within each module
- Merge template optimization entries
- Optimize commit descriptions for clarity

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Update CHANGELOG with recent improvements and fixes

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>
2025-11-22 18:18:38 +08:00
萨拉托加
c1cb1ee978 fix: 肉鸽问题修复 (#14654)
* perf: 萨米界园肉鸽添加并优化暂时撤退逻辑

* perf: 萨卡兹肉鸽关掉进入事件可能弹出的窗口

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: RolesConfirm不知道为啥点不进去

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-22 18:12:15 +08:00
uye
fc61ff8ea2 rft: 统一存截图 (#14825)
* rft: 统一存截图

* rft: 漏网之鱼

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 静态锁

* chore: map 改为全局

* fix: 避免溢出

* chore: 怎么整得这么麻烦

* perf: 避免额外std::format

* fix: ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: status102 <102887808+status102@users.noreply.github.com>
2025-11-22 18:11:42 +08:00
Manicsteiner
285628a293 fix: copilot file name (#14821) 2025-11-22 14:24:17 +08:00
github-actions[bot]
8e906402fb chore: Auto Update Game Resources - 2025-11-21
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19582060835

[skip changelog]
2025-11-21 20:04:04 +00:00
uye
cf0a248ae1 ci: Update tools/ChangelogGenerator/changelog_generator.py
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-11-22 02:47:23 +08:00
uye
f232eacbb4 fix: 单文件模式下总是传递借助战 2025-11-22 02:44:17 +08:00
travellerse
c52f79cbaa fix: 修复界园树洞偶发点击到剩余烛火,导致无法进入下一个节点 (#14806)
* fix: 修复界园树洞偶发点击到剩余烛火,导致无法进入下一个节点

* rft: 使用task任务替代Matcher

* fix: 将弹窗检测置于节点识别前

* fix: 将检测任务retry_times设为0
2025-11-22 02:41:03 +08:00
uye
0978c10dca chore: 分卷压缩包大小改成 20 MB 2025-11-22 02:39:52 +08:00
Status102
b697fdc2c7 feat: MaaCore主任务错误时保存截图 (#14812)
* feat: MaaCore主任务错误时保存截图

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-22 02:33:31 +08:00
uye
5c37d751c7 perf: 优化自动战斗界面显示 (#14795)
* perf: 优化自动战斗界面显示

* fix: 不勾选战斗列表时也会吃理智药

* i18n: KR

* i18n: 加個空白

* i18n: EN

* i18n: JP

* rft: 使用自动换行

* style: increase size a bit

* perf: 优化界面布局

* rft: UserAdditional 改为序列化存储,增加自选模组

* fix: 列表过长时超链接无法显示

* perf: 未激活追加自定干员也可以进行编辑

* perf: 战斗列表自适应宽度

* chore: 按钮放上面

* perf: 优化日志栏宽度,占用 1/2 或 2/5

* perf: 突袭改成用背景色提示

---------

Co-authored-by: HX3N <scarlet7518@gmail.com>
Co-authored-by: momomochi987 <as99us301@gmail.com>
Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
Co-authored-by: Manicsteiner <Manicsteiner@outlook.com>
Co-authored-by: status102 <102887808+status102@users.noreply.github.com>
2025-11-22 02:30:44 +08:00
pre-commit-ci[bot]
07982cfebd chore: Auto update by pre-commit hooks [skip changelog] 2025-11-21 12:57:53 +00:00
SherkeyXD
ca21c9bcca chore: 更新多模板截图工具 2025-11-21 20:54:50 +08:00
github-actions[bot]
fbeed8083f chore: Auto Update Game Resources - 2025-11-20
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19541308413

[skip changelog]
2025-11-20 15:03:33 +00:00
Rbqwow
9ae8ca3ba8 feat: 为GPU加速添加超过两年的驱动版本检测 (#14690)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: status102 <102887808+status102@users.noreply.github.com>
2025-11-20 14:45:55 +00:00
SherkeyXD
b70d6b6b7f rft: 拆分多主题识别任务 (#14774)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: DavidWang19 <dwang0340@gmail.com>
2025-11-20 13:34:02 +00:00
Hao Guan
d6dbbf194f i18n(mac): KR 2025-11-20 18:38:49 +08:00
Hao Guan
fe134e2587 chore(mac): 修复UI细节 2025-11-20 16:58:49 +08:00
github-actions[bot]
b3539e6f27 chore: Auto Update Game Resources - 2025-11-20
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19528514707

[skip changelog]
2025-11-20 07:03:47 +00:00
Manicsteiner
3f06c13ff8 chore: SSS#8 for global (#14803) 2025-11-19 17:59:56 +01:00
Constrat
036f1c55ae fix: reduce template size for QuickFormation RL 2025-11-19 17:37:56 +01:00
Constrat
bba94660d7 perf: optimize templates 2025-11-19 17:36:37 +01:00
uye
0963e88112 fix: RA 导航错误 2025-11-19 23:15:16 +08:00
uye
bbb48127ff rft: 调整 ExportOperBox 内的变量命名与结构 2025-11-19 23:08:49 +08:00
travellerse
88acc9e83d fix: 修复通宝配置解析逻辑 (#14802) 2025-11-19 23:03:52 +08:00
SherkeyXD
38a7710387 style: changelog 生成器格式化 2025-11-19 20:30:53 +08:00
github-actions[bot]
9a7318942c feat: Update Submodules MaaMacGui, maa-cli
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19498803186
[skip changelog]
2025-11-19 10:54:03 +00:00
萨拉托加
48bb385211 fix: 从主页进入终端点过头后返回 (#14698)
* fix: 从主页进入终端点过头后返回

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-19 18:52:16 +08:00
Weiyou Wang
cb897863f6 fix: 修复集成战略萨米主题下凹密闻板相关功能 (#14755) 2025-11-19 18:50:32 +08:00
travellerse
d25f8e934c fix: 保存招募券结束后等待确认招募按钮消失 (#14773)
* fix: 保存招募券结束后加点延时

* fix: 增加确认招募按钮消失的等待逻辑

* fix: 添加确认按钮未消失时继续招募流程
2025-11-19 18:50:03 +08:00
uye
5d75c247be ci: 更新下 changelog 2025-11-19 18:49:23 +08:00
travellerse
f08fdd0548 fix: 修正不期而遇事件名ocr以区分禳解的三个相近选项 (#14799) 2025-11-19 18:11:02 +08:00
status102
06f793cf59 ci: nightly版恢复pdb文件生成及上传 2025-11-19 17:47:38 +08:00
status102
8b61cac331 fix: 刷理智指定次数未完全消耗警告在剩余理智也会提示 2025-11-19 16:51:51 +08:00
status102
807a3d472d fix: 干员识别复制结果到剪贴板时丢失未拥有干员 2025-11-19 15:53:27 +08:00
status102
4a71452841 fix: 移除过旧的add_user_additional参数弃用提示 2025-11-19 15:53:05 +08:00
github-actions[bot]
d5b6d2fe60 chore: Auto Update Game Resources - 2025-11-19
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19493348827

[skip changelog]
2025-11-19 07:28:02 +00:00
travellerse
ac7d449584 feat: 适配界园肉鸽通宝交换 (#13835)
* feat: 初步实现界园肉鸽通宝交换

* feat: 实现通宝交换后弹窗点击

* fix: 使用ocr作为通宝交换完成的标志

* fix: 给通宝弹窗确认的 pre_task 加上 postDelay

* fix: 小错误修改

* fix: 添加ocrReplace

* feat: 给通宝赋予临时权重,之后再改

* refactor: 重构通宝任务插件,拆分复杂的_run

* fix: 修正通宝选择点击错误

* refactor: 把滑动函数改回直观

* feat: 新增已投出时的通宝丢弃权重

* fix: 更新通宝名称匹配规则

* chore: 增加注释和日志输出

* chore: 添加调试截图保存

* fix: 清理未使用的参数

* fix: 微调通宝权重

* fix: 修正保存截图过多

* fix: 修复Rect不匹配造成的错误

* fix: 调整debug截图

* fix: 修正选择通宝时位置错误

* fix: 修复刷不交换通宝时无法退出

* fix: 修改`已投出`识别得分的绘制位置

* fix: 启用不期而遇`饕餮廊`获取通宝

* fix: 调整通宝识别区域宽度

* fix: 添加`厉-安硕` -> `厉-安硕鼷`的替换

* fix: 为通宝名称未匹配产生的debug截图添加方框

* fix: 修正debug截图方框位置

* fix: 清理无用的ocrReplace

* fix: 删除通过任务给插件传递特殊参数

* fix: 增加"衡-霹雳"和"花-圣诏封神"的ocr替换

* docs: 添加界园肉鸽通宝交换文档

* fix: 默认刷开局模式交换通宝

* fix: 删除未使用的通宝列表行数变量

* fix: 通宝交换完成识别增加延迟

* fix: 增加"衡-军屯垦"的ocr替换

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 修正调试图像保存路径

* perf: 优化通宝创建逻辑

* refactor: 更新通宝任务模式名称

* refactor: 更新通宝稀有度键值

* chore: 更新通宝优先级

* fix: 通宝列表匹配时可能会将y轴间隔覆盖为0

* perf: 将交换通宝的信息发送到wpf

* perf: 将通宝调试截图改为jpeg

* fix:  添加"衡-旱热"的ocr替换

* refactor: 传递任务执行结果

* feat: 初步动态识别通宝列表

* perf: 将期望为空的识别逻辑改为期望匹配到

* chore: 为通宝类型模板添加mask

* refactor: 重构通宝识别逻辑

* refactor: 提取保存调试图像

* refactor: 使用std::format优化日志输出

* refactor: 收尾

* chore: 微调滑动距离

* fix: 忘了加maskRange了

* chore: 保留score小数点后六位

* fix: 修复神秘的点击停止后卡死问题

* docs: 更新文档

* docs: 添加通宝识别流程示意图

* fix: 更新通宝稀有度定义

* chore: 添加通宝交换模式的图片示意注释

* chore: 加点注释

* perf: 预分配通宝和检测结果的空间

* chore: 优化运行时状态变量注释

* fix: 仅在确实已被投出时绘制已投出的调试方框

* fix: 修正坐标变量名称以符合语义

* perf: 滑动误差较大时额外滑动一次进行回正

* fix: 仅在缓慢滑动时校准位置

* refactor: 优化通宝列表滑动

* fix: 尝试修复偶发通宝最后一列无法识别

* fix: 移除了 999

* fix: 进一步修复滑动

* chore: 更新未知通宝调试图像保存路径

* fix: 更改调试截图保存位置和matcher使用图片初始化

* fix: 添加"厉-一字落"的ocr替换

* fix: 适配MaaUtils的更改

* chore: 调整任务顺序

* chore: 添加通宝重投和开关钱盒任务配置

* chore: 文件头/注释调整

* rft: meojson反序列化

* chore: Auto update by pre-commit hooks [skip changelog]

* perf: 替换部分新log输出

* i18n: KR

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: status102 <102887808+status102@users.noreply.github.com>
Co-authored-by: HX3N <scarlet7518@gmail.com>
2025-11-19 15:22:33 +08:00
Weiyou Wang
e9bc53cb6d fix: 上调助战栏位匹配分数阈值 (#14796) 2025-11-18 21:54:06 +00:00
AnnAngela
990907fdb1 chore: Revise security support to only include v5 [skip changelog]
Updated security policy to indicate support only for v5.
2025-11-18 23:45:13 +08:00
Constrat
a4ca4ffda9 ci(testing): game resource update error comment tweaks and changes 2025-11-18 16:11:14 +01:00
AnnAngela
8e9c648f0e ci: Change curl command to fail on error
cc @Constrat
2025-11-18 22:31:57 +08:00
github-actions[bot]
b2231e3392 chore: Auto Templates Optimization
Triggered by 70075152df

[skip changelog]
2025-11-18 12:11:17 +00:00
uye
70075152df fix: 通关角标 2025-11-18 20:10:38 +08:00
travellerse
d8000250dc fix: 添加不期而遇事件名ocr替换 (#14588)
* fix: 添加不期而遇事件名ocr替换

* fix: 添加"找黍溯果"的ocr替换

* fix: 更新JieGarden的OCR替换规则
2025-11-18 19:58:13 +08:00
Constrat
37299f8758 fix: Sami IS EN 3rd floor regex 2025-11-18 11:39:52 +01:00
github-actions[bot]
bdd747fe2a chore: Auto Update Game Resources - 2025-11-18
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19457757314

[skip changelog]
2025-11-18 07:27:47 +00:00
status102
e71ade9573 chore: 路径迁移 2025-11-18 15:19:25 +08:00
Constrat
b77b8e55e5 fix: regex AD navigation EN 2025-11-17 20:06:48 +01:00
AnnAngela
222af5e23c ci: Simplify resource update workflow (#14785)
* ci: Simplify resource update workflow

Removed unnecessary delay and re-download steps for resources.

* ci: Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* ci: Remove continue-on-error from download steps

Removed 'continue-on-error' option from multiple download steps.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-17 17:41:08 +01:00
github-actions[bot]
0014167468 feat: Update Submodules MaaMacGui, maa-cli
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19412598245
[skip changelog]
2025-11-16 21:52:53 +00:00
uye
56a83bb8d7 feat: 清日志的时候把 ToolTip 手动清除一下 2025-11-16 03:32:39 +08:00
uye
fe71d9ea1c Release v5.28.0-beta.1 (#14767) 2025-11-16 03:13:09 +08:00
github-actions[bot]
565b8fa7f9 docs: Auto Update Changelogs of v5.28.0-beta.1 (#14768)
* docs: Auto Generate Changelog of Release v5.28.0-beta.1

* docs: Optimize changelog formatting for v5.28.0-beta.1 (#14769)

* Initial plan

* docs: Optimize changelog formatting per review guidelines

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Update CHANGELOG for v5.28.0-beta.1

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>
2025-11-16 03:02:46 +08:00
uye
b71f0b0a9f feat: 卫戍协议:盟约 小游戏 (#14763)
* feat: 卫戍协议:盟约 小游戏

* chore: Auto update by pre-commit hooks [skip changelog]

* feat: 调整描述

* chore: Auto update by pre-commit hooks [skip changelog]

* i18n: EN tweak

* i18n: KR tweak

* i18n: EN tweak

* feat: mac 卫戍协议:盟约

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
Co-authored-by: HX3N <scarlet7518@gmail.com>
2025-11-16 02:42:44 +08:00
Weiyou Wang
abe9affa44 fix: 进一步调整 WpfGui 助战选项显示布局 2025-11-16 00:32:14 +11:00
uye
e20508d46e fix: 自动借助战错误显示 2025-11-15 20:17:20 +08:00
HX3N
6427fdd609 i18n: KR tweak SupportUnitUsage translation 2025-11-15 13:20:51 +09:00
Status102
5c86b4b875 docs: integration zh可读性增强 (#14756)
docs: integration zh可读性增强 (#14754)

* docs: integration zh可读性增强

* docs: 再加一点

* docs: all in

* chore: Auto update by pre-commit hooks [skip changelog]

* docs: 去掉点多余的换行

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-14 22:22:48 +08:00
uye
c3f870e51e fix: 干员识别包含 盟约·辅助干员 和 领主·Sharp 2025-11-14 18:49:32 +08:00
github-actions[bot]
b99f1d4776 chore: Auto Templates Optimization
Triggered by 0d13aed500

[skip changelog]
2025-11-14 09:03:43 +00:00
github-actions[bot]
0d13aed500 chore: Auto Update Game Resources - 2025-11-14
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19359577330

[skip changelog]
2025-11-14 09:03:16 +00:00
Manicsteiner
5a1ea3c186 fix: JP paradox 2025-11-14 16:30:38 +08:00
github-actions[bot]
2c8c319657 chore: Auto Update Game Resources - 2025-11-14
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19358208540

[skip changelog]
2025-11-14 08:03:37 +00:00
Weiyou Wang
26a20755e1 rft: 修复、改进自动借助战功能 (#11105) 2025-11-14 14:20:45 +11:00
Weiyou Wang
e29d802c08 fix: 简化萨米肉鸽 "诡秘的预感" 相关任务链 (#14749) 2025-11-14 12:17:13 +11:00
Weiyou Wang
a84e87f5e7 fix: 给 open_series_list 加上失败截图机制 (#14693) 2025-11-14 12:16:41 +11:00
Weiyou Wang
6662457428 refactor: 修复 "入暂亭" 事件 (#14684) 2025-11-14 12:16:03 +11:00
Weiyou Wang
95ea200ede fix: 防止生息演算重置地图视图时因截图延迟卡死 (#14721) 2025-11-14 12:15:17 +11:00
Status102
3ded8b574a chore: 向MaaCore工程增加tasks文件以便检索 (#14731)
* chore: 向MaaCore增加tasks文件

* chore: 支持global
2025-11-14 01:23:24 +08:00
Manicsteiner
d11582f39f chore: JP ocr edits (#14748) 2025-11-13 17:02:25 +01:00
github-actions[bot]
eedee9e6ee chore: Auto Update Game Resources - 2025-11-13
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19337134611

[skip changelog]
2025-11-13 15:44:31 +00:00
github-actions[bot]
0a768d8804 chore: Auto Update Game Resources - 2025-11-13
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19326795251

[skip changelog]
2025-11-13 09:28:33 +00:00
HX3N
0ff3492415 fix: KR AD navigation (#14742) 2025-11-13 09:19:11 +01:00
Weiyou Wang
a4d4e39257 fix: ocrReplace for EN (#14740)
Co-authored-by: 萨拉托加 <151550168+saratoga-official@users.noreply.github.com>
2025-11-13 09:18:35 +01:00
github-actions[bot]
89ab18ea6c chore: Auto Update Game Resources - 2025-11-13
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19324207913

[skip changelog]
2025-11-13 07:43:04 +00:00
萨拉托加
332592d998 fix: 肉鸽可能卡进剧目获取界面和收藏品界面
fix #14723
2025-11-13 14:53:16 +08:00
uye
6a931760d6 feat: 去掉勾选框 2025-11-12 22:11:13 +08:00
status102
f0a509fb6f perf: std::signal 自动舍弃 abort / terminate 上方栈 2025-11-12 20:04:53 +08:00
Lucien Shaw
f096131e12 ci: 修正一个cli相关的action的输入 (#14730)
ci: 修正cli使用的一个action的输入
2025-11-12 09:08:51 +01:00
uye
8240390a8b chore: git blame 忽略 "c# 统一使用文件范围限定的 namespace"
[skip changelog]
2025-11-12 16:05:35 +08:00
Weiyou Wang
80c8f03b24 docs: 自动战斗文档添加 copilot_list, is_raid, is_paradox, loop_times 注释 2025-11-12 15:12:46 +08:00
uye
39a89f6361 rft: 日志汇报打包 debug 截图,支持分卷,修改存储路径 2025-11-12 14:15:18 +08:00
Weiyou Wang
74cad75e74 fix: build WpfGui for ARM architecture (#14722) 2025-11-12 12:27:02 +08:00
uye
376e929d96 feat: 任务错误日志鼠标悬浮可以查看出错时截图 2025-11-12 11:27:00 +08:00
萨拉托加
d370b5d5fe fix: 关卡复核会把8识别成g 2025-11-12 09:57:21 +08:00
Weiyou Wang
e2ac3ff4e4 fix: 肉鸽允许跳过招募组合直接开始初始招募 (#14713)
fix: 允许跳过招募组合直接开始初始招募
2025-11-12 09:12:38 +08:00
MistEO
1c233d21c4 ci: include prerelease for release-package-distribution
https://github.com/pozetroninc/github-action-get-latest-release

default 	"prerelease, draft"
2025-11-12 01:28:43 +08:00
MistEO
b7cca46076 ci: remove permissions restrictions 2025-11-12 01:23:51 +08:00
Lucien Shaw
bfacd31911 ci: 支持winget软件分发 (#14667)
* ci: 测试winget-releaser

* ci: 暂时禁用mirrorchyan

* Revert "ci: 暂时禁用mirrorchyan"

This reverts commit 83550ac47f.

* ci: release分发工作流支持指定tag

* ci: 修复判断语句

* ci: 修改主工作流的release分发部分

* ci: 添加权限

* ci: 设置默认版本tag为空

* ci: 尝试修复空版本号带来的问题

* ci: 使用独立工作流设置release tag

* ci: 补全仓库名称

* ci: 优化gh workflow run调用语句

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* style: 添加空格

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* ci: use secrets and repos of MAA

* ci: 更新secrets名称

* ci: 版本分发工作流重命名

* ci: 匹配的名称变更

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 01:04:55 +08:00
萨拉托加
714e8e5511 fix: 投资入口不知道为啥没点进去 2025-11-11 23:26:40 +08:00
uye
0179825ff8 fix: 无法区分界园肉鸽第三层与第五层 boss、界园肉鸽第五层 boss 前暂停设置无效
fix #14641
2025-11-11 22:49:03 +08:00
uye
3fa5aa028a Release v5.27.4 (#14717)
有猪没合 changelog

## Summary by Sourcery

Update CHANGELOG.md to release version 5.27.4, detailing new features,
improvements, bug fixes, and other changes.

New Features:
- Add duplicate name check for auto battle groups
- Add difficulty selection tip for Guiyuan command squad savings
- Add minigame entry point on macOS

Bug Fixes:
- Fix monthly squad failing to auto-switch
- Improve recognition matching for the “gather” theme
- Fix unintended clicks in roguelike mode (double-speed and ClickToDrops
issues)

Enhancements:
- Update extreme efficiency one-day three-shift schedule table
(2025-11-11 revision)

Documentation:
- Bump version to v5.27.4 and document release notes in CHANGELOG.md

Chores:
- Update Dependabot CI members
- Preload ads for Global build
2025-11-11 22:06:23 +08:00
github-actions[bot]
6192e7d02b docs: Auto Update Changelogs of v5.27.4 (#14715)
* docs: Auto Generate Changelog of Release v5.27.4

* Initial plan

* Update CHANGELOG.md for v5.27.4

- Merge similar commits into single lines
- Sort entries within each category
- Preserve original changelog content (v5.27.3 and earlier)

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* Move v5.27.4 section to end of changelog

Patch version content should be placed at the end, after other v5.27.x patches, not at the beginning.

Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>

* docs: Update CHANGELOG for version 5.27.4

Updated version number to v5.27.4 and modified highlights, new features, improvements, and fixes sections.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ABA2396 <99072975+ABA2396@users.noreply.github.com>
2025-11-11 22:03:13 +08:00
uye
e5c48504cd Release v5.27.4 (#14714)
## Summary by Sourcery

Add duplicate detection in battle formation parsing with UI reporting,
refactor Roguelike plugin parameter loading, update CI action versions,
and adjust Dependabot assignees.

Bug Fixes:
- Prevent duplicate groups in battle formation and report parse failures
- Add UI handler to log BattleFormationParseFailed messages

Enhancements:
- Store deep_exploration_auto_iterate flag in Roguelike plugin and
simplify mode check
- Upgrade GitHub Actions versions for release and artifact upload
- Add lucienshawls to Dependabot assignees
2025-11-11 22:02:26 +08:00
github-actions[bot]
9b1bd1c70a chore: Auto Templates Optimization
Triggered by 5be311282e

[skip changelog]
2025-11-11 13:51:08 +00:00
uye
5be311282e perf: 优化齐聚主题模板图 2025-11-11 21:50:41 +08:00
萨拉托加
bb2325babc fix: 肉鸽ClickToDrops可能会点到藏品栏 2025-11-11 21:37:15 +08:00
github-actions[bot]
60fd50a3e5 feat: Update Submodules MaaMacGui, maa-cli
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19267340013
[skip changelog]
2025-11-11 13:35:49 +00:00
Constrat
4efef06aaa chore: update dependabot with ci members 2025-11-11 14:31:11 +01:00
dependabot[bot]
2bad5258e2 ci: bump the github-actions group in /.github/workflows with 2 updates (#14705)
Bumps the github-actions group in /.github/workflows with 2 updates: [actions/upload-artifact](https://github.com/actions/upload-artifact) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release).


Updates `actions/upload-artifact` from 4 to 5
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

Updates `softprops/action-gh-release` from 2.4.1 to 2.4.2
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2.4.1...v2.4.2)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: softprops/action-gh-release
  dependency-version: 2.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 14:26:45 +01:00
uye
7941a599e9 fix: 月度小队无法自动切换 2025-11-11 20:30:30 +08:00
Zsm1n
0066d3364e perf: 更新 243 极限效率一天三换排班表(20251111 修订) (#14708) 2025-11-11 11:25:12 +01:00
Status102
7b72b729b8 feat: 自动战斗新增组名重复检查 (#14710)
---------

Co-authored-by: HX3N <scarlet7518@gmail.com>
2025-11-11 10:35:18 +01:00
Hao Guan
a1d0dc9fea feat(mac): 喀兰小游戏界面提示 2025-11-11 17:25:30 +08:00
Hao Guan
abc2e618c7 fix(mac): 小游戏 2025-11-11 17:24:34 +08:00
uye
5771ede8a9 feat: mac 小游戏 2025-11-11 17:06:43 +08:00
萨拉托加
440d53e544 fix: 齐聚也干了
fix #14703
2025-11-10 22:20:06 +08:00
Constrat
dff100d338 chore: preload AD for Global (#14700)
---------

Co-authored-by: HX3N <scarlet7518@gmail.com>
Co-authored-by: Manicsteiner <Manicsteiner@outlook.com>
2025-11-10 15:03:06 +01:00
萨拉托加
0b94d7464e fix: 肉鸽中取消选中状态可能会点到二倍速 2025-11-10 12:26:06 +08:00
uye
ef46443681 feat: 增加界园指挥分队存钱难度选择 tip 2025-11-10 12:08:03 +08:00
uye
8821df308b Release v5.27.3 (#14687) 2025-11-09 23:05:13 +08:00
status102
af81c25ba1 fix: 猪猪 2025-11-09 22:43:33 +08:00
pre-commit-ci[bot]
34843fab31 chore: Auto update by pre-commit hooks [skip changelog] 2025-11-09 14:41:21 +00:00
status102
d1736e5dd4 fix: Module base macOs 2025-11-09 22:38:39 +08:00
github-actions[bot]
6b4164e6eb docs: Auto Update Changelogs of v5.27.3 (#14688)
* docs: Auto Generate Changelog of Release v5.27.3

* docs: Update CHANGELOG for version 5.27.3

Updated CHANGELOG for version 5.27.3, highlighting new features, improvements, fixes, and documentation updates.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
2025-11-09 22:31:42 +08:00
travellerse
2fb57d65df fix: 修复界园保留招募券在1080p下识别异常 (#14637)
* fix: 将colorWithClose设为false

* fix: 更换为没有文字的模板

* fix: 改回ClickSelf
2025-11-09 22:24:17 +08:00
萨拉托加
dce3780927 chore: 肉鸽添加凛御银灰圣聆初雪招募逻辑 2025-11-09 22:22:48 +08:00
pre-commit-ci[bot]
a0b1eaa804 chore: Auto update by pre-commit hooks [skip changelog] 2025-11-09 14:13:25 +00:00
status102
3bfa21ee02 feat: MaaCore 记录 Exception 时额外记录模块基址 2025-11-09 21:54:42 +08:00
uye
7c84863a20 fix: 提高干员部署滑动的最小时长,减少因模拟器丢帧导致的部署失败 2025-11-09 21:54:22 +08:00
Constrat
ac539eb343 fix: Exusiai Alter ocr regex for EN 2025-11-09 12:57:38 +01:00
MistEO
5e07116597 ci: 提供调试符号 (#14675) 2025-11-09 16:07:25 +08:00
github-actions[bot]
290261c50e chore: Auto Update Game Resources - 2025-11-08
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19190884721

[skip changelog]
2025-11-08 09:02:32 +00:00
uye
f1c28c7258 fix: 肉鸽刷开局期望奖励无法动态隐藏/显示 2025-11-08 15:43:30 +08:00
Constrat
74fd453a53 fix: Dorothy S2 ocr regex 2025-11-07 12:33:19 +01:00
status102
bfd9010ee2 feat: Wpf i18n字符串支持直接string.Frmat 2025-11-07 19:29:46 +08:00
github-actions[bot]
eb8c024202 chore: Auto Update Game Resources - 2025-11-07
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19162631273

[skip changelog]
2025-11-07 08:29:33 +00:00
status102
b2d0251b7e fix: Wpf增加悖论模拟模式非悖论作业检测 2025-11-07 13:37:56 +08:00
status102
5e85d2c793 perf: asst Log增加crash时额外输出core版本, build时间, 路径 2025-11-07 11:18:38 +08:00
MistEO
f54d012cb9 chore: add logs 2025-11-07 09:38:00 +08:00
MistEO
10179d1a0b perf: 更好的随机点分布 (#14652)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-07 09:33:53 +08:00
github-actions[bot]
43d88575c5 chore: Auto Templates Optimization
Triggered by 3fac78c0f9

[skip changelog]
2025-11-06 14:16:18 +00:00
uye
3fac78c0f9 perf: 优化切换主题逻辑 2025-11-06 22:15:48 +08:00
Lucien Shaw
88e27977e8 build(docs): update and switch to esm (#14642)
* build(docs): switch to esm

* build(docs): bump pnpm to v10.20.0

* ci: 精简文档站构建和发布流程

* build(docs): 升级部分依赖

* ci: 补全package.json的查找路径

* build(docs): 升级plume主题

* fix(docs): 适应新版本主题的样式变动

* ci: 补全文档站工作流的权限设置
2025-11-06 16:51:31 +08:00
uye
579def4704 feat: 怎么还有 GTII 2025-11-06 16:48:40 +08:00
uye
3233653381 fix: typo
[skip changelog]
2025-11-06 16:44:43 +08:00
uye
2a455c306a feat: 增加华硕 GTIII 显卡超频工具注入导致崩溃提示 2025-11-06 16:41:27 +08:00
萨拉托加
39c16790cd fix: 界园入暂亭ocrfix 2025-11-06 15:49:13 +08:00
MistEO
636ffff7b3 refactor: CropRoi -> ImageCropper (#14379) (#14647)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: SherkeyXD <57581480+SherkeyXD@users.noreply.github.com>
Co-authored-by: Lucien Shaw <myxlc55@outlook.com>
Co-authored-by: MistEO <18511905+MistEO@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: 不留 <weinibuliu@outlook.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2025-11-06 15:32:35 +08:00
MistEO
61cdb47c00 ci: 更好的 CI 并发控制 (#14645) 2025-11-06 13:42:44 +08:00
Constrat
766c33c7b6 fix(tools): update to new data repo for sh script 2025-11-05 11:48:55 +01:00
Constrat
3bc0df7e4d fix(tools): update to new data repo for ps1 script 2025-11-05 11:48:47 +01:00
Constrat
dec2d2fef2 chore: remove expired token 2025-11-05 11:44:57 +01:00
Constrat
2ee56d2089 fix: move to public arkntools repo for txwy
Thanks to @Tsuk1ko
2025-11-05 11:44:38 +01:00
Constrat
16bf17e9b1 fix: update Sami floor regex
fix 14630 (hopeful)
2025-11-05 01:00:37 +01:00
github-actions[bot]
66d4e9b298 chore: Auto Update Game Resources - 2025-11-04
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19066618580

[skip changelog]
2025-11-04 11:08:37 +00:00
Status102
15a333fd39 rft: wpf拆分添加作业和作业集按钮 (#14624)
* rft: wpf拆分添加作业和作业集按钮

* i18n: 调整CopilotTip

* chore: 添加注释, 未来移除旧的右键行为

* perf: 统一图标格式

* perf: 统一文本描述

* chore: todo!

* feat: 调整描述

* feat: 调整悖论模拟列表启动要求描述

* i18n: KR tweak translation

* fix: typo

---------

Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
Co-authored-by: HX3N <scarlet7518@gmail.com>
2025-11-04 16:30:46 +08:00
Status102
2c2b3c5b19 feat: 战斗列表启用时, 浏览单个作业时自动添加到战斗列表 (#14625) 2025-11-04 12:34:28 +08:00
uye
8eea7e49c5 perf: 优化切换主题流程 2025-11-03 22:48:17 +08:00
github-actions[bot]
bce6a6f259 chore: Auto Update Game Resources - 2025-11-03
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/19038089979

[skip changelog]
2025-11-03 14:32:04 +00:00
uye
676a470d2d fix: 给 mujica 擦屁股 2025-11-03 22:28:11 +08:00
Constrat
c7db6347f9 fix: move from Template to OcrDetect for BattleQuickFormationClear
Needed after yostar keeps changing that stupid button
2025-11-03 13:13:37 +01:00
status102
45528c282d perf: 空stack trace输出 2025-11-03 13:51:39 +08:00
uye
7b31ad3417 fix: 部分情况下 钼铅 识别错误 2025-11-03 13:11:19 +08:00
晓丶梦丶仁
9842cb962e fix: JP 1ns ocr 2025-11-03 11:54:32 +08:00
uye
4edf48b2e5 fix: OS 小游戏回合结束改用 ocr 2025-11-03 00:20:14 +08:00
uye
9d58a1c5be fix: 结束回合按钮怎么还会闪烁啊 2025-11-02 23:23:08 +08:00
MistEO
b73377eb6a refactor: use MaaUtils instead of Utils (#14579)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-11-02 23:19:38 +08:00
uye
2394480583 fix: 动画或卡顿导致概率无法使用无人机
fix #14620
2025-11-02 22:32:27 +08:00
uye
e09b984a15 Revert "fix: 增加从主页进入终端的延迟"
This reverts commit 6a09f44a09.
2025-11-02 18:44:44 +08:00
萨拉托加
6a09f44a09 fix: 增加从主页进入终端的延迟
fix #14617
2025-11-02 17:47:05 +08:00
uye
79f69ae511 Release v5.27.2 (#14605) 2025-11-02 16:57:02 +08:00
uye
defeedcd82 docs: Update CHANGELOG with recent fixes and features 2025-11-02 16:56:12 +08:00
uye
9b463e0a05 fix: fix: 技能点击范围会点到装备应变 (#14611) 2025-11-02 16:54:15 +08:00
萨拉托加
bda15f1074 fix: 技能点击范围会点到装备应变 (#14611) 2025-11-02 16:48:49 +08:00
github-actions[bot]
7d3d40ab37 chore: Auto Templates Optimization
Triggered by 59ed067254

[skip changelog]
2025-11-02 08:45:23 +00:00
pre-commit-ci[bot]
59ed067254 chore: Auto update by pre-commit hooks [skip changelog] 2025-11-02 08:44:24 +00:00
uye
3d6541d337 docs: Update CHANGELOG for version 5.27.2 2025-11-02 16:43:36 +08:00
uye
62c3dbd126 feat: OS-喀兰贸易研发部 小游戏 (#14615) 2025-11-02 16:41:26 +08:00
Constrat
866ed07d0c fix: Ines regex EN 2025-11-01 17:41:59 +01:00
萨拉托加
340a121528 fix: 肉鸽商店投资界面加一点延迟 2025-11-01 23:15:46 +08:00
github-actions[bot]
76b5c3380a docs: Auto Update Changelogs of v5.27.2 (#14606)
* docs: Auto Generate Changelog of Release v5.27.2

* docs: Update CHANGELOG for v5.27.2

Update CHANGELOG for version 5.27.2 with new features, improvements, and bug fixes.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
2025-11-01 23:09:29 +08:00
uye
e40307f107 fix: 无法迁移就资源路径文件 2025-11-01 22:04:45 +08:00
uye
015dcbcc4f chore: SideStoryStage ocrReplace 2025-11-01 21:18:03 +08:00
Constrat
6b9612c356 fix: erosion resistant device regex fix for EN 2025-11-01 14:08:22 +01:00
MistEO
a0513fcfac Release v5.27.1 (#14598) 2025-11-01 19:06:22 +08:00
MistEO
79fce90bf8 ci: 算了你还是取消吧 2025-11-01 19:04:22 +08:00
MistEO
81793fc040 ci: fix cancel 2025-11-01 19:01:07 +08:00
MistEO
b3673409ac ci: dev do not auto cancel build 2025-11-01 18:54:31 +08:00
Hao Guan
2fa55fe15d fix(mac): 修复MaaUtils库位置 2025-11-01 18:48:30 +08:00
MistEO
a1141d2574 docs: v5.27.1 changelog 2025-11-01 18:47:11 +08:00
Hao Guan
6ba037ab4d fix(mac): GUI缺少MaaUtils库 2025-11-01 18:41:23 +08:00
SherkeyXD
011d953ffc feat: SideStory「雪山降临1101」导航 2025-11-01 18:15:43 +08:00
Copilot
cd88fd3c51 docs: fix boolean capitalization in C# documentation comments (#14599)
* Initial plan

* fix: correct boolean capitalization in C# doc comments

Co-authored-by: lucienshawls <82591976+lucienshawls@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lucienshawls <82591976+lucienshawls@users.noreply.github.com>
2025-11-01 18:06:35 +08:00
MistEO
08105aa96d fix: macos MaaXCFramework 2025-11-01 17:53:46 +08:00
HY
ba1fb36627 chore: 繁中服第十五章 & 重複訪問好友 text (#14594) 2025-11-01 17:51:23 +08:00
Lucien Shaw
b459e7149e build: bump MaaDeps to v2.10.1-maa.1 (#14596) 2025-11-01 17:51:00 +08:00
MistEO
d20030ae98 Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-01 17:50:27 +08:00
Lucien Shaw
0a566e4954 ci: 更新最新工作流的部分显示名称和部分代码注释中的表达 (#14597)
* ci: name change for submodule update workflows

* ci: if failed -> on failure

* docs: 代码注释中,succeeded与failed相对
2025-11-01 17:48:16 +08:00
MistEO
521dc3fc71 fix: xcframework typo 2025-11-01 17:46:52 +08:00
MistEO
a781c316d3 fix: macos xcframework 2025-11-01 17:39:57 +08:00
MistEO
ac01713331 ci: remove libMaaUtils.dylib headers 2025-11-01 17:38:10 +08:00
MistEO
70204e9047 build: try to fix macos package
https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/14595
2025-11-01 17:37:06 +08:00
HX3N
48ace472a8 i18n: KR varius translations (#14591) 2025-11-01 09:50:31 +01:00
Lucien Shaw
0ae7f8878d chore: 调整devcontainer环境构建流程,使其适应MaaUtils (#14580)
1. devcontainer 创建时,更新并拉取子模块
2. 更改 MaaCore 下的 CMakeLists.txt,适应不知道哪里冒出来的 --no-allow-shlib-undefined 限制

* chore: devcontainer创建时更新子模块

* build: 尝试修复链接目标未定义的问题

* build: 将改动限于Linux
2025-11-01 16:05:00 +08:00
uye
cd1b4231ec chore: ClickStageName 同步 ClickedCorrectStage ocrReplace 2025-11-01 15:37:57 +08:00
uye
b63b4aa50e fix: 关卡复核错误 2025-11-01 15:05:18 +08:00
uye
bbc09712c0 Release v5.27.0 (#14581) 2025-11-01 14:44:34 +08:00
uye
9e028b6c97 docs: Fix formatting and grammar in CHANGELOG.md
Correct formatting and grammar in CHANGELOG entries.
2025-11-01 14:43:52 +08:00
github-actions[bot]
8fbe22396f chore: Auto Update Game Resources - 2025-11-01
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18991434628

[skip changelog]
2025-11-01 04:31:25 +00:00
github-actions[bot]
e9a8773fdf docs: Auto Update Changelogs of v5.27.0 (#14582)
Co-authored-by: MistEO <18511905+MistEO@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AnnAngela <naganjue@vip.qq.com>
Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
2025-11-01 10:22:26 +08:00
github-actions[bot]
f1c680c978 chore: Auto Templates Optimization
Triggered by 9b5419708a

[skip changelog]
2025-10-31 23:09:26 +00:00
github-actions[bot]
9b5419708a chore: Auto Update Game Resources - 2025-10-31
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18987286934

[skip changelog]
2025-10-31 23:09:02 +00:00
uye
8b9f851a39 fix: 亮色模式下无法显示 “坍缩范式列表” 2025-10-31 23:57:15 +08:00
Constrat
646691e47e i18n: various english translations 2025-10-31 14:06:44 +01:00
github-actions[bot]
cedd8f4d93 chore: Auto Update Game Resources - 2025-10-31
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18968441578

[skip changelog]
2025-10-31 09:31:19 +00:00
HX3N
eca68a0504 i18n: KR tweak MuMu12ExtrasEnabledTip 2025-10-31 18:14:11 +09:00
MistEO
4f9484c31a ci: add env for release-preparation 2025-10-31 16:53:43 +08:00
MistEO
91ea7067f7 refactor: 集成 MaaUtils (#14578)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-31 14:56:56 +08:00
SherkeyXD
ae300aa00d docs: 修正插件相关描述 2025-10-31 14:13:21 +08:00
github-actions[bot]
cc50b58ca2 chore: Auto Update Game Resources - 2025-10-30
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18946105155

[skip changelog]
2025-10-30 15:32:25 +00:00
github-actions[bot]
11d427786e chore: Auto Update Game Resources - 2025-10-30
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18933497361

[skip changelog]
2025-10-30 07:45:10 +00:00
MistEO
02edf491c5 docs: Sync documents in all languages, Powered by AI (#14572)
Co-authored-by: MistEO <18511905+MistEO@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Manicsteiner <Manicsteiner@outlook.com>
2025-10-29 23:49:12 +08:00
Lucien Shaw
0f9dd867a9 ci: 补全子模块更新工作流的显示名称 2025-10-29 16:16:07 +08:00
MistEO
4159c07437 ci: perf commit log 2025-10-29 16:00:33 +08:00
MistEO
2fe6583328 Merge branch 'dev' of https://github.com/MaaAssistantArknights/MaaAssistantArknights into dev 2025-10-29 15:54:46 +08:00
MistEO
dbfea1e38a ci: update submodules for release PR, and rename gen-changelog -> release-preparation 2025-10-29 15:54:41 +08:00
github-actions[bot]
8ed6accb45 feat: Update Submodules MaaMacGui, maa-cli 2025-10-29 07:46:41 +00:00
MistEO
c9aa40f4ee ci: fix update submodules 2025-10-29 15:45:37 +08:00
MistEO
576904acc1 ci: update submodules 2025-10-29 15:42:10 +08:00
Status102
f9366249e1 feat: 记录crash log时同时记录stacktrace, 并允许 ASST_DEBUG 在 debug 目录下生成 crash.log (#14526)
* feat: 记录crash log时同时记录stacktrace, 并允许 ASST_DEBUG 在 debug 目录下生成 crash.log

* fix: 加个循环次数限制

* perf: 简单整理
2025-10-29 02:36:46 +08:00
Status102
cd0d075d8d feat: LogInfo 等宏支持is_enabled (#14551)
feat: LogInfo 等宏支持is_enable
2025-10-29 02:02:10 +08:00
uye
7332589d04 Release v5.27.0-beta.2 (#14556) 2025-10-29 01:27:33 +08:00
uye
0101fde3c0 docs: Update CHANGELOG with new fix entry
[skip changelog]
2025-10-29 01:27:11 +08:00
uye
8c7c47251a fix: 无法加载 cache 资源
fix #14451
2025-10-29 01:05:05 +08:00
github-actions[bot]
d874df3c2c docs: Auto Update Changelogs of v5.27.0-beta.2 (#14567)
* docs: Auto Generate Changelog of Release v5.27.0-beta.2

* docs: Update CHANGELOG for v5.27.0-beta.2

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
2025-10-29 00:50:07 +08:00
Weiyou Wang
5b33ff3ab6 fix: 改用 CustomeSkip 来跳过新时装动画 (#14566)
* feat: 改用 CostumeSkip 来跳过新时装动画

* fix: 删除 SS@Store@Purchase@NextAfterMerelyWaiting,任务 GetCloth 改名为 WearCostume

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-29 00:43:45 +08:00
github-actions[bot]
f5c6c96184 chore: Auto Update Game Resources - 2025-10-28
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18875534231

[skip changelog]
2025-10-28 12:59:11 +00:00
萨拉托加
7e35a6499c Revert "chore: 同心暂时去掉5选项"
This reverts commit cb9bc0f87f.
2025-10-28 20:48:20 +08:00
Weiyou Wang
529ca6a7fc feat: 界园肉鸽不期而遇实现选项识别 (#14540)
* feat: RoguelikeEncounterOptionAnalyzer

* feat: 界园肉鸽实验性功能 -- 识别选项数量后调整选项

* chore: Auto update by pre-commit hooks [skip changelog]

* refactor: 跳过不可用选项

* refactor: 设置初次滑动

* refactor: 给 save_img 日志加点描述

* feat: 加个 get_img 接口,以便于获得合成图

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 不是你怎么没有 formatter 啊?

* refactor: 把分析数据存储在插件成员变量内,为未来重构打基础

* refactor: 把不期而遇选项识别结果输出移到插件中,加入 callback

* feat: 无法识别选项文字时保存图片

* refactor: 给 save_img 日志加点描述

* refactor: int -> size_t

* refactor: choose -> select

* refactor: sort functions

refacor: sort functions

* refactor: 用 option_analyzed 来判断是否已经识别过不期而遇选项

* fix: 去掉不必要的参数 theme

* refactor: 给 OCR 配置任务加点东西(大概率没什么用吧)

* refactor: 去掉内部接口中的冗余 sanity check

* feat: 加入 view 控制

* fix: 忘了 callback 不能用 const

* feat: 处理一下 edge case

* feat: 来点 WpfGui Log

* fix: typo

* fix: 一些漏网之鱼

* fix: 再调整下滑动距离

* fix: 什么乱七八糟的

* fix: 什么乱七八糟的

* fix: 方向错了,加点 Log

* fix: 修正长图识别 roi

* fix: 再调整一下 roi

* fix: 所以说不建议再睡眠不好的时候糊屎

* fix: 对不可选选项的模版进行二值化后再 OCR

* fix: 好像得考虑一下通道

* fix: 删掉无用参数

* refactor: 再整理一下代码,减少冗余

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 再缩小点 roi

* fix: 加点延迟

* fix: clang-tidy 说这样写

* feat: 把 debug 截图加回来,收工

* docs: 给任务链加点注释

* docs: 给 RoguelikeEncounterOptionAnalyzer 加点注释

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-28 20:46:06 +08:00
Lucien Shaw
3a75653fbb docs: 更正文档编写指南的一处typo 2025-10-28 20:32:38 +08:00
Lucien Shaw
655ab65682 docs: 对codespace相关链接进行小修小补 (#14564)
* docs: add links for home page of codespaces

* docs: 去除codespace徽章链接里意义不明的color参数
2025-10-28 20:07:41 +08:00
Weiyou Wang
bffbe8d633 fix: 调换使用错误的排序函数 (#14555) 2025-10-28 20:02:34 +08:00
dependabot[bot]
1dcf2a42a7 ci: bump the github-actions group in /.github/workflows with 2 updates (#14553)
Bumps the github-actions group in /.github/workflows with 2 updates: [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact).


Updates `actions/upload-artifact` from 4 to 5
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

Updates `actions/download-artifact` from 5 to 6
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-28 11:32:20 +01:00
Lucien Shaw
846d76f137 docs: 接入DeepWiki (#14563)
* docs: 使用DeepWiki徽章和链接

* docs: 开发文档中加入deepwiki的指引

* docs: fix typo
2025-10-28 18:27:19 +08:00
Weiyou Wang
1ea6833ffe fix: 给生息演算点击 "开始行动" 的任务加点延迟,防止错过确认弹窗 2025-10-28 21:17:32 +11:00
MistEO
5e097de000 docs: 全语言开发文档章节整理 (#14562)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-28 16:00:58 +08:00
uye
8a45b1717e fix: 猪玛写 switch 不写 break 2025-10-28 15:54:12 +08:00
MistEO
fad876527a docs: 把codespace移到犄角旮旯 (#14560)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-28 15:28:29 +08:00
uye
5b7fe1c7e9 chore: 调整雷电截图增强提示,强制要求模拟器分辨率为横屏模式 2025-10-28 15:21:08 +08:00
uye
6ee884772b chore: 调整连接失败尝试启动模拟器的描述 2025-10-28 15:12:57 +08:00
uye
69ea005af3 perf: 主线导航目标关卡默认在屏幕内时不再划到最右边后往前寻找 2025-10-28 15:12:57 +08:00
Lucien Shaw
7caca829a1 chore: 移除devcontainer轻量环境的部分非必要依赖 (#14499)
对 devcontainer 的改动如下:
1. 在轻量环境中,
   - 移除 `python` 及其相关格式化扩展 `black` 和 `isort`
   - 移除 `black` 和 `isort` 等 pip 包
2. 在所有环境中,
   - 将 VS Code 的默认主题设置为 `Default Dark Modern`

* chore: 移除devcontainer轻量环境的部分非必要依赖

* chore: 将编辑器默认颜色主题调整为暗色

* chore: 将空白环境的post-create脚本独立,与其它环境一致

* chore: 把maa扩展加回来
2025-10-28 11:58:09 +08:00
萨拉托加
d59144c549 chore: 重复访问好友添加Ocr兜底 2025-10-28 10:02:03 +08:00
Weiyou Wang
2b245d291d fix: 界园肉鸽放弃探索改用纯色匹配 (#14532)
* fix: 界园肉鸽放弃探索改用普通模版匹配

chore: Auto update by pre-commit hooks [skip changelog]

* fix: 换用 HSV + pureColor

* refactor: 模版也用同样的 color scales 处理一下

* chore: Auto update by pre-commit hooks [skip changelog]

* refactor: 进一步修正 HSV 范围

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-28 01:42:00 +08:00
uye
a1e1df535a feat: 增加纯数色匹配 (#14536)
* feat: 增加纯数色匹配

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: 更新 schema

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-28 01:41:25 +08:00
github-actions[bot]
bdb49d8395 chore: Auto Templates Optimization
Triggered by a3523789d1

[skip changelog]
2025-10-27 15:44:45 +00:00
uye
a3523789d1 feat: 添加主线 16 章导航 2025-10-27 23:44:19 +08:00
github-actions[bot]
39aca97640 chore: Auto Update Game Resources - 2025-10-27
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18846503435

[skip changelog]
2025-10-27 15:30:28 +00:00
uye
04e454b3e0 feat: 支持生息演算与肉鸽遇到不认识的主题时自动切换 2025-10-27 23:24:52 +08:00
uye
4190e3c421 feat: 添加 生活队凹开局密文板 与 坍缩范式列表 TooltipBlock 2025-10-27 23:00:36 +08:00
萨拉托加
f19d49bf95 fix: 齐聚主题无法导航肉鸽和生息演算 2025-10-27 22:35:15 +08:00
uye
559ea25856 feat: core 异常退出 ui 添加日志记录 2025-10-27 18:27:52 +08:00
Constrat
88b6ceb4d0 fix: ocr for Executor the Ex Foedere for EN 2025-10-27 11:25:50 +01:00
uye
b126016538 fix: ja-jp 泰拉大陆调查团 识别错误
fix #14547
2025-10-27 16:01:27 +08:00
SherkeyXD
06454db032 chore: 添加 png 后缀 2025-10-27 15:30:13 +08:00
Weiyou Wang
1d11f4c1a4 chore: WpfGui 增加对界园肉鸽 DLC 1 三个新分队的支持 2025-10-27 14:55:00 +08:00
Weiyou Wang
a17e997e38 refactor: polish PixelAnalyzer a bit (#14538) 2025-10-27 00:12:47 +11:00
status102
df7207dfb0 chore: 增加wpf项目cmake build脚本 2025-10-26 02:17:55 +08:00
AnnAngela
a05a141fea chore: 更新 Windows 模拟器文档,调整支持列表并添加详细说明 (#14534) 2025-10-25 22:48:46 +08:00
github-actions[bot]
4e52dba787 chore: Auto Templates Optimization
Triggered by dc0751b1e2

[skip changelog]
2025-10-25 14:07:57 +00:00
github-actions[bot]
dc0751b1e2 chore: Auto Update Game Resources - 2025-10-25
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18804107643

[skip changelog]
2025-10-25 14:07:23 +00:00
uye
2b179c673c chore: ui 日志增加 adb devices 输出 2025-10-24 23:11:40 +08:00
uye
e48cb49e4a chore: 基建降低会清空其他干员效率的技能优先级
fix #14524
2025-10-24 22:51:31 +08:00
github-actions[bot]
7f7b124bc7 chore: Auto Update Game Resources - 2025-10-24
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18781459022

[skip changelog]
2025-10-24 13:38:14 +00:00
uye
2c656db087 Release v5.27.0-beta.1 (#14502) 2025-10-24 00:24:44 +08:00
SherkeyXD
63420e9808 docs: 优化文档代码的高亮主题 2025-10-23 23:24:47 +08:00
github-actions[bot]
d8207fb5b5 docs: Auto Update Changelogs of v5.27.0-beta.1 (#14523)
* docs: Auto Generate Changelog of Release v5.27.0-beta.1

* docs: Fix formatting and update entries in CHANGELOG.md

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
2025-10-23 23:19:40 +08:00
萨拉托加
cb9bc0f87f chore: 同心暂时去掉5选项 2025-10-23 23:04:04 +08:00
Weiyou Wang
f863a6f4b6 fix: 降低萨米肉鸽进入 “诡秘的预感” 所需模版匹配分数阈值 (#14521) 2025-10-23 22:46:10 +08:00
萨拉托加
2651b1bc01 fix: 公招按钮roi错误
fix #14514
2025-10-23 12:12:32 +08:00
晓丶梦丶仁
99b4e75567 fix: JP Task.png (#14516)
* fix: JP Task.png
2025-10-23 12:10:31 +08:00
Weiyou Wang
904a8f3d4c fix: 掉落识别修复 (#14508) 2025-10-23 01:15:22 +08:00
github-actions[bot]
7c710fcee5 chore: Auto Templates Optimization
Triggered by a6a3451217

[skip changelog]
2025-10-22 16:06:15 +00:00
pre-commit-ci[bot]
a6a3451217 chore: Auto update by pre-commit hooks [skip changelog] 2025-10-22 16:05:45 +00:00
pre-commit-ci[bot]
93a0e2d4a1 chore: Auto update by pre-commit hooks [skip changelog] 2025-10-23 00:03:17 +08:00
SherkeyXD
7f6622e51d feat: 界面主题「齐聚」 2025-10-23 00:03:17 +08:00
SherkeyXD
0b533468d1 chore: GetImageFromRoi 工具优化 2025-10-23 00:03:17 +08:00
Constrat
6d26ccace1 chore: remove global templates for 3294b29f54 2025-10-22 17:03:58 +02:00
HY
c101f9cea6 chore: txwy add SwitchTheme@ConfirmThemeChange.png (#14511)
* chore: txwy add SwitchTheme@ConfirmThemeChange.png

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-22 16:29:46 +02:00
github-actions[bot]
f5921c7293 chore: Auto Update Game Resources - 2025-10-22
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18715072426

[skip changelog]
2025-10-22 11:45:27 +00:00
Weiyou Wang
880bdea7d3 refactor: 将 Copilot ActionType::ResetTimer 更改为更适合的 ResetStopwatch (#14507)
* refactor: 为 ActionType::ResetTimer 加入中文变种

* refactor: Timer -> Stopwatch
2025-10-22 22:20:50 +11:00
Weiyou Wang
9c53ea10c6 docs: 补充模拟器相关文档和协议文档 (#14478)
* docs: 为 #13913 跳过使用未准备好的技能 && 全局计时器补充作业协议文档

* docs: MuMu 模拟器显存使用策略警告。

* docs: 删除冗余的蓝叠模拟器 faq

* docs: 补充外服 CopilotTask 文档

* docs: 改改

* docs: timer -> stopwatch

docs: 繁体中文文档里的指令简体化 —— 我们并不支持繁体指令啊

---------

Co-authored-by: Rbqwow <55343783+Rbqwow@users.noreply.github.com>
2025-10-22 21:49:20 +11:00
uye
9ea6057145 fix: 变更弃用的参数 2025-10-22 17:04:51 +08:00
uye
05b377981a fix: 开始唤醒会回到主界面 2025-10-22 16:49:38 +08:00
github-actions[bot]
465c2bcf62 chore: Auto Templates Optimization
Triggered by 3294b29f54

[skip changelog]
2025-10-22 08:44:58 +00:00
uye
3294b29f54 chore: 调整截图 2025-10-22 16:44:25 +08:00
uye
f967903a4b feat: 资源更新完成后等待空闲时再加载
fix: #14500
2025-10-22 16:35:51 +08:00
萨拉托加
7622cff5b4 feat: 界园DLC新关卡战斗逻辑 2025-10-22 15:34:53 +08:00
github-actions[bot]
4e36c78691 chore: Auto Templates Optimization
Triggered by afb0f8f647

[skip changelog]
2025-10-22 07:15:00 +00:00
uye
afb0f8f647 chore: 文件路径错误 2025-10-22 15:14:22 +08:00
Weiyou Wang
35e437d372 fix: 尝试为活动商店小游戏适配新的时装购买动画 (#14490)
* fix: 尝试为活动商店小游戏适配新的时装购买动画

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-22 15:00:52 +08:00
Initial-heart
3d9732a930 docs: 添加关于实体设备上账号切换问题的说明 (#14468)
* docs: 加一段关于实体设备上账号切换问题的说明

rt

* docs: 调整措辞和格式

* docs: 修正措辞

* docs: ko-kr

* i18n: en-us translation

* i18n: ja-jp translation

* docs: zh-tw

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: Lucien Shaw <myxlc55@outlook.com>
Co-authored-by: HX3N <scarlet7518@gmail.com>
Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
Co-authored-by: Manicsteiner <Manicsteiner@outlook.com>
Co-authored-by: momomochi987 <as99us301@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-22 09:15:39 +08:00
github-actions[bot]
d12588f62b chore: Auto Templates Optimization
Triggered by e3d48ae65d

[skip changelog]
2025-10-22 00:47:15 +00:00
Manicsteiner
e3d48ae65d chore: YostarJP SwitchTheme@ConfirmThemeChang 2025-10-22 08:46:15 +08:00
HX3N
2a2e360f3e chore: YostarKR add SwitchTheme@ConfirmThemeChang
ref 979e0c4b1b
2025-10-22 08:46:54 +09:00
Constrat
df5af18b93 fix: precommit maacore 2025-10-21 21:02:23 +02:00
Constrat
55b3cdafaa chore: add SwitchTheme@ConfirmThemeChange.png 2025-10-21 21:02:13 +02:00
github-actions[bot]
538760dbbe chore: Auto Templates Optimization
Triggered by 979e0c4b1b

[skip changelog]
2025-10-21 18:29:00 +00:00
uye
979e0c4b1b feat: 不是我认识的主题,直接切换 2025-10-22 02:28:17 +08:00
github-actions[bot]
d9eb1e50d9 chore: Auto Update Game Resources - 2025-10-21
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18689594250

[skip changelog]
2025-10-21 15:46:43 +00:00
Constrat
7e9f862f62 test: remove cancelled() and add mentions 2025-10-21 15:31:56 +02:00
Constrat
20c86b0fff fix: change default issue + remove always as not necessary 2025-10-21 15:31:06 +02:00
Constrat
072a98dd41 fix: add always() 2025-10-21 15:26:20 +02:00
Constrat
a053e6547d ci: test using a single issue by adding comments and hiding previous comments 2025-10-21 15:23:17 +02:00
Constrat
bfcb02104c ci: increase sleep delay for resource updater 2025-10-21 14:42:01 +02:00
Lucien Shaw
1e9ae031ea ci: refine display names for existing workflows (#14419)
---------

Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
2025-10-21 14:37:49 +02:00
github-actions[bot]
d70d939947 chore: Auto Templates Optimization
Triggered by 37ad3a2f35

[skip changelog]
2025-10-21 09:10:28 +00:00
github-actions[bot]
37ad3a2f35 chore: Auto Update Game Resources - 2025-10-21
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18678814343

[skip changelog]
2025-10-21 09:09:47 +00:00
github-actions[bot]
7d233513ff chore: Auto Update Game Resources - 2025-10-21
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18676270061

[skip changelog]
2025-10-21 07:29:13 +00:00
Goat Boring(山羊博宁88)
b93d39b77e docs: 在不支持列表中添加腾讯应用宝 (#14477)
* docs: Add Tencent App Treasure note in notSupport list

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-21 10:49:00 +08:00
Constrat
c91c1ff279 style: run prettier as there's missing stuff apparently 2025-10-20 21:30:13 +02:00
status102
d7524a4f9e perf: 进入新任务后重置任务超时计时器, 以避免非单任务卡阻的误报 2025-10-21 03:00:35 +08:00
status102
fff05d45b5 perf: ProcSubTask static 2025-10-21 02:36:49 +08:00
SherkeyXD
201c856594 chore: 我是铸币 2025-10-21 00:12:33 +08:00
SherkeyXD
97756b1200 feat: 界园 dlc2 通宝数据更新 2025-10-20 23:48:16 +08:00
uye
79bea9b98d fix: 无人机协助点击无效时增加自动重试机制
fix #13327
2025-10-20 23:37:52 +08:00
dependabot[bot]
f94a79a1a3 ci: bump actions/setup-node from 5 to 6 in /.github/workflows in the github-actions group (#14475)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-20 23:30:34 +08:00
Status102
eb90a19e8b docs: 增加换行以提升文档在GitHub的阅读体验 (#14338) 2025-10-20 23:27:04 +08:00
SherkeyXD
957b486c53 fix: 每日任务领取延迟载荷移位 2025-10-20 23:20:37 +08:00
SherkeyXD
87a892ad7a fix: 每日任务领取因为延迟卡住 2025-10-20 23:16:00 +08:00
SherkeyXD
363c4dbb47 docs: vscode插件文档视觉优化 2025-10-20 22:32:59 +08:00
SherkeyXD
b639fd3a62 docs: 利用tabs优化视觉表现-part2 2025-10-20 22:32:58 +08:00
SherkeyXD
8bbd104ea6 docs: 利用tabs优化视觉表现 2025-10-20 22:32:58 +08:00
uye
b63bd4b6eb feat: 支持剿灭关卡名识别 2025-10-20 22:27:26 +08:00
SherkeyXD
7264f26b14 docs: 利用步骤容器优化视觉效果-part2 2025-10-20 21:50:56 +08:00
SherkeyXD
e3be737a3c docs: 利用步骤容器优化视觉效果 2025-10-20 21:45:29 +08:00
SherkeyXD
e5a823d476 docs: 更新algolia配置 2025-10-20 21:27:43 +08:00
uye
25513ab692 chore: ALL~ the Announcements 中新公告标题中加 * 2025-10-20 21:26:10 +08:00
HY
26acc07463 fix: 繁中服無法進入資源收藏關卡 (#14469) 2025-10-20 10:23:43 +08:00
Constrat
38a801a8c1 i18n: translate ElapsedTime
ref: 1edd006982
2025-10-20 01:16:31 +02:00
Weiyou Wang
1edd006982 feat: 跳过使用未准备好的技能 && 全局计时器 (#13913)
* feat: skip_if_not_ready

* feat: elapsed_time

* feat: WpfGui log 输出计时器信息

* chore: Auto update by pre-commit hooks [skip changelog]

* feat: 不默认启用全局计时器

* refactor: 支持 ResetTimer 拼写变种

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-20 01:35:37 +11:00
Weiyou Wang
45025dd168 fix: 为界园放弃探索任务添加备用模版 (#14466)
* fix: add alternative template for JieGarden@Roguelike@Abandon

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-19 23:19:59 +11:00
github-actions[bot]
3b10c1518a chore: Auto Update Game Resources - 2025-10-19
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18630203409

[skip changelog]
2025-10-19 12:12:03 +00:00
Weiyou Wang
5efdab7fbf fix: 肉鸽跳一战打一战刷钱 (#14450)
* refactor: 在 RoguelikeConfig 中加入 skip_recruit_in_fast_pass flag,用于判断是否在特定情况下跳过招募

* refactor: refine 一下 RoguelikeRecruit-GiveUp 任务

* refactor: 重命名 RoutingStrategy

* feat: 一战快速投资/烧水

* refactor: 合并冗余 Roguelike@RoutingConfig 任务,重命名为 RoguelikeRouting-Config

* refactor: 统一 RoguelikeRoutingAction 命名

* refactor: 统一导航插件任务命名

* refactor: 这些任务不需要用 RoguelileRoutingAction

* fix: 重命名相关模版

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 漏网之鱼

* refactor: MapNode 模版搬家

* refactor: 岁兽残识导航相关任务搬家

* refactor: 改改任务名

* refactor: 模版改名 Roguelike@MapNodeX -> RoguelikeMapNode-X

* refactor: 换一个似乎更简单的写法

* fix: 忘了外服了

* refactor: 漏了这个

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 修修

* fix: 继续修修

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-19 22:49:08 +11:00
uye
930de73324 feat: 本次更新的公告右上角添加红点 2025-10-18 23:22:58 +08:00
萨拉托加
527ebee6af fix: 傀影不期而遇选项 2025-10-18 20:27:50 +08:00
github-actions[bot]
c24baee8ff chore: Auto Update Game Resources - 2025-10-18
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18613855248

[skip changelog]
2025-10-18 09:28:09 +00:00
Weiyou Wang
11f9d6e0a4 refactor: 拆出界园岁兽残识地图导航 (#14432)
* refactor: 舍弃 AbstractRoguelikeMap,拆到 RoguelikeMapConfig 与 RoguelikeBoskyPassageMap

* refactor: 拆出界园岁兽残识地图导航
2025-10-18 20:15:36 +11:00
Weiyou Wang
6733f49d8b fix: 界园 dlc 背景无法放弃探索 (#14425)
* fix: refine template for JieGarden@Roguelike@Abandon

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-18 15:27:27 +08:00
萨拉托加
e7f909c807 fix: 界园狭路相逢选项 2025-10-18 10:39:36 +08:00
HX3N
147cf766c1 fix: YostarKR RoguelikeCustom-HijackSquad squad recognition 2025-10-18 00:37:52 +09:00
HY
b9edba6cf5 chore: 繁中服主線、肉鴿導航 UI 更新 (#14433)
* chore: 繁中服主線、肉鴿導航 UI 更新

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: sarkaz DLC

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-17 22:43:27 +08:00
HY
39326e177b chore: 繁中服「輓歌燃燒殆盡」活動導航 (#14434)
* chore: 繁中服「輓歌燃燒殆盡」活動導航

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-17 22:42:22 +08:00
萨拉托加
e6cfa25f81 fix: Award模板阈值还是小了
fix #14431
2025-10-17 19:53:26 +08:00
MistEO
2c247bbeda fix: 掉落识别增加越界检查 (#14312)
Co-authored-by: Weiyou Wang <44151844+Alan-Charred@users.noreply.github.com>
2025-10-17 16:08:54 +08:00
萨拉托加
af69b6172c fix: 界园杂疑选项 2025-10-17 14:22:55 +08:00
github-actions[bot]
5626880d19 chore: Auto Update Game Resources - 2025-10-17
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18584128794

[skip changelog]
2025-10-17 06:11:57 +00:00
Jim-Happy
445ce5352f fix: 修复 "设置-外部通知" 存在多个通知渠道时只会发送到第一个成功的渠道问题 (#14380)
* feat: 添加选项:发送到所有通知渠道

* style: 删除调试注释

* refactor(settings): 删除原PR逻辑,改为修复通知驱动只通知一个的bug

删除原PR逻辑,改为修复通知驱动只通知一个的bug
2025-10-17 13:55:29 +08:00
travellerse
dce6fbfbce feat: 添加刷常乐节点策略 (#13868)
* feat: 支持识别常乐节点的子类型

* perf: 将树洞节点优先级拆到配置里

* refactor: 将界园树洞策略从通用Routing策略中分离出来

* feat: 初步实现刷常乐节点

* feat: 为刷常乐节点功能添加UI

* refactor: 重命名节点类型获取函数

* perf: 优化节点类型的日志输出

* feat: 添加发现目标常乐节点后退出

* i18n: CN常乐节点显示文本

* fix: 修复type2name映射初始化潜在问题

* perf: 添加目标子类型的设置和获取方法

* refactor: 优化优先级节点类型解析逻辑

* feat: 刷常乐节点策略下保存路上的招募券

* i18n: 为其它语言提供占位

* perf: 将新增的本地化键值放到一起

* chore: 调整日志输出中的空格

* perf: 仅在非开局招募时保存招募券

* perf: 保留招募券到达上限时正常招募

* fix: 修复gui日志输出没有使用本地化

* fix: 给界园树洞节点点击加上200ms的前置延时

* perf: 在 RoguelikeRoutingTaskPlugin 中添加运行模式以区分普通地图与界园树洞

* refactor: 优化RoguelikeBoskyPassageMap的单例使用

* feat: 添加界园树洞节点类型wpf输出及其颜色配置

* fix: 不在每次开始肉鸽重置m_target_subtype
2025-10-17 16:54:30 +11:00
github-actions[bot]
724130da50 chore: Auto Update Game Resources - 2025-10-17
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18583431830

[skip changelog]
2025-10-17 05:29:46 +00:00
萨拉托加
12315868c7 fix: 界园肉鸽选项 2025-10-17 13:08:00 +08:00
萨拉托加
230b3b9169 fix: 给ClickToStartPoint加点延迟
fix #14421
2025-10-17 12:51:01 +08:00
github-actions[bot]
3c61b10de5 chore: Auto Update Game Resources - 2025-10-17
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18582491372

[skip changelog]
2025-10-17 04:31:47 +00:00
萨拉托加
5456428eb7 fix: 萨卡兹去伪存真弹窗有延迟无法退出 2025-10-17 12:21:06 +08:00
github-actions[bot]
1ca780ef0d chore: Auto Update Game Resources - 2025-10-17
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18581606017

[skip changelog]
2025-10-17 03:35:51 +00:00
HX3N
8f3ff813a1 chore: YostarKR SSS#8 SSSBuffChoose 2025-10-17 11:38:29 +09:00
Constrat
a4688ebeed chore: update SSS#8 buff choose ocr for EN 2025-10-16 22:08:30 +02:00
Constrat
7d028cdbd5 chore: SSS#8 global changes (add acahuallan, remove dossoles and barrenbeasts) 2025-10-16 22:03:28 +02:00
Constrat
ef187657ba fix: cleanup ifdef + fix AsstDestroy missed calls + lldb 2025-10-16 21:49:14 +02:00
Constrat
403f3c5644 Release v5.26.2 (#14399) 2025-10-16 20:08:32 +02:00
不留
369add1890 ci: 为 CodeQL 相关工作流添加仓库所有者检查 (#14413)
* ci: 为 CodeQL 相关工作流添加仓库所有者检查

* ci: 为 CodeQL 相关工作流添加仓库所有者检查
2025-10-16 20:04:23 +02:00
github-actions[bot]
0ae21436c8 chore: Auto Templates Optimization
Triggered by a322706241

[skip changelog]
2025-10-16 14:38:37 +00:00
pre-commit-ci[bot]
a322706241 chore: Auto update by pre-commit hooks [skip changelog] 2025-10-16 14:38:00 +00:00
Constrat
ec2b92002b fix: Fix contro center mini for EN 2025-10-16 16:34:34 +02:00
晓丶梦丶仁
36dd631606 fix: MiniGame Value 重复 2025-10-16 17:10:48 +08:00
github-actions[bot]
a201b3da65 chore: Auto Update Game Resources - 2025-10-16
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18556208810

[skip changelog]
2025-10-16 09:09:46 +00:00
晓丶梦丶仁
7421100998 fix: JP GreenGrass 2025-10-16 16:44:19 +08:00
萨拉托加
e98ff0ee35 fix: 萨米肉鸽深入探索触发暂时撤退会卡住 (#14275)
* fix: 萨米肉鸽深入探索触发暂时撤退会卡住

不知道MissionFailedFlag原来的next有什么用,暂时撤退的话感觉next个MissionCompletedFlag就够了

* chore: 加点延迟
2025-10-16 15:50:32 +08:00
Lucien Shaw
d7acdfda36 docs: 为文档站字符画组件更换缩放方法和添加主题切换支持 (#14387)
* docs: 文档站字符画组件的大小调整改用transform: scale

* docs: 字符画适应窗口垂直高度

* chore: 我们精简了字符画,这样你才知道这是字符画

* fix: 调整字符画尺寸前先判断分母是否为0

* refactor: 字符画组件卸载时一并移除窗体resize事件监听

* feat: 切换主题时保留当前随机到的字符画名称

* style: prettier fix
2025-10-16 15:37:39 +08:00
github-actions[bot]
6dfffdc45b chore: Auto Templates Optimization
Triggered by 6834ee1abe

[skip changelog]
2025-10-16 04:34:13 +00:00
HX3N
6834ee1abe fix: YostarKR update Infrast Mini tempalte 2025-10-16 13:28:54 +09:00
Manicsteiner
a571e974b6 chore: YostarJP RecruitingActivities 2025-10-16 08:58:16 +08:00
github-actions[bot]
2440f365c9 docs: Auto Update Changelogs of v5.26.2 (#14400)
* docs: Auto Generate Changelog of Release v5.26.2

* i18n: simple highlight for global

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
2025-10-15 18:40:15 +02:00
Constrat
f182d36014 fix: RecruitingActivities EN 2025-10-15 16:18:03 +02:00
github-actions[bot]
cd6a3efc4e chore: Auto Update Game Resources - 2025-10-15
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18530257413

[skip changelog]
2025-10-15 13:19:46 +00:00
Manicsteiner
3ee20cee2e chore: YostarJP ocr update (#14402) 2025-10-15 11:01:05 +02:00
HX3N
d9aa14333e fix: KR update RecruitingActivities ocr text 2025-10-15 09:44:28 +09:00
github-actions[bot]
a1cc9df6bd chore: Auto Templates Optimization
Triggered by 9313a606f2

[skip changelog]
2025-10-15 00:10:10 +00:00
HX3N
9313a606f2 fix: BattleQuickFormation KR 2025-10-15 09:05:25 +09:00
github-actions[bot]
3c6c7624dd chore: Auto Templates Optimization
Triggered by 0e00b05128

[skip changelog]
2025-10-14 21:47:56 +00:00
Constrat
0e00b05128 fix: ReceptionMini for EN 2025-10-14 23:47:35 +02:00
Constrat
fbf8b5636d chore: revert temp fix 715c2c13b5 for EN / JP and KR
@momomochi987this will likely happen to txwy... Try to remember?
2025-10-14 23:26:08 +02:00
Constrat
c535cbdf6d fix: Various store OCR for EN IS 2025-10-14 23:20:56 +02:00
Constrat
a872c08a32 fix: MT minigame EN 2025-10-14 23:20:32 +02:00
Manicsteiner
ff457fbd21 chore: Enable phantom roguelike difficulty for Yostar servers (#14332)
* chore: enable phantom roguelike difficulty for Yostar servers

* chore: JP translate
2025-10-14 23:10:01 +02:00
Constrat
b4fcf37b35 i18n: update MT mini event EN 2025-10-14 23:09:04 +02:00
github-actions[bot]
b5ba39174d chore: Auto Templates Optimization
Triggered by 319ee8876a

[skip changelog]
2025-10-14 21:05:58 +00:00
Constrat
319ee8876a fix: operbox, battlequick, infrast expand role EN 2025-10-14 23:05:33 +02:00
Constrat
2a8b0f7f01 fix: Exusiai and Hoshiguma prepare for alters 2025-10-14 20:25:59 +02:00
Constrat
a7dc1f791f fix: increase ROI for Orundum and SpecialAccess 2025-10-14 20:04:16 +02:00
HX3N
16a160f3a5 chore: YostarKR MT ocr edit (#14398)
* chore: YostarKR MT ocr edit

* chore: IS1 dlc
2025-10-14 19:58:54 +02:00
Constrat
7676b7235b fix: OrundumActivities MT event for EN 2025-10-14 17:13:18 +02:00
github-actions[bot]
e100cc68e2 chore: Auto Update Game Resources - 2025-10-14
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18496105506

[skip changelog]
2025-10-14 12:14:33 +00:00
github-actions[bot]
5923efe988 chore: Auto Update Game Resources - 2025-10-14
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18494958090

[skip changelog]
2025-10-14 11:27:27 +00:00
HX3N
6b91bd8106 chore: YostarKR MiniGame (#14395)
* chore: YostarKR MiniGame

* chore: fix typo
2025-10-14 11:50:38 +02:00
github-actions[bot]
24df42e14a chore: Auto Update Game Resources - 2025-10-14
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18484871142

[skip changelog]
2025-10-14 03:49:09 +00:00
Manicsteiner
6fc5800e02 chore: YostarJP update VisitNext (#14390) 2025-10-13 16:17:00 +02:00
dependabot[bot]
eb91fc34a6 ci: bump the github-actions group in /.github/workflows with 2 updates (#14391)
Bumps the github-actions group in /.github/workflows with 2 updates: [softprops/action-gh-release](https://github.com/softprops/action-gh-release) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `softprops/action-gh-release` from 2.3.4 to 2.4.1
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2.3.4...v2.4.1)

Updates `github/codeql-action` from 3 to 4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.4.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-13 16:15:31 +02:00
萨拉托加
03f71f02cb chore: 调整Award模板阈值 2025-10-13 14:38:38 +08:00
github-actions[bot]
966c7a251a chore: Auto Templates Optimization
Triggered by 3b74c1c4c9

[skip changelog]
2025-10-12 12:50:04 +00:00
Constrat
3b74c1c4c9 fix: update ChooseDifficulty for EN phantom 2025-10-12 14:49:39 +02:00
Constrat
295e7742f1 fix: revert IS2 EN StrategyChange changes 2025-10-12 14:49:22 +02:00
Constrat
bfdd20f6ff fix: add IS2 invest mode to EN, JP and txwy
cc @Manicsteiner @momomochi987

28a768a changed unilaterally tasks that were dependant on global
5516809 fixed but I forgot to add Phantom back
2025-10-12 14:49:05 +02:00
MistEO
63cce9811f docs: update prts.plus repo link 2025-10-12 20:02:28 +08:00
MistEO
0bed1d777a docs: 移除前端公招 2025-10-12 19:59:57 +08:00
Constrat
8ec0974d1b ci: add ownership check to Deploy to GitHub Pages
thanks to @weinibuliu
2025-10-12 13:46:33 +02:00
不留
6d9a6e5a4b ci: Add repo owner judgment to some steps of website-workflow.yml (#14378)
* ci: 为 website-workflow 增加仓库所有者判断

* ci: update workflow

* ci: move ownership check to only configure-gh-pages

---------

Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
2025-10-12 13:38:02 +02:00
Constrat
7079975bd2 chore: auto run smoke testing on tools/SmokeTesting modifications 2025-10-11 22:53:01 +02:00
Constrat
f06030ac44 ci(revert): remove lldb as it just crashed the workflow erroring out 2025-10-11 22:52:11 +02:00
Constrat
b56d60aa8f fix: POSIX compliant 2025-10-11 22:43:16 +02:00
Constrat
d7f936cb3c ci(fix): use sh for smoketesting 2025-10-11 22:34:24 +02:00
Constrat
b7b80ebbea fix: preload Minigame EN 2025-10-11 20:43:55 +02:00
HX3N
daa4eab296 chore: YostarKR preload minigame (#14375) 2025-10-11 20:35:16 +02:00
Constrat
fad643985e fix: python formatting 2025-10-11 12:52:05 +02:00
HX3N
b562b6b231 fix: KR monthly card reward 2025-10-11 08:19:26 +09:00
Lucien Shaw
aa89062bdf docs: 更新plume主题并适应新版的collections配置 (#14360)
* chore: 更新pnpm版本

* chore: 更新plume主题

* docs: 适应新版文档主题的collections配置

* style: pre-commit fix
2025-10-10 21:11:54 +08:00
github-actions[bot]
374e9ed1f2 chore: Auto Update Game Resources - 2025-10-10
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18406450197

[skip changelog]
2025-10-10 12:26:59 +00:00
Constrat
959063b34c fix(ci): task sorter UTF-8 BOM fix 2025-10-10 14:25:37 +02:00
Constrat
fbf16d00c1 chore: preload minigame for MT EN 2025-10-10 14:12:10 +02:00
Manicsteiner
bacc34531e chore: YostarJP MT stages and Duel channel (#14362)
* chore: YostarJP MT stages and Duel channel
2025-10-10 14:01:30 +02:00
HX3N
6507ac0072 chore: KR MT navigation (#14365)
* chore: KR MT navigation
2025-10-10 13:59:10 +02:00
Constrat
965b6f69ce fix: EN monthly card reward 2025-10-10 13:51:01 +02:00
github-actions[bot]
eb924b816d chore: Auto Templates Optimization
Triggered by 72bc6d8ace

[skip changelog]
2025-10-10 10:58:15 +00:00
HX3N
72bc6d8ace fix: YostarKR update VisitNext
ref #14357
2025-10-10 19:57:39 +09:00
Constrat
df1a16aca3 feat: preload MT navigation EN
@Manicsteiner @HX3N Just a heads up. The tweets have been posted
2025-10-10 12:16:51 +02:00
Constrat
87f4440209 fix: update VisitNext
ref #14357
2025-10-10 12:05:57 +02:00
uye
76252d42e3 style: c# 统一使用文件范围限定的 namespace 2025-10-10 13:36:18 +08:00
github-actions[bot]
cca22c1493 chore: Auto Update Game Resources - 2025-10-10
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18396496857

[skip changelog]
2025-10-10 04:31:39 +00:00
github-actions[bot]
b0ddb9e28e chore: Auto Templates Optimization
Triggered by 3195129fa7

[skip changelog]
2025-10-10 04:24:57 +00:00
uye
3195129fa7 feat: 支持访问好友半透明界面 2025-10-10 12:24:23 +08:00
status102
42bd5ceaf0 chore: 16-16地图 2025-10-10 12:01:13 +08:00
github-actions[bot]
aae1faef41 chore: Auto Update Game Resources - 2025-10-10
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18395654688

[skip changelog]
2025-10-10 03:34:29 +00:00
Constrat
baf3bc69ca i18n: remove global info for mumu 2025-10-10 00:11:14 +02:00
uye
fde7e7dfa4 Release v5.26.1 (#14351) 2025-10-10 01:08:02 +08:00
github-actions[bot]
0af9034bad docs: Auto Update Changelogs of v5.26.1 (#14352)
* docs: Auto Generate Changelog of Release v5.26.1

* docs: Release v5.26.1 with new features and fixes

This version introduces initial support for the Rebuilding Mandate and significant improvements to the Auto I.S. recruitment strategy, enhancing gameplay experience and fixing various issues.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
2025-10-10 00:50:43 +08:00
uye
516d47bb9d fix: 游戏更新公招界面后无法确认招募 (#14335)
* fix: 游戏更新公招界面后无法确认招募

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-10 00:32:48 +08:00
uye
afc16cf6e6 feat: 新增 cdk 被封禁的提示信息 2025-10-10 00:16:47 +08:00
uye
e52f573a7f fix: 第一次访问 mirror酱 失败时错误提示 cdk 已过期 2025-10-10 00:16:47 +08:00
MistEO
04206e7e5e ci: use sh install zsh to fix resource updater
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18378946272/job/52360092110

Zsh seems to treat the array as a whole string and cannot split it, resulting in traversal errors @Constrat
2025-10-09 22:16:48 +08:00
MistEO
8c71f709db fix: resource version 2025-10-09 21:22:38 +08:00
github-actions[bot]
7f6b490d00 chore: Auto Update Game Resources - 2025-10-09
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18377623299

[skip changelog]
2025-10-09 13:18:11 +00:00
github-actions[bot]
a0bd928f75 chore: Auto Update Game Resources - 2025-10-09
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18370407108

[skip changelog]
2025-10-09 08:33:27 +00:00
github-actions[bot]
fc7c823b9f chore: Auto Update Game Resources - 2025-10-09
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18367676923

[skip changelog]
2025-10-09 06:33:51 +00:00
MistEO
488b16e8e7 fix: Update last_updated date in version.json 2025-10-09 09:07:03 +08:00
MistEO
fcc146ad2a fix: Update last_updated timestamp in version.json 2025-10-09 09:06:16 +08:00
github-actions[bot]
64ec655631 chore: Auto Templates Optimization
Triggered by 35cf87547c

[skip changelog]
2025-10-08 23:09:46 +00:00
github-actions[bot]
35cf87547c chore: Auto Update Game Resources - 2025-10-08
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18360388224

[skip changelog]
2025-10-08 23:08:38 +00:00
uye
4db7a06f01 fix: 手动关闭模拟器后未重启 MAA 时 minitouch 可能失效 2025-10-08 16:48:27 +08:00
Weiyou Wang
24bb443e08 docs: 补充 CopilotTask 的文档 (#14319) 2025-10-08 19:28:21 +11:00
Weiyou Wang
02133548c4 fix: 尝试修复生息演算任务识别并删除编队时卡住的问题 (#14290)
* fix: 尝试修复生息演算任务识别并删除编队时卡住的问题

* refactor: 改用 #self
2025-10-08 16:07:45 +08:00
uye
eff2818404 refactor: 使用 BeginAnimation 替代 新建 Storyboard 并添加动画 2025-10-07 21:38:43 +08:00
dependabot[bot]
8017430308 ci: bump the github-actions group across 1 directory with 2 updates (#14311)
Bumps the github-actions group with 2 updates in the /.github/workflows directory: [softprops/action-gh-release](https://github.com/softprops/action-gh-release) and [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact).


Updates `softprops/action-gh-release` from 2.3.3 to 2.3.4
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2.3.3...v2.3.4)

Updates `actions/upload-pages-artifact` from 3 to 4
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/upload-pages-artifact
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 15:28:22 +02:00
github-actions[bot]
9b10bb6e02 chore: Auto Update Game Resources - 2025-10-07
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18306279350

[skip changelog]
2025-10-07 08:11:26 +00:00
Horror Proton
b89777ec07 chore: run smoke test in lldb 2025-10-07 05:41:49 +00:00
Lucien Shaw
e72b6d5e24 docs: 添加目录自动跳转组件并使locale自动生成 (#14299)
* feat: 文档站添加重定向vue小组件

* revert: "docs: 将文档中指向部分文档目录的链接改为指向对应目录下的第一篇文档 (#14292)"

This reverts commit a24c772880.

* docs: zh-tw 目录自动跳转

* docs: zh-cn 目录自动跳转

* docs: ko-kr 目录自动跳转

* docs: ja-jp 目录自动跳转

* docs: en-us 目录自动跳转

* docs: 修复了多语言faq文章中的外链对应语言错误的问题

* refactor: 将matter模块改为default import

* feat: 将文档站的i18n和导航相关设置改为全自动生成

* fix: 去除了冗余的locale属性

文档站根据文件目录名称进行索引,linkName和dirName不可能不相同,故简化为单属性name

* refactor: 调整导航组件生成模块中的部分数据类型

* style: prettier fix
2025-10-04 23:44:54 +08:00
Lucien Shaw
fb0bf0a510 docs: 文档站新增字符画组件 (#14270)
* docs: 拯救牛牛!

* chore: 字符画使用单独目录

* feat: 随机动态加载字符画

* feat: 文档站的开发者工具console会打印随机字符画

* fix: 调整字符画初始行高,修正比例

* refactor: 简化冗余的缩放逻辑

* fix: 测量基准宽度时添加100ms延迟

* chore: Auto update by pre-commit hooks [skip changelog]

* refactor: 加上类型注解,避免编辑器报错

* chore: 更改prettier配置,typescript行尾不使用分号

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 完善字符画大小调整算法,稳定后再调整字体

* fix: 字符画的自适应调整逻辑

* feat: 字符画支持自定义主题

* docs: 调整“字号不要用小数”的注释提示

* fix: 判断document是否定义,避免构建失败

* refactor: 完善字符画获取逻辑

* feat: 为console中展示的字符画添加自动检测主题功能

* fix: 避免因滚动条等原因造成的字符画尺寸抖动

* chore: Priestess

* refactor: 将字符画调取模块置于插件目录下

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-04 23:21:12 +08:00
Goat Boring(山羊博宁88)
a24c772880 docs: 将文档中指向部分文档目录的链接改为指向对应目录下的第一篇文档 (#14292)
* Update newbie.md

* Update newbie.md

* Update newbie.md

* Update newbie.md

* Update newbie.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md
2025-10-04 02:12:26 +08:00
Pylinx171
7a3484dc52 chore: 将mac开发环境下的cmake_osx版本改为13.4 (#14283)
Co-authored-by: lihao2Gops5m9x <li@m8@cx7H5g3eM>
2025-10-03 19:12:11 +08:00
晓丶梦丶仁
2aa2e87fd6 fix: "MiniGame@RM-1@Wait" 2025-10-03 17:20:12 +08:00
Status102
2ef25416f9 perf: RegionOCRer 中 useRaw=false 时, 使用原图二值蒙版代替直接 OCR 二值图像 (#14276)
perf: RegionOCRer中useRaw=false时, 使用原图裁剪代替二值化图像
2025-10-03 16:13:59 +08:00
Rain Yang
435e17867e fix: 增强 playtools 关闭连接时的异常处理,确保套接字安全关闭 (#14280)
* fix: 增强playtools关闭连接时的异常处理,确保套接字安全关闭

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-10-03 14:14:02 +08:00
Constrat
707d31bb30 fix: EN IS3 encounter ocr
fix MAA,EN服水月肉鸽 事件名识别错误bug
Fixes #1427214272
2025-10-01 15:32:24 +02:00
status102
de08a33db1 fix: 理智药使用数量ocr不准确时中断使用 2025-10-01 19:25:07 +08:00
status102
d724b8ff9c fix: 使用理智药 执行减少次数循环在asst_stop时缺少中断判断 2025-10-01 19:21:47 +08:00
萨拉托加
1bb7828255 chore: YostarJP ocr fix 2025-10-01 15:26:15 +08:00
萨拉托加
d2a81987b2 fix: 修复因失败导致次生预算出错 (#14267) 2025-10-01 07:38:13 +08:00
github-actions[bot]
ed7ee78952 chore: Auto Update Game Resources - 2025-09-30
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18137728844

[skip changelog]
2025-09-30 17:07:49 +00:00
晓丶梦丶仁
2973ebbbdb feat: RM-1 (#14271) 2025-10-01 00:54:41 +08:00
Lucien Shaw
e461208bf9 chore: 完善容器配置及依赖安装 (#14208)
格式化工具部分:
1. pre-commit 引入 python 的格式化工具,包括 black(代码格式化)和 isort(对“包导入顺序”的规范)
2. 允许 prettier 对文档站的 markdown 文件格式化
3. 不允许 prettier 对 markdown 文件中的代码块的代码本身进行格式化
4. 升级了 pre-commit 的各个 hook 的版本
5. 优化了 pre-commit 的日志文本显示

容器总览部分:
1. 由原来的单一轻量环境转为区分空环境、轻量环境和全量环境
2. 空环境是裸 Linux 镜像(Ubuntu),为默认环境
3. 轻量环境适合开发文档站前端
4. 全量环境适合开发 MaaCore
5. 目前,全量环境完整包含了轻量环境,轻量环境完整包含了空环境
6. 在仓库 README.md 中更新了三个环境的描述,并将链接分别设置为对应环境的创建链接
   **注意:没有修改文档站中的对应文件**
7. 在各个语言的开发指南的最后,移除了 Codespace 部分的“安装额外依赖”相关描述,且将链接设置为全量环境的创建链接
   **注意:没有添加“开发文档站”的指南和对应 codespace 的使用方式**

容器的轻量环境和全量环境共有部分:
1. 安装 black 和 isort 包
2. 调整 VS Code 设置,取消先前(对 markdown 文件单独指定 markdownlint 扩展作为格式化工具)的错误设置,现在 markdown 文件仍然使用默认的 prettier 扩展作为格式化工具
3. 引入 markdown-all-in-one 扩展作为语法提示工具
4. 将 node_modules 和 3rdparty 排除在 VS Code 的文本的搜索路径之外

容器的全量环境部分:
1. 为 tools 下的所有 python 脚本安装依赖
2. 使用 tools/maadeps-download.py 下载 maadeps,且将必要二进制文件软链接到 /usr/local/bin/
3. 使用 apt 安装 cmake 和 clangd-20,将后者通过 update-alternatives 设置为系统 clangd 的默认版本
4. 使用 cmake tools 扩展,并按照 Linux 编译方法进行配置
5. 使用 clang-format 作为 c/cpp 的格式化工具,clang-format 程序主体来自 maadeps(已经软链接到 /usr/local/bin/)
6. 使用 clangd 作为 c/cpp 的语法提示工具
7. 将 MaaDeps、install 和 build 排除在 VS Code 的文本搜索路径之外

其它手动调整:
1. 更新文档站的 package.json,指定 pnpm 包管理器的版本
2. 手动保证 markdown 文件中的列表前后有空行(注意到 MarkdownLint 官方规则不一定能精准定位所有“列表前后空行”的问题,详见:https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md032---lists-should-be-surrounded-by-blank-lines )
3. 修改了部分 markdown 文件中的 json 代码块的语法问题
   **注意:相同的问题并未全部发现,仅修改了两处**
4. 在 tools 目录中,一处 python 脚本的包名误用(本地包名和某个 pip 包重名),这里修改了相应代码
5. 在 tools 目录中,一处 python 脚本使用了弃用的包 cchardet 的问题,这里更换了推荐使用的功能相近的包并修改了相应代码

自动化脚本提交的修改:
1. 自动格式化了大量 tools 中的 python 脚本
2. 自动格式化了大量 docs 中的 markdown 文件

Commits:

* chore: pre-commit引入black和isort规范py文件

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: devcontainer添加isort扩展,排序python导入

* chore: pre-commit任务命名及更名

* style: isort fix

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: 更新pre-commit的hook版本

* fix: 模块名与第三方库重名,大忌

* chore: 容器构建时额外安装isort

* docs: md -> markdown

* chore: 容器安装python包和maadeps

* fix: 修复过时python包

* chore: 指定pnpm版本

* chore: container支持选择轻量环境

* chore: 去掉rust

* chore: add plain env

* chore: 使用clangd语言服务器

* chore: 无需单独设置markdown的格式化工具

* chore: 更新安装的clangd版本

* docs: 简易文档适配

* docs: 在仓库README中重新编排codespaces相关指引

* chore: Auto update by pre-commit hooks [skip changelog]

* style: 调整缩进

* chore: 格式化工具不用特意排除被gitignore忽略的文件

* chore: sh文件在gitattributes中单列一类

* chore: 格式化docs下的markdown文件

* chore: 暂时不修改md文件中的代码块

* style: 人为明确markdown中的部分列表相关格式

* docs: 补上部分markdown的json代码块中缺失的逗号

* chore: Auto update by pre-commit hooks [skip changelog]

* chore: Auto update by pre-commit hooks [skip changelog]

* fix: 补上tools的服务器排序相关代码中缺失的逗号

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: 使用maadeps的clangd

* build: 更新maadeps工具链版本

* style: prettier fix

* revert: 还原maadeps版本

* revert: 取消使用maadeps的clangd依赖,改用系统apt安装

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-30 19:39:48 +08:00
github-actions[bot]
22faefe71a chore: Auto Update Game Resources - 2025-09-30
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18121756589

[skip changelog]
2025-09-30 07:09:27 +00:00
uye
7d080de077 Release v5.26.0 (#14261) 2025-09-30 14:21:11 +08:00
github-actions[bot]
cc65a68384 docs: Auto Update Changelogs of v5.26.0 (#14262)
* docs: Auto Generate Changelog of Release v5.26.0

* docs: Update CHANGELOG for v5.26.0 enhancements and fixes

* docs: Update CHANGELOG with recent fixes and optimizations

* docs: 更新 CHANGELOG,添加次生预案支持和自动肉鸽优化说明

* docs: 修正 CHANGELOG 中关于次生预案的描述格式

* docs: 更新 CHANGELOG,添加「次生预案」和自动肉鸽的提示信息

* docs: 修正 CHANGELOG 中关于次生预案的描述,优化提示信息

* docs: 更新 CHANGELOG,修正次生预案部分的描述,优化资源点数说明

* docs: 修正 CHANGELOG 中关于次生预案提示信息的描述格式

* docs: 更新 CHANGELOG,完善次生预案功能描述,增加资源点数和材料信息

* docs: Revise CHANGELOG for recent updates and fixes

Updated the changelog to reflect changes in recruitment strategy, settings guide improvements, and documentation website redesign.

* docs: Revise CHANGELOG for new features and fixes

Updated the changelog to reflect changes in the '次生预案' feature and adjustments in the automatic meat pigeon recruitment strategy.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
Co-authored-by: AnnAngela <naganjue@vip.qq.com>
2025-09-30 14:20:54 +08:00
萨拉托加
0bb19a7376 fix: 水月肉鸽委托任务完成检测优先级过低 2025-09-30 13:59:19 +08:00
Weiyou Wang
ea6540cf6b fix: 商店刷新两步走 (#14201)
* fix: 商店刷新两步走

* chore: Auto update by pre-commit hooks [skip changelog]

* refactor: buy once only when both steps succeed (suggested by status102)

Co-Authored-By: Status102 <102887808+status102@users.noreply.github.com>

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Status102 <102887808+status102@users.noreply.github.com>
2025-09-29 17:20:32 +08:00
萨拉托加
df75025dc5 perf: 调整界园肉鸽招募策略 (#14255) 2025-09-29 12:32:25 +08:00
Rbqwow
7ab8994ed8 docs: 更新文档 (#14236)
* docs: 补充自动战斗前提

* docs: 自动战斗傀影开局添加丰川祥子

* docs: 更新肉鸽闪断处理相关描述

* chore: Auto update by pre-commit hooks [skip changelog]

* docs: 更新肉鸽文档

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: 萨拉托加 <151550168+Saratoga-Official@users.noreply.github.com>
2025-09-29 12:29:40 +08:00
Manicsteiner
a263b62e63 feat: 萨卡兹肉鸽 待诉说的故事 二次选择 (#14246) 2025-09-29 12:21:24 +08:00
萨拉托加
bf7b2e633b fix: 水月肉鸽商店刷新延迟不够
fix #14256
2025-09-29 10:49:25 +08:00
github-actions[bot]
65b84f5dbd chore: Auto Update Game Resources - 2025-09-28
https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/18079189511

[skip changelog]
2025-09-28 20:08:28 +00:00
Manicsteiner
347f1e191e chore: YostarJP roguelike edits (#14252) 2025-09-28 21:00:23 +02:00
uye
7905eb9fed fix: 按钮显示文字错误 2025-09-28 13:55:30 +08:00
萨拉托加
3a6c49de0c fix: 次生预案模拟器卡了容易点过头 2025-09-28 09:38:03 +08:00
Hao Guan
0be1253334 ci: update macOS runner 2025-09-27 23:29:43 +08:00
Hao Guan
a10ab607b0 chore(mac): 新图标和界面风格 2025-09-27 22:24:14 +08:00
Lancarus
45649de131 perf: 优化界园肉鸽部分关卡策略 (#14244)
* perf: 优化界园肉鸽部分关卡策略

* fix: 按照建议修改

* chore: Auto update by pre-commit hooks [skip changelog]

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-09-27 20:03:03 +08:00
uye
c3ebfce07b feat: mac 支持次生预案 2025-09-27 14:59:39 +08:00
Constrat
a57e5cf98a fix: clang 2025-09-26 21:54:06 +02:00
uye
78ff33d6f0 fix: 怎么还有人在用 adb input 2025-09-27 00:32:11 +08:00
uye
a64bfc5ba3 perf: 优化次生预案执行速度 2025-09-26 23:21:22 +08:00
1695 changed files with 248555 additions and 40421 deletions

View File

@@ -17,11 +17,12 @@ RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -
# Configure conda environment
RUN eval "$(conda shell.bash hook)" \
&& conda create -n maa python=$PYTHON_VERSION -y \
&& conda create -n maa \
&& conda activate maa \
&& conda install -y conda-forge::nodejs=$NODEJS_VERSION \
&& pip install pre-commit black \
&& npm install -g pnpm
&& conda install -y \
python=$PYTHON_VERSION \
conda-forge::nodejs=$NODEJS_VERSION \
&& pip install pre-commit
# Finalize conda setup
RUN conda init \

View File

@@ -0,0 +1,48 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "MAA Docs Env (Light)",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
// "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"build": {
"dockerfile": "Dockerfile"
},
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3001],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "bash .devcontainer/0/post-create.sh",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"nekosu.maa-support",
"esbenp.prettier-vscode",
"DavidAnson.vscode-markdownlint",
"yzhang.markdown-all-in-one",
"vue.volar",
"mkxml.vscode-filesize"
],
"settings": {
// Color theme
"workbench.colorTheme": "Default Dark Modern",
// Editor formatting
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
// Performance optimizations
"search.exclude": {
"**/node_modules": true,
"**/3rdparty": true
}
}
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

View File

@@ -0,0 +1,21 @@
#!/bin/bash
WORKSPACE=$(pwd)
# conda activate maa
echo "===================="
cd "$WORKSPACE"
echo "Setting up git safe.directory..."
git config --global --add safe.directory "$WORKSPACE"
git submodule foreach --recursive 'git config --global --add safe.directory "$toplevel/$path"'
echo "===================="
cd "$WORKSPACE"
echo "Updating submodules..."
git submodule update --init --recursive
echo "===================="
cd "$WORKSPACE"/docs
echo "Installing node modules..."
npm install -g pnpm
pnpm install --frozen-lockfile

View File

@@ -0,0 +1,37 @@
FROM mcr.microsoft.com/devcontainers/base:ubuntu
USER vscode
ENV CONDA_DIR=/home/vscode/miniconda
ENV PATH="$CONDA_DIR/bin:$PATH"
ARG CLANGD_VERSION=20
ARG PYTHON_VERSION=3.12
ARG NODEJS_VERSION=24
# Install system dependencies
RUN sudo apt update \
&& sudo apt upgrade -y \
&& sudo apt install -y \
cmake
# Install Miniconda
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh \
&& bash ~/miniconda.sh -b -p ${CONDA_DIR} \
&& rm ~/miniconda.sh \
&& conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main \
&& conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
# Configure conda environment
RUN eval "$(conda shell.bash hook)" \
&& conda create -n maa \
&& conda activate maa \
&& conda install -y \
python=${PYTHON_VERSION} \
conda-forge::nodejs=${NODEJS_VERSION} \
&& pip install pre-commit black isort
# Finalize conda setup
RUN conda init \
&& conda config --set auto_activate false \
&& echo "conda activate maa" >> ~/.bashrc

View File

@@ -0,0 +1,86 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "MAA Core Env (Full)",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
// "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"build": {
"dockerfile": "Dockerfile"
},
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3001],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "bash .devcontainer/1/post-create.sh",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"nekosu.maa-support",
"ms-vscode.cmake-tools",
"xaver.clang-format",
"llvm-vs-code-extensions.vscode-clangd",
"ms-python.python",
"ms-python.black-formatter",
"ms-python.isort",
"esbenp.prettier-vscode",
"DavidAnson.vscode-markdownlint",
"yzhang.markdown-all-in-one",
"vue.volar",
"mkxml.vscode-filesize"
],
"settings": {
// Color theme
"workbench.colorTheme": "Default Dark Modern",
// Editor formatting
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
// Language-specific formatting
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
},
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"[c]": {
"editor.defaultFormatter": "xaver.clang-format"
},
// Python formatting and linting
"isort.args": ["--profile", "black"],
// Python runtime
"python.terminal.launchArgs": ["-u"],
"python.defaultInterpreterPath": "/home/vscode/miniconda/envs/maa/bin/python",
"python.terminal.activateEnvironment": false,
// CMake settings
"cmake.configureSettings": {
"BUILD_DEBUG_DEMO": "ON",
"CMAKE_TOOLCHAIN_FILE": "src/MaaUtils/MaaDeps/cmake/maa-x64-linux-toolchain.cmake"
},
"cmake.configureOnOpen": false,
// Performance optimizations
"search.exclude": {
"**/node_modules": true,
"**/build": true,
"**/install": true,
"**/MaaDeps": true,
"**/3rdparty": true
}
}
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

View File

@@ -0,0 +1,47 @@
#!/bin/bash
WORKSPACE=$(pwd)
# conda activate maa
echo "===================="
cd "$WORKSPACE"
echo "Setting up git safe.directory..."
git config --global --add safe.directory "$WORKSPACE"
git submodule foreach --recursive 'git config --global --add safe.directory "$toplevel/$path"'
echo "===================="
cd "$WORKSPACE"
echo "Updating submodules..."
git submodule update --init --recursive
echo "===================="
cd "$WORKSPACE"/docs
echo "Installing node modules..."
npm install -g pnpm
pnpm install --frozen-lockfile
echo "===================="
cd "$WORKSPACE"
echo "Installing Python dependencies..."
# Install Python dependencies from all tools
for req_file in tools/*/requirements.txt; do
if [ -f "$req_file" ]; then
echo "Installing from $req_file"
pip install -r "$req_file"
fi
done
for req_file in tools/*/requirements-dev.txt; do
if [ -f "$req_file" ]; then
echo "Installing from $req_file"
pip install -r "$req_file"
fi
done
echo "===================="
cd "$WORKSPACE"
echo "Installing MaaDeps..."
python tools/maadeps-download.py
# Link clang-format & clangd to /usr/local/bin for easy access
sudo ln -s $WORKSPACE/src/MaaUtils/MaaDeps/x-tools/llvm/bin/clang-format /usr/local/bin/clang-format
sudo ln -s $WORKSPACE/src/MaaUtils/MaaDeps/x-tools/llvm/bin/clangd /usr/local/bin/clangd

View File

@@ -1,50 +1,13 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "MAA",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
// "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"build": {
"dockerfile": "Dockerfile"
},
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3001],
// Use 'postCreateCommand' to run commands after the container is created.
"name": "Plain Env (Nothing Installed)",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"postCreateCommand": "bash .devcontainer/post-create.sh",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"mkxml.vscode-filesize",
"nekosu.maa-support",
"DavidAnson.vscode-markdownlint",
"esbenp.prettier-vscode",
"vue.volar",
"ms-python.python",
"ms-python.black-formatter"
],
"settings": {
// format
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[markdown]": {
"editor.defaultFormatter": "DavidAnson.vscode-markdownlint"
},
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
// python
"python.terminal.launchArgs": ["-u"],
"python.defaultInterpreterPath": "/home/vscode/miniconda/envs/maa/bin/python",
"python.terminal.activateEnvironment": false
// Color theme
"workbench.colorTheme": "Default Dark Modern"
}
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

View File

@@ -1,21 +1,13 @@
#!/bin/bash
WORKSPACE=$(pwd)
# conda activate maa
echo "===================="
echo "Setting up git safe.directory for $WORKSPACE and its submodules..."
cd "$WORKSPACE"
echo "Setting up git safe.directory..."
git config --global --add safe.directory "$WORKSPACE"
git submodule foreach --recursive 'git config --global --add safe.directory "$toplevel/$path"'
echo "===================="
cd "$WORKSPACE"
echo "Installing dependencies for python..."
# pip install -r tools/.../requirements.txt
# pip install -r tools/.../requirements-dev.txt
echo "===================="
echo "Installing dependencies for nodejs..."
cd "$WORKSPACE"/docs
pnpm install --frozen-lockfile
echo "Updating submodules..."
git submodule update --init --recursive

View File

@@ -46,6 +46,9 @@ e3d63894b28b2ef5e2405e144a32a6981de5e1b2
# refactor: divide tasks.json into multiple jsons
dce6e317c8e56836662b64ac4b3d1a69b4ff4dd8
# c# 统一使用文件范围限定的 namespace
76252d42e3febae1aef396e8ee5482fa46d565c6
# usage: add "[blame ignore]" to the commit message
# This file is managed by an automated workflow
# Do not add, remove or modify lines below this comment

2
.gitattributes vendored
View File

@@ -10,3 +10,5 @@
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf

View File

@@ -41,11 +41,9 @@ body:
attributes:
label: 日志和配置文件
description: |
**请在 MAA -> 设置 -> 问题反馈中找到生成日志压缩包按钮,点击并上传压缩包**
**请直接将完整的文件拖拽进来,而非自己裁切或复制的片段;若文件体积过大可压缩后再上传**
如果你在使用 MacBook请点击屏幕左上角的“文件”点击“打开日志文件夹”
**请在 MAA -> 设置 -> 问题反馈中找到生成日志压缩包按钮,点击并上传压缩包**
**若待上传压缩包大于 25MB请转而上传该压缩包同日期文件夹中的若干小压缩包**
若正在使用 macOS请点击屏幕左上角的“文件”点击“打开日志文件夹”
placeholder: |
请确认上传文件前已关闭 MAA
validations:
@@ -55,8 +53,8 @@ body:
attributes:
label: 配置信息
description: |
请说明操作系统及版本、模拟器品牌、模拟器分辨率、DPI、帧率
若正在使用 MuMu 或雷电 9请说明截图增强是否开启
请说明操作系统及版本、模拟器品牌、模拟器分辨率、DPI、帧率
若正在使用 MuMu 或雷电 9请说明截图增强是否开启
最后请说明 GPU 加速推理是否开启,若开启请提供 GPU 型号。
validations:
required: true
@@ -65,11 +63,9 @@ body:
attributes:
label: 截图或录屏
description: |
`debug` 目录下按功能分类的文件夹内,有一些自动截图的错误图片,若有相关的,请一并打包上传
可上传屏幕截图或录制以帮助解释你的问题,包括但不限于 MAA 软件截图、游戏画面截图
若是**识别相关问题**,请尽可能提供模拟器自带的截图工具截取的无遮挡的**原图**(或通过 adb 截取原图)
用其他的工具如QQ/微信截取的图片包含窗口边框且长宽比、分辨率不固定不利于我们排除bug
可上传屏幕截图或录制以帮助解释你的问题,包括但不限于 MAA 软件截图、游戏画面截图
若是**识别相关问题**,请尽可能提供模拟器自带的截图工具截取的无遮挡的**原图**(或通过 adb 截取原图)
用其他的工具如QQ/微信截取的图片包含窗口边框且长宽比、分辨率不固定不利于我们排除bug
若文件体积过大可压缩后再上传
validations:
required: false

View File

@@ -43,11 +43,9 @@ body:
attributes:
label: Log and config files
description: |
**Please locate the Generate Support Payload button under MAA Settings -> Issue Report, click the button, and upload the generated zip file**
**Please drag and drop the full file in, not your own cuttings or copies; compress it before uploading if too large.**
If you are using MacBook, please click the "File" option in the top-left corner of the screen, then click "Open Log Folder".
**Please locate the Generate Support Payload button under MAA Settings -> Issue Report, click the button, and upload the generated zip file**
**If the archive to upload is larger than 25MB, please upload smaller archives from the same date folder instead.**
If you are using macOS, please click the "File" option in the top-left corner of the screen, then click "Open Log Folder".
placeholder: |
Please confirm that MAA is not running before uploading files.
validations:
@@ -57,8 +55,8 @@ body:
attributes:
label: Configuration information
description: |
Please specify the operating system and version, emulator brand, emulator resolution, DPI, and frame rate;
If you are using MuMu or LDPlayer 9, please specify whether Screenshot Enhancement is enabled;
Please specify the operating system and version, emulator brand, emulator resolution, DPI, and frame rate.
If you are using MuMu or LDPlayer 9, please specify whether Screenshot Enhancement is enabled.
Finally, please specify whether GPU accelerated inference is enabled, and if so, provide the GPU model.
validations:
required: true
@@ -67,22 +65,15 @@ body:
attributes:
label: Screenshots or recordings
description: |
In the `debug` directory, within the functionally categorized folders,
there are some error images captured automatically.
If related to this issue, please upload them together.
If available, upload screenshots and recordings to help explain your problem,
including but not limited to screenshots of MAA software,
screenshots of game screens.
screenshots of game screens.
If the problem is **recognition related**, please help by providing
the **original image** taken by the emulator's own screenshot tool
(or via adb).
(or via adb).
Screenshots taken with other tools may contain the frames of the window/emulator
and their aspect ratio and resolution are inconsistent,
which makes it harder for us to debug.
which makes it harder for us to debug.
If the file size is too large, you may compress it before uploading.
validations:
required: false

View File

@@ -9,6 +9,7 @@ updates:
assignees:
- AnnAngela
- Constrat
- lucienshawls
groups:
github-actions:
patterns:

View File

@@ -335,7 +335,7 @@ labels:
# `MacGui`
- name: MacGui
content: "client: MacGui"
regexes: '/mac(?:book|os|\s*(?:操作系统|系统|电脑|版))|playcover/i'
regexes: '(?:[Mm][Aa][Cc](?:[Bb][Oo][Oo][Kk]|[Oo][Ss]|\s*(?:操作系统|系统|电脑|版|[Gg][Uu][Ii]))|[Pp][Ll][Aa][Yy][Cc][Oo][Vv][Ee][Rr]|[Mm][Aa][Cc]\s+[Gg][Uu][Ii])'
skip-if:
- skip all
- skip client

View File

@@ -1,4 +1,4 @@
name: Git Blame Ignore
name: Blame Ignore Update
on:
schedule:
@@ -7,12 +7,13 @@ on:
jobs:
blame-ignore:
name: Update Git Blame Ignore Revs
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false # Needed to bypass protection rules in Push changes
@@ -26,7 +27,7 @@ jobs:
git diff --quiet .git-blame-ignore-revs
- name: Commit and Push changes
- name: Commit changes
if: ${{ steps.check_changes.outcome == 'failure' }}
run: |
git config user.name "github-actions[bot]"

View File

@@ -1,4 +1,4 @@
name: Delete Cache
name: Cache Cleanup
on:
pull_request:
@@ -11,13 +11,14 @@ on:
jobs:
cache-delete:
name: Delete PR Cache
# Run only on organization branches with PRs
if: github.event_name == 'workflow_dispatch' ||
github.event.pull_request.head.repo.full_name ==
github.event.pull_request.base.repo.full_name
runs-on: ubuntu-latest
steps:
- name: Delete cache on PR merged
- name: Delete PR cache
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
PR_NUMBER=${{ github.event.inputs.pr_number }}

View File

@@ -1,4 +1,4 @@
name: ci
name: Release Pipeline
on:
push:
@@ -7,79 +7,70 @@ on:
branches-ignore:
- "master"
paths:
- ".github/workflows/ci.yml"
- "3rdparty/include/**"
- "include/**"
- "src/**"
- "cmake/**"
- "CMakeLists.txt"
- ".github/workflows/ci.yml"
- "!**/*.md"
- "include/**"
- "src/**"
- "tools/maadeps-download.py"
- "!**/*.md"
pull_request:
branches:
- "dev"
paths:
- ".github/workflows/ci.yml"
- "3rdparty/include/**"
- "include/**"
- "src/**"
- "cmake/**"
- "CMakeLists.txt"
- "!**/*.md"
- "include/**"
- "src/**"
- "tools/maadeps-download.py"
- "!**/*.md"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref == 'refs/heads/dev' && github.sha }}
cancel-in-progress: true
jobs:
meta:
# Prevent duplicate runs on organization branches with PRs
if: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name
name: Gather Meta Information
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.set_tag.outputs.tag }}
prerelease: ${{ steps.set_pre.outputs.prerelease }}
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
path: temp
fetch-depth: 0
show-progress: false
- name: Fetch history
if: ${{ !startsWith(github.ref, 'refs/pull/') }}
run: |
git init
cp $GITHUB_WORKSPACE/temp/.git/config ./.git
rm -rf $GITHUB_WORKSPACE/temp
# git config remote.origin.fetch '+refs/*:refs/*'
git fetch --filter=tree:0 # --update-head-ok
git reset --hard origin/$(git branch --show-current) || true
git checkout ${{ github.ref_name }}
- name: Set tag
id: set_tag
run: |
${{ startsWith(github.ref, 'refs/pull/') && 'cd temp' || '' }}
echo tag=$(git describe --tags --match "v*" ${{ github.ref }} || git rev-parse --short HEAD) | tee -a $GITHUB_OUTPUT
exit ${PIPESTATUS[0]}
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
# For tag pushes, use the tag name
tag="${{ github.ref_name }}"
else
# For PRs and branch pushes, use git describe or fallback
tag=$(git describe --tags --match "v*" HEAD 2>/dev/null || echo "v0.0.1-$(git rev-parse --short HEAD)")
fi
echo "tag=${tag}" | tee -a $GITHUB_OUTPUT
- name: Judge pre-release
- name: Check if it is a pre-release
id: set_pre
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
if: startsWith(github.ref, 'refs/tags/v')
run: |
if [[ '${{ steps.set_tag.outputs.tag }}' =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo prerelease=false | tee -a $GITHUB_OUTPUT
echo "prerelease=false" | tee -a $GITHUB_OUTPUT
else
echo prerelease=true | tee -a $GITHUB_OUTPUT
echo "prerelease=true" | tee -a $GITHUB_OUTPUT
fi
- name: Generate changelog
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
- name: Finalize changelog
if: startsWith(github.ref, 'refs/tags/v')
run: |
this_tag=${{ steps.set_tag.outputs.tag }}
if [[ '${{ steps.set_pre.outputs.prerelease }}' != 'false' ]]; then
@@ -92,19 +83,15 @@ jobs:
echo >> CHANGELOG.md
echo "[已有 Mirror酱 CDK前往 Mirror酱 高速下载](https://mirrorchyan.com/zh/projects?rid=MAA&source=maagh-release)" >> CHANGELOG.md
- name: Upload changelog to Github
uses: actions/upload-artifact@v4
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
- name: Upload changelog to GitHub
uses: actions/upload-artifact@v5
if: startsWith(github.ref, 'refs/tags/v')
with:
name: changelog
path: CHANGELOG.md
windows:
# Prevent duplicate runs on organization branches with PRs
if: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name
name: Build for Windows
needs: meta
strategy:
matrix:
@@ -113,21 +100,23 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Fetch submodules
run: |
git submodule update --init --depth 1 src/MaaUtils
git submodule update --init --depth 1 3rdparty/EmulatorExtras
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v4
continue-on-error: true
with:
path: |
./MaaDeps
./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
@@ -140,20 +129,21 @@ jobs:
- name: Config cmake
run: |
mkdir -p build
cmake -B build ${{ matrix.arch == 'arm64' && '-A ARM64' }} -DCMAKE_BUILD_TYPE=Release -DMAADEPS_TRIPLET='maa-${{ matrix.arch }}-windows' -DINSTALL_RESOURCE=ON -DINSTALL_PYTHON=ON -DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}' -DBUILD_WPF_GUI=OFF
cmake -B build ${{ matrix.arch == 'arm64' && '-A ARM64' }} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DMAADEPS_TRIPLET='maa-${{ matrix.arch }}-windows' -DINSTALL_RESOURCE=ON -DINSTALL_PYTHON=ON -DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}' -DBUILD_WPF_GUI=OFF
- name: Build
run: |
cmake --build build --config Release --parallel $env:NUMBER_OF_PROCESSORS
cmake --build build --config RelWithDebInfo --parallel $env:NUMBER_OF_PROCESSORS
- name: Install
run: |
mkdir -p install
cmake --install build --prefix install --config Release
cmake --install build --prefix install --config RelWithDebInfo
- name: Cache .nuke/temp, ~/.nuget/packages
id: cache-nuget
uses: actions/cache@v4
continue-on-error: true
with:
path: |
.nuke/temp
@@ -164,7 +154,7 @@ jobs:
if: steps.cache-nuget.outputs.cache-hit != 'true'
run: dotnet restore src/MaaWpfGui/MaaWpfGui.csproj
- name: Taggify Version for csproj
- name: Taggify version for csproj
run: |
$csprojPath = "src/MaaWpfGui/MaaWpfGui.csproj"
$csprojPath = Resolve-Path -Path $csprojPath
@@ -185,11 +175,24 @@ jobs:
- name: Publish WPF GUI
continue-on-error: true
run: |
dotnet publish src/MaaWpfGui/MaaWpfGui.csproj -c Release -o install
dotnet publish src/MaaWpfGui/MaaWpfGui.csproj -c Release -p:Platform=${{ matrix.arch == 'arm64' && 'ARM64' || 'x64' }} -o install
- name: Organize Install Files
- name: Collect PDB files
run: |
cp build/bin/RelWithDebInfo/*.pdb install/
Compress-Archive -Path install/*.pdb -DestinationPath install/MAAComponent-DebugSymbol-${{ needs.meta.outputs.tag }}-win-${{ matrix.arch }}.zip
continue-on-error: true
- name: Upload PDB files
uses: actions/upload-artifact@v5
with:
name: MAAComponent-DebugSymbol-win-${{ matrix.arch }}
path: install/MAAComponent-DebugSymbol-${{ needs.meta.outputs.tag }}-win-${{ matrix.arch }}.zip
- name: Organize install files
shell: bash
run: |
rm -rf install/MAAComponent-DebugSymbol-*.zip
rm -rf install/*.pdb
rm -rf install/msvc-debug
rm -rf install/*.h
@@ -201,18 +204,14 @@ jobs:
cd install
Compress-Archive -Destination MAA-${{ needs.meta.outputs.tag }}-win-${{ matrix.arch }}.zip -Path ./*
- name: Upload MAA to Github
uses: actions/upload-artifact@v4
- name: Upload MAA to GitHub
uses: actions/upload-artifact@v5
with:
name: MAA-win-${{ matrix.arch }}
path: install/*.zip
path: install/MAA-*.zip
ubuntu:
# Prevent duplicate runs on organization branches with PRs
if: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name
name: Build for Ubuntu
needs: meta
runs-on: ubuntu-latest
strategy:
@@ -220,21 +219,23 @@ jobs:
arch: [aarch64, x86_64]
fail-fast: false
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Fetch submodules
run: |
git submodule update --init --depth 1 src/MaaUtils
git submodule update --init --depth 1 3rdparty/EmulatorExtras
git submodule update --init --depth 1 src/maa-cli
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v4
continue-on-error: true
with:
path: ./MaaDeps
path: ./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
@@ -248,28 +249,27 @@ jobs:
run: |
mkdir -p build
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DMAADEPS_TRIPLET='maa-${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-linux' \
-DINSTALL_RESOURCE=ON \
-DINSTALL_PYTHON=ON \
-DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}' \
-DCMAKE_TOOLCHAIN_FILE=MaaDeps/cmake/maa-${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-linux-toolchain.cmake
-DCMAKE_TOOLCHAIN_FILE=src/MaaUtils/MaaDeps/cmake/maa-${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-linux-toolchain.cmake
- name: Build
run: |
cmake --build build --config Release --parallel $(nproc)
cmake --build build --config RelWithDebInfo --parallel $(nproc)
env:
CLICOLOR_FORCE: 1
- name: Install
run: |
mkdir -p install
cmake --install build --prefix install --config Release
cmake --install build --prefix install --config RelWithDebInfo
- name: Setup Cross Compile Toolchains for CLI
- name: Setup cross compile toolchains for CLI
uses: ./src/maa-cli/.github/actions/setup
with:
os: ubuntu-latest
target_arch: ${{ matrix.arch }}
- name: Build CLI
@@ -323,8 +323,8 @@ jobs:
cd install
tar czvf $GITHUB_WORKSPACE/release/MAA-${{ needs.meta.outputs.tag }}-linux-${{ matrix.arch }}.tar.gz .
- name: Upload MAA to Github
uses: actions/upload-artifact@v4
- name: Upload MAA to GitHub
uses: actions/upload-artifact@v5
with:
name: MAA-linux-${{ matrix.arch }}
path: |
@@ -332,78 +332,74 @@ jobs:
release/*.tar.gz
macOS-Core:
# Prevent duplicate runs on organization branches with PRs
if: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name
name: Build Core for macOS
needs: meta
runs-on: macos-latest
runs-on: macos-26
strategy:
matrix:
arch: [arm64, x86_64]
fail-fast: false
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Fetch submodules
run: |
git submodule update --init --depth 1 src/MaaUtils
# ninja 1.13.1 is already installed and up-to-date.
# - name: Install Dependencies
# - name: Install dependencies
# run: |
# brew install ninja
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v4
continue-on-error: true
with:
path: ./MaaDeps
path: ./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
run: |
[[ ${{ matrix.arch }} = "arm64" ]] && triplet="arm64-osx" || triplet="x64-osx"
python3 tools/maadeps-download.py ${triplet}
python3 tools/maadeps-download.py ${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-osx
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Config cmake
run: |
cmake -B build -GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_OSX_ARCHITECTURES='${{ matrix.arch }}' \
-DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}'
- name: Build
run: |
cmake --build build --config Release --parallel $(sysctl -n hw.logicalcpu)
cmake --build build --config RelWithDebInfo --parallel $(sysctl -n hw.logicalcpu)
- name: Install
run: |
cmake --install build --prefix install --config Release
cmake --install build --prefix install --config RelWithDebInfo
- name: Upload MAA to Github
uses: actions/upload-artifact@v4
- name: Upload MAA to GitHub
uses: actions/upload-artifact@v5
with:
name: MAACore-macos-${{ matrix.arch }}
path: "install/*.dylib"
macOS-GUI:
# Prevent duplicate runs on organization branches with PRs
if: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name
name: Build GUI for macOS
needs: [meta, macOS-Core]
runs-on: macos-latest
runs-on: macos-26
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Install Dependencies
- name: Install dependencies
if: startsWith(github.ref, 'refs/tags/v')
run: |
brew install graphicsmagick imagemagick
@@ -413,26 +409,26 @@ jobs:
run: |
git submodule update --init --depth 1 src/MaaMacGui
- name: Download Arm64 MAA from Github
uses: actions/download-artifact@v5
- name: Download MAA (arm64) from GitHub
uses: actions/download-artifact@v6
with:
name: MAACore-macos-arm64
path: install-arm64
- name: Download x64 MAA from Github
uses: actions/download-artifact@v5
- name: Download MAA (x64) from GitHub
uses: actions/download-artifact@v6
with:
name: MAACore-macos-x86_64
path: install-x86_64
- name: Install Developer ID Certificate
- name: Install Developer ID certificate
if: startsWith(github.ref, 'refs/tags/v')
uses: apple-actions/import-codesign-certs@v5
with:
p12-file-base64: ${{ secrets.HGUANDL_SIGN_CERT_P12 }}
p12-password: ${{ secrets.HGUANDL_SIGN_CERT_PASSWD }}
- name: Download Provisioning Profiles
- name: Download provisioning profiles
if: startsWith(github.ref, 'refs/tags/v')
uses: apple-actions/download-provisioning-profiles@v4
with:
@@ -441,19 +437,19 @@ jobs:
api-key-id: ${{ secrets.HGUANDL_APPSTORE_KEYID }}
api-private-key: ${{ secrets.HGUANDL_APPSTORE_KEY }}
- name: Setup Xcode Toolchain
if: true
- name: Setup Xcode toolchain
if: false
run: |
sudo xcode-select -s /Applications/Xcode_16.1.app/Contents/Developer
- name: Build Universal Binaries
- name: Build universal binaries
run: |
mkdir build
for LIB_NAME in $(ls install-arm64); do
lipo -create install-arm64/$LIB_NAME install-x86_64/$LIB_NAME -output build/$LIB_NAME
done
- name: Archive Runtime Files
- name: Archive runtime files
run: |
mkdir runtime && cd runtime
name='MAA-${{ needs.meta.outputs.tag }}-macos-runtime-universal'
@@ -465,8 +461,8 @@ jobs:
cd .. || exit 1
zip -yrX9 "$name.zip" "$name"
- name: Upload MAA runtime to Github
uses: actions/upload-artifact@v4
- name: Upload MAA runtime to GitHub
uses: actions/upload-artifact@v5
with:
name: MAA-macos-runtime-universal
path: runtime/MAA-${{ needs.meta.outputs.tag }}-macos-runtime-universal.zip
@@ -474,12 +470,13 @@ jobs:
- name: Build XCFramework
run: |
xcodebuild -create-xcframework -library libMaaCore.dylib -headers ../include -output MaaCore.xcframework
xcodebuild -create-xcframework -library libMaaUtils.dylib -output MaaUtils.xcframework
xcodebuild -create-xcframework -library libfastdeploy_ppocr.dylib -output fastdeploy_ppocr.xcframework
xcodebuild -create-xcframework -library libonnxruntime.*.dylib -output ONNXRuntime.xcframework
xcodebuild -create-xcframework -library libopencv*.dylib -output OpenCV.xcframework
working-directory: build
- name: Setup GUI Version
- name: Setup GUI version
run: |
RELEASE_COUNT=$(git ls-remote --tags origin | grep refs/tags/v | awk 'END{print NR}')
echo 'MARKETING_VERSION = ${{ needs.meta.outputs.tag }}' | tee src/MaaMacGui/Version.xcconfig
@@ -500,20 +497,20 @@ jobs:
xcodebuild -exportArchive -archivePath MAA.xcarchive -exportOptionsPlist ExportOptions.plist -exportPath Export
working-directory: src/MaaMacGui
- name: Create Disk Image
- name: Create disk image
if: startsWith(github.ref, 'refs/tags/v')
run: |
create-dmg Export/MAA.app
mv MAA*.dmg MAA.dmg
working-directory: src/MaaMacGui
- name: Archive Debug Symbols
- name: Archive debug symbols
if: startsWith(github.ref, 'refs/tags/v')
run: |
ditto -c -k --keepParent MAA.app.dSYM MAA.app.dSYM.zip
working-directory: src/MaaMacGui/MAA.xcarchive/dSYMs
- name: Place Packages
- name: Place packages
if: startsWith(github.ref, 'refs/tags/v')
run: |
GIT_TAG=${{ needs.meta.outputs.tag }}
@@ -523,7 +520,7 @@ jobs:
mv src/MaaMacGui/MAA.dmg release/${APP_DMG}
mv src/MaaMacGui/MAA.xcarchive/dSYMs/MAA.app.dSYM.zip release/${APP_SYM}
- name: Notarize Image
- name: Notarize image
if: startsWith(github.ref, 'refs/tags/v')
uses: nick-fields/retry@v3
with:
@@ -539,34 +536,31 @@ jobs:
APPSTORE_KEY: ${{ secrets.HGUANDL_APPSTORE_KEY }}
ISSUER_ID: ${{ secrets.HGUANDL_APPSTORE_ISSUER }}
- name: Attach Notarization Tickets
- name: Attach notarization tickets
if: startsWith(github.ref, 'refs/tags/v')
run: |
dmg="MAA-${{ needs.meta.outputs.tag }}-macos-universal.dmg"
xcrun stapler staple ${dmg}
working-directory: release
- name: Upload MAA to Github
uses: actions/upload-artifact@v4
- name: Upload MAA to GitHub
uses: actions/upload-artifact@v5
with:
name: MAA-macos-universal
path: ${{ startsWith(github.ref, 'refs/tags/v') && 'release/MAA*' || 'src/MaaMacGui/MAA.xcarchive/**' }}
release:
# Prevent duplicate runs on organization branches with PRs
if: (github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name) && startsWith(github.ref, 'refs/tags/v')
name: Publish Release
if: startsWith(github.ref, 'refs/tags/v')
needs: [meta, windows, ubuntu, macOS-Core, macOS-GUI]
runs-on: ubuntu-latest
steps:
- name: Download MAA from Github
uses: actions/download-artifact@v5
- name: Download MAA from GitHub
uses: actions/download-artifact@v6
with:
path: assets
- name: Cleanup files
- name: Clean up files
run: |
mv -vf assets/changelog/* .
rm -rf assets/MAACore-macos-*
@@ -574,32 +568,35 @@ jobs:
# find . -type f | xargs mv -fvt .
find . -type f | while read f; do mv -fvt . $f; done
- name: Release to Github
uses: softprops/action-gh-release@v2.3.3
- name: Publish release to GitHub
uses: softprops/action-gh-release@v2.4.2
with:
body_path: CHANGELOG.md
files: |
assets/*
prerelease: ${{ needs.meta.outputs.prerelease != 'false' }}
- name: Trigger MirrorChyan
- name: Trigger release distribution workflows
run: |
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan_release_note
gh workflow run --repo $GITHUB_REPOSITORY release-package-distribution.yml \
-f release_tag="${{ needs.meta.outputs.tag }}" \
-f mirrorchyan=true \
-f winget=${{ needs.meta.outputs.prerelease == 'false' }}
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan_release_note.yml
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Trigger secondary workflows # ref: https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow
- name: Trigger OTA release workflow # ref: https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow
run: |
gh workflow run --repo $GITHUB_REPOSITORY release-ota
gh workflow run --repo $GITHUB_REPOSITORY release-ota.yml
env:
GH_TOKEN: ${{ secrets.MISTEOWORKFLOW }}
- name: Create issue if failed
- name: Create issue on failure
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: "create-issue"
title: "Failed Release"
title: "Errors occured during release ${{ needs.meta.outputs.tag }}"
body: |
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

View File

@@ -1,15 +1,15 @@
name: "CodeQL MaaCore and MaaWpfGui Analysis"
name: CodeQL Code Analysis
on:
pull_request:
branches: ["dev"]
paths:
- ".github/workflows/codeql-core.yml"
- "3rdparty/include/**"
- "include/**"
- "src/**"
- "cmake/**"
- "CMakeLists.txt"
- ".github/workflows/codeql-core.yml"
- "include/**"
- "src/**"
- "!**/*.md"
- "!**/*.xaml"
schedule:
@@ -25,23 +25,22 @@ permissions:
jobs:
analyze-manual:
name: Analyze MaaCore and MaaWpfGui
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
show-progress: false
- name: Setup CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: c-cpp,csharp
build-mode: manual
- name: Run CodeQL
uses: github/codeql-action/analyze@v3
with:
category: "/language:multi-manual"
uses: github/codeql-action/analyze@v4
- name: Delete old caches
shell: pwsh

View File

@@ -1,4 +1,4 @@
name: "CodeQL Workflows Analysis"
name: CodeQL Workflow Analysis
on:
pull_request:
@@ -17,20 +17,21 @@ permissions:
jobs:
analyze-workflows:
name: Analyze GitHub Workflows
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
show-progress: false
- name: Setup CodeQL for GitHub Actions
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: actions
build-mode: none
- name: Run CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:multi-none"

View File

@@ -1,4 +1,4 @@
name: Auto Close not reading issues or Fold checkboxes
name: Issue Review
on:
issues:
@@ -6,6 +6,7 @@ on:
jobs:
check-then-close-or-fold:
name: Review and Modify Issues
runs-on: ubuntu-latest
permissions:
issues: write
@@ -63,7 +64,7 @@ jobs:
}
}
- name: Check checkbox status
- name: Check for issue checkboxes
id: unread-checkbox-check
uses: actions/github-script@v8
with:
@@ -86,7 +87,7 @@ jobs:
'I have checked all the options without carefully reading the content and believe this will not affect issue resolution.'];
return texts.some(text => new RegExp(`- \\[x\\]\\s*${text}`).test(context.payload.issue.body));
- name: Close and lock issue
- name: Close low-quality issue
if: steps.unread-checkbox-check.outputs.result == 'true'
uses: actions/github-script@v8
with:

View File

@@ -1,4 +1,4 @@
name: "Issue Checker"
name: Issue Triage
on:
issues:
@@ -15,9 +15,11 @@ permissions:
jobs:
triage:
name: Triage Issues and PRs
runs-on: ubuntu-latest
steps:
- uses: MaaAssistantArknights/issue-checker@v1.14
- name: Label issues and PRs Automatically
uses: MaaAssistantArknights/issue-checker@v1.14
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
configuration-path: .github/issue-checker.yml

View File

@@ -1,4 +1,4 @@
name: Check Dead Links
name: Markdown Link Check
on:
schedule:
@@ -7,22 +7,22 @@ on:
branches:
- dev
paths:
- "**/*.md"
- "docs/**"
- ".github/workflows/markdown-checker.yml"
- "docs/**"
- "**/*.md"
pull_request:
branches:
- dev
paths:
- "**/*.md"
- "docs/**"
- ".github/workflows/markdown-checker.yml"
- "docs/**"
- "**/*.md"
workflow_dispatch:
jobs:
check-links:
if: github.repository_owner == 'MaaAssistantArknights' && github.event.head_commit.author.email != '41898282+github-actions[bot]@users.noreply.github.com'
name: Check Dead Links
if: github.repository_owner == 'MaaAssistantArknights' && github.event.head_commit.author.email != '41898282+github-actions[bot]@users.noreply.github.com'
runs-on: ubuntu-latest
permissions:
pull-requests: write
@@ -30,19 +30,19 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Check out code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Cache Primes
id: cache-primes
- name: Cache lychee responses
uses: actions/cache@v4
continue-on-error: true
with:
path: .lycheecache
key: lychee-cache
- name: Check dead links
- name: Check dead internal links
uses: lycheeverse/lychee-action@v2
with:
# 仅检查内部链接,排除所有外部链接

View File

@@ -1,71 +0,0 @@
name: mirrorchyan
on:
workflow_dispatch:
jobs:
mirrorchyan:
runs-on: macos-latest
steps:
- name: Upload MAA win x64
uses: MirrorChyan/uploading-action@v1
if: always()
with:
filetype: latest-release
filename: "*MAA-*-win-x64.zip"
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: win
arch: x64
- name: Upload MAA win arm64
uses: MirrorChyan/uploading-action@v1
if: always()
with:
filetype: latest-release
filename: "*MAA-*-win-arm64.zip"
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: win
arch: arm64
- name: Upload MAA macos arm64
uses: MirrorChyan/uploading-action@v1
if: always()
with:
filetype: latest-release
filename: "MAA-*-macos-universal.dmg"
extra_zip: true
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: macos
arch: arm64
- name: Upload MAA macos x64
uses: MirrorChyan/uploading-action@v1
if: always()
with:
filetype: latest-release
filename: "MAA-*-macos-universal.dmg"
extra_zip: true
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: macos
arch: x64

View File

@@ -1,5 +1,4 @@
name: mirrorchyan_release_note
name: Release Note Distribution
on:
workflow_dispatch:
release:
@@ -7,10 +6,11 @@ on:
jobs:
mirrorchyan:
name: Upload to MirrorChyan
runs-on: macos-latest
steps:
- name: Release Note for MAA
- name: Upload release notes to MirrorChyan
uses: MirrorChyan/release-note-action@v1
with:
mirrorchyan_rid: MAA

View File

@@ -1,14 +1,12 @@
name: Optimize PNG Templates
name: PNG Image Optimization
on:
push:
branches:
- "dev"
paths:
- "resource/**/*.png"
- "docs/.vuepress/public/images/**"
- "website/apps/web/public/**"
- "website/apps/web/src/assets/links/**"
- "resource/**/*.png"
workflow_dispatch:
inputs:
commit_message:
@@ -18,12 +16,13 @@ on:
jobs:
optimize-png:
name: Optimize PNG Images
# Skip workflow to prevent double consecutive runs
# Skip workflow on PR merges
if: github.repository_owner == 'MaaAssistantArknights' && ${{ github.event.head_commit.author.email != '41898282+github-actions[bot]@users.noreply.github.com' }}
runs-on: ubuntu-latest
steps:
- name: Check for direct push
- name: Check if it is a direct push
id: check_push
run: |
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]]; then
@@ -44,7 +43,7 @@ jobs:
- name: Checkout repository
if: steps.check_push.outputs.is_pr != 'True'
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
show-progress: false
persist-credentials: false
@@ -59,6 +58,7 @@ jobs:
# id: cache_python
# if: steps.check_push.outputs.is_pr != 'True' && always()
# uses: actions/cache@v4
# continue-on-error: true
# with:
# path: ${{ env.pythonLocation }}/lib/python3.11/site-packages
# key: ${{ runner.os }}-pip-optimize-templates-${{ hashFiles('./tools/OptimizeTemplates/requirements.txt') }}
@@ -75,7 +75,7 @@ jobs:
with:
crate: oxipng
- name: Run optimize_templates
- name: Optimize png images
if: steps.check_push.outputs.is_pr != 'True'
run: |
python3 tools/OptimizeTemplates/optimize_templates.py

View File

@@ -1,4 +1,4 @@
name: Auto Tag Release PR
name: Release Version Tagging
on:
pull_request:
@@ -15,22 +15,23 @@ on:
jobs:
auto_tag_release:
name: Tag Release
if: github.event.pull_request.merged == true && (startsWith(github.event.pull_request.title, 'Release v') || startsWith(github.event.pull_request.title, 'release v')) || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.MAARELEASE_RELEASE }}
- name: Git config
- name: Configure git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Extract tag name
- name: Determine tag name
id: extract_tag
run: |
if ${{ github.event_name != 'workflow_dispatch' }}; then
@@ -40,12 +41,12 @@ jobs:
echo "tag_name=${{ inputs.tag }}" >> $GITHUB_OUTPUT
fi
- name: Create release tag and push
- name: Create and push release tag
run: |
git tag -a "${{ steps.extract_tag.outputs.tag_name }}" -m "${{ steps.extract_tag.outputs.tag_name }}" -f
git push origin "${{ steps.extract_tag.outputs.tag_name }}"
- name: Merge into dev and push
- name: Merge tag into dev and push
run: |
git switch dev
git merge "${{ steps.extract_tag.outputs.tag_name }}"

View File

@@ -1,4 +1,4 @@
name: PR Checker
name: PR Commit Check
on:
pull_request_target:
@@ -6,10 +6,11 @@ on:
jobs:
check_commit_name_in_pr:
name: Check Commits in PR
if: ${{ !github.event.pull_request.merged && github.base_ref != 'master' }}
runs-on: ubuntu-latest
steps:
- name: Cleanup Previous Comment
- name: Clean up previous comment
uses: actions/github-script@v8
with:
script: |
@@ -27,7 +28,7 @@ jobs:
comment_id: previousComment.id
});
}
- name: Check Commits
- name: Check commits
uses: actions/github-script@v8
with:
script: |

View File

@@ -1,4 +1,4 @@
name: release-nightly-ota
name: Release Pipeline (Nightly OTA)
on:
schedule:
@@ -26,6 +26,7 @@ on:
jobs:
build-win-nightly:
name: Build Nightly for Windows
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: windows-latest
strategy:
@@ -38,7 +39,8 @@ jobs:
main_tag_name: ${{ steps.push_main_tag.outputs.main_tag_name }}
changelog: ${{ steps.read_changelog.outputs.content }}
steps:
- uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
# repository: 'MaaAssistantArknights/MaaAssistantArknights'
#ref: ${{ inputs.ref }}
@@ -51,6 +53,7 @@ jobs:
- name: Fetch submodules
run: |
git submodule update --init --depth 1 src/MaaUtils
git submodule update --init --depth 1 3rdparty/EmulatorExtras
- name: Checkout ref (if provided)
@@ -138,7 +141,7 @@ jobs:
gh run watch ${{ github.run_id }}
- name: Generate Changelog
- name: Generate changelog
id: generate_changelog
run: |
python3 tools/ChangelogGenerator/changelog_generator.py --latest "${{ steps.set_tag.outputs.latest_tag }}" --tag "${{ steps.set_tag.outputs.tag }}"
@@ -160,7 +163,7 @@ jobs:
gh run watch ${{ github.run_id }}
- name: Read Changelog to variable
- name: Read changelog to variable
id: read_changelog
uses: juliangruber/read-file-action@v1
with:
@@ -169,9 +172,10 @@ jobs:
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v4
continue-on-error: true
with:
path: |
./MaaDeps
./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
@@ -184,20 +188,21 @@ jobs:
- name: Config cmake
run: |
mkdir -p build
cmake -B build ${{ matrix.arch == 'arm64' && '-A ARM64' }} -DCMAKE_BUILD_TYPE=Release -DMAADEPS_TRIPLET='maa-${{ matrix.arch }}-windows' -DINSTALL_RESOURCE=ON -DINSTALL_PYTHON=ON -DMAA_HASH_VERSION='${{ steps.set_tag.outputs.tag }}' -DBUILD_WPF_GUI=OFF
cmake -B build ${{ matrix.arch == 'arm64' && '-A ARM64' }} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DMAADEPS_TRIPLET='maa-${{ matrix.arch }}-windows' -DINSTALL_RESOURCE=ON -DINSTALL_PYTHON=ON -DMAA_HASH_VERSION='${{ steps.set_tag.outputs.tag }}' -DBUILD_WPF_GUI=OFF
- name: Build
run: |
cmake --build build --config Release --parallel $env:NUMBER_OF_PROCESSORS
cmake --build build --config RelWithDebInfo --parallel $env:NUMBER_OF_PROCESSORS
- name: Install
run: |
mkdir -p install
cmake --install build --prefix install --config Release
cmake --install build --prefix install --config RelWithDebInfo
- name: Cache .nuke/temp, ~/.nuget/packages
id: cache-nuget
uses: actions/cache@v4
continue-on-error: true
with:
path: |
.nuke/temp
@@ -208,7 +213,7 @@ jobs:
if: steps.cache-nuget.outputs.cache-hit != 'true'
run: dotnet restore src/MaaWpfGui/MaaWpfGui.csproj
- name: Taggify Version for csproj
- name: Taggify version for csproj
run: |
$csprojPath = "src/MaaWpfGui/MaaWpfGui.csproj"
$csprojPath = Resolve-Path -Path $csprojPath
@@ -230,17 +235,30 @@ jobs:
run: |
dotnet publish src/MaaWpfGui/MaaWpfGui.csproj -c Release -o install
- name: Organize Install Files
- name: Collect PDB files
run: |
cp build/bin/RelWithDebInfo/*.pdb install/
Compress-Archive -Path install/*.pdb -DestinationPath install/MAAComponent-DebugSymbol-${{ steps.set_tag.outputs.tag }}-win-${{ matrix.arch }}.zip
continue-on-error: true
- name: Upload PDB files
uses: actions/upload-artifact@v5
with:
name: MAAComponent-DebugSymbol-win-${{ matrix.arch }}
path: install/MAAComponent-DebugSymbol-${{ steps.set_tag.outputs.tag }}-win-${{ matrix.arch }}.zip
- name: Organize install files
shell: bash
run: |
rm -rf install/MAAComponent-DebugSymbol-*.zip
rm -rf install/*.pdb
rm -rf install/msvc-debug
rm -rf install/*.h
cp tools/DependencySetup_依赖库安装.bat install
- name: Upload MAA to Github
uses: actions/upload-artifact@v4
- name: Upload MAA to GitHub
uses: actions/upload-artifact@v5
with:
name: MAA-win-${{ matrix.arch }}
path: install
@@ -257,12 +275,13 @@ jobs:
echo "main_tag_name=$main_tag_name" >> $env:GITHUB_OUTPUT
push-tag:
name: Push Tag to MaaRelease
if: github.repository_owner == 'MaaAssistantArknights'
needs: build-win-nightly
runs-on: ubuntu-latest
steps:
- name: Fetch MaaRelease
uses: actions/checkout@v5
- name: Checkout MaaRelease
uses: actions/checkout@v6
with:
repository: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
fetch-depth: 0
@@ -280,6 +299,7 @@ jobs:
git push --tags origin HEAD:refs/tags/${{ needs.build-win-nightly.outputs.tag }}
make-ota:
name: Build and Upload Nightly OTA for Windows
if: github.repository_owner == 'MaaAssistantArknights'
needs: [build-win-nightly, push-tag]
strategy:
@@ -287,24 +307,24 @@ jobs:
target: [x64]
runs-on: ubuntu-latest
steps:
- name: Echo tag version
- name: Show tag version
run: |
echo ${{ needs.build-win-nightly.outputs.tag }}
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
path: MaaAssistantArknights
token: ${{ secrets.MAARELEASE_RELEASE }}
show-progress: false
- name: Download MAA from Github
uses: actions/download-artifact@v5
- name: Download MAA from GitHub
uses: actions/download-artifact@v6
with:
name: MAA-win-${{ matrix.target }}
path: ${{ format('{0}/{1}', 'build-ota', needs.build-win-nightly.outputs.tag) }}
- name: Fetch release info
- name: Fetch release information
run: |
mkdir -pv build-ota && cd build-ota

View File

@@ -1,4 +1,4 @@
name: release-ota
name: Release Pipeline (OTA)
on:
release:
@@ -22,10 +22,11 @@ env:
jobs:
create-tag:
name: Create OTA Release Tag in MaaRelease
runs-on: ubuntu-latest
steps:
- name: Fetch MaaRelease
uses: actions/checkout@v5
- name: Checkout MaaRelease
uses: actions/checkout@v6
with:
show-progress: false
repository: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
@@ -33,7 +34,7 @@ jobs:
fetch-depth: 0
token: ${{ secrets.MAARELEASE_RELEASE }}
- name: Fetch release info
- name: Fetch release information
id: fetchReleaseInfo
run: |
mkdir -pv build-ota && cd build-ota
@@ -76,7 +77,7 @@ jobs:
PUSH_REMOTE: https://github-actions[bot]:${{ secrets.MAARELEASE_RELEASE }}@github.com/${{ github.repository_owner }}/MaaRelease
- name: Upload release config to GitHub
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: MaaReleaseConfig
path: ./build-ota/config
@@ -86,6 +87,7 @@ jobs:
release_tag: ${{ steps.fetchReleaseInfo.outputs.release_tag }}
make-ota:
name: Build and Upload OTA for Windows
needs: create-tag
runs-on: ubuntu-latest
strategy:
@@ -94,13 +96,13 @@ jobs:
- x64
steps:
- name: Download release config
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: MaaReleaseConfig
path: ./MaaReleaseConfig
- name: Fetch MaaRelease
uses: actions/checkout@v5
- name: Checkout MaaRelease
uses: actions/checkout@v6
with:
show-progress: false
repository: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
@@ -108,8 +110,8 @@ jobs:
fetch-depth: 0
token: ${{ secrets.MAARELEASE_RELEASE }}
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
path: MaaAssistantArknights
@@ -137,20 +139,21 @@ jobs:
prerelease: ${{ fromJSON(needs.create-tag.outputs.prerelease) }}
overwrite: true
- name: Create issue if failed
- name: Create issue on failure
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: "create-issue"
title: "Failed make release OTA for Windows"
title: "Failed to make OTA release for Windows"
body: |
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
make-ota-mac:
name: Build and Upload OTA for macOS
needs: create-tag
runs-on: macos-14
steps:
- name: Fetch release info
- name: Fetch release information
run: gh release list --repo 'MaaAssistantArknights/MaaAssistantArknights' --limit ${{ inputs.limit || 31 }} | tee ./release_maa.txt
- name: Download release packages
@@ -166,7 +169,7 @@ jobs:
run: |
gh release download --repo 'sparkle-project/Sparkle' --clobber -O - -p 'Sparkle-*.tar.xz' | tar xf -
- name: Generate Update Packages
- name: Generate update packages
run: |
if [ $(head -n 1 release_maa.txt | awk '{ print $2 }') = 'Pre-release' ]; then
echo ${{ secrets.SPARKLE_PRIV_KEY }} | ./bin/generate_appcast --channel beta --ed-key-file - ./packages
@@ -174,7 +177,7 @@ jobs:
echo ${{ secrets.SPARKLE_PRIV_KEY }} | ./bin/generate_appcast --ed-key-file - ./packages
fi
- name: Cleanup files
- name: Clean up files
run: |
find ./packages -type f ! \( -name 'MAA-${{ needs.create-tag.outputs.release_tag }}-macos-universal.dmg' -o -name '*.delta' -o -name '*.xml' \) -print -delete
@@ -189,16 +192,17 @@ jobs:
prerelease: ${{ fromJSON(needs.create-tag.outputs.prerelease) }}
overwrite: true
- name: Create issue if failed
- name: Create issue on failure
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: "create-issue"
title: "Failed make release OTA for macos"
title: "Failed to make OTA release for macOS"
body: |
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
release:
name: Publish to Release Mirrors
needs:
- make-ota
- make-ota-mac

View File

@@ -0,0 +1,151 @@
name: Release Package Distribution
on:
workflow_dispatch:
inputs:
release_tag:
description: "Release Tag (empty for latest)"
type: string
required: false
default: ""
mirrorchyan:
description: "Upload to MirrorChyan"
type: boolean
required: false
default: true
winget:
description: "Upload to WinGet"
type: boolean
required: false
default: true
env:
RELEASE_TAG_RAW: ${{ github.event.inputs.release_tag || 'latest' }}
jobs:
meta:
name: Define Release Tag
if: ${{ github.repository_owner == 'MaaAssistantArknights' }}
runs-on: ubuntu-latest
outputs:
RELEASE_TAG: ${{ steps.define_release_tag.outputs.RELEASE_TAG }}
steps:
- name: Get latest release tag
id: get_latest
if: ${{ env.RELEASE_TAG_RAW == 'latest' }}
uses: pozetroninc/github-action-get-latest-release@master
with:
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
token: ${{ secrets.GITHUB_TOKEN }}
excludes: "draft"
- name: Define release tag
id: define_release_tag
run: |
if [ "${{ env.RELEASE_TAG_RAW }}" == "latest" ]; then
echo "RELEASE_TAG=${{ steps.get_latest.outputs.release }}" >> $GITHUB_OUTPUT
else
echo "RELEASE_TAG=${{ env.RELEASE_TAG_RAW }}" >> $GITHUB_OUTPUT
fi
mirrorchyan:
name: Upload to MirrorChyan
needs: meta
if: ${{ github.event.inputs.mirrorchyan == 'true' }}
runs-on: macos-latest
continue-on-error: true
env:
RELEASE_TAG: ${{ needs.meta.outputs.RELEASE_TAG }}
steps:
- name: Upload MAA win x64
uses: MirrorChyan/uploading-action@v1
continue-on-error: true
with:
filetype: latest-release
filename: "*MAA-*-win-x64.zip"
tag: ${{ env.RELEASE_TAG }}
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: win
arch: x64
- name: Upload MAA win arm64
uses: MirrorChyan/uploading-action@v1
continue-on-error: true
with:
filetype: latest-release
filename: "*MAA-*-win-arm64.zip"
tag: ${{ env.RELEASE_TAG }}
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: win
arch: arm64
- name: Upload MAA macos arm64
uses: MirrorChyan/uploading-action@v1
continue-on-error: true
with:
filetype: latest-release
filename: "MAA-*-macos-universal.dmg"
extra_zip: true
tag: ${{ env.RELEASE_TAG }}
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: macos
arch: arm64
- name: Upload MAA macos x64
uses: MirrorChyan/uploading-action@v1
continue-on-error: true
with:
filetype: latest-release
filename: "MAA-*-macos-universal.dmg"
extra_zip: true
tag: ${{ env.RELEASE_TAG }}
mirrorchyan_rid: MAA
github_token: ${{ secrets.GITHUB_TOKEN }}
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
upload_token: ${{ secrets.MirrorChyanUploadToken }}
os: macos
arch: x64
winget:
name: Upload to WinGet
needs: meta
if: ${{ github.event.inputs.winget == 'true' }}
runs-on: windows-latest
continue-on-error: true
env:
RELEASE_TAG: ${{ needs.meta.outputs.RELEASE_TAG }}
steps:
- name: Upload MAA to WinGet
uses: vedantmgoyal9/winget-releaser@main
with:
identifier: MaaAssistantArknights.MaaAssistantArknights
version: ""
installers-regex: "-win-"
max-versions-to-keep: 0
release-tag: ${{ env.RELEASE_TAG }}
fork-user: MaaAssistantArknights
token: ${{ secrets.MAABOT_WINGET_TOKEN }}

View File

@@ -1,4 +1,4 @@
name: gen-changelog
name: Release Preparation
on:
pull_request:
@@ -9,18 +9,19 @@ on:
workflow_dispatch:
jobs:
gen:
generate-changelog:
name: Generate Changelog
# startsWith 表达式不区分大小写
if: github.event.pull_request.draft == false && startsWith(github.event.pull_request.title, 'Release v')
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
show-progress: false
- name: Extract tag name
- name: Extract release information
id: extract_tag
env:
PR_BODY: ${{ format('{0}/{1}', runner.temp, 'output' ) }}
@@ -50,7 +51,7 @@ jobs:
echo 'Target PR: ${{ github.event.pull_request.html_url }}' >> $PR_BODY
echo '' >> $PR_BODY
echo '<details><summary>Debug info</summary>' >> $PR_BODY
echo '<details><summary>Debug information</summary>' >> $PR_BODY
echo '' >> $PR_BODY
echo '```' >> $PR_BODY
sed 's/=/: /1' $GITHUB_OUTPUT >> $PR_BODY
@@ -60,14 +61,14 @@ jobs:
cat $PR_BODY
- name: Generate Changelog
- name: Generate changelog
run: |
git switch dev
python3 tools/ChangelogGenerator/changelog_generator.py --tag "${{ steps.extract_tag.outputs.tag_name }}" --latest "${{ steps.extract_tag.outputs.latest }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Add files to git
- name: Commit changes
run: |
git status
@@ -78,7 +79,7 @@ jobs:
commit_msg="docs: Auto Generate Changelog of Release ""${{ steps.extract_tag.outputs.tag_name }}"
git commit -m "$commit_msg"
- name: Create PR
- name: Create changelog PR
uses: peter-evans/create-pull-request@v7
with:
sign-commits: true
@@ -93,7 +94,18 @@ jobs:
assignees: |
AnnAngela
- name: Add reviewers to release PR
- name: Assign reviewers to release PR
uses: kentaro-m/auto-assign-action@v2.0.0
with:
configuration-path: ".github/release_reviewers.yaml"
update-submodules:
name: Update Submodules
if: github.event.pull_request.draft == false && startsWith(github.event.pull_request.title, 'Release v')
runs-on: ubuntu-latest
steps:
- name: Trigger submodule update workflow
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh workflow run --repo $GITHUB_REPOSITORY update-submodules.yml

View File

@@ -1,4 +1,4 @@
name: Resource Updater
name: Game Resource Update
on:
schedule:
@@ -12,11 +12,12 @@ on:
jobs:
clone-resources-official:
name: Download Official Resources
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
steps:
- name: Clone ArknightsGameResource for Official
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
show-progress: false
repository: yuanyan3060/ArknightsGameResource
@@ -35,19 +36,20 @@ jobs:
/gamedata/excel/roguelike_topic_table.json
/gamedata/excel/activity_table.json
- name: Upload Official
uses: actions/upload-artifact@v4
- name: Upload Official resources
uses: actions/upload-artifact@v5
with:
name: official
path: ./Official
compression-level: 0
clone-resources-overseas:
name: Download Overseas Resources
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
steps:
- name: Clone ArknightsGameResource_Yostar for Overseas
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
show-progress: false
repository: ArknightsAssets/ArknightsGamedata
@@ -77,25 +79,25 @@ jobs:
/kr/gamedata/excel/roguelike_topic_table.json
/kr/gamedata/excel/activity_table.json
- name: Upload Official
uses: actions/upload-artifact@v4
- name: Upload Overseas resources
uses: actions/upload-artifact@v5
with:
name: overseas
path: ./Overseas
compression-level: 0
clone-resources-txwy:
name: Download Taiwan Resources
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
steps:
- name: Clone arknights-toolbox-update for Taiwan
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
show-progress: false
repository: arkntools/arknights-toolbox-update
ref: data-tw
repository: arkntools/arknights-data-tw-for-maa
ref: main
path: ./excel
token: ${{ secrets.ARKNTOOLS_MAA_RESOURCE_UPDATER}}
- name: Download stages.json from Penguin Stats
run: |
@@ -105,34 +107,45 @@ jobs:
parameters=("CN" "US" "JP" "KR")
pids=()
for param in "${parameters[@]}"; do
{
if curl -s -o "stages_${param}.json" "${baseUrl}${param}"; then
if curl -f -s -o "stages_${param}.json" "${baseUrl}${param}"; then
echo "Successfully fetched data for ${param}"
else
echo "Failed to fetch data for ${param}" >&2
exit 1
fi
} &
pids+=($!)
done
wait
- name: Upload Official
uses: actions/upload-artifact@v4
failed=0
for pid in "${pids[@]}"; do
if ! wait "$pid"; then
failed=1
fi
done
if [ $failed -ne 0 ]; then
echo "One or more downloads failed" >&2
exit 1
fi
- name: Upload Taiwan resources
uses: actions/upload-artifact@v5
with:
name: txwy
path: ./excel
compression-level: 0
update-game-resources:
# In case of rate limitations on the runners/instances, add dependency, by removing the comment
# needs: [clone-resources-official, clone-resources-overseas, clone-resources-txwy]
name: Update Game Resources
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: macos-latest
steps:
- name: Checkout MAA
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
# TL;DR https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/9872#issuecomment-2251378371
# actions/checkout uses ${{ secrets.GITHUB_TOKEN }} by default, meaning all steps will inherit it
@@ -140,9 +153,14 @@ jobs:
show-progress: false
fetch-depth: 3
- name: Fetch submodules
run: |
git submodule update --init --depth 1 src/MaaUtils
- name: Restore ResourceUpdater from cache
id: resupd-cache
uses: actions/cache/restore@v4
continue-on-error: true
with:
key: ResourceUpdater-${{ runner.os }}-${{ hashFiles('tools/ResourceUpdater/main.cpp') }}
path: |
@@ -153,9 +171,10 @@ jobs:
if: steps.resupd-cache.outputs.cache-hit != 'true'
id: maadeps-cache
uses: actions/cache@v4
continue-on-error: true
with:
path: |
./MaaDeps
./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-arm64-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
@@ -188,77 +207,46 @@ jobs:
- name: Save ResourceUpdater to cache
if: always() && steps.resupd-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
continue-on-error: true
with:
key: ResourceUpdater-${{ runner.os }}-${{ hashFiles('tools/ResourceUpdater/main.cpp') }}
path: |
./tools/ResourceUpdater/libopencv_world4.4.11.0.dylib
./tools/ResourceUpdater/res_updater
- name: Download txwy
id: download-txwy
uses: actions/download-artifact@v5
continue-on-error: true
- name: Wait for resource cloning
uses: yogeshlonkar/wait-for-jobs@v0
with:
name: txwy
path: ./tools/ResourceUpdater/Overseas/tw/gamedata/excel
ignore-skipped: 'false'
jobs: |
Download Official Resources
Download Overseas Resources
Download Taiwan Resources
ttl: 15
- name: Delay txwy
if: steps.download-txwy.outcome == 'failure'
run: |
sleep 10
- name: Re-download txwy
if: steps.download-txwy.outcome == 'failure'
uses: actions/download-artifact@v5
- name: Download txwy
uses: actions/download-artifact@v6
with:
name: txwy
path: ./tools/ResourceUpdater/Overseas/tw/gamedata/excel
- name: Download Overseas
id: download-overseas
uses: actions/download-artifact@v5
continue-on-error: true
with:
name: overseas
path: ./tools/ResourceUpdater/Overseas
- name: Delay Overseas
if: steps.download-overseas.outcome == 'failure'
run: |
sleep 10
- name: Re-download Overseas
if: steps.download-overseas.outcome == 'failure'
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: overseas
path: ./tools/ResourceUpdater/Overseas
- name: Download Official
id: download-official
uses: actions/download-artifact@v5
continue-on-error: true
uses: actions/download-artifact@v6
with:
name: official
path: ./tools/ResourceUpdater/Official
- name: Delay Official
if: steps.download-official.outcome == 'failure'
run: |
sleep 10
- name: Re-download Official
if: steps.download-official.outcome == 'failure'
uses: actions/download-artifact@v5
with:
name: official
path: ./tools/ResourceUpdater/Official
- name: Run Resource Updater
- name: Update resources
run: |
./tools/ResourceUpdater/res_updater
- name: Task Sorting
- name: Sort tasks
id: task_sorting
run: |
python3 tools/TaskSorter/TaskSorter.py
@@ -272,7 +260,7 @@ jobs:
- name: Update version.json date if necessary
id: update_version
run: |
./tools/ResourceUpdater/version.zsh
sh ./tools/ResourceUpdater/version.sh
- name: Setup python
if: steps.update_version.outputs.contains_png == 'True'
@@ -280,10 +268,11 @@ jobs:
with:
python-version: "3.11"
- name: Cache Python packages
- name: Cache python packages
if: always() && steps.update_version.outputs.contains_png == 'True'
id: cache_python
uses: actions/cache@v4
continue-on-error: true
with:
path: ${{ env.pythonLocation }}/Lib/site-packages
key: ${{ runner.os }}-pip-optimize-templates-${{ hashFiles('./tools/OptimizeTemplates/requirements.txt') }}
@@ -299,12 +288,12 @@ jobs:
with:
crate: oxipng
- name: Run optimize_templates
- name: Optimize png images
if: steps.update_version.outputs.contains_png == 'True'
run: |
python3 tools/OptimizeTemplates/optimize_templates.py -p resource/template/items/ resource/template/infrast/
- name: Add files to git
- name: Commit changes
if: steps.update_version.outputs.changes == 'True'
id: add_files
run: |
@@ -349,4 +338,42 @@ jobs:
# - name: Release # ref: https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow
# if: steps.add_files.outputs.have_commits == 'True'
# run: |
# gh workflow run release-nightly-ota -f release_body="Auto Release of Resource Updates"
# gh workflow run release-nightly-ota.yml -f release_body="Auto Release of Resource Updates"
- name: Upsert failure comment (single active)
if: failure() && github.ref == 'refs/heads/dev'
run: |
run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
latest_id=$(gh api --paginate repos/${{ github.repository }}/issues/14493/comments | jq -r '.[] | select(.user.login=="github-actions[bot]") | .id' | tail -n 1)
if [ -n "$latest_id" ]; then
body=$(gh api repos/${{ github.repository }}/issues/comments/$latest_id --jq '.body')
if echo "$body" | grep -q '/actions/runs/'; then
# Count existing run URLs
count=$(echo "$body" | grep -o 'https://github.com/[^[:space:]]*' | wc -l)
# Collapse existing content
old_content=$(echo "$body" | sed 's|https://github.com/[^[:space:]]*|<details>\n<summary>⚠️ Previous failures ('"$count"')</summary>\n\n###### &\n\n</details>|g')
new_body="$run_url
@MistEO @ABA2396 @Constrat
$old_content"
gh api repos/${{ github.repository }}/issues/comments/$latest_id -X PATCH -f body="$new_body" || echo "Patch failed"
exit 0
fi
fi
# Create new failure comment if none suitable
gh issue comment 14493 -R ${{ github.repository }} --body "$run_url
@MistEO @ABA2396 @Constrat"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Minimize failure comment on success/cancelled
if: ${{ !failure() && github.ref == 'refs/heads/dev' }}
run: |
latest_node=$(gh api --paginate repos/${{ github.repository }}/issues/14493/comments | jq -r '.[] | select(.user.login=="github-actions[bot]") | .node_id' | tail -n 1)
if [ -n "$latest_node" ]; then
gh api graphql -f query='mutation { minimizeComment(input: {subjectId: "'"$latest_node"'", classifier: OUTDATED}) { minimizedComment { isMinimized } } }' || true
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,58 +1,67 @@
name: smoke-testing
name: Smoke Test
permissions:
contents: read
on:
push:
paths:
- ".github/workflows/smoke-testing.yml"
- "3rdparty/include/**"
- "include/**"
- "src/Cpp/**"
- "src/MaaCore/**"
- "resource/**"
- "!**/*.md"
- "cmake/**"
- "CMakeLists.txt"
- "include/**"
- "resource/**"
- "src/Cpp/**"
- "src/MaaCore/**"
- "tools/maadeps-download.py"
- "tools/SmokeTesting/**"
- "!**/*.md"
pull_request:
paths:
- ".github/workflows/smoke-testing.yml"
- "3rdparty/include/**"
- "include/**"
- "src/Cpp/**"
- "src/MaaCore/**"
- "resource/**"
- "!**/*.md"
- "cmake/**"
- "CMakeLists.txt"
- "include/**"
- "resource/**"
- "src/Cpp/**"
- "src/MaaCore/**"
- "tools/maadeps-download.py"
- "tools/SmokeTesting/**"
- "!**/*.md"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref == 'refs/heads/dev' && github.sha }}
cancel-in-progress: true
jobs:
smoke-testing:
# Prevent duplicate runs on organization branches with PRs
if: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name
name: Run Smoke Test
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Generate cache key
id: cache_key
continue-on-error: true
run: |
echo "key=Smoke-testing-${{ hashFiles('src/Cpp/**', 'src/MaaCore/**', '3rdparty/include/**', 'include/**', 'cmake/**', 'CMakeLists.txt', 'tools/maadeps-download.py', 'tools/linux-toolchain-download.py') }}" >> $GITHUB_OUTPUT
- name: Restore cache smoke-testing
- name: Restore cache for Smoke Test
if: ${{ steps.cache_key.outputs.key != '' }}
id: smoke-cache
uses: actions/cache/restore@v4
continue-on-error: true
with:
key: ${{ steps.cache_key.outputs.key }}
path: |
./install/libfastdeploy_ppocr.dylib
./install/libMaaCore.dylib
./install/libMaaUtils.dylib
./install/libonnxruntime.1.19.2.dylib
./install/libopencv_world4.4.11.0.dylib
./install/smoke_test
@@ -60,14 +69,15 @@ jobs:
- name: Fetch submodules
if: steps.smoke-cache.outputs.cache-hit != 'true'
run: |
git submodule update --init --depth 1 3rdparty/EmulatorExtras
git submodule update --init --depth 1 src/MaaUtils
- name: Cache MaaDeps
if: steps.smoke-cache.outputs.cache-hit != 'true'
id: maadeps-cache
uses: actions/cache@v4
continue-on-error: true
with:
path: ./MaaDeps
path: ./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-arm64-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
@@ -99,22 +109,24 @@ jobs:
mkdir -p install
cmake --install build --prefix install --config Debug
- name: Make link for cache smoke-testing
- name: Make link to Smoke Test cache
if: steps.smoke-cache.outputs.cache-hit == 'true'
run: |
ln -s "$(pwd)/resource" install/resource
- name: Run tests
run: |
./tools/SmokeTesting/run_tests.zsh
sh ./tools/SmokeTesting/run_tests.sh
- name: Save cache smoke-testing (only in dev)
- name: Save cache for Smoke Test (only in dev)
if: steps.smoke-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/dev'
uses: actions/cache/save@v4
continue-on-error: true
with:
key: ${{ steps.cache_key.outputs.key }}
path: |
./install/libfastdeploy_ppocr.dylib
./install/libMaaUtils.dylib
./install/libMaaCore.dylib
./install/libonnxruntime.1.19.2.dylib
./install/libopencv_world4.4.11.0.dylib
@@ -122,7 +134,7 @@ jobs:
- name: Upload logs
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: logs
path: ./install/debug

View File

@@ -1,4 +1,4 @@
name: "Inactive Issues Closer"
name: Issue Staleness Management
on:
schedule:
@@ -11,6 +11,7 @@ env: # config
jobs:
stale:
name: Handle Stale Issues
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
permissions:
@@ -20,7 +21,7 @@ jobs:
pull-requests: none
contents: none
steps:
- name: Close inactive issues
- name: Handle stale issues
uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,33 +1,34 @@
name: sync-resource
name: Resource Sync
on:
push:
branches:
- dev
paths:
- "resource/**"
- ".github/workflows/sync-resource.yml"
- "resource/**"
workflow_dispatch:
jobs:
sync-resource:
name: Sync Resource to MaaResource
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
steps:
- name: Checkout MaaAssistantArknights
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Setup Git
- name: Configure git
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git show -s
- name: Checkout MaaResource
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
repository: MaaAssistantArknights/MaaResource
show-progress: false

33
.github/workflows/update-submodules.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Submodule Update
on:
schedule:
- cron: "50 21 * * *" # Runs daily at 21:50 UTC (before `Release Pipeline (Nightly OTA)`)
workflow_dispatch:
jobs:
update-submodules:
name: Update Submodules
runs-on: ubuntu-latest
if: github.repository_owner == 'MaaAssistantArknights'
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: true
- name: Update submodules
run: |
git submodule update --remote src/MaaMacGui
git submodule update --remote src/maa-cli
- name: Commit and push changes
uses: actions-js/push@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
message: "feat: Update Submodules MaaMacGui, maa-cli
https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
[skip changelog]"
branch: ${{ github.ref }}

View File

@@ -1,4 +1,4 @@
name: MaaWebsite Workflow
name: Documentation Site
on:
push:
@@ -24,48 +24,51 @@ concurrency:
group: "pages"
cancel-in-progress: false
permissions:
# required for peaceiris/actions-gh-pages
contents: write
jobs:
build:
name: Build and Deploy
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
package_json_file: "./docs/package.json"
run_install: false
- name: Setup Node.js environment
uses: actions/setup-node@v5
- name: Setup node.js environment
uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: "./docs/pnpm-lock.yaml"
- name: Install dependencies
- name: Install node modules
run: pnpm install --frozen-lockfile
working-directory: "./docs"
- name: Build documentation
- name: Build
run: pnpm run build
working-directory: "./docs"
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
- name: Upload artifact to GitHub
uses: actions/upload-artifact@v5
with:
name: dist
path: "./docs/.vuepress/dist"
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
if: ${{ inputs.deploy-to-prod == true || github.ref == 'refs/heads/master' }}
if: github.repository_owner == 'MaaAssistantArknights' && (inputs.deploy-to-prod == true || github.ref == 'refs/heads/master')
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: "./docs/.vuepress/dist"

3
.gitignore vendored
View File

@@ -457,7 +457,8 @@ tools/RoguelikeRecruitmentTool/output
.lycheecache
# MaaDeps
/MaaDeps/*
MaaDeps
src/MaaUtils/*
# ResourceUpdater workflow
/original/*

3
.gitmodules vendored
View File

@@ -10,3 +10,6 @@
[submodule "3rdparty/EmulatorExtras"]
path = 3rdparty/EmulatorExtras
url = https://github.com/MaaXYZ/EmulatorExtras.git
[submodule "src/MaaUtils"]
path = src/MaaUtils
url = https://github.com/MaaXYZ/MaaUtils

View File

@@ -4,36 +4,47 @@ ci:
autofix_prs: true
repos:
- repo: https://github.com/shssoichiro/oxipng
rev: v9.1.4
rev: v9.1.5
hooks:
- id: oxipng
name: PNG Image Compression
args: ["-q", "-o", "2", "-s", "--ng"]
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v20.1.0
rev: v21.1.1
hooks:
- id: clang-format
name: Clang-Format (MaaCore)
files: ^src/MaaCore/.*
args: ["--assume-filename", ".clang-format"]
- repo: https://github.com/rbubley/mirrors-prettier
rev: v3.5.3
rev: v3.6.2
hooks:
- id: prettier
name: prettier (config files)
name: Prettier (Config Files)
files: ^((\.github/ISSUE_TEMPLATE|resource|src|tools)/.*|\.pre-commit-config\.yaml|package-definition\.json)
types_or:
- yaml
- json
- repo: https://github.com/rbubley/mirrors-prettier
rev: v3.5.3
hooks:
- id: prettier
name: prettier (docs)
name: Prettier (Documentation)
files: ^docs/.*
- repo: https://github.com/psf/black
rev: 25.9.0
hooks:
- id: black
name: Black Formatter (Python)
- repo: https://github.com/pycqa/isort
rev: 6.0.1
hooks:
- id: isort
name: Isort (Python)
args: ["--profile", "black", "--filter-files"]
- repo: https://github.com/DavidAnson/markdownlint-cli2
rev: v0.17.2
rev: v0.18.1
hooks:
- id: markdownlint-cli2
name: MarkdownLint (Documentation)
files: ^docs/.*|^README\.md$
types:
- markdown
args: ["--fix", "--config", "docs/.markdownlint.yaml", "#**/node_modules"]
args: ["--fix", "--config", "docs/.markdownlint.yaml"]

View File

@@ -1,18 +1,12 @@
**/node_modules/
**/pnpm-lock.yaml
docs/**/*.md
MaaDeps/
3rdparty/
src/maa-cli
src/MaaMacGui
# website/
# docs/
src/MaaUtils
resource/Arknights-Tile-Pos/
tools/OptimizeTemplates/optimize_templates.json
CITATION.cff
CHANGELOG.md
## FUCK FUCK

View File

@@ -1,688 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <initializer_list>
#include <optional>
#include <ostream>
#include <string>
#include <tuple>
#include <type_traits>
#include <vector>
#include "exception.hpp"
#include "utils.hpp"
namespace json
{
template <typename string_t>
class basic_array
{
friend class basic_value<string_t>;
friend class basic_object<string_t>;
public:
using raw_array = std::vector<basic_value<string_t>>;
using value_type = typename raw_array::value_type;
using iterator = typename raw_array::iterator;
using const_iterator = typename raw_array::const_iterator;
using reverse_iterator = typename raw_array::reverse_iterator;
using const_reverse_iterator = typename raw_array::const_reverse_iterator;
using char_t = typename string_t::value_type;
public:
basic_array() = default;
basic_array(const basic_array<string_t>& rhs) = default;
basic_array(basic_array<string_t>&& rhs) noexcept = default;
basic_array(std::initializer_list<value_type> init_list);
basic_array(typename raw_array::size_type size);
// explicit basic_array(const basic_value<string_t>& val);
// explicit basic_array(basic_value<string_t>&& val);
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_to_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_to_json_array_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
basic_array(const jsonization_t& value)
: basic_array(ext::jsonization<string_t, jsonization_t>().to_json(value))
{
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_to_json_array_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
basic_array(const jsonization_t& value)
: basic_array(ext::jsonization<string_t, jsonization_t>().to_json_array(value))
{
}
template <
typename jsonization_t,
std::enable_if_t<
std::is_rvalue_reference_v<jsonization_t&&>
&& _utils::has_move_to_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_move_to_json_array_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
basic_array(jsonization_t&& value)
: basic_array(ext::jsonization<string_t, jsonization_t>().move_to_json(std::move(value)))
{
}
//template <
// typename jsonization_t,
// std::enable_if_t<
// std::is_rvalue_reference_v<jsonization_t&&>
// && _utils::has_move_to_json_array_in_templ_spec<jsonization_t, string_t>::value,
// bool> = true>
//basic_array(jsonization_t&& value)
// : basic_array(
// ext::jsonization<string_t, jsonization_t>().move_to_json_array(std::move(value)))
//{
//}
~basic_array() noexcept = default;
bool empty() const noexcept { return _array_data.empty(); }
size_t size() const noexcept { return _array_data.size(); }
bool contains(size_t pos) const { return pos < _array_data.size(); }
bool exists(size_t pos) const { return contains(pos); }
const basic_value<string_t>& at(size_t pos) const;
string_t dumps(std::optional<size_t> indent = std::nullopt) const
{
return indent ? format(*indent) : to_string();
}
string_t to_string() const;
string_t format(size_t indent = 4) const { return format(indent, 0); }
template <typename value_t>
bool all() const;
template <typename value_t, template <typename...> typename collection_t = std::vector>
collection_t<value_t> as_collection() const;
template <
typename value_t,
size_t Size,
template <typename, size_t> typename fixed_array_t = std::array>
fixed_array_t<value_t, Size> as_fixed_array() const;
template <typename... elem_ts>
std::tuple<elem_ts...> as_tuple() const;
template <typename first_t, typename second_t>
std::pair<first_t, second_t> as_pair() const;
template <
typename value_t,
std::enable_if_t<
_utils::has_from_json_array_in_templ_spec<value_t, string_t>::value,
bool> = true>
value_t as() const&
{
value_t res;
ext::jsonization<string_t, value_t>().from_json_array(*this, res);
return res;
}
template <
typename value_t,
std::enable_if_t<
_utils::has_move_from_json_array_in_templ_spec<value_t, string_t>::value,
bool> = true>
value_t as() &&
{
value_t res;
ext::jsonization<string_t, value_t>().move_from_json_array(std::move(*this), res);
return res;
}
// Usage: get(key_1, key_2, ..., default_value);
template <typename... key_then_default_value_t>
auto get(key_then_default_value_t&&... keys_then_default_value) const;
template <typename value_t = basic_value<string_t>>
std::optional<value_t> find(size_t pos) const;
template <typename... args_t>
decltype(auto) emplace_back(args_t&&... args);
template <typename... args_t>
decltype(auto) push_back(args_t&&... args);
void clear() noexcept;
bool erase(size_t pos);
bool erase(iterator iter);
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
reverse_iterator rbegin() noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
const basic_value<string_t>& operator[](size_t pos) const;
basic_value<string_t>& operator[](size_t pos);
basic_array<string_t> operator+(const basic_array<string_t>& rhs) const&;
basic_array<string_t> operator+(basic_array<string_t>&& rhs) const&;
basic_array<string_t> operator+(const basic_array<string_t>& rhs) &&;
basic_array<string_t> operator+(basic_array<string_t>&& rhs) &&;
basic_array<string_t>& operator+=(const basic_array<string_t>& rhs);
basic_array<string_t>& operator+=(basic_array<string_t>&& rhs);
basic_array<string_t>& operator=(const basic_array<string_t>&) = default;
basic_array<string_t>& operator=(basic_array<string_t>&&) noexcept = default;
template <
typename value_t,
std::enable_if_t<std::is_convertible_v<value_t, basic_array<string_t>>, bool> = true>
basic_array<string_t>& operator=(value_t rhs)
{
return *this = basic_array<string_t>(std::move(rhs));
}
bool operator==(const basic_array<string_t>& rhs) const;
bool operator!=(const basic_array<string_t>& rhs) const { return !(*this == rhs); }
template <
typename value_t,
template <typename...> typename collection_t = std::vector,
std::enable_if_t<_utils::is_collection<collection_t<value_t>>, bool> = true>
explicit operator collection_t<value_t>() const
{
return as_collection<value_t, collection_t>();
}
template <
typename value_t,
size_t Size,
template <typename, size_t> typename fixed_array_t = std::array,
std::enable_if_t<_utils::is_fixed_array<fixed_array_t<value_t, Size>>, bool> = true>
explicit operator fixed_array_t<value_t, Size>() const
{
return as<fixed_array_t<value_t, Size>>();
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_from_json_array_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() const&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().from_json(*this, dst)) {
throw exception("Wrong JSON");
}
return dst;
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_from_json_array_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() const&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().from_json_array(*this, dst)) {
throw exception("Wrong JSON");
}
return dst;
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_move_from_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_move_from_json_array_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() &&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().from_json(std::move(*this), dst)) {
throw exception("Wrong JSON");
}
return dst;
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_move_from_json_array_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() &&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().move_from_json_array(
std::move(*this),
dst)) {
throw exception("Wrong JSON");
}
return dst;
}
private:
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
auto
get(std::tuple<key_then_default_value_t...> keys_then_default_value,
std::index_sequence<keys_indexes_t...>) const;
template <typename value_t, typename... rest_keys_t>
auto get_helper(const value_t& default_value, size_t pos, rest_keys_t&&... rest) const;
template <typename value_t>
auto get_helper(const value_t& default_value, size_t pos) const;
string_t format(size_t indent, size_t indent_times) const;
private:
raw_array _array_data;
};
template <typename string_t>
inline basic_array<string_t>::basic_array(std::initializer_list<value_type> init_list)
: _array_data(init_list)
{
}
template <typename string_t>
inline basic_array<string_t>::basic_array(typename raw_array::size_type size)
: _array_data(size)
{
}
// template <typename string_t>
// inline basic_array<string_t>::basic_array(const basic_value<string_t>& val) :
// basic_array<string_t>(val.as_array())
//{}
//
// template <typename string_t>
// inline basic_array<string_t>::basic_array(basic_value<string_t>&& val)
// : basic_array<string_t>(std::move(val.as_array()))
//{}
template <typename string_t>
inline void basic_array<string_t>::clear() noexcept
{
_array_data.clear();
}
template <typename string_t>
inline bool basic_array<string_t>::erase(size_t pos)
{
return erase(_array_data.begin() + pos);
}
template <typename string_t>
inline bool basic_array<string_t>::erase(iterator iter)
{
return _array_data.erase(iter) != _array_data.end();
}
template <typename string_t>
template <typename... args_t>
inline decltype(auto) basic_array<string_t>::emplace_back(args_t&&... args)
{
static_assert(
std::is_constructible_v<value_type, args_t...>,
"Parameter can't be used to construct a raw_array::value_type");
return _array_data.emplace_back(std::forward<args_t>(args)...);
}
template <typename string_t>
template <typename... args_t>
inline decltype(auto) basic_array<string_t>::push_back(args_t&&... args)
{
return emplace_back(std::forward<args_t>(args)...);
}
template <typename string_t>
inline const basic_value<string_t>& basic_array<string_t>::at(size_t pos) const
{
return _array_data.at(pos);
}
template <typename string_t>
inline string_t basic_array<string_t>::to_string() const
{
string_t str { '[' };
for (auto iter = _array_data.cbegin(); iter != _array_data.cend();) {
str += iter->to_string();
if (++iter != _array_data.cend()) {
str += ',';
}
}
str += char_t(']');
return str;
}
template <typename string_t>
inline string_t basic_array<string_t>::format(size_t indent, size_t indent_times) const
{
const string_t tail_indent(indent * indent_times, ' ');
const string_t body_indent(indent * (indent_times + 1), ' ');
string_t str { '[', '\n' };
for (auto iter = _array_data.cbegin(); iter != _array_data.cend();) {
str += body_indent + iter->format(indent, indent_times + 1);
if (++iter != _array_data.cend()) {
str += ',';
}
str += '\n';
}
str += tail_indent + char_t(']');
return str;
}
template <typename string_t>
template <typename value_t>
inline bool basic_array<string_t>::all() const
{
for (const auto& elem : _array_data) {
if (!elem.template is<value_t>()) {
return false;
}
}
return true;
}
template <typename string_t>
template <typename value_t, template <typename...> typename collection_t>
inline collection_t<value_t> basic_array<string_t>::as_collection() const
{
return as<collection_t<value_t>>();
}
template <typename string_t>
template <typename value_t, size_t Size, template <typename, size_t> typename fixed_array_t>
inline fixed_array_t<value_t, Size> basic_array<string_t>::as_fixed_array() const
{
return as<fixed_array_t<value_t, Size>>();
}
template <typename string_t>
template <typename... elem_ts>
inline std::tuple<elem_ts...> basic_array<string_t>::as_tuple() const
{
return as<std::tuple<elem_ts...>>();
}
template <typename string_t>
template <typename first_t, typename second_t>
inline std::pair<first_t, second_t> basic_array<string_t>::as_pair() const
{
return as<std::pair<first_t, second_t>>();
}
template <typename string_t>
template <typename... key_then_default_value_t>
inline auto basic_array<string_t>::get(key_then_default_value_t&&... keys_then_default_value) const
{
return get(
std::forward_as_tuple(keys_then_default_value...),
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
}
template <typename string_t>
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
inline auto basic_array<string_t>::get(
std::tuple<key_then_default_value_t...> keys_then_default_value,
std::index_sequence<keys_indexes_t...>) const
{
constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1;
return get_helper(
std::get<default_value_index>(keys_then_default_value),
std::get<keys_indexes_t>(keys_then_default_value)...);
}
template <typename string_t>
template <typename value_t, typename... rest_keys_t>
inline auto basic_array<string_t>::get_helper(
const value_t& default_value,
size_t pos,
rest_keys_t&&... rest) const
{
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|| std::is_same_v<basic_array<string_t>, value_t>
|| std::is_same_v<basic_object<string_t>, value_t>;
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
if (!contains(pos)) {
if constexpr (is_string) {
return string_t(default_value);
}
else {
return value_t(default_value);
}
}
return at(pos).get_helper(default_value, std::forward<rest_keys_t>(rest)...);
}
template <typename string_t>
template <typename value_t>
inline auto basic_array<string_t>::get_helper(const value_t& default_value, size_t pos) const
{
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|| std::is_same_v<basic_array<string_t>, value_t>
|| std::is_same_v<basic_object<string_t>, value_t>;
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
if (!contains(pos)) {
if constexpr (is_string) {
return string_t(default_value);
}
else {
return value_t(default_value);
}
}
auto val = _array_data.at(pos);
if (val.template is<value_t>()) {
if constexpr (is_string) {
return val.template as<string_t>();
}
else {
return val.template as<value_t>();
}
}
else {
if constexpr (is_string) {
return string_t(default_value);
}
else {
return value_t(default_value);
}
}
}
template <typename string_t>
template <typename value_t>
inline std::optional<value_t> basic_array<string_t>::find(size_t pos) const
{
if (!contains(pos)) {
return std::nullopt;
}
const auto& val = _array_data.at(pos);
return val.template is<value_t>() ? std::optional<value_t>(val.template as<value_t>())
: std::nullopt;
}
template <typename string_t>
inline typename basic_array<string_t>::iterator basic_array<string_t>::begin() noexcept
{
return _array_data.begin();
}
template <typename string_t>
inline typename basic_array<string_t>::iterator basic_array<string_t>::end() noexcept
{
return _array_data.end();
}
template <typename string_t>
inline typename basic_array<string_t>::const_iterator basic_array<string_t>::begin() const noexcept
{
return _array_data.begin();
}
template <typename string_t>
inline typename basic_array<string_t>::const_iterator basic_array<string_t>::end() const noexcept
{
return _array_data.end();
}
template <typename string_t>
inline typename basic_array<string_t>::const_iterator basic_array<string_t>::cbegin() const noexcept
{
return _array_data.cbegin();
}
template <typename string_t>
inline typename basic_array<string_t>::const_iterator basic_array<string_t>::cend() const noexcept
{
return _array_data.cend();
}
template <typename string_t>
inline typename basic_array<string_t>::reverse_iterator basic_array<string_t>::rbegin() noexcept
{
return _array_data.rbegin();
}
template <typename string_t>
inline typename basic_array<string_t>::reverse_iterator basic_array<string_t>::rend() noexcept
{
return _array_data.rend();
}
template <typename string_t>
inline typename basic_array<string_t>::const_reverse_iterator
basic_array<string_t>::rbegin() const noexcept
{
return _array_data.rbegin();
}
template <typename string_t>
inline typename basic_array<string_t>::const_reverse_iterator
basic_array<string_t>::rend() const noexcept
{
return _array_data.rend();
}
template <typename string_t>
inline typename basic_array<string_t>::const_reverse_iterator
basic_array<string_t>::crbegin() const noexcept
{
return _array_data.crbegin();
}
template <typename string_t>
inline typename basic_array<string_t>::const_reverse_iterator
basic_array<string_t>::crend() const noexcept
{
return _array_data.crend();
}
template <typename string_t>
inline basic_value<string_t>& basic_array<string_t>::operator[](size_t pos)
{
return _array_data[pos];
}
template <typename string_t>
inline const basic_value<string_t>& basic_array<string_t>::operator[](size_t pos) const
{
return _array_data[pos];
}
template <typename string_t>
inline basic_array<string_t>
basic_array<string_t>::operator+(const basic_array<string_t>& rhs) const&
{
basic_array<string_t> temp = *this;
temp._array_data.insert(_array_data.end(), rhs.begin(), rhs.end());
return temp;
}
template <typename string_t>
inline basic_array<string_t> basic_array<string_t>::operator+(basic_array<string_t>&& rhs) const&
{
basic_array<string_t> temp = *this;
temp._array_data.insert(
_array_data.end(),
std::make_move_iterator(rhs.begin()),
std::make_move_iterator(rhs.end()));
return temp;
}
template <typename string_t>
inline basic_array<string_t> basic_array<string_t>::operator+(const basic_array<string_t>& rhs) &&
{
_array_data.insert(_array_data.end(), rhs.begin(), rhs.end());
return std::move(*this);
}
template <typename string_t>
inline basic_array<string_t> basic_array<string_t>::operator+(basic_array<string_t>&& rhs) &&
{
_array_data.insert(
_array_data.end(),
std::make_move_iterator(rhs.begin()),
std::make_move_iterator(rhs.end()));
return std::move(*this);
}
template <typename string_t>
inline basic_array<string_t>& basic_array<string_t>::operator+=(const basic_array<string_t>& rhs)
{
_array_data.insert(_array_data.end(), rhs.begin(), rhs.end());
return *this;
}
template <typename string_t>
inline basic_array<string_t>& basic_array<string_t>::operator+=(basic_array<string_t>&& rhs)
{
_array_data.insert(
_array_data.end(),
std::make_move_iterator(rhs.begin()),
std::make_move_iterator(rhs.end()));
return *this;
}
template <typename string_t>
inline bool basic_array<string_t>::operator==(const basic_array<string_t>& rhs) const
{
return _array_data == rhs._array_data;
}
template <
typename ostream_t,
typename string_t,
typename std_ostream_t = std::basic_ostream<
typename string_t::value_type,
std::char_traits<typename string_t::value_type>>,
typename enable_t = std::enable_if_t<
std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
ostream_t& operator<<(ostream_t& out, const basic_array<string_t>& arr)
{
out << arr.format();
return out;
}
} // namespace json

View File

@@ -1,35 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <exception>
#include <string>
namespace json
{
class exception : public std::exception
{
public:
exception() = default;
exception(const std::string& msg)
: _what(msg)
{
}
exception(const exception&) = default;
exception& operator=(const exception&) = default;
exception(exception&&) = default;
exception& operator=(exception&&) = default;
virtual ~exception() noexcept override = default;
virtual const char* what() const noexcept override
{
return _what.empty() ? "Unknown exception" : _what.c_str();
}
protected:
std::string _what;
};
}

View File

@@ -1,605 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <initializer_list>
#include <map>
#include <optional>
#include <ostream>
#include <string>
#include <tuple>
#include "exception.hpp"
#include "utils.hpp"
namespace json
{
template <typename string_t>
class basic_object
{
friend class basic_value<string_t>;
friend class basic_array<string_t>;
public:
using raw_object = std::map<string_t, basic_value<string_t>>;
using key_type = typename raw_object::key_type;
using mapped_type = typename raw_object::mapped_type;
using value_type = typename raw_object::value_type;
using iterator = typename raw_object::iterator;
using const_iterator = typename raw_object::const_iterator;
using char_t = typename string_t::value_type;
public:
basic_object() = default;
basic_object(const basic_object<string_t>& rhs) = default;
basic_object(basic_object<string_t>&& rhs) noexcept = default;
basic_object(std::initializer_list<value_type> init_list);
// explicit basic_object(const basic_value<string_t>& val);
// explicit basic_object(basic_value<string_t>&& val);
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_to_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_to_json_object_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
basic_object(const jsonization_t& value)
: basic_object(ext::jsonization<string_t, jsonization_t>().to_json(value))
{
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_to_json_object_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
basic_object(const jsonization_t& value)
: basic_object(ext::jsonization<string_t, jsonization_t>().to_json_object(value))
{
}
template <
typename jsonization_t,
std::enable_if_t<
std::is_rvalue_reference_v<jsonization_t&&>
&& _utils::has_move_to_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_move_to_json_object_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
basic_object(jsonization_t&& value)
: basic_object(ext::jsonization<string_t, jsonization_t>().move_to_json(std::move(value)))
{
}
//template <
// typename jsonization_t,
// std::enable_if_t<
// std::is_rvalue_reference_v<jsonization_t&&>
// && _utils::has_move_to_json_object_in_templ_spec<jsonization_t, string_t>::value,
// bool> = true>
//basic_object(jsonization_t&& value)
// : basic_object(
// ext::jsonization<string_t, jsonization_t>().move_to_json_object(std::move(value)))
//{
//}
~basic_object() = default;
bool empty() const noexcept { return _object_data.empty(); }
size_t size() const noexcept { return _object_data.size(); }
bool contains(const string_t& key) const;
bool exists(const string_t& key) const { return contains(key); }
const basic_value<string_t>& at(const string_t& key) const;
string_t dumps(std::optional<size_t> indent = std::nullopt) const
{
return indent ? format(*indent) : to_string();
}
string_t to_string() const;
string_t format(size_t indent = 4) const { return format(indent, 0); }
template <typename value_t>
bool all() const;
template <typename value_t, template <typename...> typename map_t = std::map>
map_t<string_t, value_t> as_map() const;
template <
typename value_t,
std::enable_if_t<
_utils::has_from_json_object_in_templ_spec<value_t, string_t>::value,
bool> = true>
value_t as() const&
{
value_t res;
ext::jsonization<string_t, value_t>().from_json_object(*this, res);
return res;
}
template <
typename value_t,
std::enable_if_t<
_utils::has_move_from_json_object_in_templ_spec<value_t, string_t>::value,
bool> = true>
value_t as() &&
{
value_t res;
ext::jsonization<string_t, value_t>().move_from_json_object(std::move(*this), res);
return res;
}
// Usage: get(key_1, key_2, ..., default_value);
template <typename... key_then_default_value_t>
auto get(key_then_default_value_t&&... keys_then_default_value) const;
template <typename value_t = basic_value<string_t>>
std::optional<value_t> find(const string_t& key) const;
template <typename... args_t>
decltype(auto) emplace(args_t&&... args);
template <typename... args_t>
decltype(auto) insert(args_t&&... args);
void clear() noexcept;
bool erase(const string_t& key);
bool erase(iterator iter);
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
basic_value<string_t>& operator[](const string_t& key);
basic_value<string_t>& operator[](string_t&& key);
basic_object<string_t> operator|(const basic_object<string_t>& rhs) const&;
basic_object<string_t> operator|(basic_object<string_t>&& rhs) const&;
basic_object<string_t> operator|(const basic_object<string_t>& rhs) &&;
basic_object<string_t> operator|(basic_object<string_t>&& rhs) &&;
basic_object<string_t>& operator|=(const basic_object<string_t>& rhs);
basic_object<string_t>& operator|=(basic_object<string_t>&& rhs);
basic_object<string_t>& operator=(const basic_object<string_t>&) = default;
basic_object<string_t>& operator=(basic_object<string_t>&&) = default;
template <
typename value_t,
std::enable_if_t<std::is_convertible_v<value_t, basic_object<string_t>>, bool> = true>
basic_object<string_t>& operator=(value_t rhs)
{
return *this = basic_object<string_t>(std::move(rhs));
}
bool operator==(const basic_object<string_t>& rhs) const;
bool operator!=(const basic_object<string_t>& rhs) const { return !(*this == rhs); }
template <
typename value_t,
template <typename...> typename map_t = std::map,
std::enable_if_t<_utils::is_map<map_t<string_t, value_t>>, bool> = true>
explicit operator map_t<string_t, value_t>() const
{
return as_map<value_t, map_t>();
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_from_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_from_json_object_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() const&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().from_json(*this, dst)) {
throw exception("Wrong JSON");
}
return dst;
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_from_json_object_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() const&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().from_json_object(*this, dst)) {
throw exception("Wrong JSON");
}
return dst;
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_move_from_json_in_templ_spec<jsonization_t, string_t>::value
&& !_utils::has_move_from_json_object_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() &&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().from_json(std::move(*this), dst)) {
throw exception("Wrong JSON");
}
return dst;
}
template <
typename jsonization_t,
std::enable_if_t<
_utils::has_move_from_json_object_in_templ_spec<jsonization_t, string_t>::value,
bool> = true>
explicit operator jsonization_t() &&
{
jsonization_t dst {};
if (!ext::jsonization<string_t, jsonization_t>().move_from_json_object(
std::move(*this),
dst)) {
throw exception("Wrong JSON");
}
return dst;
}
private:
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
auto
get(std::tuple<key_then_default_value_t...> keys_then_default_value,
std::index_sequence<keys_indexes_t...>) const;
template <typename value_t, typename... rest_keys_t>
auto get_helper(const value_t& default_value, const string_t& key, rest_keys_t&&... rest) const;
template <typename value_t>
auto get_helper(const value_t& default_value, const string_t& key) const;
string_t format(size_t indent, size_t indent_times) const;
private:
raw_object _object_data;
};
template <typename string_t>
inline basic_object<string_t>::basic_object(std::initializer_list<value_type> init_list)
: _object_data(
std::make_move_iterator(init_list.begin()),
std::make_move_iterator(init_list.end()))
{
}
// template <typename string_t>
// inline basic_object<string_t>::basic_object(const basic_value<string_t>& val) :
// basic_object<string_t>(val.as_object())
//{}
//
// template <typename string_t>
// inline basic_object<string_t>::basic_object(basic_value<string_t>&& val)
// : basic_object<string_t>(std::move(val.as_object()))
//{}
template <typename string_t>
inline bool basic_object<string_t>::contains(const string_t& key) const
{
return _object_data.find(key) != _object_data.cend();
}
template <typename string_t>
inline const basic_value<string_t>& basic_object<string_t>::at(const string_t& key) const
{
return _object_data.at(key);
}
template <typename string_t>
inline void basic_object<string_t>::clear() noexcept
{
_object_data.clear();
}
template <typename string_t>
inline bool basic_object<string_t>::erase(const string_t& key)
{
return _object_data.erase(key) > 0 ? true : false;
}
template <typename string_t>
inline bool basic_object<string_t>::erase(iterator iter)
{
return _object_data.erase(iter) != _object_data.end();
}
template <typename string_t>
template <typename... args_t>
inline decltype(auto) basic_object<string_t>::emplace(args_t&&... args)
{
static_assert(
std::is_constructible_v<value_type, args_t...>,
"Parameter can't be used to construct a raw_object::value_type");
return _object_data.insert_or_assign(std::forward<args_t>(args)...);
}
template <typename string_t>
template <typename... args_t>
inline decltype(auto) basic_object<string_t>::insert(args_t&&... args)
{
return emplace(std::forward<args_t>(args)...);
}
template <typename string_t>
inline string_t basic_object<string_t>::to_string() const
{
string_t str { '{' };
for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) {
const auto& [key, val] = *iter;
str +=
char_t('"') + _utils::unescape_string(key) + string_t { '\"', ':' } + val.to_string();
if (++iter != _object_data.cend()) {
str += ',';
}
}
str += char_t('}');
return str;
}
template <typename string_t>
inline string_t basic_object<string_t>::format(size_t indent, size_t indent_times) const
{
const string_t tail_indent(indent * indent_times, ' ');
const string_t body_indent(indent * (indent_times + 1), ' ');
string_t str { '{', '\n' };
for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) {
const auto& [key, val] = *iter;
str += body_indent + char_t('"') + _utils::unescape_string(key)
+ string_t { '\"', ':', ' ' } + val.format(indent, indent_times + 1);
if (++iter != _object_data.cend()) {
str += ',';
}
str += '\n';
}
str += tail_indent + char_t('}');
return str;
}
template <typename string_t>
template <typename value_t>
inline bool basic_object<string_t>::all() const
{
for (const auto& [_, val] : _object_data) {
if (!val.template is<value_t>()) {
return false;
}
}
return true;
}
template <typename string_t>
template <typename value_t, template <typename...> typename map_t>
inline map_t<string_t, value_t> basic_object<string_t>::as_map() const
{
return as<map_t<string_t, value_t>>();
}
template <typename string_t>
template <typename... key_then_default_value_t>
inline auto basic_object<string_t>::get(key_then_default_value_t&&... keys_then_default_value) const
{
return get(
std::forward_as_tuple(keys_then_default_value...),
std::make_index_sequence<sizeof...(keys_then_default_value) - 1> {});
}
template <typename string_t>
template <typename... key_then_default_value_t, size_t... keys_indexes_t>
inline auto basic_object<string_t>::get(
std::tuple<key_then_default_value_t...> keys_then_default_value,
std::index_sequence<keys_indexes_t...>) const
{
constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1;
return get_helper(
std::get<default_value_index>(keys_then_default_value),
std::get<keys_indexes_t>(keys_then_default_value)...);
}
template <typename string_t>
template <typename value_t, typename... rest_keys_t>
inline auto basic_object<string_t>::get_helper(
const value_t& default_value,
const string_t& key,
rest_keys_t&&... rest) const
{
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|| std::is_same_v<basic_array<string_t>, value_t>
|| std::is_same_v<basic_object<string_t>, value_t>;
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
if (!contains(key)) {
if constexpr (is_string) {
return string_t(default_value);
}
else {
return value_t(default_value);
}
}
return at(key).get_helper(default_value, std::forward<rest_keys_t>(rest)...);
}
template <typename string_t>
template <typename value_t>
inline auto
basic_object<string_t>::get_helper(const value_t& default_value, const string_t& key) const
{
constexpr bool is_json = std::is_same_v<basic_value<string_t>, value_t>
|| std::is_same_v<basic_array<string_t>, value_t>
|| std::is_same_v<basic_object<string_t>, value_t>;
constexpr bool is_string = std::is_constructible_v<string_t, value_t> && !is_json;
if (!contains(key)) {
if constexpr (is_string) {
return string_t(default_value);
}
else {
return value_t(default_value);
}
}
auto val = _object_data.at(key);
if (val.template is<value_t>()) {
if constexpr (is_string) {
return val.template as<string_t>();
}
else {
return val.template as<value_t>();
}
}
else {
if constexpr (is_string) {
return string_t(default_value);
}
else {
return value_t(default_value);
}
}
}
template <typename string_t>
template <typename value_t>
inline std::optional<value_t> basic_object<string_t>::find(const string_t& key) const
{
auto iter = _object_data.find(key);
if (iter == _object_data.end()) {
return std::nullopt;
}
const auto& val = iter->second;
return val.template is<value_t>() ? std::optional<value_t>(val.template as<value_t>())
: std::nullopt;
}
template <typename string_t>
inline typename basic_object<string_t>::iterator basic_object<string_t>::begin() noexcept
{
return _object_data.begin();
}
template <typename string_t>
inline typename basic_object<string_t>::iterator basic_object<string_t>::end() noexcept
{
return _object_data.end();
}
template <typename string_t>
inline typename basic_object<string_t>::const_iterator
basic_object<string_t>::begin() const noexcept
{
return _object_data.begin();
}
template <typename string_t>
inline typename basic_object<string_t>::const_iterator basic_object<string_t>::end() const noexcept
{
return _object_data.end();
}
template <typename string_t>
inline typename basic_object<string_t>::const_iterator
basic_object<string_t>::cbegin() const noexcept
{
return _object_data.cbegin();
}
template <typename string_t>
inline typename basic_object<string_t>::const_iterator basic_object<string_t>::cend() const noexcept
{
return _object_data.cend();
}
template <typename string_t>
inline basic_value<string_t>& basic_object<string_t>::operator[](const string_t& key)
{
return _object_data[key];
}
template <typename string_t>
inline basic_value<string_t>& basic_object<string_t>::operator[](string_t&& key)
{
return _object_data[std::move(key)];
}
template <typename string_t>
inline basic_object<string_t>
basic_object<string_t>::operator|(const basic_object<string_t>& rhs) const&
{
basic_object<string_t> temp = *this;
temp._object_data.insert(rhs.begin(), rhs.end());
return temp;
}
template <typename string_t>
inline basic_object<string_t> basic_object<string_t>::operator|(basic_object<string_t>&& rhs) const&
{
basic_object<string_t> temp = *this;
// temp._object_data.merge(std::move(rhs._object_data));
temp._object_data.insert(
std::make_move_iterator(rhs.begin()),
std::make_move_iterator(rhs.end()));
return temp;
}
template <typename string_t>
inline basic_object<string_t>
basic_object<string_t>::operator|(const basic_object<string_t>& rhs) &&
{
_object_data.insert(rhs.begin(), rhs.end());
return std::move(*this);
}
template <typename string_t>
inline basic_object<string_t> basic_object<string_t>::operator|(basic_object<string_t>&& rhs) &&
{
//_object_data.merge(std::move(rhs._object_data));
_object_data.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
return std::move(*this);
}
template <typename string_t>
inline basic_object<string_t>& basic_object<string_t>::operator|=(const basic_object<string_t>& rhs)
{
_object_data.insert(rhs.begin(), rhs.end());
return *this;
}
template <typename string_t>
inline basic_object<string_t>& basic_object<string_t>::operator|=(basic_object<string_t>&& rhs)
{
_object_data.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
return *this;
}
template <typename string_t>
inline bool basic_object<string_t>::operator==(const basic_object<string_t>& rhs) const
{
return _object_data == rhs._object_data;
}
template <
typename ostream_t,
typename string_t,
typename std_ostream_t = std::basic_ostream<
typename string_t::value_type,
std::char_traits<typename string_t::value_type>>,
typename enable_t = std::enable_if_t<
std::is_same_v<std_ostream_t, ostream_t> || std::is_base_of_v<std_ostream_t, ostream_t>>>
ostream_t& operator<<(ostream_t& out, const basic_object<string_t>& obj)
{
out << obj.format();
return out;
}
} // namespace json

View File

@@ -1,207 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <type_traits>
#include "types.hpp"
#include "utils.hpp"
namespace json
{
namespace _serialization_helper
{
template <typename in_t, typename serializer_t>
class is_serializable
{
template <typename U>
static auto test(int)
-> decltype(std::declval<serializer_t>()(std::declval<U>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<in_t>(0))::value;
};
struct empty_serializer
{
// sample:
// json::value operator()(const type_1&) const { return ...; }
// json::value operator()(const type_2&) const { return ...; }
// json::value operator()(const type_3&) const { return ...; }
};
template <typename T>
void unable_to_serialize()
{
static_assert(
!sizeof(T),
"Unable to serialize T. "
#ifdef _MSC_VER
"See T below: " __FUNCSIG__
#else
// "See T below: " __PRETTY_FUNCTION__
#endif
);
}
}
namespace _serialization_helper
{
template <typename out_t, typename deserializer_t, typename string_t = default_string_t>
class is_deserializable
{
template <typename U>
static auto test(int)
-> decltype(std::declval<deserializer_t>()(std::declval<basic_value<string_t>>(), std::declval<U&>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<out_t>(0))::value;
};
struct empty_deserializer
{
// sample:
// bool operator()(const json::value&, type_1&) const { return ...; }
// bool operator()(const json::value&, type_2&) const { return ...; }
// bool operator()(const json::value&, type_3&) const { return ...; }
};
template <typename T>
void unable_to_deserialize()
{
static_assert(
!sizeof(T),
"Unable to deserialize T. "
#ifdef _MSC_VER
"See T below: " __FUNCSIG__
#else
// "See T below: " __PRETTY_FUNCTION__
#endif
);
}
}
template <
typename in_t,
typename serializer_t = _serialization_helper::empty_serializer,
typename string_t = default_string_t>
basic_value<string_t> serialize(in_t&& in, const serializer_t& serializer = {})
{
if constexpr (_serialization_helper::is_serializable<in_t, serializer_t>::value) {
return serializer(std::forward<in_t>(in));
}
else if constexpr (
_utils::is_collection<std::decay_t<in_t>> || _utils::is_fixed_array<std::decay_t<in_t>>) {
basic_array<string_t> arr;
for (auto&& elem : in) {
using elem_t = decltype(elem);
auto j_elem =
serialize<elem_t, serializer_t, string_t>(std::forward<elem_t>(elem), serializer);
arr.emplace_back(std::move(j_elem));
}
return arr;
}
else if constexpr (_utils::is_map<std::decay_t<in_t>>) {
basic_object<string_t> obj;
for (auto&& [key, elem] : in) {
using key_t = decltype(key);
using elem_t = decltype(elem);
auto j_elem =
serialize<elem_t, serializer_t, string_t>(std::forward<elem_t>(elem), serializer);
obj.emplace(std::forward<key_t>(key), std::move(j_elem));
}
return obj;
}
else if constexpr (std::is_constructible_v<basic_value<string_t>, in_t>) {
return basic_value<string_t>(std::forward<in_t>(in));
}
else {
_serialization_helper::unable_to_serialize<in_t>();
}
}
template <
typename out_t,
typename deserializer_t = _serialization_helper::empty_deserializer,
typename string_t = default_string_t>
bool deserialize(
const basic_value<string_t>& in,
out_t& out,
const deserializer_t& deserializer = {})
{
if constexpr (_serialization_helper::is_deserializable<out_t, deserializer_t>::value) {
return deserializer(in, out);
}
else if constexpr (_utils::is_collection<std::decay_t<out_t>>) {
if (!in.is_array()) {
return false;
}
for (auto&& j_elem : in.as_array()) {
using elem_t = typename out_t::value_type;
elem_t elem {};
if (!deserialize<elem_t, deserializer_t, string_t>(j_elem, elem, deserializer)) {
return false;
}
if constexpr (_as_collection_helper::has_emplace_back<out_t>::value) {
out.emplace_back(std::move(elem));
}
else {
out.emplace(std::move(elem));
}
}
return true;
}
else if constexpr (_utils::is_fixed_array<std::decay_t<out_t>>) {
if (!in.is_array()) {
return false;
}
auto&& in_as_arr = in.as_array();
constexpr size_t out_size = _utils::fixed_array_size<out_t>;
if (in_as_arr.size() != out_size) {
return false;
}
for (size_t i = 0; i < out_size; ++i) {
auto&& j_elem = in_as_arr.at(i);
using elem_t = typename out_t::value_type;
elem_t elem {};
if (!deserialize<elem_t, deserializer_t, string_t>(j_elem, elem, deserializer)) {
return false;
}
out.at(i) = std::move(elem);
}
return true;
}
else if constexpr (_utils::is_map<std::decay_t<out_t>>) {
if (!in.is_object()) {
return false;
}
for (auto&& [key, j_elem] : in.as_object()) {
using elem_t = typename out_t::mapped_type;
elem_t elem {};
if (!deserialize<elem_t, deserializer_t, string_t>(j_elem, elem, deserializer)) {
return false;
}
out.emplace(std::forward<decltype(key)>(key), std::move(elem));
}
return true;
}
else if constexpr (std::is_constructible_v<out_t, basic_value<string_t>>) {
out = out_t(in);
return true;
}
else {
_serialization_helper::unable_to_deserialize<out_t>();
}
}
} // namespace json

View File

@@ -1,7 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include "array.hpp"
#include "object.hpp"
#include "value.hpp"

View File

@@ -1,473 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <iomanip>
#include <limits>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>
#include <variant>
namespace json
{
template <typename string_t>
class basic_value;
template <typename string_t>
class basic_array;
template <typename string_t>
class basic_object;
using default_string_t = std::string;
using value = basic_value<default_string_t>;
using array = basic_array<default_string_t>;
using object = basic_object<default_string_t>;
using wvalue = basic_value<std::wstring>;
using warray = basic_array<std::wstring>;
using wobject = basic_object<std::wstring>;
}
namespace json::ext
{
template <typename string_t, typename T, typename = void>
class jsonization
{
public:
// json::value to_json(const T&) const;
// bool check_json(const json::value&) const;
// bool from_json(const json::value&, T&) const;
};
}
namespace json::_utils
{
template <typename T>
using iterator_t = decltype(std::declval<T&>().begin());
template <typename T>
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
template <typename T>
using iter_value_t = typename std::iterator_traits<remove_cvref_t<T>>::value_type;
template <typename R>
using range_value_t = iter_value_t<iterator_t<R>>;
template <typename T, typename = void>
constexpr bool is_string = false;
template <typename T>
constexpr bool is_string<T, std::void_t<typename T::traits_type>> =
std::is_same_v<typename T::traits_type, std::char_traits<typename T::value_type>>;
template <typename T, typename = void>
constexpr bool is_container = false;
template <typename T>
constexpr bool is_container<T, std::void_t<typename T::value_type, range_value_t<T>>> =
std::is_same_v<typename T::value_type, range_value_t<T>> && !is_string<T>;
template <typename T, typename = void>
constexpr bool is_map = false;
template <typename T>
constexpr bool is_map<T, std::void_t<typename T::key_type, typename T::mapped_type>> =
is_container<T>;
template <typename T, typename = void>
constexpr bool is_fixed_array = false;
template <template <typename, size_t> typename arr_t, typename value_t, size_t size>
constexpr bool is_fixed_array<arr_t<value_t, size>> = true;
template <typename T, typename = std::enable_if_t<is_fixed_array<T>>>
constexpr size_t fixed_array_size = 0;
template <template <typename, size_t> typename arr_t, typename value_t, size_t size>
constexpr size_t fixed_array_size<arr_t<value_t, size>> = size;
template <typename T, typename = void>
constexpr bool is_collection = false;
template <typename T>
constexpr bool is_collection<T> = is_container<T> && !is_map<T> && !is_fixed_array<T>;
template <typename T>
constexpr bool is_variant = false;
template <typename... args_t>
constexpr bool is_variant<std::variant<args_t...>> = true;
template <typename T>
constexpr bool is_tuple = false;
template <typename... args_t>
constexpr bool is_tuple<std::tuple<args_t...>> = true;
template <typename T>
constexpr bool is_pair = false;
template <typename... args_t>
constexpr bool is_pair<std::pair<args_t...>> = true;
template <typename T, typename = void>
constexpr bool is_tuple_like = false;
template <template <typename...> typename tuple_t, typename... args_t>
constexpr bool is_tuple_like<
tuple_t<args_t...>,
std::void_t<decltype(std::tuple_size<tuple_t<args_t...>>::value)>> =
std::tuple_size<tuple_t<args_t...>>::value == sizeof...(args_t);
template <typename T>
class has_emplace_back
{
template <typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T>
class has_to_json_in_member
{
template <typename U>
static auto test(int) -> decltype(std::declval<U>().to_json(), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_check_json_in_member
{
template <typename U>
static auto test(int)
-> decltype(std::declval<U>().check_json(std::declval<json::basic_value<string_t>>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_from_json_in_member
{
template <typename U>
static auto test(int)
-> decltype(std::declval<U>().from_json(std::declval<json::basic_value<string_t>>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_to_json_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().to_json(std::declval<U>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_check_json_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().check_json(std::declval<json::basic_value<string_t>>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_from_json_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().from_json(std::declval<json::basic_value<string_t>>(), std::declval<U&>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_move_to_json_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().move_to_json(std::declval<U>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_move_from_json_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().move_from_json(std::declval<json::basic_value<string_t>>(), std::declval<U&>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_to_json_array_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().to_json_array(std::declval<U>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_check_json_array_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().check_json_array(std::declval<json::basic_array<string_t>>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_from_json_array_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().from_json_array(std::declval<json::basic_array<string_t>>(), std::declval<U&>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_move_to_json_array_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().move_to_json_array(std::declval<U>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_move_from_json_array_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().move_from_json_array(std::declval<json::basic_array<string_t>>(), std::declval<U&>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_to_json_object_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().to_json_object(std::declval<U>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_check_json_object_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().check_json_object(std::declval<json::basic_object<string_t>>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_from_json_object_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().from_json_object(std::declval<json::basic_object<string_t>>(), std::declval<U&>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_move_to_json_object_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().move_to_json_object(std::declval<U>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename T, typename string_t>
class has_move_from_json_object_in_templ_spec
{
template <typename U>
static auto test(int)
-> decltype(std::declval<ext::jsonization<string_t, U>>().move_from_json_object(std::declval<json::basic_object<string_t>>(), std::declval<U&>()), std::true_type());
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(0))::value;
};
template <typename string_t>
inline constexpr string_t unescape_string(const string_t& str)
{
using char_t = typename string_t::value_type;
string_t result {};
auto cur = str.cbegin();
auto end = str.cend();
auto no_escape_beg = cur;
char_t escape = 0;
for (; cur != end; ++cur) {
switch (*cur) {
case '"':
escape = '"';
break;
case '\\':
escape = '\\';
break;
case '\b':
escape = 'b';
break;
case '\f':
escape = 'f';
break;
case '\n':
escape = 'n';
break;
case '\r':
escape = 'r';
break;
case '\t':
escape = 't';
break;
default:
break;
}
if (escape) {
result += string_t(no_escape_beg, cur) + char_t('\\') + escape;
no_escape_beg = cur + 1;
escape = 0;
}
}
result += string_t(no_escape_beg, cur);
return result;
}
template <typename string_t>
inline constexpr string_t true_string()
{
return { 't', 'r', 'u', 'e' };
}
template <typename string_t>
inline constexpr string_t false_string()
{
return { 'f', 'a', 'l', 's', 'e' };
}
template <typename string_t>
inline constexpr string_t null_string()
{
return { 'n', 'u', 'l', 'l' };
}
template <typename string_t, typename any_t>
inline string_t to_basic_string(any_t&& arg)
{
#ifdef MEOJSON_KEEP_FLOATING_PRECISION
using real_type = std::remove_reference_t<any_t>;
if constexpr (std::is_floating_point_v<real_type>) {
if constexpr (std::is_same_v<string_t, std::string>) {
std::ostringstream oss;
oss << std::setprecision(std::numeric_limits<real_type>::max_digits10) << arg;
return oss.str();
}
else if constexpr (std::is_same_v<string_t, std::wstring>) {
std::wostringstream oss;
oss << std::setprecision(std::numeric_limits<real_type>::max_digits10) << arg;
return oss.str();
}
}
#endif
if constexpr (std::is_same_v<string_t, std::string>) {
return std::to_string(std::forward<any_t>(arg));
}
else if constexpr (std::is_same_v<string_t, std::wstring>) {
return std::to_wstring(std::forward<any_t>(arg));
}
else {
static_assert(!sizeof(any_t), "Unsupported type");
}
}
} // namespace json::_utils
#include "../reflection/extensions.hpp"

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +0,0 @@
#pragma once
// IWYU pragma: begin_exports
#include "common/types.hpp"
#include "parser/parser.hpp"
#include "reflection/jsonization.hpp"
// IWYU pragma: end_exports

View File

@@ -1,139 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
#include <bit>
namespace json::_bitops
{
using std::countl_one;
using std::countl_zero;
using std::countr_one;
using std::countr_zero;
inline constexpr bool is_little_endian()
{
return std::endian::native == std::endian::little;
}
}
#else
#include <cstdint>
namespace json::_bitops
{
#if defined(__GNUC__) || defined(__clang__)
inline constexpr int countl_zero(uint32_t x)
{
if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) {
return x == 0 ? 32 : __builtin_clz(x);
}
if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) {
return x == 0 ? 32 : __builtin_clzl(x);
}
return x == 0 ? 32 : __builtin_clzll(x);
}
inline constexpr int countr_zero(uint32_t x)
{
if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) {
return x == 0 ? 32 : __builtin_ctz(x);
}
if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) {
return x == 0 ? 32 : __builtin_ctzl(x);
}
return x == 0 ? 32 : __builtin_ctzll(x);
}
inline constexpr int countl_zero(uint64_t x)
{
return x == 0 ? 64 : __builtin_clzll(x);
}
inline constexpr int countr_zero(uint64_t x)
{
return x == 0 ? 64 : __builtin_ctzll(x);
}
#elif defined(_MSC_VER)
#ifdef __AVX2__
// lzcnt intrinsics is not constexpr
inline int countl_zero(uint32_t x)
{
return __lzcnt(x);
}
inline int countr_zero(uint32_t x)
{
return _tzcnt_u32(x);
}
inline int countl_zero(uint64_t x)
{
return (int)__lzcnt64(x);
}
inline int countr_zero(uint64_t x)
{
return (int)_tzcnt_u64(x);
}
#else
inline constexpr int countl_zero(uint32_t x)
{
unsigned long index = 0;
return _BitScanReverse(&index, x) ? 31 - index : 32;
}
inline constexpr int countr_zero(uint32_t x)
{
unsigned long index = 0;
return _BitScanForward(&index, x) ? index : 32;
}
inline constexpr int countl_zero(uint64_t x)
{
unsigned long index = 0;
return _BitScanReverse64(&index, x) ? 63 - index : 64;
}
inline constexpr int countr_zero(uint64_t x)
{
unsigned long index = 0;
return _BitScanForward64(&index, x) ? index : 64;
}
#endif // __AVX2__
#else // compiler
#error "bring your own bit counting implementation"
#endif
inline int countl_one(uint32_t x)
{
return countl_zero(~x);
}
inline int countr_one(uint32_t x)
{
return countr_zero(~x);
}
inline int countl_one(uint64_t x)
{
return countl_zero(~x);
}
inline int countr_one(uint64_t x)
{
return countr_zero(~x);
}
// no constexpr endian awareness before C++20
inline bool is_little_endian()
{
union
{
uint32_t u32;
uint8_t u8;
} u = { 0x01020304 };
return u.u8 == 4;
}
} // namespace json::_bitops
#endif // C++20

View File

@@ -1,161 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <cstdint>
#include <cstring>
#include <type_traits>
#include "bitops.hpp"
#if defined(__GNUC__) || defined(__clang__)
#define __packed_bytes_strong_inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define __packed_bytes_strong_inline __forceinline
#else
#define __packed_bytes_strong_inline inline
#endif
namespace json::_packed_bytes
{
struct packed_bytes_trait_none
{
static constexpr bool available = false;
};
template <size_t N>
struct packed_bytes
{
using traits = packed_bytes_trait_none;
};
}
#ifndef MEOJSON_DISABLE_PACKED_BYTES
#if defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP)
#include "packed_bytes_x86.hpp"
#elif defined(__ARM_NEON) || defined(_M_ARM) || defined(_M_ARM64)
#include "packed_bytes_arm.hpp"
#endif
#endif
namespace json::_packed_bytes
{
struct packed_bytes_trait_uint64
{
static constexpr bool available = sizeof(void*) >= 8;
static constexpr auto step = 8;
using value_type = uint64_t;
__packed_bytes_strong_inline static value_type load_unaligned(const void* ptr)
{
value_type result;
memcpy((void*)&result, ptr, 8);
return result;
}
__packed_bytes_strong_inline static value_type less(value_type x, uint8_t n)
{
return (((x)-UINT64_C(0x0101010101010101) * (n)) & ~(x)&UINT64_C(0x8080808080808080));
}
__packed_bytes_strong_inline static value_type is_zero_memberwise(value_type v)
{
return (((v)-UINT64_C(0x0101010101010101)) & ~(v)&UINT64_C(0x8080808080808080));
}
__packed_bytes_strong_inline static bool is_all_zero(value_type v) { return v == UINT64_C(0); }
__packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n)
{
return is_zero_memberwise((x) ^ (UINT64_C(0x0101010101010101) * (n)));
}
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
{
return a | b;
}
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
{
if (_bitops::is_little_endian()) {
return _bitops::countr_zero(x) / 8;
}
else {
return _bitops::countl_zero(x) / 8;
}
}
};
struct packed_bytes_trait_uint32
{
static constexpr bool available = true;
static constexpr auto step = 4;
using value_type = uint32_t;
__packed_bytes_strong_inline static value_type load_unaligned(const void* ptr)
{
value_type result;
memcpy((void*)&result, ptr, 4);
return result;
}
__packed_bytes_strong_inline static value_type less(value_type x, uint8_t n)
{
return (((x) - ~UINT32_C(0) / 255 * (n)) & ~(x) & ~UINT32_C(0) / 255 * 128);
}
__packed_bytes_strong_inline static value_type is_zero_memberwise(value_type v)
{
return (((v)-UINT32_C(0x01010101)) & ~(v)&UINT32_C(0x80808080));
;
}
__packed_bytes_strong_inline static bool is_all_zero(value_type v) { return v == UINT32_C(0); }
__packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n)
{
return is_zero_memberwise((x) ^ (~UINT32_C(0) / 255 * (n)));
}
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
{
return a | b;
}
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
{
if (_bitops::is_little_endian()) {
return _bitops::countr_zero(x) / 8;
}
else {
return _bitops::countl_zero(x) / 8;
}
}
};
template <>
struct packed_bytes<8>
{
using traits = packed_bytes_trait_uint64;
};
template <>
struct packed_bytes<4>
{
using traits = packed_bytes_trait_uint32;
};
template <size_t N>
using packed_bytes_trait = typename packed_bytes<N>::traits;
using packed_bytes_trait_max = std::conditional_t<
packed_bytes_trait<32>::available,
packed_bytes_trait<32>,
std::conditional_t<
packed_bytes_trait<16>::available,
packed_bytes_trait<16>,
std::conditional_t<
packed_bytes_trait<8>::available,
packed_bytes_trait<8>,
packed_bytes_trait<4>>>>;
} // namespace json::_packed_bytes

View File

@@ -1,79 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
// current NEON implementation doesn't outperform 64-bit scalar implementation
#ifdef MEOJSON_ENABLE_NEON
#include "packed_bytes.hpp"
#include <arm_neon.h>
#if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
#define __packed_bytes_trait_arm64
#endif
namespace json::_packed_bytes
{
struct packed_bytes_trait_neon
{
static constexpr bool available = true;
static constexpr auto step = 16;
using value_type = uint8x16_t;
__packed_bytes_strong_inline static value_type load_unaligned(const void* ptr)
{
return vld1q_u8((uint8_t*)ptr);
}
__packed_bytes_strong_inline static value_type less(value_type x, uint8_t n)
{
auto bcast = vdupq_n_u8(n);
auto is_less = vcltq_u8(x, bcast);
return is_less;
}
__packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n)
{
return vceqq_u8(x, vdupq_n_u8(n));
}
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y)
{
return vceqq_u8(x, y);
}
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
{
return vorrq_u8(a, b);
}
__packed_bytes_strong_inline static bool is_all_zero(value_type x)
{
#ifdef __packed_bytes_trait_arm64
return vmaxvq_u8(x) == 0;
#else
auto fold64 = vorr_u64(
vget_high_u64(vreinterpretq_u8_u64(x), 0),
vget_low_u64(vreinterpretq_u8_u64(x), 1));
auto fold32 = vget_lane_u32(vreinterpret_u64_u32(fold64), 0)
| vget_lane_u32(vreinterpret_u64_u32(fold64), 1);
return fold32 == 0;
#endif
}
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
{
// https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
auto cmp = equal(x, 0);
auto res = vshrn_n_u16(cmp, 4);
auto mask64 = vget_lane_u64(vreinterpret_u64_u8(res), 0);
return _bitops::countr_one(mask64) >> 2;
}
};
template <>
struct packed_bytes<16>
{
using traits = packed_bytes_trait_neon;
};
}
#endif

View File

@@ -1,140 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include "packed_bytes.hpp"
#include <emmintrin.h>
#if defined(__SSE4_1__) || defined(__AVX2__) || defined(_MSC_VER)
// MSVC enables all SSE4.1 intrinsics by default
#include <smmintrin.h>
#endif
namespace json::_packed_bytes
{
struct packed_bytes_trait_sse
{
static constexpr bool available = true;
static constexpr auto step = 16;
using value_type = __m128i;
__packed_bytes_strong_inline static value_type load_unaligned(const void* ptr)
{
return _mm_loadu_si128(reinterpret_cast<const __m128i*>(ptr));
}
__packed_bytes_strong_inline static value_type less(value_type x, uint8_t n)
{
auto bcast = _mm_set1_epi8(static_cast<char>(n));
auto all1 = _mm_set1_epi8(-1);
auto max_with_n = _mm_max_epu8(x, bcast);
auto is_greater_or_equal = _mm_cmpeq_epi8(max_with_n, x);
auto is_less = _mm_andnot_si128(is_greater_or_equal, all1);
return is_less;
}
__packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n)
{
return _mm_cmpeq_epi8(x, _mm_set1_epi8(static_cast<char>(n)));
}
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y)
{
return _mm_cmpeq_epi8(x, y);
}
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
{
return _mm_or_si128(a, b);
}
__packed_bytes_strong_inline static bool is_all_zero(value_type x)
{
#if defined(__SSE4_1__) || defined(__AVX2__) || defined(_MSC_VER)
// SSE4.1 path
return !!_mm_testz_si128(x, x);
#else
// SSE2 path
auto cmp = _mm_cmpeq_epi8(x, _mm_set1_epi8(0));
auto mask = (uint16_t)_mm_movemask_epi8(cmp);
return mask == UINT16_C(0xFFFF);
#endif
}
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
{
auto cmp = _mm_cmpeq_epi8(x, _mm_set1_epi8(0));
auto mask = (uint16_t)_mm_movemask_epi8(cmp);
return _bitops::countr_one((uint32_t)mask);
}
};
template <>
struct packed_bytes<16>
{
using traits = packed_bytes_trait_sse;
};
}
#ifdef __AVX2__
#include <immintrin.h>
namespace json::_packed_bytes
{
struct packed_bytes_trait_avx2
{
static constexpr bool available = true;
static constexpr auto step = 32;
using value_type = __m256i;
__packed_bytes_strong_inline static value_type load_unaligned(const void* ptr)
{
return _mm256_loadu_si256(reinterpret_cast<const __m256i*>(ptr));
}
__packed_bytes_strong_inline static value_type less(value_type x, uint8_t n)
{
auto bcast = _mm256_set1_epi8(static_cast<char>(n));
auto all1 = _mm256_set1_epi8(-1);
auto max_with_n = _mm256_max_epu8(x, bcast);
auto is_greater_or_equal = _mm256_cmpeq_epi8(max_with_n, x);
auto is_less = _mm256_andnot_si256(is_greater_or_equal, all1);
return is_less;
}
__packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n)
{
return _mm256_cmpeq_epi8(x, _mm256_set1_epi8(static_cast<char>(n)));
}
__packed_bytes_strong_inline static value_type equal(value_type x, value_type y)
{
return _mm256_cmpeq_epi8(x, y);
}
__packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b)
{
return _mm256_or_si256(a, b);
}
__packed_bytes_strong_inline static bool is_all_zero(value_type x)
{
return (bool)_mm256_testz_si256(x, x);
}
__packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x)
{
auto cmp = _mm256_cmpeq_epi8(x, _mm256_set1_epi8(0));
auto mask = (uint32_t)_mm256_movemask_epi8(cmp);
// AVX512 alternative: _mm_cmpeq_epi8_mask
return _bitops::countr_one(mask);
}
};
template <>
struct packed_bytes<32>
{
using traits = packed_bytes_trait_avx2;
};
}
#endif

View File

@@ -1,862 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <cctype>
#include <fstream>
#include <optional>
#include <ostream>
#include <string>
#include <tuple>
#include "../common/types.hpp"
#include "packed_bytes.hpp"
namespace json
{
// ****************************
// * parser declare *
// ****************************
template <
bool accept_jsonc = false,
typename string_t = default_string_t,
typename parsing_t = void,
typename accel_traits = _packed_bytes::packed_bytes_trait_max>
class parser
{
public:
using parsing_iter_t = typename parsing_t::const_iterator;
public:
~parser() noexcept = default;
static std::optional<basic_value<string_t>> parse(const parsing_t& content);
private:
parser(parsing_iter_t cbegin, parsing_iter_t cend) noexcept
: _cur(cbegin)
, _end(cend)
{
;
}
std::optional<basic_value<string_t>> parse();
basic_value<string_t> parse_value();
basic_value<string_t> parse_null();
basic_value<string_t> parse_boolean();
basic_value<string_t> parse_number();
// parse and return a basic_value<string_t> whose type is value_type::string
basic_value<string_t> parse_string();
basic_value<string_t> parse_array();
basic_value<string_t> parse_object();
// parse and return a string_t
std::optional<string_t> parse_stdstring();
bool skip_string_literal_with_accel();
bool skip_whitespace() noexcept;
bool skip_comment() noexcept;
bool skip_digit();
bool skip_unicode_escape(uint16_t& pair_high, string_t& result);
private:
parsing_iter_t _cur;
parsing_iter_t _end;
};
// ***************************
// * utils declare *
// ***************************
template <typename parsing_t>
auto parse(const parsing_t& content);
template <typename char_t>
auto parse(char_t* content);
template <typename parsing_t>
auto parsec(const parsing_t& content);
template <typename char_t>
auto parsec(char_t* content);
template <
typename istream_t,
typename = std::enable_if_t<
std::is_base_of_v<std::basic_istream<typename istream_t::char_type>, istream_t>>>
auto parse(istream_t& istream, bool check_bom = false, bool with_commets = false);
template <typename ifstream_t = std::ifstream, typename path_t = void>
auto open(const path_t& path, bool check_bom = false, bool with_commets = false);
namespace literals
{
value operator""_json(const char* str, size_t len);
wvalue operator""_json(const wchar_t* str, size_t len);
value operator""_jvalue(const char* str, size_t len);
wvalue operator""_jvalue(const wchar_t* str, size_t len);
array operator""_jarray(const char* str, size_t len);
warray operator""_jarray(const wchar_t* str, size_t len);
object operator""_jobject(const char* str, size_t len);
wobject operator""_jobject(const wchar_t* str, size_t len);
}
template <typename string_t = default_string_t>
const basic_value<string_t> invalid_value();
// *************************
// * parser impl *
// *************************
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline std::optional<basic_value<string_t>>
parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse(const parsing_t& content)
{
return parser<accept_jsonc, string_t, parsing_t, accel_traits>(content.cbegin(), content.cend())
.parse();
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline std::optional<basic_value<string_t>>
parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse()
{
if (!skip_whitespace()) {
return std::nullopt;
}
basic_value<string_t> result_value;
switch (*_cur) {
case '[':
result_value = parse_array();
break;
case '{':
result_value = parse_object();
break;
default: // A JSON payload should be an basic_object or basic_array
return std::nullopt;
}
if (!result_value.valid()) {
return std::nullopt;
}
// After the parsing is complete, there should be no more content other than spaces behind
if (skip_whitespace()) {
return std::nullopt;
}
return result_value;
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline basic_value<string_t> parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_value()
{
switch (*_cur) {
case 'n':
return parse_null();
case 't':
case 'f':
return parse_boolean();
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return parse_number();
case '"':
return parse_string();
case '[':
return parse_array();
case '{':
return parse_object();
default:
return invalid_value<string_t>();
}
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline basic_value<string_t> parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_null()
{
for (const auto& ch : _utils::null_string<string_t>()) {
if (_cur != _end && *_cur == ch) {
++_cur;
}
else {
return invalid_value<string_t>();
}
}
return basic_value<string_t>();
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline basic_value<string_t>
parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_boolean()
{
switch (*_cur) {
case 't':
for (const auto& ch : _utils::true_string<string_t>()) {
if (_cur != _end && *_cur == ch) {
++_cur;
}
else {
return invalid_value<string_t>();
}
}
return true;
case 'f':
for (const auto& ch : _utils::false_string<string_t>()) {
if (_cur != _end && *_cur == ch) {
++_cur;
}
else {
return invalid_value<string_t>();
}
}
return false;
default:
return invalid_value<string_t>();
}
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline basic_value<string_t> parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_number()
{
const auto first = _cur;
if (*_cur == '-') {
++_cur;
}
// numbers cannot have leading zeroes
if (_cur != _end && *_cur == '0' && _cur + 1 != _end && std::isdigit(*(_cur + 1))) {
return invalid_value<string_t>();
}
if (!skip_digit()) {
return invalid_value<string_t>();
}
if (*_cur == '.') {
++_cur;
if (!skip_digit()) {
return invalid_value<string_t>();
}
}
if (*_cur == 'e' || *_cur == 'E') {
if (++_cur == _end) {
return invalid_value<string_t>();
}
if (*_cur == '+' || *_cur == '-') {
++_cur;
}
if (!skip_digit()) {
return invalid_value<string_t>();
}
}
return basic_value<string_t>(basic_value<string_t>::value_type::number, string_t(first, _cur));
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline basic_value<string_t> parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_string()
{
auto string_opt = parse_stdstring();
if (!string_opt) {
return invalid_value<string_t>();
}
return basic_value<string_t>(
basic_value<string_t>::value_type::string,
std::move(string_opt).value());
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline basic_value<string_t> parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_array()
{
if (*_cur == '[') {
++_cur;
}
else {
return invalid_value<string_t>();
}
if (!skip_whitespace()) {
return invalid_value<string_t>();
}
else if (*_cur == ']') {
++_cur;
// empty basic_array
return basic_array<string_t>();
}
typename basic_array<string_t>::raw_array result;
while (true) {
if (!skip_whitespace()) {
return invalid_value<string_t>();
}
if constexpr (accept_jsonc) {
if (*_cur == ']') {
break;
}
}
basic_value<string_t> val = parse_value();
if (!val.valid() || !skip_whitespace()) {
return invalid_value<string_t>();
}
result.emplace_back(std::move(val));
if (*_cur == ',') {
++_cur;
}
else {
break;
}
}
if (skip_whitespace() && *_cur == ']') {
++_cur;
}
else {
return invalid_value<string_t>();
}
return basic_array<string_t>(std::move(result));
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline basic_value<string_t> parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_object()
{
if (*_cur == '{') {
++_cur;
}
else {
return invalid_value<string_t>();
}
if (!skip_whitespace()) {
return invalid_value<string_t>();
}
else if (*_cur == '}') {
++_cur;
// empty basic_object
return basic_object<string_t>();
}
typename basic_object<string_t>::raw_object result;
while (true) {
if (!skip_whitespace()) {
return invalid_value<string_t>();
}
if constexpr (accept_jsonc) {
if (*_cur == '}') {
break;
}
}
auto key_opt = parse_stdstring();
if (key_opt && skip_whitespace() && *_cur == ':') {
++_cur;
}
else {
return invalid_value<string_t>();
}
if (!skip_whitespace()) {
return invalid_value<string_t>();
}
basic_value<string_t> val = parse_value();
if (!val.valid() || !skip_whitespace()) {
return invalid_value<string_t>();
}
auto emplaced = result.emplace(std::move(*key_opt), std::move(val)).second;
if (!emplaced) {
return invalid_value<string_t>();
}
if (*_cur == ',') {
++_cur;
}
else {
break;
}
}
if (skip_whitespace() && *_cur == '}') {
++_cur;
}
else {
return invalid_value<string_t>();
}
return basic_object<string_t>(std::move(result));
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline std::optional<string_t>
parser<accept_jsonc, string_t, parsing_t, accel_traits>::parse_stdstring()
{
if (*_cur == '"') {
++_cur;
}
else {
return std::nullopt;
}
string_t result;
auto no_escape_beg = _cur;
uint16_t pair_high = 0;
while (_cur != _end) {
if constexpr (sizeof(*_cur) == 1 && accel_traits::available) {
if (!skip_string_literal_with_accel()) {
return std::nullopt;
}
}
switch (*_cur) {
case '\t':
case '\r':
case '\n':
return std::nullopt;
case '\\': {
result += string_t(no_escape_beg, _cur++);
if (_cur == _end) {
return std::nullopt;
}
if (pair_high && *_cur != 'u') {
return std::nullopt;
}
switch (*_cur) {
case '"':
result.push_back('"');
break;
case '\\':
result.push_back('\\');
break;
case '/':
result.push_back('/');
break;
case 'b':
result.push_back('\b');
break;
case 'f':
result.push_back('\f');
break;
case 'n':
result.push_back('\n');
break;
case 'r':
result.push_back('\r');
break;
case 't':
result.push_back('\t');
break;
case 'u':
if (!skip_unicode_escape(pair_high, result)) {
return std::nullopt;
}
break;
default:
// Illegal backslash escape
return std::nullopt;
}
no_escape_beg = ++_cur;
break;
}
case '"': {
if (pair_high) {
return std::nullopt;
}
result += string_t(no_escape_beg, _cur++);
return result;
}
default:
if (pair_high) {
return std::nullopt;
}
++_cur;
break;
}
}
return std::nullopt;
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline bool parser<accept_jsonc, string_t, parsing_t, accel_traits>::skip_unicode_escape(
uint16_t& pair_high,
string_t& result)
{
uint16_t cp = 0;
for (int i = 0; i < 4; ++i) {
if (++_cur == _end) {
return false;
}
if (!std::isxdigit(static_cast<unsigned char>(*_cur))) {
return false;
}
cp <<= 4;
if ('0' <= *_cur && *_cur <= '9') {
cp |= *_cur - '0';
}
else if ('a' <= *_cur && *_cur <= 'f') {
cp |= *_cur - 'a' + 10;
}
else if ('A' <= *_cur && *_cur <= 'F') {
cp |= *_cur - 'A' + 10;
}
else {
return false;
}
}
uint32_t ext_cp = cp;
uint16_t hi_cp = 0, lo_cp = 0;
if (0xD800 <= cp && cp <= 0xDBFF) {
if (pair_high) {
return false;
}
pair_high = cp;
return true;
}
if (0xDC00 <= cp && cp <= 0xDFFF) {
if (!pair_high) {
return false;
}
ext_cp = (((pair_high - 0xD800) << 10) | (cp - 0xDC00)) + 0x10000;
hi_cp = pair_high;
lo_cp = cp;
pair_high = 0;
}
if constexpr (std::is_same_v<typename string_t::value_type, char>) {
// utf8
if (ext_cp <= 0x7F) {
result.push_back(static_cast<char>(ext_cp));
}
else if (ext_cp <= 0x7FF) {
result.push_back(static_cast<char>(((ext_cp >> 6) & 0b00011111) | 0b11000000u));
result.push_back(static_cast<char>((ext_cp & 0b00111111) | 0b10000000u));
}
else if (ext_cp <= 0xFFFF) {
result.push_back(static_cast<char>(((ext_cp >> 12) & 0b00001111) | 0b11100000u));
result.push_back(static_cast<char>(((ext_cp >> 6) & 0b00111111) | 0b10000000u));
result.push_back(static_cast<char>((ext_cp & 0b00111111) | 0b10000000u));
}
else {
result.push_back(static_cast<char>(((ext_cp >> 18) & 0b00000111) | 0b11110000u));
result.push_back(static_cast<char>(((ext_cp >> 12) & 0b00111111) | 0b10000000u));
result.push_back(static_cast<char>(((ext_cp >> 6) & 0b00111111) | 0b10000000u));
result.push_back(static_cast<char>((ext_cp & 0b00111111) | 0b10000000u));
}
}
else if constexpr (std::is_same_v<typename string_t::value_type, wchar_t>) {
if constexpr (sizeof(wchar_t) == 4) {
result.push_back(static_cast<wchar_t>(ext_cp));
}
else if constexpr (sizeof(wchar_t) == 2) {
if (ext_cp <= 0xFFFF) {
result.push_back(static_cast<wchar_t>(ext_cp));
}
else {
result.push_back(static_cast<wchar_t>(hi_cp));
result.push_back(static_cast<wchar_t>(lo_cp));
}
}
else {
static_assert(!sizeof(typename string_t::value_type), "Unsupported wchar");
}
}
else {
static_assert(!sizeof(typename string_t::value_type), "Unsupported type");
}
return true;
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline bool
parser<accept_jsonc, string_t, parsing_t, accel_traits>::skip_string_literal_with_accel()
{
if constexpr (sizeof(*_cur) != 1) {
return false;
}
while (_end - _cur >= accel_traits::step) {
auto pack = accel_traits::load_unaligned(&(*_cur));
auto result = accel_traits::less(pack, 32);
result =
accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast<uint8_t>('"')));
result =
accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast<uint8_t>('\\')));
if (accel_traits::is_all_zero(result)) {
_cur += accel_traits::step;
}
else {
auto index = accel_traits::first_nonzero_byte(result);
_cur += index;
break;
}
}
return _cur != _end;
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline bool parser<accept_jsonc, string_t, parsing_t, accel_traits>::skip_whitespace() noexcept
{
while (_cur != _end) {
switch (*_cur) {
case ' ':
case '\t':
case '\r':
case '\n':
++_cur;
break;
case '/':
if constexpr (accept_jsonc) {
if (!skip_comment()) {
return false;
}
// else continue;
}
else {
return false;
}
break;
case '\0':
return false;
default:
return true;
}
}
return false;
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
bool json::parser<accept_jsonc, string_t, parsing_t, accel_traits>::skip_comment() noexcept
{
if (_cur == _end || *_cur != '/') {
return false;
}
if (++_cur == _end) {
return false;
}
enum class comment_type
{
invalid,
line,
block,
} t = comment_type::invalid;
switch (*_cur++) {
case '/':
t = comment_type::line;
break;
case '*':
t = comment_type::block;
break;
default:
return false;
}
while (_cur != _end) {
switch (*_cur++) {
case '\n':
if (t == comment_type::line) {
return true;
}
break;
case '*':
if (t == comment_type::block && _cur != _end && *_cur == '/') {
++_cur;
return true;
}
break;
default:
break;
}
}
// _cur == _end
return t == comment_type::line;
}
template <bool accept_jsonc, typename string_t, typename parsing_t, typename accel_traits>
inline bool parser<accept_jsonc, string_t, parsing_t, accel_traits>::skip_digit()
{
// At least one digit
if (_cur != _end && std::isdigit(*_cur)) {
++_cur;
}
else {
return false;
}
while (_cur != _end && std::isdigit(*_cur)) {
++_cur;
}
if (_cur != _end) {
return true;
}
else {
return false;
}
}
// *************************
// * utils impl *
// *************************
template <typename parsing_t>
auto parse(const parsing_t& content)
{
using string_t = std::basic_string<typename parsing_t::value_type>;
return parser<false, string_t, parsing_t>::parse(content);
}
template <typename char_t>
auto parse(char_t* content)
{
return parse(std::basic_string_view<std::decay_t<char_t>> { content });
}
template <typename istream_t, typename _>
auto parse(istream_t& ifs, bool check_bom, bool with_commets)
{
using string_t = std::basic_string<typename istream_t::char_type>;
ifs.seekg(0, std::ios::end);
auto file_size = ifs.tellg();
ifs.seekg(0, std::ios::beg);
string_t str(file_size, '\0');
ifs.read(str.data(), file_size);
if (check_bom) {
using uchar = unsigned char;
static constexpr uchar Bom_0 = 0xEF;
static constexpr uchar Bom_1 = 0xBB;
static constexpr uchar Bom_2 = 0xBF;
if (str.size() >= 3 && static_cast<uchar>(str.at(0)) == Bom_0
&& static_cast<uchar>(str.at(1)) == Bom_1 && static_cast<uchar>(str.at(2)) == Bom_2) {
str.assign(str.begin() + 3, str.end());
}
}
return with_commets ? parsec(str) : parse(str);
}
template <typename ifstream_t, typename path_t>
auto open(const path_t& filepath, bool check_bom, bool with_commets)
{
using char_t = typename ifstream_t::char_type;
using string_t = std::basic_string<char_t>;
using json_t = json::basic_value<string_t>;
using return_t = std::optional<json_t>;
ifstream_t ifs(filepath, std::ios::in);
if (!ifs.is_open()) {
return return_t(std::nullopt);
}
auto opt = parse(ifs, check_bom, with_commets);
ifs.close();
return opt;
}
template <typename parsing_t>
auto parsec(const parsing_t& content)
{
using string_t = std::basic_string<typename parsing_t::value_type>;
return parser<true, string_t, parsing_t>::parse(content);
}
template <typename char_t>
auto parsec(char_t* content)
{
return parsec(std::basic_string_view<std::decay_t<char_t>> { content });
}
namespace literals
{
inline value operator""_json(const char* str, size_t len)
{
return operator""_jvalue(str, len);
}
inline wvalue operator""_json(const wchar_t* str, size_t len)
{
return operator""_jvalue(str, len);
}
inline value operator""_jvalue(const char* str, size_t len)
{
return parse(std::string_view(str, len)).value_or(value());
}
inline wvalue operator""_jvalue(const wchar_t* str, size_t len)
{
return parse(std::wstring_view(str, len)).value_or(wvalue());
}
inline array operator""_jarray(const char* str, size_t len)
{
auto val = parse(std::string_view(str, len)).value_or(value());
return val.is_array() ? val.as_array() : array();
}
inline warray operator""_jarray(const wchar_t* str, size_t len)
{
auto val = parse(std::wstring_view(str, len)).value_or(wvalue());
return val.is_array() ? val.as_array() : warray();
}
inline object operator""_jobject(const char* str, size_t len)
{
auto val = parse(std::string_view(str, len)).value_or(value());
return val.is_object() ? val.as_object() : object();
}
inline wobject operator""_jobject(const wchar_t* str, size_t len)
{
auto val = parse(std::wstring_view(str, len)).value_or(wvalue());
return val.is_object() ? val.as_object() : wobject();
}
} // namespace literals
template <typename string_t>
const basic_value<string_t> invalid_value()
{
return basic_value<string_t>(
basic_value<string_t>::value_type::invalid,
typename basic_value<string_t>::var_t());
}
} // namespace json

View File

@@ -1,656 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <cstddef>
#include <filesystem>
#include <queue>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
#include "../common/types.hpp"
namespace json::ext
{
template <typename string_t, typename impl_t, typename var_t, size_t len> // (size_t)-1 for no
// restriction
class __jsonization_array
{
public:
json::basic_value<string_t> to_json(const var_t& value) const
{
return static_cast<const impl_t*>(this)->to_json_array(value);
}
bool check_json(const json::basic_value<string_t>& json) const
{
if (!json.is_array()) {
return false;
}
const auto& arr = json.as_array();
if constexpr (len != static_cast<size_t>(-1)) {
if (len != arr.size()) {
return false;
}
}
return static_cast<const impl_t*>(this)->check_json_array(arr);
}
bool from_json(const json::basic_value<string_t>& json, var_t& value) const
{
if (!json.is_array()) {
return false;
}
const auto& arr = json.as_array();
if constexpr (len != static_cast<size_t>(-1)) {
if (len != arr.size()) {
return false;
}
}
return static_cast<const impl_t*>(this)->from_json_array(arr, value);
}
json::basic_value<string_t> move_to_json(var_t value) const
{
return static_cast<const impl_t*>(this)->move_to_json_array(std::move(value));
}
bool move_from_json(json::basic_value<string_t> json, var_t& value) const
{
if (!json.is_array()) {
return false;
}
auto& arr = json.as_array();
if constexpr (len != static_cast<size_t>(-1)) {
if (len != arr.size()) {
return false;
}
}
return static_cast<const impl_t*>(this)->move_from_json_array(std::move(arr), value);
}
};
template <typename string_t, typename impl_t, typename var_t>
class __jsonization_object
{
public:
json::basic_value<string_t> to_json(const var_t& value) const
{
return static_cast<const impl_t*>(this)->to_json_object(value);
}
bool check_json(const json::basic_value<string_t>& json) const
{
if (!json.is_object()) {
return false;
}
const auto& obj = json.as_object();
return static_cast<const impl_t*>(this)->check_json_object(obj);
}
bool from_json(const json::basic_value<string_t>& json, var_t& value) const
{
if (!json.is_object()) {
return false;
}
const auto& obj = json.as_object();
return static_cast<const impl_t*>(this)->from_json_object(obj, value);
}
json::basic_value<string_t> move_to_json(var_t value) const
{
return static_cast<const impl_t*>(this)->move_to_json_object(std::move(value));
}
bool move_from_json(json::basic_value<string_t> json, var_t& value) const
{
if (!json.is_object()) {
return false;
}
auto& obj = json.as_object();
return static_cast<const impl_t*>(this)->move_from_json_object(std::move(obj), value);
}
};
template <typename string_t>
class jsonization<string_t, std::nullptr_t>
{
public:
json::basic_value<string_t> to_json(const std::nullptr_t&) const
{
return json::basic_value<string_t> {};
}
bool check_json(const json::basic_value<string_t>& json) const { return json.is_null(); }
bool from_json(const json::basic_value<string_t>& json, std::nullptr_t&)
{
return check_json(json);
}
};
template <typename string_t>
class jsonization<
string_t,
std::filesystem::path,
std::enable_if_t<
std::is_same_v<string_t, std::filesystem::path::string_type>
|| std::is_same_v<string_t, std::string>>>
{
public:
json::basic_value<string_t> to_json(const std::filesystem::path& path) const
{
if constexpr (std::is_same_v<string_t, std::filesystem::path::string_type>) {
return path.native();
}
else if constexpr (std::is_same_v<string_t, std::string>) {
#if __cplusplus >= 202002L
std::u8string u8str = path.u8string();
return std::string { u8str.begin(), u8str.end() };
#else
return path.u8string();
#endif
}
#if __cplusplus >= 202002L
else if constexpr (std::is_same_v<string_t, std::u8string>) {
return path.u8string();
}
#endif
}
bool check_json(const json::basic_value<string_t>& json) const { return json.is_string(); }
bool from_json(const json::basic_value<string_t>& json, std::filesystem::path& path) const
{
path = json.as_string();
return true;
}
};
template <
typename string_t,
template <typename, size_t> typename arr_t,
typename value_t,
size_t size>
class jsonization<string_t, arr_t<value_t, size>>
: public __jsonization_array<
string_t,
jsonization<string_t, arr_t<value_t, size>>,
arr_t<value_t, size>,
size>
{
public:
json::basic_array<string_t> to_json_array(const arr_t<value_t, size>& value) const
{
json::basic_array<string_t> result;
for (size_t i = 0; i < size; i++) {
result.emplace_back(value.at(i));
}
return result;
}
bool check_json_array(const json::basic_array<string_t>& arr) const
{
return arr.template all<value_t>();
}
bool from_json_array(const json::basic_array<string_t>& arr, arr_t<value_t, size>& value) const
{
if (!check_json_array(arr)) {
return false;
}
for (size_t i = 0; i < size; i++) {
value.at(i) = arr[i].template as<value_t>();
}
return true;
}
json::basic_array<string_t> move_to_json_array(arr_t<value_t, size> value) const
{
json::basic_array<string_t> result;
for (size_t i = 0; i < size; i++) {
result.emplace_back(std::move(value.at(i)));
}
return result;
}
bool move_from_json_array(json::basic_array<string_t> arr, arr_t<value_t, size>& value) const
{
if (!check_json_array(arr)) {
return false;
}
for (size_t i = 0; i < size; i++) {
value.at(i) = std::move(arr[i]).template as<value_t>();
}
return true;
}
};
template <typename string_t, typename collection_t>
class jsonization<string_t, collection_t, std::enable_if_t<_utils::is_collection<collection_t>>>
: public __jsonization_array<
string_t,
jsonization<string_t, collection_t>,
collection_t,
(size_t)-1>
{
public:
json::basic_array<string_t> to_json_array(const collection_t& value) const
{
json::basic_array<string_t> result;
for (const auto& val : value) {
result.emplace_back(val);
}
return result;
}
bool check_json_array(const json::basic_array<string_t>& arr) const
{
return arr.template all<typename collection_t::value_type>();
}
bool from_json_array(const json::basic_array<string_t>& arr, collection_t& value) const
{
if (!check_json_array(arr)) {
return false;
}
value = {};
for (const auto& val : arr) {
if constexpr (_utils::has_emplace_back<collection_t>::value) {
value.emplace_back(val.template as<typename collection_t::value_type>());
}
else {
value.emplace(val.template as<typename collection_t::value_type>());
}
}
return true;
}
json::basic_array<string_t> move_to_json_array(collection_t value) const
{
json::basic_array<string_t> result;
for (auto& val : value) {
result.emplace_back(std::move(val));
}
return result;
}
bool move_from_json_array(json::basic_array<string_t> arr, collection_t& value) const
{
if (!check_json_array(arr)) {
return false;
}
for (auto& val : arr) {
if constexpr (_utils::has_emplace_back<collection_t>::value) {
value.emplace_back(std::move(val).template as<typename collection_t::value_type>());
}
else {
value.emplace(std::move(val).template as<typename collection_t::value_type>());
}
}
return true;
}
};
template <typename string_t, template <typename...> typename tuple_t, typename... args_t>
class jsonization<
string_t,
tuple_t<args_t...>,
std::enable_if_t<_utils::is_tuple_like<tuple_t<args_t...>>>>
: public __jsonization_array<
string_t,
jsonization<string_t, tuple_t<args_t...>>,
tuple_t<args_t...>,
std::tuple_size_v<tuple_t<args_t...>>>
{
public:
constexpr static size_t tuple_size = std::tuple_size_v<tuple_t<args_t...>>;
json::basic_array<string_t> to_json_array(const tuple_t<args_t...>& value) const
{
json::basic_array<string_t> result;
to_json_impl(result, value, std::make_index_sequence<tuple_size>());
return result;
}
template <std::size_t... Is>
void to_json_impl(
json::basic_array<string_t>& arr,
const tuple_t<args_t...>& t,
std::index_sequence<Is...>) const
{
using std::get;
(arr.emplace_back(get<Is>(t)), ...);
}
bool check_json_array(const json::basic_array<string_t>& arr) const
{
return check_json_impl(arr, std::make_index_sequence<tuple_size>());
}
template <std::size_t... Is>
bool check_json_impl(const json::basic_array<string_t>& arr, std::index_sequence<Is...>) const
{
return (arr[Is].template is<std::tuple_element_t<Is, tuple_t<args_t...>>>() && ...);
}
bool from_json_array(const json::basic_array<string_t>& arr, tuple_t<args_t...>& value) const
{
if (!check_json_array(arr)) {
return false;
}
from_json_impl(arr, value, std::make_index_sequence<tuple_size>());
return true;
}
template <std::size_t... Is>
void from_json_impl(
const json::basic_array<string_t>& arr,
tuple_t<args_t...>& t,
std::index_sequence<Is...>) const
{
using std::get;
((get<Is>(t) = arr[Is].template as<std::tuple_element_t<Is, tuple_t<args_t...>>>()), ...);
}
json::basic_array<string_t> move_to_json_array(tuple_t<args_t...> value) const
{
json::basic_array<string_t> result;
move_to_json_impl(result, std::move(value), std::make_index_sequence<tuple_size>());
return result;
}
template <std::size_t... Is>
void move_to_json_impl(
json::basic_array<string_t>& arr,
tuple_t<args_t...> t,
std::index_sequence<Is...>) const
{
using std::get;
(arr.emplace_back(std::move(get<Is>(t))), ...);
}
bool move_from_json_array(json::basic_array<string_t> arr, tuple_t<args_t...>& value) const
{
if (!check_json_array(arr)) {
return false;
}
move_from_json_impl(arr, value, std::make_index_sequence<tuple_size>());
return true;
}
template <std::size_t... Is>
void move_from_json_impl(
json::basic_array<string_t> arr,
tuple_t<args_t...>& t,
std::index_sequence<Is...>) const
{
using std::get;
((get<Is>(t) =
std::move(arr[Is]).template as<std::tuple_element_t<Is, tuple_t<args_t...>>>()),
...);
}
};
template <typename string_t, typename map_t>
class jsonization<
string_t,
map_t,
std::enable_if_t<_utils::is_map<map_t> && std::is_same_v<typename map_t::key_type, string_t>>>
: public __jsonization_object<string_t, jsonization<string_t, map_t>, map_t>
{
public:
json::basic_object<string_t> to_json_object(const map_t& value) const
{
json::basic_object<string_t> result;
for (const auto& [key, val] : value) {
result.emplace(key, val);
}
return result;
}
bool check_json_object(const json::basic_object<string_t>& arr) const
{
for (const auto& [key, val] : arr) {
if (!val.template is<typename map_t::mapped_type>()) {
return false;
}
}
return true;
}
bool from_json_object(const json::basic_object<string_t>& arr, map_t& value) const
{
// TODO: 是不是直接from不check了算了
if (!check_json_object(arr)) {
return false;
}
value = {};
for (const auto& [key, val] : arr) {
value.emplace(key, val.template as<typename map_t::mapped_type>());
}
return true;
}
json::basic_object<string_t> move_to_json_object(map_t value) const
{
json::basic_object<string_t> result;
for (auto& [key, val] : value) {
result.emplace(key, std::move(val));
}
return result;
}
bool move_from_json_object(json::basic_object<string_t> arr, map_t& value) const
{
// TODO: 是不是直接from不check了算了
if (!check_json_object(arr)) {
return false;
}
value = {};
for (auto& [key, val] : arr) {
value.emplace(key, std::move(val).template as<typename map_t::mapped_type>());
}
return true;
}
};
template <typename string_t, typename... args_t>
class jsonization<string_t, std::variant<args_t...>>
{
public:
using variant_t = std::variant<args_t...>;
constexpr static size_t variant_size = std::variant_size_v<variant_t>;
json::basic_value<string_t> to_json(const variant_t& value) const
{
json::basic_value<string_t> result;
to_json_impl(result, value, std::make_index_sequence<variant_size>());
return result;
}
template <std::size_t... Is>
void to_json_impl(
json::basic_value<string_t>& val,
const variant_t& t,
std::index_sequence<Is...>) const
{
using std::get;
std::ignore = ((t.index() == Is ? (val = get<Is>(t), true) : false) || ...);
}
bool check_json(const json::basic_value<string_t>& json) const
{
return check_json_impl(json, std::make_index_sequence<variant_size>());
}
template <std::size_t... Is>
bool check_json_impl(const json::basic_value<string_t>& val, std::index_sequence<Is...>) const
{
return (val.template is<std::variant_alternative_t<Is, variant_t>>() || ...);
}
bool from_json(const json::basic_value<string_t>& json, variant_t& value) const
{
if (!check_json_impl(json, std::make_index_sequence<variant_size>())) {
return false;
}
from_json_impl(json, value, std::make_index_sequence<variant_size>());
return true;
}
template <std::size_t... Is>
void from_json_impl(
const json::basic_value<string_t>& json,
variant_t& t,
std::index_sequence<Is...>) const
{
std::ignore =
((json.template is<std::variant_alternative_t<Is, variant_t>>()
? (t = json.template as<std::variant_alternative_t<Is, variant_t>>(), true)
: false)
|| ...);
}
json::basic_value<string_t> move_to_json(variant_t value) const
{
json::basic_value<string_t> result;
move_to_json_impl(result, std::move(value), std::make_index_sequence<variant_size>());
return result;
}
template <std::size_t... Is>
void
move_to_json_impl(json::basic_value<string_t>& val, variant_t t, std::index_sequence<Is...>)
const
{
using std::get;
std::ignore = ((t.index() == Is ? (val = std::move(get<Is>(t)), true) : false) || ...);
}
bool move_from_json(json::basic_value<string_t> json, variant_t& value) const
{
if (!check_json_impl(json, std::make_index_sequence<variant_size>())) {
return false;
}
move_from_json_impl(std::move(json), value, std::make_index_sequence<variant_size>());
return true;
}
template <std::size_t... Is>
void move_from_json_impl(
json::basic_value<string_t> json,
variant_t& t,
std::index_sequence<Is...>) const
{
std::ignore =
((json.template is<std::variant_alternative_t<Is, variant_t>>()
? (t = std::move(json).template as<std::variant_alternative_t<Is, variant_t>>(),
true)
: false)
|| ...);
}
};
// TODO: check if has move_xxx in member
template <typename string_t, typename var_t>
class jsonization<
string_t,
var_t,
std::enable_if_t<
_utils::has_to_json_in_member<var_t>::value
&& _utils::has_check_json_in_member<var_t, string_t>::value
&& _utils::has_from_json_in_member<var_t, string_t>::value>>
{
public:
json::basic_value<string_t> to_json(const var_t& value) const { return value.to_json(); }
bool check_json(const json::basic_value<string_t>& json) const
{
var_t value;
return value.check_json(json);
}
bool from_json(const json::basic_value<string_t>& json, var_t& value) const
{
return value.from_json(json);
}
json::basic_value<string_t> move_to_json(var_t value) const { return to_json(value); }
bool move_from_json(json::basic_value<string_t> json, var_t& value) const
{
return from_json(json, value);
}
};
// really need this fucking queue?
template <typename string_t, typename value_t>
class jsonization<string_t, std::queue<value_t>>
: public __jsonization_array<
string_t,
jsonization<string_t, std::queue<value_t>>,
std::queue<value_t>,
(size_t)-1>
{
public:
json::basic_array<string_t> to_json_array(const std::queue<value_t>& value) const
{
return move_to_json_array(value);
}
bool check_json_array(const json::basic_array<string_t>& arr) const
{
return arr.template all<value_t>();
}
bool from_json_array(const json::basic_array<string_t>& arr, std::queue<value_t>& value) const
{
if (!check_json_array(arr)) {
return false;
}
value = {};
for (const auto& val : arr) {
value.emplace(val.template as<value_t>());
}
return true;
}
json::basic_array<string_t> move_to_json_array(std::queue<value_t> value) const
{
json::basic_array<string_t> result;
while (!value.empty()) {
result.emplace_back(std::move(value.front()));
value.pop();
}
return result;
}
bool move_from_json_array(json::basic_array<string_t> arr, std::queue<value_t>& value) const
{
if (!check_json_array(arr)) {
return false;
}
for (auto& val : arr) {
value.emplace(std::move(val).template as<value_t>());
}
return true;
}
};
}

View File

@@ -1,648 +0,0 @@
// IWYU pragma: private, include <meojson/json.hpp>
#pragma once
#include <string>
#include <type_traits>
#include <utility>
#include "../common/types.hpp"
#include "extensions.hpp"
namespace json::_jsonization_helper
{
template <typename value_t>
struct is_optional_t : public std::false_type
{
};
template <typename value_t>
struct is_optional_t<std::optional<value_t>> : public std::true_type
{
};
template <typename value_t>
inline constexpr bool is_optional_v = is_optional_t<value_t>::value;
struct next_is_optional_t
{
};
struct next_override_key_t
{
const char* key;
};
struct next_state_t
{
bool is_optional = false;
const char* override_key = nullptr;
};
struct va_arg_end
{
};
template <typename tag_t>
struct is_tag_t : public std::false_type
{
};
template <>
struct is_tag_t<next_is_optional_t> : public std::true_type
{
};
template <>
struct is_tag_t<next_override_key_t> : public std::true_type
{
};
struct dumper
{
void _to_json(json::object&, va_arg_end) const {}
template <typename... rest_t>
void _to_json(json::object& result, const char* key, rest_t&&... rest) const
{
_to_json(result, next_state_t {}, key, std::forward<rest_t>(rest)...);
}
template <
typename var_t,
typename... rest_t,
typename _ = std::enable_if_t<!is_tag_t<var_t>::value, void>>
void _to_json(
json::object& result,
next_state_t state,
const char* key,
const var_t& var,
rest_t&&... rest) const
{
if (state.override_key) {
key = state.override_key;
}
if constexpr (is_optional_v<var_t>) {
if (!state.is_optional) {
throw exception("std::optional must be used with MEO_OPT");
}
if (var.has_value()) {
result.emplace(key, var.value());
}
}
else {
result.emplace(key, var);
}
_to_json(result, std::forward<rest_t>(rest)...);
}
template <typename... rest_t>
void _to_json(
json::object& result,
next_state_t state,
const char*,
next_is_optional_t,
rest_t&&... rest) const
{
state.is_optional = true;
_to_json(result, state, std::forward<rest_t>(rest)...);
}
template <typename... rest_t>
void _to_json(
json::object& result,
next_state_t state,
const char*,
next_override_key_t override_key,
rest_t&&... rest) const
{
state.override_key = override_key.key;
_to_json(result, state, std::forward<rest_t>(rest)...);
}
};
struct checker
{
bool _check_json(const json::value&, std::string&, va_arg_end) const { return true; }
template <typename... rest_t>
bool _check_json(
const json::value& in,
std::string& error_key,
const char* key,
rest_t&&... rest) const
{
return _check_json(in, error_key, next_state_t {}, key, std::forward<rest_t>(rest)...);
}
template <
typename var_t,
typename... rest_t,
typename _ = std::enable_if_t<!is_tag_t<var_t>::value, void>>
bool _check_json(
const json::value& in,
std::string& error_key,
next_state_t state,
const char* key,
const var_t&,
rest_t&&... rest) const
{
if (state.override_key) {
key = state.override_key;
}
auto opt = in.find(key);
if constexpr (is_optional_v<var_t>) {
if (!state.is_optional) {
throw exception("std::optional must be used with MEO_OPT");
}
if (opt && !opt->is<typename var_t::value_type>()) {
error_key = key;
return false;
}
}
else {
if (state.is_optional) {
if (opt && !opt->is<var_t>()) {
error_key = key;
return false;
} // is_optional, ignore key not found
}
else if (!opt || !opt->is<var_t>()) {
error_key = key;
return false;
}
}
return _check_json(in, error_key, std::forward<rest_t>(rest)...);
}
template <typename... rest_t>
bool _check_json(
const json::value& in,
std::string& error_key,
next_state_t state,
const char*,
next_is_optional_t,
rest_t&&... rest) const
{
state.is_optional = true;
return _check_json(in, error_key, state, std::forward<rest_t>(rest)...);
}
template <typename... rest_t>
bool _check_json(
const json::value& in,
std::string& error_key,
next_state_t state,
const char*,
next_override_key_t override_key,
rest_t&&... rest) const
{
state.override_key = override_key.key;
return _check_json(in, error_key, state, std::forward<rest_t>(rest)...);
}
};
struct loader
{
bool _from_json(const json::value&, std::string&, va_arg_end) const { return true; }
template <typename... rest_t>
bool
_from_json(const json::value& in, std::string& error_key, const char* key, rest_t&&... rest)
{
return _from_json(in, error_key, next_state_t {}, key, std::forward<rest_t>(rest)...);
}
template <
typename var_t,
typename... rest_t,
typename _ = std::enable_if_t<!is_tag_t<var_t>::value, void>>
bool _from_json(
const json::value& in,
std::string& error_key,
next_state_t state,
const char* key,
var_t& var,
rest_t&&... rest)
{
if (state.override_key) {
key = state.override_key;
}
auto opt = in.find(key);
if constexpr (is_optional_v<var_t>) {
if (!state.is_optional) {
throw exception("std::optional must be used with MEO_OPT");
}
if (opt && !opt->is<typename var_t::value_type>()) {
error_key = key;
return false;
}
if (opt) {
var = std::move(opt)->as<typename var_t::value_type>();
}
else {
var = std::nullopt;
}
}
else {
if (state.is_optional) {
if (opt && !opt->is<var_t>()) {
error_key = key;
return false;
} // is_optional, ignore key not found
}
else if (!opt || !opt->is<var_t>()) {
error_key = key;
return false;
}
if (opt) {
var = std::move(opt)->as<var_t>();
}
}
return _from_json(in, error_key, std::forward<rest_t>(rest)...);
}
template <typename... rest_t>
bool _from_json(
const json::value& in,
std::string& error_key,
next_state_t state,
const char*,
next_is_optional_t,
rest_t&&... rest)
{
state.is_optional = true;
return _from_json(in, error_key, state, std::forward<rest_t>(rest)...);
}
template <typename... rest_t>
bool _from_json(
const json::value& in,
std::string& error_key,
next_state_t state,
const char*,
next_override_key_t override_key,
rest_t&&... rest)
{
state.override_key = override_key.key;
return _from_json(in, error_key, state, std::forward<rest_t>(rest)...);
}
};
} // namespace json::_jsonization_helper
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#endif
namespace json::_private_macro
{
#define _MEOJSON_STRINGIZE(arg) _MEOJSON_STRINGIZE1(arg)
#define _MEOJSON_STRINGIZE1(arg) _MEOJSON_STRINGIZE2(arg)
#define _MEOJSON_STRINGIZE2(arg) #arg
#define _MEOJSON_CONCATENATE(arg1, arg2) _MEOJSON_CONCATENATE1(arg1, arg2)
#define _MEOJSON_CONCATENATE1(arg1, arg2) _MEOJSON_CONCATENATE2(arg1, arg2)
#define _MEOJSON_CONCATENATE2(arg1, arg2) arg1##arg2
#define _MEOJSON_EXPAND(x) x
#define _MEOJSON_FOR_EACH_1(pred, x) pred(x)
#define _MEOJSON_FOR_EACH_2(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_1(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_3(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_2(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_4(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_3(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_5(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_4(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_6(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_5(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_7(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_6(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_8(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_7(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_9(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_8(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_10(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_9(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_11(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_10(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_12(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_11(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_13(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_12(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_14(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_13(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_15(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_14(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_16(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_15(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_17(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_16(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_18(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_17(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_19(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_18(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_20(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_19(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_21(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_20(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_22(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_21(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_23(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_22(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_24(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_23(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_25(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_24(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_26(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_25(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_27(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_26(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_28(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_27(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_29(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_28(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_30(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_29(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_31(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_30(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_32(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_31(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_33(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_32(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_34(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_33(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_35(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_34(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_36(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_35(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_37(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_36(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_38(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_37(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_39(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_38(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_40(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_39(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_41(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_40(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_42(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_41(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_43(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_42(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_44(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_43(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_45(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_44(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_46(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_45(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_47(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_46(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_48(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_47(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_49(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_48(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_50(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_49(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_51(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_50(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_52(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_51(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_53(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_52(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_54(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_53(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_55(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_54(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_56(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_55(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_57(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_56(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_58(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_57(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_59(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_58(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_60(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_59(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_61(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_60(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_62(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_61(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_63(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_62(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH_64(pred, x, ...) \
pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_63(pred, __VA_ARGS__))
#define _MEOJSON_ARG_COUNT(...) \
_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT1( \
0, \
##__VA_ARGS__, \
64, \
63, \
62, \
61, \
60, \
59, \
58, \
57, \
56, \
55, \
54, \
53, \
52, \
51, \
50, \
49, \
48, \
47, \
46, \
45, \
44, \
43, \
42, \
41, \
40, \
39, \
38, \
37, \
36, \
35, \
34, \
33, \
32, \
31, \
30, \
29, \
28, \
27, \
26, \
25, \
24, \
23, \
22, \
21, \
20, \
19, \
18, \
17, \
16, \
15, \
14, \
13, \
12, \
11, \
10, \
9, \
8, \
7, \
6, \
5, \
4, \
3, \
2, \
1, \
0))
#define _MEOJSON_ARG_COUNT1( \
_0, \
_1, \
_2, \
_3, \
_4, \
_5, \
_6, \
_7, \
_8, \
_9, \
_10, \
_11, \
_12, \
_13, \
_14, \
_15, \
_16, \
_17, \
_18, \
_19, \
_20, \
_21, \
_22, \
_23, \
_24, \
_25, \
_26, \
_27, \
_28, \
_29, \
_30, \
_31, \
_32, \
_33, \
_34, \
_35, \
_36, \
_37, \
_38, \
_39, \
_40, \
_41, \
_42, \
_43, \
_44, \
_45, \
_46, \
_47, \
_48, \
_49, \
_50, \
_51, \
_52, \
_53, \
_54, \
_55, \
_56, \
_57, \
_58, \
_59, \
_60, \
_61, \
_62, \
_63, \
_64, \
N, \
...) \
N
#define _MEOJSON_FOR_EACH_(N, pred, ...) \
_MEOJSON_EXPAND(_MEOJSON_CONCATENATE(_MEOJSON_FOR_EACH_, N)(pred, __VA_ARGS__))
#define _MEOJSON_FOR_EACH(pred, ...) \
_MEOJSON_EXPAND( \
_MEOJSON_FOR_EACH_(_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT(__VA_ARGS__)), pred, __VA_ARGS__))
#define _MEOJSON_VARNAME(x) _MEOJSON_CONCATENATE(_meojson_jsonization_, x)
#define _MEOJSON_KEY_VALUE(x) _MEOJSON_STRINGIZE(x), x,
} // namespace json::_private_macro
#define MEO_TOJSON(...) \
json::value to_json() const \
{ \
json::object result; \
json::_jsonization_helper::dumper()._to_json( \
result, \
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
json::_jsonization_helper::va_arg_end {}); \
return result; \
}
#define MEO_CHECKJSON(...) \
bool check_json(const json::value& _MEOJSON_VARNAME(in)) const \
{ \
std::string _MEOJSON_VARNAME(error_key); \
return check_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \
} \
bool check_json( \
const json::value& _MEOJSON_VARNAME(in), \
std::string& _MEOJSON_VARNAME(error_key)) const \
{ \
return json::_jsonization_helper::checker()._check_json( \
_MEOJSON_VARNAME(in), \
_MEOJSON_VARNAME(error_key), \
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
json::_jsonization_helper::va_arg_end {}); \
}
#define MEO_FROMJSON(...) \
bool from_json(const json::value& _MEOJSON_VARNAME(in)) \
{ \
std::string _MEOJSON_VARNAME(error_key); \
return from_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \
} \
bool from_json( \
const json::value& _MEOJSON_VARNAME(in), \
std::string& _MEOJSON_VARNAME(error_key)) \
{ \
return json::_jsonization_helper::loader()._from_json( \
_MEOJSON_VARNAME(in), \
_MEOJSON_VARNAME(error_key), \
_MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \
json::_jsonization_helper::va_arg_end {}); \
}
#define MEO_JSONIZATION(...) \
_MEOJSON_EXPAND(MEO_TOJSON(__VA_ARGS__)) \
_MEOJSON_EXPAND(MEO_CHECKJSON(__VA_ARGS__)) \
_MEOJSON_EXPAND(MEO_FROMJSON(__VA_ARGS__))
#define MEO_OPT json::_jsonization_helper::next_is_optional_t {},
#define MEO_KEY(key) json::_jsonization_helper::next_override_key_t { key },
#if defined(__clang__)
#pragma clang diagnostic pop // -Wgnu-zero-variadic-macro-arguments
#endif

View File

@@ -1,49 +1,253 @@
## v5.26.0-beta.1
## v5.28.4
### Highlights
#### 继续修 BUG
在这个版本,我们继续修复了大量 BUG并且优化了遇到各类错误时的调试体验。
#### 小工具 - 小游戏 - PV-烟花筹委会v5.28.2 及以上版本)
新增 PV-烟花筹委会 小游戏支持,在小游戏界面最左侧开始。
#### 错误处理方面
* 出错时鼠标悬浮在任务错误日志上即可查看出错时的截图,方便快速定位问题。
* 「生成日志压缩包」 功能现在支持同时打包 `debug` 文件夹的截图,并支持分卷压缩,在 GitHub 之类有文件大小限制的地方可以传分卷包(单个分卷最大 20 MB更加灵活方便。
#### 自动战斗方面
* 自动战斗在只缺一个干员的时候,现在支持自动借缺少的干员,让自动战斗更加智能和便捷。
* 根据 B 站官号投票动态的结果,我们优化了自动战斗界面的显示效果,布局更加合理,操作更加便捷。
#### 肉鸽相关修复
修复了大量集成战略相关问题,包括界园肉鸽 boss 识别、通宝配置解析、不期而遇事件识别、萨米肉鸽任务链等,提升了肉鸽自动化的稳定性。
#### 其他方面
我们发现,牛牛在使用 GPU 推理时,如果 GPU 驱动过旧可能会产生兼容性问题,因此我们添加了一项检测,当发现你的 GPU 驱动超过 2 年没有更新时会给出提示,我们建议你更新驱动以获得更好的体验。
#### 新增功能v5.28.4 及以上版本)
* 关卡选择验证输入,非当期活动的关卡名会当做未开放关卡
* 當左上角進行中活動因太多被折疊時,增加展開領取的狀態判斷
* UR 活动导航
----
In this version, we continued to fix numerous bugs and optimized the debugging experience when encountering various types of errors.
#### Mini-game - PV-Fireworks Committee (v5.28.2 and above)
Added support for the PV-Fireworks Committee mini-game. Start from the leftmost side of the mini-game interface.
#### Error Handling
* When an error occurs, hovering the mouse over the task error log now displays a screenshot, allowing you to quickly locate the problem.
* The "Generate Support Payload" feature now supports packaging screenshots of the `debug` folder simultaneously and supports multi-part compression. This allows for uploading multi-part packages (each part up to 20 MB) to platforms with file size limits, such as GitHub.
#### *EN Only* I.S. stuck issues.
* The maintainers are aware of MAA getting stuck in the formation before starting an I.S. fighting stage. We still haven't been able to 100% deduct (and reproduce) the issue. Multiple fixes have been attempted. This stable version attemps to fix by completely overwriting the current template `Quick Select`. After various discussions on the Discord support channel, it appears the template really was the issue(?). Comparing with the older template (pre Tragodia update) the position seems slightly changed (and apparently) even the clicking box hence why the issues.
#### *Copilot*
* When only one operator is missing in *Copilot*, MAA can now supports automatically borrow the missing Support Unit, making *Copilot* more intelligent and convenient.
* Based on the results of a poll on the official Bilibili account, we optimized the layout of the *Copilot* interface, making it more intuitive and easier to use.
#### *Auto I.S.* Fixes
We fixed numerous issues related to *Auto I.S.*, including Boss recognition in the *Sui's Garden of Grotesqueries*, Tongbao configuration parsing, Encounter event recognition, and quest chains in the *Expeditioner's Jǫklumarkar*, improving the stability of *Auto I.S.*.
#### Other Aspects
We found that outdated GPU drivers may cause compatibility issues when MAA performs GPU inference. Therefore, we added a detection feature that alerts you when your GPU driver has not been updated for more than 2 years and recommends updating it for a better experience.
#### New Features (v5.28.4 and above)
* Stage selection input validation - stages from inactive events are treated as unavailable stages
* Added status detection for expanding and claiming rewards when ongoing activities in the top-left corner are collapsed due to too many activities
* UR activity navigation
----
以下是详细内容:
## v5.28.0
### 新增 | New
* 次生预案十里坡剑神 @ABA2396
* 设置指引添加更新设置 @ABA2396
* 设置指引添加性能设置 @ABA2396
* 任务错误日志鼠标悬浮可以查看出错时截图 @ABA2396
* 自动战斗支持切换技能用法使用坐标 @status102
* 为 GPU 加速添加超过 2 年的驱动版本检测 (#14690) @Rbqwow @status102
### 改进 | Improved
* 改进自动借助战功能 (#11105) @Alan-Charred
* 优化自动战斗界面显示 (#14795) @ABA2396 @HX3N @Constrat @Manicsteiner @status102
* 日志汇报打包 debug 截图,支持分卷,修改存储路径 @ABA2396
* 拆分多主题识别任务 (#14774) @SherkeyXD
### 修复 | Fix
* 文档首页语言选择按钮的宽度定义方式 (#14199) @lucienshawls
* 傀影肉鸽无法识别四结局 (#14193) @Saratoga-Official
* GamePassSkip2 识别到错误的跳过 @Saratoga-Official
* 萨米肉鸽不期而遇避战 @Saratoga-Official
* Google Play Games Developer shutdown @Constrat
* manual set resource version time @MistEO
* prettier @Constrat
* 部分名片无法进入线索交接 @ABA2396
* 修复放弃通宝的后续任务逻辑 (#14840) @travellerse
* 在未进入缩小的全局总览的时可能进错宿舍 @ABA2396
* 修复 "入暂亭" 事件 (#14684) @Alan-Charred
* 修复界园肉鸽第 3 层与第 5 层 boss 无法区分、第 5 层 boss 前暂停设置无效 @ABA2396
* 修复界园树洞偶发点击到剩余烛火,导致无法进入下一个节点 (#14806) @travellerse
* 修复通宝配置解析逻辑及左侧通宝解析失败的情况 (#14802, #14820) @travellerse
* 修正通宝识别中的坐标 (#14829) @travellerse
* 修复集成战略萨米主题下凹密闻板相关功能 (#14755) @Alan-Charred
* 简化萨米肉鸽 "诡秘的预感" 相关任务链 (#14749) @Alan-Charred
* 修正不期而遇事件名 OCR 以区分禳解的 3 个相近选项,添加不期而遇事件名 OCR 替换 (#14799, #14588) @travellerse
* 肉鸽可能卡进剧目获取界面和收藏品界面 @Saratoga-Official
* 肉鸽允许跳过招募组合直接开始初始招募 (#14713) @Alan-Charred
* 保存招募券结束后等待确认招募按钮消失 (#14773) @travellerse
* 防止生息演算重置地图视图时因截图延迟卡死 (#14721) @Alan-Charred
* 给 open_series_list 加上失败截图机制 (#14693) @Alan-Charred
* 投资入口识别失败 @Saratoga-Official
* 进一步调整 WpfGui 助战选项显示布局 @Alan-Charred
* 上调助战栏位匹配分数阈值 (#14796) @Alan-Charred
* 单文件模式下总是传递借助战 @ABA2396
* 自动借助战错误显示 @ABA2396
* 干员识别包含 盟约·辅助干员 和 领主·Sharp @ABA2396
* 干员识别复制结果到剪贴板时丢失未拥有干员 @status102
* 关卡复核会把 8 识别成 g @Saratoga-Official
* 通关角标识别错误 @ABA2396
* 刷理智指定次数未完全消耗警告在剩余理智也会提示 @status102
* 避免输出空矩阵 @ABA2396
* RA 导航错误 @ABA2396
* build WpfGui for ARM architecture (#14722) @Alan-Charred
* copilot file name (#14821) @Manicsteiner
* JP paradox @Manicsteiner
* KR 引航任务识别 @Daydreamer114
* KR AD navigation (#14742) @HX3N
* ocrReplace for EN (#14740) @Alan-Charred @Saratoga-Official
* reduce template size for QuickFormation RL @Constrat
* Sami IS EN 3rd floor regex @Constrat
* regex AD navigation EN @Constrat
### 文档 | Docs
* 补充vsc插件繁中文档 @Rbqwow
* 修复文档站 readme 盾换行 @Rbqwow
* 调整文档站的标题和尾注文本显示 (#14213) @lucienshawls
* 更新网页开发相关文档 (#14167) @Rbqwow @Manicsteiner
* 完善任务流程协议文档 (#13232) @zzyyyl
* 回调消息协议文档视觉更新 @SherkeyXD
* 集成文档视觉更新 @SherkeyXD
* 文档启用 b 站视频播放功能 @SherkeyXD
* 文档添加字段容器功能 @SherkeyXD
* 文档添加功能 @SherkeyXD
* 更新文档编写指南 @SherkeyXD
* 标题 MAA 统一采用缩写 @MistEO
* 再次调整文档站标题( @MistEO
* 调整文档站标题 @MistEO
* Update JP(#14227) @wallsman
* markdown pre-commit @zzyyyl
* add extension's evaluating feature @neko-para
* add telegram icon @SherkeyXD
* 自动战斗文档添加 copilot_list, is_raid, is_paradox, loop_times 注释 @Alan-Charred
### 其他 | Other
* 统一显示效果 @ABA2396
* 水月萨米肉鸽不期而遇避战 @Saratoga-Official
* 重写完成后动作仅一次的 ui 字符串 (#14196) @Rbqwow
* 贸易站没其他好用的人再用锏 @ABA2396
* YostarJP Sarkaz roguelike StageEncounter (#14223) @Manicsteiner
* YostarJP sami roguelike 720p (#14210) @Manicsteiner
* YostarJP Mizuki StageEncounter (#14206) @Manicsteiner
* devcontainer.json (#14169) @Rbqwow @lucienshawls
* 移除过旧的 `add_user_additional` 参数弃用提示 @status102
* 简化 ROI 修正逻辑 @ABA2396
* 调整 ExportOperBox 内的变量命名与结构 @ABA2396
* 清日志时手动清除 ToolTip @ABA2396
* std::signal 自动舍弃 abort / terminate 上方栈 @status102
* 分卷压缩包大小改成 20 MB @ABA2396
* 向 MaaCore 工程增加 tasks 文件以便检索 (#14731) @status102
* 更新多模板截图工具 @SherkeyXD
* 移除部分无需的 include @status102
* 路径迁移 @status102
* 修复 UI 细节 @hguandl
* optimize templates @Constrat
* JP ocr edits (#14748) @Manicsteiner
* KR tweak SupportUnitUsage translation @HX3N
* KR @hguandl
* SSS#8 for global (#14803) @Manicsteiner
----
## v5.28.1
### 新增 | New
* PV-烟花筹委会 小游戏 @ABA2396 @weinibuliu
* 刷理智失败次数达到上限时报错 @ABA2396
* update meojson to v5.0.0 (#14849) @MistEO
### 改进 | Improved
* wpf Debug 压缩包切片增加时间前缀 @status102
* 改进 ImageCropper @weinibuliu
* 更新肉鸽协议文档和界园肉鸽商品列表 (#14873) @DavidWang19
### 修复 | Fix
* 基建换班卡死在无人机使用界面 @ABA2396
* 齐聚主题会在基建同时存在红蓝两个提示的时候无法进入 @ABA2396
* 战斗列表只有第一关会使用助战干员 @status102
* 避免通宝插件通过任务链作用到通宝以外的地方 (#14867) @travellerse
* 功能入口添加重试机制 (#14872) @ABA2396
* fix regex_error(error_badrepeat) @Constrat
### 文档 | Docs
* issue 模板修改 25 MB 压缩包上传提示 (#14850) @Rbqwow
### 其他 | Other
* 遗漏的 MaaCore.pdb 和 MaaUtils/pdb
* 整理截图 @ABA2396
* 调整 StartToVisit 阈值 @ABA2396
* remove and sort usings (#14877) @SherkeyXD
----
## v5.28.2
### 修复 | Fix
* 概率无法进入小游戏第八关之后的关卡 @weinibuliu
----
## v5.28.3
### 新增 | New
* 支持 PV 小游戏从当前关卡开始 @ABA2396
* PV 小游戏 macOS 支持 @hguandl
### 改进 | Improved
* 优化 PV 小游戏识别范围与部分复杂背景关卡的识别 @ABA2396
* 优化卫戍协议流程 @ABA2396
* 调整小游戏描述 @ABA2396
### 修复 | Fix
* 修复宿舍确认按钮识别yj 的小杯 UI @ABA2396
* 修复 PV 小游戏进入关卡时遇到网络连接会少选烟花样片 @ABA2396
* 修复 MaaCore 异常日志基址解析 @status102
* 修复 Windows 平台的 pdb 文件压缩 @status102
### 其他 | Other
* Debug 截图默认保存最近 10 张 @ABA2396
* 繁中服「眾生行記」活動導航 @momomochi987
* 繁中服「爭鋒頻道:青草城」小遊戲 @momomochi987
----
## v5.28.4
### 新增 | New
* 关卡选择验证输入,非当期活动的关卡名会当做未开放关卡 @ABA2396
* 當左上角進行中活動因太多被折疊時,增加展開領取的狀態判斷 (#14957) @momomochi987
* UR 活动导航 @ABA2396
### 改进 | Improved
* 优化小游戏任务选择逻辑及提示 (#14951) @Daydreamer114 @ABA2396
### 修复 | Fix
* 繁中服周年月卡領取及贈送單抽的處理錯誤 (#14953) @momomochi987
* 卫戍协议因网络问题卡在结算界面 @Saratoga-Official
* 代理失败后等待动画结束后再点击任务失败 @ABA2396
* 自定义基建排班使用无人机加速未进驻干员的设施导致卡死 @ABA2396
* 干员识别异常(荒芜拉普兰德) (#14934) @dikxingmengya
* issue-checker.yml 中 MacGui 正则不包含 MacGui @Rbqwow
* 预提交模板优化配置 @Constrat
### 其他 | Other
* 調整繁中服傀影肉鴿能夠選擇的難度 (#14952) @momomochi987

View File

@@ -1,12 +1,7 @@
cmake_minimum_required(VERSION 3.28)
project(MAA)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules")
option(BUILD_WPF_GUI "build MaaWpfGui" ${WIN32})
option(BUILD_DEBUG_DEMO "build debug demo" OFF)
option(BUILD_XCFRAMEWORK "build xcframework for macOS app" OFF)
@@ -17,29 +12,23 @@ option(INSTALL_FLATTEN "do not use bin lib include directory" ON)
option(WITH_EMULATOR_EXTRAS "build with emulator extras" ${WIN32})
option(WITH_HASH_VERSION "generate version from git hash" OFF)
include(${PROJECT_SOURCE_DIR}/MaaDeps/maadeps.cmake)
if(INSTALL_FLATTEN)
set(RPATH_LIBRARY_INSTALL_DIR .)
set(MaaCore_install_flatten_args RUNTIME DESTINATION . LIBRARY DESTINATION . PUBLIC_HEADER DESTINATION .)
endif()
include(src/MaaUtils/MaaUtils.cmake)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules")
include(${PROJECT_SOURCE_DIR}/cmake/config.cmake)
include(${PROJECT_SOURCE_DIR}/cmake/utils.cmake)
include(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
if(APPLE)
include(${PROJECT_SOURCE_DIR}/cmake/macos.cmake)
endif()
if(INSTALL_FLATTEN)
set(MaaCore_install_flatten_args RUNTIME DESTINATION . LIBRARY DESTINATION . PUBLIC_HEADER DESTINATION .)
endif()
add_library(HeaderOnlyLibraries INTERFACE)
target_include_directories(HeaderOnlyLibraries INTERFACE 3rdparty/include)
find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs)
find_package(Boost REQUIRED CONFIG COMPONENTS system)
find_package(ZLIB REQUIRED)
find_package(fastdeploy_ppocr REQUIRED)
find_package(ONNXRuntime REQUIRED)
add_subdirectory(src/MaaCore)
if(BUILD_WPF_GUI)

View File

@@ -21,6 +21,9 @@
<img alt="stars" src="https://img.shields.io/github/stars/MaaAssistantArknights/MaaAssistantArknights?style=social">
<img alt="GitHub all releases" src="https://img.shields.io/github/downloads/MaaAssistantArknights/MaaAssistantArknights/total?style=social">
</div>
<div>
<a href="https://deepwiki.com/MaaAssistantArknights/MaaAssistantArknights"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
</div>
<br>
<!-- markdownlint-restore -->
@@ -98,11 +101,9 @@ MAA 支持命令行界面CLI操作支持 LinuxmacOS 和 Windows
### 主要关联项目
**目前项目组非常缺前端大佬,若您有相关经验,欢迎加入我们!**
- 全新框架:[MaaFramework](https://github.com/MaaXYZ/MaaFramework)
- [作业站](https://prts.plus) 前端:[maa-copilot-frontend](https://github.com/MaaAssistantArknights/maa-copilot-frontend)
- [作业站](https://prts.plus) 后端:[MaaBackendCenter](https://github.com/MaaAssistantArknights/MaaBackendCenter)
- [作业站](https://prts.plus) 前端:[zoot-plus-frontend](https://github.com/ZOOT-Plus/zoot-plus-frontend)
- [作业站](https://prts.plus) 后端:[ZootPlusBackend](https://github.com/ZOOT-Plus/ZootPlusBackend)
- [官网](https://maa.plus)[前端](https://github.com/MaaAssistantArknights/maa-website)
- 深度学习:[MaaAI](https://github.com/MaaAssistantArknights/MaaAI)
@@ -112,15 +113,9 @@ MAA 以中文(简体)为第一语言,翻译词条均以中文(简体)
### 参与开发
#### Windows
请参阅 [开发指南](https://docs.maa.plus/zh-cn/develop/development.html)。
请参阅 [开始开发](https://docs.maa.plus/zh-cn/develop/development.html)。
#### Linux | macOS
请参阅 [Linux 编译教程](https://docs.maa.plus/zh-cn/develop/linux-tutorial.html)。
#### API
### API
- [C 接口](include/AsstCaller.h)[集成示例](src/Cpp/main.cpp)
- [Python 接口](src/Python/asst/asst.py)[集成示例](src/Python/sample.py)
@@ -136,15 +131,11 @@ MAA 以中文(简体)为第一语言,翻译词条均以中文(简体)
- [任务流程协议](https://docs.maa.plus/zh-cn/protocol/task-schema.html)
- [自动抄作业协议](https://docs.maa.plus/zh-cn/protocol/copilot-schema.html)
#### 外服适配
### 外服适配
请参阅 [外服适配教程](https://docs.maa.plus/zh-cn/develop/overseas-client-adaptation.html),对于国服已支持的功能,绝大部分的外服适配工作仅需要截图 + 简单的 JSON 修改即可。
#### 想参与开发,但不太会用 GitHub?
[GitHub Pull Request 流程简述](https://docs.maa.plus/zh-cn/develop/development.html#github-pull-request-流程简述)
#### Issue bot
### Issue bot
请参阅 [Issue Bot 使用方法](https://docs.maa.plus/zh-cn/develop/issue-bot-usage.html)

View File

@@ -2,11 +2,11 @@
## 受支持的版本 / Supported Versions
我们仅对 v4 和 v5 两个大版本的最新稳定版提供安全支持,如有安全问题,我们将会尽可能快地发布新的稳定版解决。
我们仅对 v5 的最新稳定版提供安全支持,如有安全问题,我们将会尽可能快地发布新的稳定版解决。
内测版、公测版仅供测试,我们不会对其提供安全支持。
We only provide security support for the latest Stable Release versions of v4 and v5. If there are security issues, we will release a new stable version as soon as possible to solve them.
We only provide security support for the latest Stable Release versions of v5. If there are security issues, we will release a new stable version as soon as possible to solve them.
The Nightly Release version and the Beta Release version are for testing only, and we will not provide security support for them.

View File

@@ -1,83 +1,2 @@
set(debug_comp_defs "_DEBUG;ASST_DEBUG")
add_compile_definitions("$<$<CONFIG:Debug>:${debug_comp_defs}>")
if(APPLE)
set(CMAKE_INSTALL_RPATH "@loader_path;@executable_path")
set(CMAKE_BUILD_RPATH "@loader_path;@executable_path")
elseif(UNIX)
set(CMAKE_INSTALL_RPATH "$ORIGIN")
set(CMAKE_BUILD_RPATH "$ORIGIN")
endif()
if(MSVC)
add_compile_options("/utf-8")
add_compile_options("/MP")
add_compile_options("/W4;/WX;/Gy;/permissive-;/sdl")
add_compile_options("/wd4127") # conditional expression is constant
add_compile_options("/wd4251") # export dll with templates
add_compile_options("/DWINVER=0x0A00")
add_compile_options("/D_WIN32_WINNT=0x0A00")
# https://github.com/actions/runner-images/issues/10004 https://github.com/microsoft/STL/releases/tag/vs-2022-17.10
add_compile_definitions("_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR")
set(release_link_options "/OPT:REF;/OPT:ICF")
add_link_options("$<$<CONFIG:Release>:${release_link_options}>")
SET(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO "RelWithDebInfo;Release;")
SET(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL "MinSizeRel;Release;")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
else()
add_compile_options("-Wall;-Werror;-Wextra;-Wpedantic;-Wno-missing-field-initializers")
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13)
add_compile_options("-Wno-restrict")
endif()
endif()
if(LINUX)
function(copy_and_add_rpath_library LIBNAME)
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=${LIBNAME}.so.1 -target ${CMAKE_CXX_COMPILER_TARGET} --sysroot=${CMAKE_SYSROOT}
OUTPUT_VARIABLE LIB_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if("${LIB_PATH}" STREQUAL "${LIBNAME}.so.1")
message(FATAL_ERROR "Could not locate ${LIBNAME}.so.1 using compiler")
endif()
file(READ_SYMLINK "${LIB_PATH}" LINK_TARGET)
if(NOT LINK_TARGET)
set(LIB_PATH_REAL "${LIB_PATH}")
elseif(NOT IS_ABSOLUTE "${LINK_TARGET}")
get_filename_component(LIB_PATH_DIR "${LIB_PATH}" DIRECTORY)
file(REAL_PATH "${LIB_PATH_DIR}/${LINK_TARGET}" LIB_PATH_REAL)
else()
set(LIB_PATH_REAL "${LINK_TARGET}")
endif()
if(NOT EXISTS "${LIB_PATH_REAL}")
message(FATAL_ERROR "File not found: ${LIB_PATH_REAL}")
endif()
message(STATUS "${LIBNAME}.so.1 path: ${LIB_PATH_REAL}")
install(FILES "${LIB_PATH_REAL}" DESTINATION . RENAME "${LIBNAME}.so.1" COMPONENT libcxx)
get_filename_component(LIB_PATH_DIR "${LIB_PATH_REAL}" DIRECTORY)
list(APPEND CMAKE_BUILD_RPATH "${LIB_PATH_DIR}")
set(CMAKE_BUILD_RPATH "${CMAKE_BUILD_RPATH}" PARENT_SCOPE)
endfunction()
copy_and_add_rpath_library(libc++)
copy_and_add_rpath_library(libc++abi)
copy_and_add_rpath_library(libunwind)
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

View File

@@ -4,24 +4,30 @@ if (BUILD_XCFRAMEWORK)
COMMAND xcodebuild -create-xcframework -library libMaaCore.dylib -headers ${PROJECT_SOURCE_DIR}/include -output MaaCore.xcframework
DEPENDS MaaCore
)
add_custom_command(OUTPUT MaaUtils.xcframework
COMMAND rm -rf MaaUtils.xcframework
COMMAND xcodebuild -create-xcframework -library libMaaUtils.dylib -output MaaUtils.xcframework
DEPENDS MaaUtils
)
add_custom_command(OUTPUT OpenCV.xcframework
COMMAND rm -rf OpenCV.xcframework
COMMAND xcodebuild -create-xcframework -library "${PROJECT_SOURCE_DIR}/MaaDeps/runtime/${MAADEPS_TRIPLET}/libopencv_world4.408.dylib" -output OpenCV.xcframework
COMMAND xcodebuild -create-xcframework -library "${MAADEPS_DIR}/runtime/${MAADEPS_TRIPLET}/libopencv_world4.408.dylib" -output OpenCV.xcframework
)
add_custom_command(OUTPUT ONNXRuntime.xcframework
COMMAND rm -rf ONNXRuntime.xcframework
COMMAND xcodebuild -create-xcframework -library "${PROJECT_SOURCE_DIR}/MaaDeps/runtime/${MAADEPS_TRIPLET}/libonnxruntime.1.18.0.dylib" -output ONNXRuntime.xcframework
COMMAND xcodebuild -create-xcframework -library "${MAADEPS_DIR}/runtime/${MAADEPS_TRIPLET}/libonnxruntime.1.18.0.dylib" -output ONNXRuntime.xcframework
)
add_custom_command(OUTPUT fastdeploy_ppocr.xcframework
COMMAND rm -rf fastdeploy_ppocr.xcframework
COMMAND xcodebuild -create-xcframework -library "${PROJECT_SOURCE_DIR}/MaaDeps/runtime/${MAADEPS_TRIPLET}/libfastdeploy_ppocr.dylib" -output fastdeploy_ppocr.xcframework
COMMAND xcodebuild -create-xcframework -library "${MAADEPS_DIR}/runtime/${MAADEPS_TRIPLET}/libfastdeploy_ppocr.dylib" -output fastdeploy_ppocr.xcframework
)
add_custom_target(MaaXCFramework ALL
DEPENDS MaaCore MaaCore.xcframework OpenCV.xcframework ONNXRuntime.xcframework fastdeploy_ppocr.xcframework
DEPENDS MaaCore MaaCore.xcframework MaaUtils MaaUtils.xcframework OpenCV.xcframework ONNXRuntime.xcframework fastdeploy_ppocr.xcframework
)
endif (BUILD_XCFRAMEWORK)

View File

@@ -1,41 +0,0 @@
find_path(ONNXRuntime_INCLUDE_DIR NAMES onnxruntime/onnxruntime_c_api.h)
find_library(ONNXRuntime_LIBRARY_IMP NAMES onnxruntime)
if (WIN32)
get_filename_component(ONNXRuntime_PATH_LIB ${ONNXRuntime_LIBRARY_IMP} DIRECTORY)
find_file(ONNXRuntime_LIBRARY NAMES onnxruntime_maa.dll PATHS "${ONNXRuntime_PATH_LIB}/../bin")
find_file(ONNXRuntime_LIBRARY_IMP_DEBUG NAMES onnxruntime.lib PATHS "${ONNXRuntime_PATH_LIB}/../debug/lib")
find_file(ONNXRuntime_LIBRARY_DEBUG NAMES onnxruntime_maa.dll PATHS "${ONNXRuntime_PATH_LIB}/../debug/bin")
else ()
set(ONNXRuntime_LIBRARY ${ONNXRuntime_LIBRARY_IMP})
endif (WIN32)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
ONNXRuntime
REQUIRED_VARS ONNXRuntime_LIBRARY_IMP ONNXRuntime_INCLUDE_DIR
)
if(ONNXRuntime_FOUND)
set(ONNXRuntime_INCLUDE_DIRS ${ONNXRuntime_INCLUDE_DIR})
if(NOT TARGET ONNXRuntime::ONNXRuntime)
add_library(ONNXRuntime::ONNXRuntime SHARED IMPORTED)
set_property(TARGET ONNXRuntime::ONNXRuntime APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
if (WIN32)
set_property(TARGET ONNXRuntime::ONNXRuntime APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(ONNXRuntime::ONNXRuntime PROPERTIES
IMPORTED_IMPLIB_RELEASE "${ONNXRuntime_LIBRARY_IMP}"
)
set_target_properties(ONNXRuntime::ONNXRuntime PROPERTIES
IMPORTED_IMPLIB_DEBUG "${ONNXRuntime_LIBRARY_IMP_DEBUG}"
IMPORTED_LOCATION_DEBUG "${ONNXRuntime_LIBRARY_DEBUG}"
)
endif (WIN32)
set_target_properties(ONNXRuntime::ONNXRuntime PROPERTIES
IMPORTED_LOCATION_RELEASE "${ONNXRuntime_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${ONNXRuntime_INCLUDE_DIR}"
)
endif()
endif()

View File

@@ -1,50 +1,3 @@
function(download_and_decompress url filename sha256_checksum decompress_dir)
if(EXISTS ${filename})
file(SHA256 ${filename} CHECKSUM_VARIABLE)
endif()
if(NOT EXISTS ${filename} OR NOT CHECKSUM_VARIABLE STREQUAL sha256_checksum)
message("Downloading file from ${url} to ${filename} ...")
file(
DOWNLOAD ${url} "${filename}.tmp"
SHOW_PROGRESS
EXPECTED_HASH SHA256=${sha256_checksum})
file(RENAME "${filename}.tmp" ${filename})
endif()
if(NOT EXISTS ${decompress_dir})
file(MAKE_DIRECTORY ${decompress_dir})
endif()
message("Decompress file ${filename} ...")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${filename} WORKING_DIRECTORY ${decompress_dir})
endfunction()
function(get_osx_architecture)
if(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
set(CURRENT_OSX_ARCH
"arm64"
PARENT_SCOPE)
elseif(CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64")
set(CURRENT_OSX_ARCH
"x86_64"
PARENT_SCOPE)
else()
set(CURRENT_OSX_ARCH
${CMAKE_HOST_SYSTEM_PROCESSOR}
PARENT_SCOPE)
endif()
endfunction()
if(APPLE)
set(CMAKE_OSX_DEPLOYMENT_TARGET 13.3) # for to_chars
get_osx_architecture()
endif(APPLE)
if(NOT DEFINED MAADEPS_TRIPLET)
detect_maadeps_triplet(MAADEPS_TRIPLET)
endif()
# 创建资源目录链接的函数
function(create_resource_link TARGET_NAME OUTPUT_DIR)
if(WIN32)
@@ -70,4 +23,4 @@ function(create_resource_link TARGET_NAME OUTPUT_DIR)
COMMENT "Creating symlink for resource directory for ${TARGET_NAME}"
)
endif()
endfunction()
endfunction()

View File

@@ -1,27 +0,0 @@
# define MAA_HASH_VERSION from git
set(MAA_HASH_VERSION
"DEBUG_VERSION"
CACHE STRING "maa version")
if(WITH_HASH_VERSION AND MAA_HASH_VERSION STREQUAL "DEBUG_VERSION")
find_package(Git)
if(GIT_FOUND)
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE err
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(result EQUAL 0)
set(MAA_HASH_VERSION "${output}")
else()
message(WARNING "git rev-parse returning ${result}, output:\n${err}")
endif()
endif()
endif()
message(STATUS "MAA_HASH_VERSION=${MAA_HASH_VERSION}")
add_compile_definitions(MAA_VERSION="${MAA_HASH_VERSION}")

View File

@@ -1,2 +1 @@
**/pnpm-lock.yaml
**/*.md

View File

@@ -11,12 +11,6 @@ module.exports = {
arrowParens: 'always',
overrides: [
{
files: ['**/*.ts'],
options: {
semi: true,
},
},
{
files: ['**/*.*css'],
options: {
@@ -36,5 +30,11 @@ module.exports = {
tabWidth: 4,
},
},
{
files: ['**/*.md'],
options: {
embeddedLanguageFormatting: 'off',
},
},
],
}

View File

@@ -1,11 +1,21 @@
import { defineClientConfig } from 'vuepress/client';
import { defineClientConfig } from 'vuepress/client'
import ImageGrid from './components/ImageGrid.vue';
import { getAsciiArt } from './plugins/asciiArt'
import './styles/index.scss';
import AsciiArt from './components/AsciiArt.vue'
import ImageGrid from './components/ImageGrid.vue'
import Redirect from './components/Redirect.vue'
import './styles/index.scss'
export default defineClientConfig({
enhance: ({ app }) => {
app.component('ImageGrid', ImageGrid);
app.component('AsciiArt', AsciiArt)
app.component('ImageGrid', ImageGrid)
app.component('Redirect', Redirect)
// 输出一个随机的字符画
const asciiArtData = getAsciiArt(undefined, 'auto', 'console')
console.log('%c' + asciiArtData.text, 'white-space: pre;')
},
});
})

View File

@@ -0,0 +1,106 @@
<template>
<div ref="asciiArtWrapperElement" class="ascii-art-wrapper">
<pre ref="asciiArtContentElement" class="ascii-art-content">{{ asciiArtText }}</pre>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { getAsciiArt, ThemeType, AsciiArtScope } from '../plugins/asciiArt'
// -------- Props --------
interface AsciiArtProps {
name?: string
theme?: ThemeType
scope?: AsciiArtScope
}
const props = defineProps<AsciiArtProps>()
// -------- Refs --------
const asciiArtWrapperElement = ref<HTMLElement>()
const asciiArtContentElement = ref<HTMLElement>()
// -------- Data --------
let asciiArtNameInUse = props.name
const asciiArtText = ref('')
let layoutObserver: ResizeObserver
let themeObserver: MutationObserver
let isScaleUpLocked = false
let lastScaleRatio = 1
function refreshAsciiArt() {
const asciiArtData = getAsciiArt(asciiArtNameInUse, props.theme, props.scope)
asciiArtNameInUse = asciiArtData.name
asciiArtText.value = asciiArtData.text
}
function scaleAsciiArt() {
if (!asciiArtWrapperElement.value || !asciiArtContentElement.value) return
// 原始高度和宽度无视scale
const contentWidth = asciiArtContentElement.value.scrollWidth
const contentHeight = asciiArtContentElement.value.scrollHeight
if (contentWidth === 0 || contentHeight === 0) return
const targetWidth = asciiArtWrapperElement.value.clientWidth
const targetHeight = window.innerHeight
const scaleRatio = Math.min(targetWidth / contentWidth, targetHeight / contentHeight)
// 锁定状态不允许放大
if (scaleRatio > lastScaleRatio && isScaleUpLocked) return
lastScaleRatio = scaleRatio
isScaleUpLocked = true
asciiArtContentElement.value.style.transform = `scale(${scaleRatio})`
asciiArtWrapperElement.value.style.height = `${contentHeight * scaleRatio}px`
}
function forceScaleAsciiArt() {
isScaleUpLocked = false
scaleAsciiArt()
}
onMounted(() => {
if (!asciiArtWrapperElement.value || !asciiArtContentElement.value) return
layoutObserver = new ResizeObserver(scaleAsciiArt)
layoutObserver.observe(asciiArtContentElement.value)
layoutObserver.observe(asciiArtWrapperElement.value)
themeObserver = new MutationObserver(refreshAsciiArt)
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] })
window.addEventListener('resize', forceScaleAsciiArt)
refreshAsciiArt()
})
onBeforeUnmount(() => {
if (layoutObserver) {
layoutObserver.disconnect()
}
if (themeObserver) {
themeObserver.disconnect()
}
window.removeEventListener('resize', forceScaleAsciiArt)
})
</script>
<style scoped>
.ascii-art-wrapper {
display: flex;
justify-content: center;
align-items: flex-start;
}
.ascii-art-content {
display: block;
white-space: pre;
margin: 0 auto;
transform-origin: top;
line-height: 1;
font-family: 'JetBrains Mono', monospace;
}
</style>

View File

@@ -0,0 +1,25 @@
<template />
<script setup lang="ts">
import { onMounted } from 'vue'
import { useRouter, useRoute } from 'vuepress/client'
interface Props {
to?: string
}
const props = defineProps<Props>()
const route = useRoute()
const router = useRouter()
function resolvePath(to: string) {
const target = new URL(to, 'http://example.com' + route.path) // 使用一个虚拟的基础 URL
return target.pathname
}
onMounted(() => {
if (!props.to) return
const targetPath = resolvePath(props.to)
router.replace(targetPath)
})
</script>

View File

@@ -1,11 +1,13 @@
import { viteBundler } from '@vuepress/bundler-vite';
import { defineUserConfig } from 'vuepress';
import { googleAnalyticsPlugin } from '@vuepress/plugin-google-analytics';
import { plumeTheme } from 'vuepress-theme-plume';
import { viteBundler } from '@vuepress/bundler-vite'
import { defineUserConfig } from 'vuepress'
import { googleAnalyticsPlugin } from '@vuepress/plugin-google-analytics'
import { plumeTheme } from 'vuepress-theme-plume'
import DocSearchConfig from './plugins/search';
import { genSiteLocales } from './navigation/genLocales'
const isProd = process.env.NODE_ENV === 'production';
import DocSearchConfig from './plugins/search'
const isProd = process.env.NODE_ENV === 'production'
export default defineUserConfig({
base: '/',
@@ -15,33 +17,7 @@ export default defineUserConfig({
host: '0.0.0.0',
port: 3001,
locales: {
'/zh-cn/': {
lang: 'zh-CN',
title: 'MAA 文档站',
description: '文档',
},
'/zh-tw/': {
lang: 'zh-TW',
title: 'MAA 文件站',
description: '文件',
},
'/en-us/': {
lang: 'en-US',
title: 'MAA Documentation Site',
description: 'Documentation',
},
'/ja-jp/': {
lang: 'ja-JP',
title: 'MAA ドキュメントサイト',
description: 'ドキュメント',
},
'/ko-kr/': {
lang: 'ko-KR',
title: 'MAA 문서 사이트',
description: '문서',
},
},
locales: genSiteLocales(),
head: [
['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }],
@@ -88,17 +64,16 @@ export default defineUserConfig({
contributors: false,
changelog: false,
blog: false,
cache: 'filesystem',
search: DocSearchConfig,
codeHighlighter: {
themes: { light: 'one-light', dark: 'one-dark-pro' },
themes: { light: 'snazzy-light', dark: 'night-owl' },
},
markdown: {
annotation: true,
image: {
lazyload: true,
mark: true,
@@ -132,4 +107,4 @@ export default defineUserConfig({
id: 'G-FJQDKG394Z',
}),
],
});
})

View File

@@ -1,5 +0,0 @@
declare module '*.vue' {
import { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}

View File

@@ -1,19 +0,0 @@
import { defineNavbarConfig } from 'vuepress-theme-plume';
export const enusNavbar = defineNavbarConfig([
{
text: 'User Manual',
icon: 'mdi:user',
link: '/en-us/manual/newbie.html',
},
{
text: 'Development Docs',
icon: 'ph:code-bold',
link: '/en-us/develop/development.html',
},
{
text: 'Protocol Docs',
icon: 'basil:document-solid',
link: '/en-us/protocol/integration.html',
},
]);

View File

@@ -1,5 +0,0 @@
export * from './zh-cn';
export * from './zh-tw';
export * from './en-us';
export * from './ja-jp';
export * from './ko-kr';

View File

@@ -1,19 +0,0 @@
import { defineNavbarConfig } from 'vuepress-theme-plume';
export const jajpNavbar = defineNavbarConfig([
{
text: '使用説明',
icon: 'mdi:user',
link: '/ja-jp/manual/newbie.html',
},
{
text: '開発関連',
icon: 'ph:code-bold',
link: '/ja-jp/develop/development.html',
},
{
text: 'プロトコルドキュメント',
icon: 'basil:document-solid',
link: '/ja-jp/protocol/integration.html',
},
]);

View File

@@ -1,19 +0,0 @@
import { defineNavbarConfig } from 'vuepress-theme-plume';
export const kokrNavbar = defineNavbarConfig([
{
text: '사용자 설명서',
icon: 'mdi:user',
link: '/ko-kr/manual/newbie.html',
},
{
text: '개발 문서',
icon: 'ph:code-bold',
link: '/ko-kr/develop/development.html',
},
{
text: '프로토콜 문서',
icon: 'basil:document-solid',
link: '/ko-kr/protocol/integration.html',
},
]);

View File

@@ -1,19 +0,0 @@
import { defineNavbarConfig } from 'vuepress-theme-plume';
export const zhcnNavbar = defineNavbarConfig([
{
text: '用户手册',
icon: 'mdi:user',
link: '/zh-cn/manual/newbie.html',
},
{
text: '开发文档',
icon: 'ph:code-bold',
link: '/zh-cn/develop/development.html',
},
{
text: '协议文档',
icon: 'basil:document-solid',
link: '/zh-cn/protocol/integration.html',
},
]);

View File

@@ -1,19 +0,0 @@
import { defineNavbarConfig } from 'vuepress-theme-plume';
export const zhtwNavbar = defineNavbarConfig([
{
text: '用戶說明書',
icon: 'mdi:user',
link: '/zh-tw/manual/newbie.html',
},
{
text: '開發文件',
icon: 'ph:code-bold',
link: '/zh-tw/develop/development.html',
},
{
text: '協議文件',
icon: 'basil:document-solid',
link: '/zh-tw/protocol/integration.html',
},
]);

View File

@@ -0,0 +1,29 @@
import { SiteLocaleConfig, LocaleConfig } from 'vuepress'
import { ThemeLocaleData } from 'vuepress-theme-plume'
import { locales } from './i18n'
import { genNavigationComponents } from './genNavigationComponents'
export function genSiteLocales(): SiteLocaleConfig {
const siteLocales: SiteLocaleConfig = {}
for (const locale of locales) {
siteLocales[`/${locale.name}/`] = {
lang: locale.htmlLang,
title: locale.siteTitle,
description: locale.siteDescription,
}
}
return siteLocales
}
export function genThemeLocales(): LocaleConfig<ThemeLocaleData> {
const themeLocales: LocaleConfig<ThemeLocaleData> = {}
for (const locale of locales) {
const navigationComponents = genNavigationComponents(locale)
themeLocales[`/${locale.name}/`] = {
navbar: navigationComponents.navbar,
collections: navigationComponents.collections,
}
}
return themeLocales
}

View File

@@ -0,0 +1,161 @@
import * as fs from 'fs'
import * as path from 'path'
import { default as matter } from 'gray-matter'
import { ThemeCollectionItem, ThemeNavItem, ThemeSidebarItem } from 'vuepress-theme-plume'
import { Locale } from './i18n'
interface MetaData {
baseName: string
order: number
title: string
icon: string
index: boolean
}
interface NavigationComponents {
navbar: ThemeNavItem[]
collections: ThemeCollectionItem[]
}
type SidebarItem = ThemeSidebarItem | string
function getMetaData(dir: string, entry: fs.Dirent): MetaData | null {
const currentPath = path.join(dir, entry.name)
if (!fs.existsSync(currentPath)) {
return null
}
let mdFilePath = ''
if (entry.isDirectory()) {
mdFilePath = path.join(currentPath, 'README.md')
} else if (entry.isFile() && entry.name.endsWith('.md') && entry.name.toLowerCase() !== 'readme.md') {
mdFilePath = currentPath
} else {
return null
}
if (!fs.existsSync(mdFilePath)) {
return null
}
const fileContent = fs.readFileSync(mdFilePath, 'utf-8')
const meta = matter(fileContent).data ?? {}
// 文件名,不含扩展名
const baseName = path.parse(entry.name).name
// 获取顺序目录的order在meta.dir.order里文件的order在meta.order里默认值为一个大数
const order = Number((entry.isDirectory() ? meta?.dir?.order : meta?.order) ?? Number.MAX_SAFE_INTEGER)
// 获取标题先从matter里找title再用正则获取一级标题最后fallback到文件名不含扩展名
const title = String(meta?.title ?? RegExp('# (.+)').exec(fileContent)?.[1] ?? baseName)
// 获取图标
const icon = String(meta?.icon ?? '')
// 是否添加到索引文件永远为true目录则看meta.index默认true
const index = entry.isDirectory() ? (Boolean(meta?.index) ?? true) : true
return {
baseName: baseName,
order: order,
title: title,
icon: icon,
index: index,
}
}
function getSidebarItems(dir: string): SidebarItem[] {
interface WrappedSidebarItem {
sidebarItem: SidebarItem
order: number
}
const entries = fs.readdirSync(dir, { withFileTypes: true }).filter((e) => !e.name.startsWith('.'))
const sidebarItemsWithOrder: WrappedSidebarItem[] = []
for (const entry of entries) {
let sidebarItem: SidebarItem
const metaData = getMetaData(dir, entry)
if (!metaData) {
continue
}
if (entry.isDirectory()) {
const children = getSidebarItems(path.join(dir, entry.name))
// 可折叠的子目录
sidebarItem = {
text: metaData.title,
// 只有当目录设置了index: true时才生成链接否则点击时不跳转、只切换折叠状态
link: metaData.index ? `${metaData.baseName}/` : undefined,
icon: metaData.icon,
// 目前没有文档使用了badge这个特性故不处理
// badge: undefined,
collapsed: true,
// 前面不能加斜杠,必须用相对路径
prefix: `${metaData.baseName}/`,
items: children,
}
} else if (entry.isFile() && entry.name.endsWith('.md') && entry.name.toLowerCase() !== 'readme.md') {
// 普通文件,取完整文件名作为链接
sidebarItem = entry.name
}
sidebarItemsWithOrder.push({ sidebarItem: sidebarItem, order: metaData.order })
}
sidebarItemsWithOrder.sort((a, b) => a.order - b.order)
return sidebarItemsWithOrder.map((i) => i.sidebarItem)
}
export function genNavigationComponents(
locale: Locale,
baseDir = path.resolve(__dirname, '../../'),
): NavigationComponents {
interface WrappedNavigationComponent {
navItem: ThemeNavItem
collectionItem: ThemeCollectionItem
order: number
}
const navigationComponentsWithOrder: WrappedNavigationComponent[] = []
// 进入指定语言目录即docs/<i18n>/
const langDir = path.join(baseDir, locale.name)
// 获取所有非隐藏文件和目录
const entries = fs.readdirSync(langDir, { withFileTypes: true }).filter((e) => !e.name.startsWith('.'))
for (const entry of entries) {
if (!entry.isDirectory()) continue
const metaData = getMetaData(langDir, entry)
if (!metaData) {
continue
}
const navbarItem: ThemeNavItem = {
text: metaData.title,
icon: metaData.icon,
link: `/${locale.name}/${metaData.baseName}/`,
}
const collectionItem: ThemeCollectionItem = {
type: 'doc',
title: metaData.title,
dir: metaData.baseName,
linkPrefix: `/${metaData.baseName}/`,
sidebar: getSidebarItems(path.join(langDir, entry.name)),
}
navigationComponentsWithOrder.push({
navItem: navbarItem,
collectionItem: collectionItem,
order: metaData.order,
})
}
navigationComponentsWithOrder.sort((a, b) => a.order - b.order)
return {
navbar: navigationComponentsWithOrder.map((i) => i.navItem),
collections: navigationComponentsWithOrder.map((i) => i.collectionItem),
}
}

View File

@@ -0,0 +1,45 @@
export interface Locale {
name: string
// displayName: string
htmlLang: string
siteTitle: string
siteDescription: string
}
export const locales: Locale[] = [
{
name: 'zh-cn',
// displayName: '简体中文',
htmlLang: 'zh-CN',
siteTitle: 'MAA 文档站',
siteDescription: '文档',
},
{
name: 'zh-tw',
// displayName: '繁體中文',
htmlLang: 'zh-TW',
siteTitle: 'MAA 文件站',
siteDescription: '文件',
},
{
name: 'en-us',
// displayName: 'English',
htmlLang: 'en-US',
siteTitle: 'MAA Documentation Site',
siteDescription: 'Documentation',
},
{
name: 'ja-jp',
// displayName: '日本語',
htmlLang: 'ja-JP',
siteTitle: 'MAA ドキュメントサイト',
siteDescription: 'ドキュメント',
},
{
name: 'ko-kr',
// displayName: '한국어',
htmlLang: 'ko-KR',
siteTitle: 'MAA 문서 사이트',
siteDescription: '문서',
},
]

View File

@@ -1,8 +0,0 @@
import { defineNotesConfig } from 'vuepress-theme-plume';
import { genNotes } from './genSidebar';
export const enusNotes = defineNotesConfig({
dir: 'en-us',
link: '/en-us/',
notes: genNotes('en-us'),
});

View File

@@ -1,119 +0,0 @@
import * as fs from 'fs';
import * as path from 'path';
import * as matterModule from 'gray-matter';
import { defineNoteConfig, ThemeNote, ThemeSidebarItem } from 'vuepress-theme-plume';
const matter = (matterModule as any).default;
interface MetaData {
baseName: string;
order: number;
title: string;
icon: string;
index: boolean;
}
function getMetaData(dir: string, entry: fs.Dirent): MetaData | null {
const currentPath = path.join(dir, entry.name);
if (!fs.existsSync(currentPath)) {
return null;
}
let mdFilePath = '';
if (entry.isDirectory()) {
mdFilePath = path.join(currentPath, 'README.md');
} else if (entry.isFile() && entry.name.endsWith('.md') && entry.name.toLowerCase() !== 'readme.md') {
mdFilePath = currentPath;
} else {
return null;
}
if (!fs.existsSync(mdFilePath)) {
return null;
}
const fileContent = fs.readFileSync(mdFilePath, 'utf-8');
const meta = matter(fileContent).data ?? {};
const baseName = path.parse(entry.name).name;
// 获取顺序目录的order在meta.dir.order里文件的order在meta.order里默认值为一个大数
const order = Number((entry.isDirectory() ? meta?.dir?.order : meta?.order) ?? Number.MAX_SAFE_INTEGER);
// 获取标题先从matter里找title再用正则获取一级标题最后fallback到文件名不含扩展名
const title = String(meta?.title ?? RegExp('# (.+)').exec(fileContent)?.[1] ?? baseName);
// 获取图标
const icon = String(meta?.icon ?? '');
// 是否作为索引页文件永远为true目录则看meta.index默认true
const index = entry.isDirectory() ? (Boolean(meta?.index) ?? true) : true;
return {
baseName: baseName,
order: order,
title: title,
icon: icon,
index: index,
};
}
export function genNotes(lang: string, baseDir = path.resolve(__dirname, '../../')): ThemeNote[] {
// 进入指定语言目录即docs/<i18n>/
const langDir = path.join(baseDir, lang);
// 递归获取目录和文件
function getItems(dir: string, isRoot: boolean): any[] {
// 将内容与对应顺序进行包装
interface Wrapped {
content: ThemeNote | ThemeSidebarItem | string;
order: number;
}
let itemsWithOrder: Wrapped[] = [];
// 获取所有非隐藏文件和目录
const entries = fs.readdirSync(dir, { withFileTypes: true }).filter((e) => !e.name.startsWith('.'));
for (const entry of entries) {
const metaData = getMetaData(dir, entry);
if (!metaData) {
continue;
}
if (entry.isDirectory()) {
// 递归获取子目录内容
const children = getItems(path.join(dir, entry.name), false);
if (isRoot) {
// 一级目录,作为“专题”
const item = defineNoteConfig({
dir: metaData.baseName,
link: `/${metaData.baseName}/`,
text: metaData.title,
sidebar: children,
});
itemsWithOrder.push({ content: item, order: metaData.order });
} else {
// 非一级目录,作为可折叠的子目录
const item: ThemeSidebarItem = {
text: metaData.title,
// 只有当目录设置了index: true时才生成链接否则点击时不跳转、只切换折叠状态
link: metaData.index ? `${metaData.baseName}/` : undefined,
icon: metaData.icon,
// 目前没有文档使用了这个特性,故不处理
// badge: undefined,
collapsed: true,
// 前面不能加斜杠,必须用相对路径
prefix: `${metaData.baseName}/`,
items: children,
};
itemsWithOrder.push({ content: item, order: metaData.order });
}
} else if (entry.isFile() && entry.name.endsWith('.md') && entry.name.toLowerCase() !== 'readme.md') {
// 普通文件,取完整文件名作为链接
const item = entry.name;
itemsWithOrder.push({ content: item, order: metaData.order });
}
}
// 当前dir的内容读取完毕进行排序并返回返回时丢弃order
itemsWithOrder.sort((a, b) => a.order - b.order);
return itemsWithOrder.map((i) => i.content);
}
// 递归起点只有这里是一级目录isRoot传true
return getItems(langDir, true);
}

View File

@@ -1,5 +0,0 @@
export * from './zh-cn';
export * from './zh-tw';
export * from './en-us';
export * from './ja-jp';
export * from './ko-kr';

View File

@@ -1,8 +0,0 @@
import { defineNotesConfig } from 'vuepress-theme-plume';
import { genNotes } from './genSidebar';
export const jajpNotes = defineNotesConfig({
dir: 'ja-jp',
link: '/ja-jp/',
notes: genNotes('ja-jp'),
});

View File

@@ -1,8 +0,0 @@
import { defineNotesConfig } from 'vuepress-theme-plume';
import { genNotes } from './genSidebar';
export const kokrNotes = defineNotesConfig({
dir: 'ko-kr',
link: '/ko-kr/',
notes: genNotes('ko-kr'),
});

View File

@@ -1,8 +0,0 @@
import { defineNotesConfig } from 'vuepress-theme-plume';
import { genNotes } from './genSidebar';
export const zhcnNotes = defineNotesConfig({
dir: 'zh-cn',
link: '/zh-cn/',
notes: genNotes('zh-cn'),
});

View File

@@ -1,8 +0,0 @@
import { defineNotesConfig } from 'vuepress-theme-plume';
import { genNotes } from './genSidebar';
export const zhtwNotes = defineNotesConfig({
dir: 'zh-tw',
link: '/zh-tw/',
notes: genNotes('zh-tw'),
});

View File

@@ -0,0 +1,90 @@
const modules = import.meta.glob<string>('../../asciiArts/*.txt', { query: '?raw', import: 'default', eager: true })
const asciiArts: Record<string, string> = {}
for (const path in modules) {
const name = path
.split('/')
.pop()
?.replace(/\.txt$/, '')!
asciiArts[name] = modules[path]
}
export type ThemeType = 'auto' | 'disable' | string
export type AsciiArtScope = 'web' | 'console'
interface AsciiArtData {
name: string | null
text: string
}
function pickAsciiArt(
arts: Record<string, string>,
artFilter?: (key: string) => boolean,
keyToName?: (key: string) => string,
): AsciiArtData {
const keys = artFilter ? Object.keys(arts).filter(artFilter) : Object.keys(arts)
let asciiArtKey: string | null
let asciiArtText: string
if (keys.length === 0) {
asciiArtKey = null
asciiArtText = ''
} else if (keys.length === 1) {
asciiArtKey = keys[0]
asciiArtText = arts[keys[0]]
} else {
const randomKey = keys[Math.floor(Math.random() * keys.length)]
asciiArtKey = randomKey
asciiArtText = arts[randomKey]
}
if (!asciiArtKey || !keyToName) {
return { name: asciiArtKey, text: asciiArtText }
} else {
return { name: keyToName(asciiArtKey), text: asciiArtText }
}
}
export function getAsciiArt(name?: string, theme: ThemeType = 'auto', scope: AsciiArtScope = 'web'): AsciiArtData {
let resolvedTheme: ThemeType = theme
// auto 模式
if (theme === 'auto') {
let currentTheme: string | null = null
if (scope === 'web' && typeof document !== 'undefined') {
// 浏览器中读取 HTML data-theme
currentTheme = document?.documentElement?.getAttribute('data-theme')
} else if (scope === 'console' && typeof window !== 'undefined' && window.matchMedia) {
// fallback: 检查系统首选主题
currentTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
resolvedTheme = currentTheme ? currentTheme : 'disable'
}
if (resolvedTheme !== 'disable') {
// light/dark/... 模式
return name
? pickAsciiArt(
asciiArts,
(k) => k === name + '.' + resolvedTheme,
() => name,
)
: pickAsciiArt(
asciiArts,
(k) => k.endsWith('.' + resolvedTheme),
(k) => k.replace(new RegExp('\\.' + resolvedTheme + '$'), ''),
)
} else {
// disable 模式
return name
? pickAsciiArt(
asciiArts,
(k) => k === name || k.startsWith(name + '.'),
() => name,
)
: pickAsciiArt(
asciiArts,
() => true,
(k) => k,
)
}
}

View File

@@ -1,7 +1,7 @@
export default {
provider: 'algolia' as const,
appId: '99JM20SIFG',
apiKey: '7596a5a8c95cd64d4cf3050c9a4f878e',
appId: '9ARM1N4899',
apiKey: 'f42bf1d18c786d5a46da30eccac5cb34',
indexName: 'maa',
locales: {
'/zh-cn/': {
@@ -81,4 +81,4 @@ export default {
},
},
},
};
}

View File

@@ -1,6 +1,5 @@
import { defineThemeConfig } from 'vuepress-theme-plume';
import { zhcnNavbar, zhtwNavbar, enusNavbar, jajpNavbar, kokrNavbar } from './navbar';
import { zhcnNotes, zhtwNotes, enusNotes, jajpNotes, kokrNotes } from './notes';
import { defineThemeConfig } from 'vuepress-theme-plume'
import { genThemeLocales } from './navigation/genLocales'
export default defineThemeConfig({
logo: '/images/maa-logo_512x512.png',
@@ -25,28 +24,7 @@ export default defineThemeConfig({
footer: false,
locales: {
'/zh-cn/': {
navbar: zhcnNavbar,
notes: zhcnNotes,
},
'/zh-tw/': {
navbar: zhtwNavbar,
notes: zhtwNotes,
},
'/en-us/': {
navbar: enusNavbar,
notes: enusNotes,
},
'/ja-jp/': {
navbar: jajpNavbar,
notes: jajpNotes,
},
'/ko-kr/': {
navbar: kokrNavbar,
notes: kokrNotes,
},
},
locales: genThemeLocales(),
autoFrontmatter: false,
@@ -126,4 +104,4 @@ export default defineThemeConfig({
// },
// ],
//},
});
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 KiB

View File

@@ -25,7 +25,7 @@
align-items: center;
justify-content: center;
.container {
.doc-hero-container {
margin: 0 auto;
display: flex;
align-items: center;
@@ -37,4 +37,24 @@
font-size: var(--vp-home-hero-name-font-size) !important;
line-height: var(--vp-home-hero-name-line-height) !important;
}
/* 首页标题 */
.name.clip {
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
/* 按钮组容器 */
.actions .action {
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 100%;
padding: 0;
}
/* 按钮 */
.actions .action .vp-button {
margin: 0.5rem;
min-width: 7em;
}
}

View File

@@ -1,22 +1,2 @@
@use "home.scss";
@use "fonts.scss";
/* 按钮组容器 */
.actions .action {
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 100%;
padding: 0;
}
/* 按钮 */
.actions .action .vp-button {
margin: 0.5rem;
min-width: 7em;
}
/* 首页标题 */
.is-home .name.clip {
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

View File

@@ -1,74 +1,14 @@
---
home: true
pageInfo: false
breadcrumb: false
navbar: false
sidebar: false
index: false
lastUpdated: false
editLink: false
contributors: false
prev: false
next: false
config:
- type: custom
---
!: .7:~!.
:. :?55 ?5~::~J?:
:P5YY?7~: .!JYYJG. 7P! .7Y!.
^5JJJY55PPG5!. .?JYYJYG. ~P?. ~YJ: :PY~.
^5YYYYYYY5PPPPYJ??7!!~^!?YYYYY5 :5Y. :J5!. :G&#5^
~PY5555555PPPGGPPPPPPPPJ5YJYPP???5?57::.. !5J: Y&##P:
^YPP5JJY5555PPGG55PP555PGPPPGGPPP555555555YYYJJ?77!~^::...~5P^:. P####7
!GPPJ?JYYYYY5P5PPG57:...:!5GG?~!?JJY55PPPPPPPPPPP555555555YJYPYY57!~^::... .#####!
.?PY?YYYYYYY5PP5G?..:!??JYYPYY7. .....:^~!?JJYY5PPPPPPPP555555555555YYYJJ?77!!B####P
.5Y5YYYYYY555PGY.!?JYJJYJ5P:.?5^...:.::^~^^:::... ....::::~!!7?J5P55PPPPPPPP5P55PPGG###P
.:~?P5555PPPPGY:J77YYJY55Y: ..Y5?Y5PPGGBBBBGGGGP555J!^. ^~...^!77YY5G5::~:.:!5#G
^5555PPPG5?.~5JYYYYY7: :~?5PPG5BBBBB########BBB####BGY7~~^:..:: .:^!~^~?Y7~. ~J7Y
P55PPPGY~...?5?~^:...:75PPGP5PG#####BGBBBBBBBBBB######BGGP5YJ???7!7JY?!!?YYYJYJ^^GJ..
.!?P5YPB^ ....... :!J5PGB#######BBGY7~!!7?PYJJ7!5GB#######BBGPYYYYYJJYYYYY55GB##5^...
75YYPG... .::::JPGB####BGPP55J5?^~~~~~~~~~~!!!?PGGBBBB#####GGBBBBBB##########&G^^~
Y5YYGY... ..:^7PBB#####GPJ!~~~^~?!~~~~~~~~~~~~!!J7!7?JPG###&###############&&&&#5~
.PYY5B!... ..^YBBBB####GPJ~~~~~~~?J!~~~^^~~^^~~^^~!!::^75GB####&&&&&&&&&&&&&&##BG5
^PYY5G:... .^^PB#B###GP5JJ7~~~~~~~!7?~~~^..^:^~~~!~~~!~^~~5JJ555G##&&&&&&&#BBBGGPB!
?5YYPP......:Y######G?!~!!~~~~~~~~~~!7^^^^:^~~~~~~!7~~!~^~~~~~!7?YGB###P77!:JGGGGB:
5YYYGJ..... 7#B####GP!^~!~~~~~~^::!~~!~^^~~~~!~~~~~!J!~7!^~~~~~~!?Y5GPPPP5!^PGGGGP
.7 .PYY5B^..:::^GBB####PP!^7!^^~~~^^:^7~~~!^~~~~~~7~!~~~?5J?J7:~~~~~~~!?YY5YY55PPPGGGP~^:
^5 ~PYYPG...:.!PP#####G5J!:?!^^~~~~~~~!~~~~^~~~~~!J7!??!!J!!JY~^~~~~~~~7?Y5YY55PPGGGGGB#P
^G J5YYGY ..:!5YB####G5!^~~?!~~~!~~~~~~~~~~~~~~~!!77..~7^7~ .:7^~~~~!!~JGPPGGGBGB#####GY^
^&! 5YY5B! ^J5YGB###B5!^~~~?7~~~!7~~^??!~~~!~~~~~~!! :77!.::~!^~~~7!~!Y#########BBP.
^&#~ :PYY5B:.!YYJG#####GG!~~~~7?~~~?J~7?P57~~~!7~~~!~7:..:~5PGBJ~^!^~~!J~~!7P##B###BGGG7
^&##Y^. ?P5PGGJYYYYPB#####BG!~~~~~J!~!55?7?!~J?!!77!777?::JPBBGP5J~ .!~~7J!~~!7YGG5BBGGGGB:
^&###BG555YYYY5GBBB#B#####GGJ~~~~^7775?J~!!. .~??J?7??J7..!:7?7YY~7.^!~?J!~~!!7JP55PBGGGGG
^&######BBBBB##########&#B5?!~~~~^~55~.7!~ .:~!7Y?J?!!~. :!~^~~.:^.??!!!7??YP5PPBGGGGY
^&###################&##PY7~~!~~~~:?~ ^7:.^?5GBG7?!:. ... .:.:J????JY?5P57^:^75B!
.G&&&############&&&###GYJ?~~7~~~~~:!:.!YBBBGP5J^ :?JJJJJYGPG!. .. .5:
!G#&&&&&&&&&&&&#B5?GGGY5?~~~~~~~~~^755^~Y??57~!. :!J55YYY55GGPY .. !.
.~YBBBB#GYJ?77~7BBP55P7~7!~!77~~~~~~~^^^!~^~! .. ^?PGGGGGGG#BP7 !.
^5YY5G^ ..!GP55555?YP5!~~!77!!7?J~. .^:. .. .^5#57GPBBBBBBP. ....:Y~
J5YYPP:...:7GP55555GP5G#P!~~~~!!!7?!:^:...:^: .^J?5GP:.YPY7JJGB#Y .:~YGB.
5YYYGJ:::^YGGY:?P5G#BB##B57!77777777???JJJYY: ..:~!!YP7YYP^ ??7~7?5BBBJ~!5GG5
:PYY5B!:^JGGPGBJ5G#####PJGPPJ5Y????JJJJJYY5PY?YYY??JJJ?7~!~JBG: !??~!?YBBB#BGGGB7
!5YYPG5GGGGB###?B###BB?!JG555PPYJ?77JYPP5GP57!J5G5YGGPY?!:~BP~^. .7J?~~?JBBB#5Y5GB:
Y5YY5Y5P5555^!PJPJ^?GGJYGPPGG!. .!Y55Y5Y: ..:~7J555JPPY!P~.~YJ?~~7JG#BBYYYPG
^7?JJYYYY5557:.^^:7PPY55YY5P7 :. !PPPBP^... .J!5B5BB57JYP7?~~!J5B#GYYYGY
...^J!~^.^JG55PPPPPGJ... . ~BP55PYJJJ?7~~^?5PGBBBGGPGGJ!^^~JYBBPYY5B!
^^^:.:::?. ...:^~~~~^^::~!.:PGGPPPP5555555555555555PPPGP??7?YYBB5YY5B.
...::^~!7?JYY5PPPPPPPP55555YYY555555555YYPP
...:^~!7??JY555PPPPP55555BJ
...:^^~!7?Y^
. . . . .
7^.::?7:^: :7?:...P:. :~~~7P~~~^. :Y ^~~G!~~. :J?:^.?^^5 !! Y^ :Y.. ~~~^~Y!^~~: :P. :^^^JY .7~!.!~::5.
.:. ~^ 7? :YJ.77.P:~? Y~~7P~~J: ~7J^~!!P7!!.::JY?J:Y ?^ ^G..5~:P^!J .YJ Y7^Y Y^ :? 5 Y. P
Y: :JY? .GY^?!.P.~? :!!~?P~~?7 .^? !?!!!7? .7YJ~~ Y ^7.~Y.!7!!!~7: :7!~Y.!!^ 5 ~7^^!G^^::? 5 7~^~?J
Y^ ^~^.~! 7?!.::.P::: ~!!~?P!!J5. .J JJ!!~7P .57:^P Y: Y^ J.5 !7 PY 7~ :5 ^^ .YP: P :5~5:^^^^.P
!!~7!^:::!~ ~! Y .~?7 .. .? ?^ .~!J ?7^~5 J::. J.7::^7^~! :5 .!: : :~J ^^!?
.
# Ciallo (∠・ω< )⌒★
<!-- markdownlint-disable-file -->
<!-- Use a Random Ascii Art -->
<AsciiArt theme="auto" />
<!-- Use a specific Ascii Art -->
<!-- <AsciiArt name="maa-logo-with-endorsement" theme="disable" /> -->

View File

@@ -1,5 +1,5 @@
---
pageLayout: home
home: true
title: 首页
config:
- type: doc-hero

View File

@@ -0,0 +1,59 @@
!: .7:~!.
:. :?55 ?5~::~J?:
:P5YY?7~: .!JYYJG. 7P! .7Y!.
^5JJJY55PPG5!. .?JYYJYG. ~P?. ~YJ: :PY~.
^5YYYYYYY5PPPPYJ??7!!~^!?YYYYY5 :5Y. :J5!. :G&#5^
~PY5555555PPPGGPPPPPPPPJ5YJYPP???5?57::.. !5J: Y&##P:
^YPP5JJY5555PPGG55PP555PGPPPGGPPP555555555YYYJJ?77!~^::...~5P^:. P####7
!GPPJ?JYYYYY5P5PPG57:...:!5GG?~!?JJY55PPPPPPPPPPP555555555YJYPYY57!~^::... .#####!
.?PY?YYYYYYY5PP5G?..:!??JYYPYY7. .....:^~!?JJYY5PPPPPPPP555555555555YYYJJ?77!!B####P
.5Y5YYYYYY555PGY.!?JYJJYJ5P:.?5^...:.::^~^^:::... ....::::~!!7?J5P55PPPPPPPP5P55PPGG###P
.:~?P5555PPPPGY:J77YYJY55Y: ..Y5?Y5PPGGBBBBGGGGP555J!^. ^~...^!77YY5G5::~:.:!5#G
^5555PPPG5?.~5JYYYYY7: :~?5PPG5BBBBB########BBB####BGY7~~^:..:: .:^!~^~?Y7~. ~J7Y
P55PPPGY~...?5?~^:...:75PPGP5PG#####BGBBBBBBBBBB######BGGP5YJ???7!7JY?!!?YYYJYJ^^GJ..
.!?P5YPB^ ....... :!J5PGB#######BBGY7~!!7?PYJJ7!5GB#######BBGPYYYYYJJYYYYY55GB##5^...
75YYPG... .::::JPGB####BGPP55J5?^~~~~~~~~~~!!!?PGGBBBB#####GGBBBBBB##########&G^^~
Y5YYGY... ..:^7PBB#####GPJ!~~~^~?!~~~~~~~~~~~~!!J7!7?JPG###&###############&&&&#5~
.PYY5B!... ..^YBBBB####GPJ~~~~~~~?J!~~~^^~~^^~~^^~!!::^75GB####&&&&&&&&&&&&&&##BG5
^PYY5G:... .^^PB#B###GP5JJ7~~~~~~~!7?~~~^..^:^~~~!~~~!~^~~5JJ555G##&&&&&&&#BBBGGPB!
?5YYPP......:Y######G?!~!!~~~~~~~~~~!7^^^^:^~~~~~~!7~~!~^~~~~~!7?YGB###P77!:JGGGGB:
5YYYGJ..... 7#B####GP!^~!~~~~~~^::!~~!~^^~~~~!~~~~~!J!~7!^~~~~~~!?Y5GPPPP5!^PGGGGP
.7 .PYY5B^..:::^GBB####PP!^7!^^~~~^^:^7~~~!^~~~~~~7~!~~~?5J?J7:~~~~~~~!?YY5YY55PPPGGGP~^:
^5 ~PYYPG...:.!PP#####G5J!:?!^^~~~~~~~!~~~~^~~~~~!J7!??!!J!!JY~^~~~~~~~7?Y5YY55PPGGGGGB#P
^G J5YYGY ..:!5YB####G5!^~~?!~~~!~~~~~~~~~~~~~~~!!77..~7^7~ .:7^~~~~!!~JGPPGGGBGB#####GY^
^&! 5YY5B! ^J5YGB###B5!^~~~?7~~~!7~~^??!~~~!~~~~~~!! :77!.::~!^~~~7!~!Y#########BBP.
^&#~ :PYY5B:.!YYJG#####GG!~~~~7?~~~?J~7?P57~~~!7~~~!~7:..:~5PGBJ~^!^~~!J~~!7P##B###BGGG7
^&##Y^. ?P5PGGJYYYYPB#####BG!~~~~~J!~!55?7?!~J?!!77!777?::JPBBGP5J~ .!~~7J!~~!7YGG5BBGGGGB:
^&###BG555YYYY5GBBB#B#####GGJ~~~~^7775?J~!!. .~??J?7??J7..!:7?7YY~7.^!~?J!~~!!7JP55PBGGGGG
^&######BBBBB##########&#B5?!~~~~^~55~.7!~ .:~!7Y?J?!!~. :!~^~~.:^.??!!!7??YP5PPBGGGGY
^&###################&##PY7~~!~~~~:?~ ^7:.^?5GBG7?!:. ... .:.:J????JY?5P57^:^75B!
.G&&&############&&&###GYJ?~~7~~~~~:!:.!YBBBGP5J^ :?JJJJJYGPG!. .. .5:
!G#&&&&&&&&&&&&#B5?GGGY5?~~~~~~~~~^755^~Y??57~!. :!J55YYY55GGPY .. !.
.~YBBBB#GYJ?77~7BBP55P7~7!~!77~~~~~~~^^^!~^~! .. ^?PGGGGGGG#BP7 !.
^5YY5G^ ..!GP55555?YP5!~~!77!!7?J~. .^:. .. .^5#57GPBBBBBBP. ....:Y~
J5YYPP:...:7GP55555GP5G#P!~~~~!!!7?!:^:...:^: .^J?5GP:.YPY7JJGB#Y .:~YGB.
5YYYGJ:::^YGGY:?P5G#BB##B57!77777777???JJJYY: ..:~!!YP7YYP^ ??7~7?5BBBJ~!5GG5
:PYY5B!:^JGGPGBJ5G#####PJGPPJ5Y????JJJJJYY5PY?YYY??JJJ?7~!~JBG: !??~!?YBBB#BGGGB7
!5YYPG5GGGGB###?B###BB?!JG555PPYJ?77JYPP5GP57!J5G5YGGPY?!:~BP~^. .7J?~~?JBBB#5Y5GB:
Y5YY5Y5P5555^!PJPJ^?GGJYGPPGG!. .!Y55Y5Y: ..:~7J555JPPY!P~.~YJ?~~7JG#BBYYYPG
^7?JJYYYY5557:.^^:7PPY55YY5P7 :. !PPPBP^... .J!5B5BB57JYP7?~~!J5B#GYYYGY
...^J!~^.^JG55PPPPPGJ... . ~BP55PYJJJ?7~~^?5PGBBBGGPGGJ!^^~JYBBPYY5B!
^^^:.:::?. ...:^~~~~^^::~!.:PGGPPPP5555555555555555PPPGP??7?YYBB5YY5B.
...::^~!7?JYY5PPPPPPPP55555YYY555555555YYPP
...:^~!7??JY555PPPPP55555BJ
...:^^~!7?Y^
. . . . .
7^.::?7:^: :7?:...P:. :~~~7P~~~^. :Y ^~~G!~~. :J?:^.?^^5 !! Y^ :Y.. ~~~^~Y!^~~: :P. :^^^JY .7~!.!~::5.
.:. ~^ 7? :YJ.77.P:~? Y~~7P~~J: ~7J^~!!P7!!.::JY?J:Y ?^ ^G..5~:P^!J .YJ Y7^Y Y^ :? 5 Y. P
Y: :JY? .GY^?!.P.~? :!!~?P~~?7 .^? !?!!!7? .7YJ~~ Y ^7.~Y.!7!!!~7: :7!~Y.!!^ 5 ~7^^!G^^::? 5 7~^~?J
Y^ ^~^.~! 7?!.::.P::: ~!!~?P!!J5. .J JJ!!~7P .57:^P Y: Y^ J.5 !7 PY 7~ :5 ^^ .YP: P :5~5:^^^^.P
!!~7!^:::!~ ~! Y .~?7 .. .? ?^ .~!J ?7^~5 J::. J.7::^7^~! :5 .!: : :~J ^^!?
.

View File

@@ -0,0 +1,72 @@
. ,:.
;, .,NNd'.
. 'cl:. .' ..
;;'... ,clllc. .' ..
.,cll;::;,'. .loclllc. .'. '.
.;lolllccc::;;,. .olccclcc. ., '. ...
:ccccccccc:::;,.. locccllcc. '' .,. .....
ccccccccccc:::;;::::;;,,'...xlccclcc: ''. '. .....
.cccccc:::::::::,;;;;:::ccc:llc:clcc''....lkx. ,. ......
';::;:cc:;::;;;;;,;::::;;;::,c::cc:,:ccccc::;;;,''.... ,. .......
,:::;odlcccc::::;;';:::::;;::;,;:;;,;::cccccccccccccccc::;;;,''.... .'';. .......
,:::;dlcccccccc:::;,;::;:d00Oxoc;,';;,,,,,;;;;;:::::cccccccccccccccc::;;;,'.',dx:. .......
.:::;dolcccccccc:::::;,lONNNNNKOkl;;:kXXKOkkxdolc::;,,,,;;;:::::::ccccccccccccccc:::;;,''.... .......
;;lolccccccccc:::::;kNNNOdlc:::cc;l;lXNNNNNNNNNXWWNXKOkxdoc:;;,,,,;;;;:::::ccccccccccccccccc:::;;,'......'.....
:occccccccccc::::;:NKdl:llllcccc,KO;:O0KXXNNNNNWNNNWWWWWWNXNNXKOdollccc:;,,,,;;;;::::::ccccccccccccccc:.;.....
,lcccccccccc:::::;;O0:odllllllll;lNNO;;0KKK000OkxooooddxxO0XNNNK0KXNNNNWWNX0Okxdoc;;;,,,,,;;;::::::;c:;;':.....
.::ccccc:::::;;,xO:xxoccllllc;cXNNNk;okdlc:,,;;;;,;;;;,,',;:ldx0NNNNNMWNNNNNNNN0x0XXKkdlcl:;;;,,c0OOok0xl,...
';::::;;;;;;;kKoloocllllc;:kNNNKkd,;,;:;;;;;,'''.'',,,;;;;;,'',:oxKNNNNKKXNNXkkKNNNKKkkxddxdo,XOOOXWNNNXd;.
:ccc::::::::dNN;lllll:;:oONN0Oxc;:,:'c,,,,'''..........''...'...''':lddkOKXXX00XNNXNKKkxdxxxdccoxXNNNNKclO;
'cc:::::;;;oK0X0;c::cod0XKXNKo;:c:;oolo'.......''....''........''..',;:cc:cclodxk0KNKOdodOKKOcc;:::oKN0;.;O0
;c;;;;;,'oXXNXN0;lxKNNXXXKXd::c:;,,',,......',,c;,,;;;;;;,,;;''.....'''',;:clolc:::c:c:;clc::cloool:,o0cckXN
.:ccc;'ONNNKXNNXXXXNX0Od::c;,''''.....''';;:dxxxdol:,::coxx;;,.......'''''',:ccloooooooooooollc:,...;K0XN0
,cccc;'XXNNNNNN00XO0NOc;c;'.....',',,,,;;;okkkkkkkkxoxxdddkkc:;'........'...'::;;;;:::;;;,,,'........,0K0O
;ccc:;;XXXNNNNNX00O0x;:;'......;';;::ccolckkkkkkkkkkkkkkkxodxo;;;;;,,,'......,,.......................;OO,
:ccc:,lXKXXNNNXK0Oko,:'.'.....'c,odxxkkkkoxkkkkkkkkkkkkkkkkdodcoolc::;c'...............................o.
.cccc;,xXKXXNNXKKOOl;,'''.....';;lxkkkkkkklldkkkkkkkkkkkkkkkk0xoxkOOkxo,:'............................''.
'cccc;'0XXXXNNXKKOo,,.'''...'',:lkkkkkkkkkdoldkkkkkOkkkOkkkkkOOkddkKKOxo;:,..........................';,
,cccc;,XXXXXNNKK0l''''''...';;::lxkkkkkkkkxoolkkkkOXKOkKKkkkkxkkkxdxO0kkx,;;;,,,,..................,;;;'
;ccc:,cNXXXXNXxkd.,''...';::coxdxkkkkkkkkkkddodOkkO0XXOkOkkkkkdxkkkdxOkkklxxdlccc:''..........,:l';;;;;'
:ccc:,xXXXXXNX0O;',..'...:ldkkddkkkkkkkkkkkkkxoOk0Ok0KOkkkkkkkkddkkkdk0kkkkkkkxoooc,'....,odxok0x';;;;;.
.cccc;'0XXKKXNXXx''..'..',cdkkkxkkkkkkkkkOOxkkkxxOOOkkkkkkkkkkkkkooxkxox0kkkkkkkkxool;;;,'';loxX0l,;;;;,.
'cccc;'XXXKKKNN0''''.'..'::xkkokkkkkkkkkkKKdxkkko0kOkkkkkkdkkkkkkkloxkdokOkkkkkkkkxocl:;::;;;,cxk:,;;;;,
,ccc:;:XXKKK0XN:;'''...',:ckkklkkkkkkkk0OK0dxkkkdkOkkkkkkkoxkkkkkkx:lodolkOkkkkkkkkkdlcclcccccc:;,,,,,,'.
. ;ccc:,dXXKKKkkx,,'''...':,;o0klkO0kkkkkkkkkdxkkkkx0kkkkkkkkoOddxdddcc:lllcKkkkkkkkkkkkdlc::ccc::::::::;;,,,,
. .cccc:,ONXKKK0d'c'''...',c:dx0xlkkkkkkkkkkkkdkkkkkk0kkkkkkxdcddo:ddxd:kxccld0kkkkkkkkxxolc::ccc::;:,;;;;;,,,,
. .cccc;'NNXKKK0;c:''...';;:kkkkxoxkkkkxkkkkkkxkkkkkkOkkkkkdoolkKXOlkkkcOXXko:0kkkkkkxkkd:cccc::::;;;'.........
.. ,ccc:;;WNXK0k::l'''...,,ckkkkkdoxkkkkxkkkkkkxkkkkkkkkkkkkkkkdoXNN0ckkoxXNNN0xOkkkkkdxkxc',,;''''''........
.. ;ccc:;lWNXKk;cl,''...',ldkkkkkdodkkkkxdkkkkxoxkkkkkxkkkkkkkkxoNNNNKlkoxNNNNNo0kkkkkoxkxd:''.........'''.
... :ccc;,xNNXl;ll:'''...,,cdkkkkkxldkkkkdokkkkl:cxkkkkxxxxkxxkkd0NNNNN0lcllc::lc0kkkkxlkkxxd,.........';;;.
.... .cccc;,ONk:colc,'.....';,xkkkkkkcdkkkklckkoc;:oxkkkxxdxxxxxxxoNK0K0xl,;'':kKNx0kkkkookxxxdc'......',;;;;
...'. 'ccc:;'l:clll:;........;'xkkkkk0cdxkkx::dcoxckcldkxxxdxxxxddlOk0d:''',;:ccXWNxOkkkocxkxxxdl,':l';';;;;;,
....',....';,,,,:lll:::;';.......:'kkkkkkOooxkxoc:lkkcOKOlcodxdddddddlxXX;'',;:::cdxOWWxkkkolokkxxxoo,:;:',';;;;;,
.....',:ccccllllc:;,'''..'......'c':kkkkkkOodxo;ockkddXNNXOocooooooolc0WNdOXlodl:;xxxWXdkxlloxxxxxdoo;:::;,';;;;;'
........',;;;;,''''.............:;ldkkkkkk0olc;x0ckxdNNNXK00xdccoollooco0WWWNkxxxOOkoNxdOKloxxxxddooo,::::;,;;;;;.
............'.................',,dxxkkkkkk0d:;kXKoxoXNNNKKOxdkOlocoxxkOKNWWWWNkdkkdxKNXK0Nldddddooooo,c:::,,;;;;;
..............................;clxxkxkkkkkkKckKXkoxNNXOo:''';l,lxKNWWWWWWWWWWWWX00KNNNdXK0cooooolllol;c;:xxkxl,;,
.............................'lolxxxdxkkkkkOOdNNxONOl,''',,;OWOXWWWWWNNNNNNWWWWNNNNNNXXXXoollllllc,o::ckNNNNNN0:'
...........................',locxxxxdkkkkkk0xdXNx:'',;;::colKWWWWWNNNNNNNNNWWNNNNNNNNNXdllllllll;;,,cXWWNX00NNK.
......................'o:,;,ll:xkkkkkkkkkkkOko:,lk::cl::lxxkWWWWWNNNNNNNNWWWNNNNNNNKdccccccllc;;::,KWWNNNNXNNX.
................':okc';,,cc:xkkxkxdkkkkkkklloNW0lxxdoOkkdWWWWWNNNNNNWWWWWWWWWN0o::::cccc:;;,',c:WWWNNNNNNNN:
.'.....';clodkkkc'',:cc:lxkxxkkxldkkkkkkkxod0KkxxO0OdkWWWWWWNWWWWWNNWWWWWWWKdl:;;;;,,,:;''':lWWNNNNNNNNN,
;cccc;:0NNNKOkkx';::::c;dxd:ckkkkoodxkkkkkxdckNOxdddONNWWWWWWWWWNOOXWWWWWWWWNx,',,':,'''',,;;NWNNNNNNNKd
:ccc:,oKNNNNXXx,;::::c:;lc;:;oxkkkxxddddoc;xXNNNXXXNNNNNNNNWWWWWNNWWWWWWWWNk:'':kO,:,,,,'''''oNXNNNNX0:.
.cccc;'kKNXXK0O,;;::::cc;;:c;''oxkxxkkkxxxxlckXK0XKXXXNX0NNNNWWWWWWWWWWWN0o:l;;'xK0;;:ldolc''''0XOOkd:;,
'cccc;,kO0O0Ox,;;:o:::cc,':,'..,dxxxxxxxxdxxxolodxkkxdoloNNNWWWWWWWWWNKko,,x:l;:KXXcoodkool,'''kNNK0:,;,
,cccc;;OO000x,;;,kNk;::'......',;ddddddddddddddddllccllcKWWWWWWWWN0kxddo,ckl;o,ONNNcoodkooo,''''oxkc,;;'
:ccc:;c000Oc,;;;;;o::;.......;,;::docdddooooooolllllcc;dOOOOOOkoc:;::cddkkx,,:xNNNXooodkdoo;'''''';;;;;.
.cccc:,oOko;,;;;,'.d,,......,ld;;::;c,:cloooolllccccc:;:;;'''';olcodkkkOxOd;;'oNNNNXxoodkxoo;''''.::;;;;.
'cccc;,:,,;;;,,'..'d''...'':ddd':::::;c:,;cllc:cc::;;::lxxl:;';oc;',:ldk0Nc'':0kNNNKolodkkoo:''''.ccc;;;
,cccc;::,,,,,,',,''d..';,:,odd:;:::,c:dOXNWWWN0x;,:l':c:OXXXK0xoc;'''';'.d:;lXX:oNN0llodkkool'''''cccc;,
;cccccccccccccoNKd:o:o0Nd',;::,;;;,'cKWWWWWWWWWWXdc,lc:;;kXNNNNNXK0kxllld:;:':;,kKkocllxkkdol,.'',ccc:;'
,;:::ccccccccckNN0dkWXd;;ccccccc::,KNNNNNNNNNNOKWNc:::;,:OXNXNNNNNNNdx0k,.;,';dxcd;:dckkkxol;'.';ccc:;'
',:ONNKk:,;;:cccccccccNNNNNNNNNNNkKNWo,,;;,'oxOKKXXNNNNK:;;;,c,''';o;:;klkkkkolc,'.:ccc:;.
,kOxkNNO:. .,,,;;;:;;0NNXXXNNNNNKNNWl;;ccccc::::cclodxdoo:,;',';;,;,;,olkkkkolc,,'cccc:,
'XKl dXX: .:kKXXXXNK0NNK;;;ccccccccccccccccc::;;;;,;;;,,,,;xkkkkllc,,,cccc;,
ox;,,,,;;;::::::ccccccccccccccccccc::;::ccc::;'',cccc;'
.,,,,;;;;::::cccccccccccccccccccc::c:ccc;.
.,,;;;::::::cccccccccc:cc:,
.,,;;;:::::cc;,
..,'

View File

@@ -0,0 +1,72 @@
xX XkdKx
kxk: cKk :kKd
lXK .NOoldx .XO' xK0
cxxO0KXN0 Okolllok l0x xK0
kXkollxddxkOKk Klcolllok XOc OKO d'
xxlcllloooddxxkKx Oclooolook ;Kk. OKO x0KNl
.dooooooooodddxkKXNNNNXl. lcooollooc KOd ,kKx :000KK
,ooooooooooodddxxddddxxkkO00K;looolood' .NOO: OKN O000Kx
loooooodddddddddkxxxxdddooodllodolooOO0KKKl,;0d. 'k0O .00000X.
cOxddxdoodxddxxxxxkxddddxxxddkoddoodkdoooooddxxxkOO0KXXNNWK; 'kKO l00000K'
dkdddxc:looooddddxxOxdddddxxddxkxdxxkxddooooooooooooooooddxxxkOO0KXXNNWO' cOOxK; 0000000
okdddx:loooooooodddxkxddxd:..';coxkOxxkkkkkxxxxxdddddooooooooooooooooddxxxkO0Ok:;d0Nd. c000000x
;dddx:cloooooooodddddxkl' .',lxxd,...',,;:cloddxkkkkxxxdddddddooooooooooooooodddxxkOO00KXNNNWKc .0000000
xxlclooooooooodddddx, ':lodddooxlxl. . ..',;:codxxkkkkxxxxdddddooooooooooooooooodddxxkO00KXK0O00000
cdcoooooooooooddddxd .:ldllllooook.'xd'.... . ..':cllooodxkkkkxxxxddddddoooooooooooooood0x00000
;kloooooooooodddddxx'.dc:llllllllxl 'xx.......',;cccc::;;'.. .... ..',;:coxxxkkkkkxxxddddddxodxxOd00000
:ddooooodddddxxk;'d;;coolllloxo. ,xc,:lodkkxxxxkxxxxkkOkxdl:;. .;....,:loldxxxkko.''c,.;lk000
Oxddddxxxxxxx,.clccolllloxd, .,:kxkxdxxxxxkOOO0OOkkkxxxxxkOOkdc;. ... .,,. ..,,;::;:ck.'''. .:x0
ddooodddddddd: xllllldxdc' .';oxdkdOokkkkOOO0000000000OO000O000OOOdl::,'....... . ..,;:;;;:ooc;. .ol'x
.Ooodddddxxxc....xoddoc:.... .cxdodxcclcO0000000OO0000OO00000000OO00Okxdoodoolc:;,.. .':c:'..'ooxdddc. .x0x'.
,xoxxxxxkOc.. . .xl;. .....:ddodxkkOkk000000OkkoxkkxxxxxxkkxxOO00000OOOOkxdolclodddododxoloddolcccldkc.oo,.
0doooxO' .. .... ..':ddoxkOOOO00000OOOxxd:;;;:cldkddoc;;xxk0000000OOOOOOkdoolccccccccccccllodk000x... .
.kooooxO.. ...'. 'oxoxO00000OkOkkkkxxxc,,,,,,,,;c;;:::,,odxO00000000O000OddxxxxdddxxxkkkO00000000k...'
;xooodxx... ...'.;xdxO000000xOxxddooclo,,,,,,,,,,,,,,,;c:;cxxxxxkkkO000000kk00000000000000000000000x'':
ldooodkl.... ...',ckdO0O00000Ookc:;;,,,,c;,,,,,,,,,,,,,,,,:c:occloddxoO0000000000000000000000000KKKK00c'
xooooxk;.... ...''lxkOOO00000Oxxl;,,,,,,,ll:,,,,,,,,,,,,,,,,.;c;,'',;ckdO000KKKKKK0000000000000KKKKK0OOx
kooooxO..... ...'ckk0OOO000OOkdl,,,,,,,,,:cl:,,,,,',,,',,,,,'',::,..';cxdk00000KKKKKKKKKKKKKKKKKKKK0Oxkc
.kooooxk..... ...lOOOOOO000Oxxddl;,,,,,,,,;ccl,,,,'..',..,,,,;,,,;:;'.,,;kxxxkkkk0KKKKKKKKKKKKKKKK0kxxxO'
;xooodko .... .;,:0kOO000Oxddoc;:;,,,,,,,,,,::c:',,'...',',,,,,:;,,,:;',,,l;;:looodOO0KKKKKKKK0kdlOxxxxxO
odooodk;..... ..'xOk00O000dl:,,::,,,,,,,,,,,,,;c',.',..',,,,,,,,::,,,:,.,,,,,,,;cccokO0000kc:;c,.;Oxxxxxk
kooooxO...... ..;OO00O00Oko:,,,;,,,,,,,,,'';,,,;;''',,,,,,,,,,,,,cc;,;c;.,,,,,,,,;cclxxxkOOxlc;..lkxxxxkl
OooooxO...... .OOOO0O00Odd;,,c,,,,,,,,,,..:;,,,c.,',,,,,,:,,,,,,,lc;,:c,',,,,,,,,;coldxddxxxko;,dkxxxxk;
Nc 'kooodxd....... dxOOO000Okdo,,,l,,,,,,,,.'..:;,,,:,',,,,,,,c;,,,,,,;dlc:cl,',,,,,,,,,:looloooooodxkkkkkkOXNd.
0' cxooodk:.....,,;kkOOO000Odkxc.,l,'.,,,,,,,,,:;,,,,;.,,,,,,,,c'::;:::oodlllo.,,,,,,,,,,,:loddoooddddddddxxkkkk
0, xoooodk' .....:OoOOO000Okod:;.;l,,,,,,,,,,,,:,,,,,,.,,,,,,;:o::cd::;:d,;ool:.,,,,,,,,;;cloddoooddxdkxxxxxkkkk
0c 0ooooxO .....xodOO000Oxxd,,,,;c;,,,,;,,,,,,;,,,,,,',,,,,:ccl,..'l,,,o'..,cd.,,,,,,;,,:dooooddddxxxO00000000l
0k .kooodxx ...,ddlOOO000kko,,,,,:c;,,,,;,,,,,,;,,,,,,,,,,,,,,,:c. .o,,c;. .;',,,,,:;,;oOkkxOOOOOO0000000l
00; ;xooodxl ..,xolkOO000Okl:,,,,,:c:,,,,;:,,,,;c;,,,,,;,,,,,,,,;c .l,c; c.,,,,,c;,;:dOO000000000OOOO
00K. ddoooxk; .lxlldOOO000kko:,,,,,;l:,,,,:c,,,,ldo;,,,,;;;;,;;,,:. .lolloddlo.,,,,;l,,;;:k000000000Oxxxx
000K, Oooooxk' ,doclokO00000Oxk;,,,,,,o:,,,,lo,,coxdc;,,,;;:;;;;;;;c ....;lkxOOd,. ;.,,,,cc,;;;:oO000000Okxxxxl
000O0O OooodxOldollldx00000000xO;,,,,,.o:;,,;dd:oc;o,ol:,;;;:;;;;::l',.:dOOOkxdoo. ;',,,co;,;;;:lkOdlOxOxxxxxk;
0000Ok0XXXOxkkkkdllldddxOx0000000dO,,,,,,'cc;,;codl,,o'.'loc:;:::::::l;..xOOkxdddo:;' ;,,,clc,,;;;cckdxdOkOxxxxxk.
00000OkdoooollllodxkOOO00O000000OoOd,,,,,,'c:;cxco,,::. .'coccccccclo. :'.lc:ldx;;; .:,;llc;;;;;:ccxdddxkOxxxxxO
00000000OkxxxxkOOOO000000000KK00dxl:,,,,,,.clox;.o,;: ....;:ooccllccoc. ,;;;'',c ;:'.lc;;;;::ccckddddxkxxxxxx
000000000000O00000000000000KK0Okk:;;,,,,,,.:dx,..c;c. ..';:,'lcoc;;,'. ,:,,:;. ... l:::::ccccckodddkkxxxxxl
K0000000000000000000000000KK00xol;;,;,,,,,,.o,..,c; .'cdOOOxlkl;. .... :...occccclllclxoxd;;,;lkxk,
0KK000000000000000000000KKK00Olcl;;;:;,,,,,'': ;' 'lkOOOkkx' '. ....ccllllllokcddo, .dO.
kKKKK00000000KK00000KKKKK00Oklco;;;;:,,,,,,.;:. ;dOOkxxddocl. .:llllllllxxkko. ... .x
:0KKKKKKKKKKKKKKKKKKKKOcdkxklld;,,,,,,,,,,,',cdkl,ddolddl;;, .:oooooolloxxddk. . .o
.00KKKKKKKKKKKKKKOdc,oOxkkood;,,;,;:,,,,,,,llc .l;;:c',,: .cddddoooodxxkOkod d
.0O00000Oxolc:,,,oOOkdoodl;,;;,,;l:,,,,,,,;c:..,;;'.':, .:ldxxxxkkkdxOOOdl l
;xooooxd. .',,;Oxddddox:;:do,,,,cc:;,,,,,;:o, ';:::' ''. ;kOkkOdkOOOOkkxx .:
odooodkc. ..;kxddddodxloxdxc;,,,;;::::cox;. ... ,dOOd,'kdkkkkOOOOOc . ..dx
OooooxO,. ....'kxxddddooxxdoxOOc;,;;,,,;;;;lo,........ .. .cdlxxO;..xxdl:cloOOOO..'',:dxkc
Oooooxk,'.'.';kxxdcdddookOdkO00k:;;;;;;;;:;;;clc:;,,;:clc .,ckk;dlxd...occ:,cclkOOO, ..dkxk'
,kooooxx''...;kxxk, ,xddO000000Okx::::::::::::::::lloollo. .,;::cko,lxck' occ:,ccckOOOOc;,okxxO
cdooodxo...'okxxxxxcddx0000000xkxdd:co:::cccccccllllloox:'''''',codxddo::,,;kkd; .ccc:,:ccxOOOOOOxxxxxx
koooodkc',cxkxxxkO0:kk000000kl:xxddxokdolcccclllooooodxdxxOOOOxcloc:,,,';':xxOc .;cc:,;ccxOOOO0ddxxxxo
OooooxkdkkxxxkkO00O:OO000OOd:::Odddddxodkxollodooddxxddl;;ldxOxcoxOkdl:,. oOOd., .clc:,,ccdOOOO0oooxxx:
.kooooxddkkkkkkOkkOO:00Oxkdkc::dxdddkod:'. .;xkdlOdod'.....;coxOOOOxO0:dxl..dc .llc:,,cclOOOOOooooxk'
;xoooooooooooooc .:dcdc. :OkxddkxxxkOo. .:oklodxx,. ...,;lll:dxdOdxk,.,coll;,,:clk0OOkooodxO.
.dxdddooooooooo, .:, .:xxoooooooddk. '. odddxkd'. . :;.,k0xkOx:;o:xd:o,,,;clxO0Oxooodxk
.ckd' .,dkxxdooooooooo ,. ckkxxkOc;'.... .dxxxkokOOOxcxdx,l,,,,clokO0dooodxo
'k,';, 'dc'dkkkxxxdxx. ... . lxxoooooddddoolc:;:ccdkxOkOxxkxkxkcl,,,,clokkOoooodk:
.k..; ,..dc ,c,..... .. .xxxoooooooooooooooooddxxxxkxxxkkkkx;,,,,llokkkooooxk.
,,lkkkkxxxddddddoooooooooooooooooooddxddoooddxOOkooooxO
;xkkkxxxxddddooooooooooooooooooooddodoooxx
.lkkxxxddddddoooooooooodoodkc
.dkkxxxdddddooxk'
;xkO.

Some files were not shown because too many files have changed in this diff Show More