Compare commits

..

147 Commits

Author SHA1 Message Date
MistEO
68346c009d 更新版本号05 2021-08-03 00:50:44 +08:00
MistEO
850e9db0d3 优化公招策略 2021-08-03 00:48:49 +08:00
MistEO
11ef2934ad 公招功能一些小优化 2021-07-31 12:33:20 +08:00
MistEO
c8da20dd96 update log 2021-07-31 01:23:51 +08:00
MistEO
0dd2815ee4 update readme 2021-07-31 00:53:52 +08:00
MistEO
f48018bce6 完善公开招募基本功能,初始化界面 2021-07-31 00:32:26 +08:00
MistEO
09bcc04078 支持替换OCR常见的识别错误、增加点击9小时的功能 2021-07-29 23:45:25 +08:00
MistEO
79e80a61c8 修改OCR参数,尝试提高文字识别率 2021-07-29 23:01:23 +08:00
MistEO
5aa570040e 解决部分auto滥用问题 2021-07-29 22:39:24 +08:00
MistEO
b9db39b134 优化JSON文件的读取和解析 2021-07-29 22:21:42 +08:00
MistEO
8f1298caf2 行尾格式化 2021-07-29 21:35:02 +08:00
MistEO
9385ac3ae1 改善部分auto滥用的情况 2021-07-29 20:14:35 +08:00
MistEO
5f68dc6180 更新meojson库,新增部分接口 2021-07-29 20:14:04 +08:00
MistEO
e2a0a94a1f update 2021-07-29 17:18:12 +08:00
MistEO
96f27e6a61 优化高资tag的判断方法 2021-07-29 12:25:55 +08:00
MistEO
a783b92168 公招tag添加点击按钮的功能 2021-07-29 00:58:39 +08:00
MistEO
4c73d1d9e0 完成公招tag识别及计算功能 2021-07-29 00:37:38 +08:00
MistEO
34f20ed129 初始化公开招募Tags的读取和识别 2021-07-28 21:44:59 +08:00
MistEO
8cb23c48cf 更新导出符号相关 2021-07-28 19:33:51 +08:00
MistEO
e7387bba97 修改DEBUG相关宏定义 2021-07-28 16:06:20 +08:00
MistEO
142149a0ee 整理目录结构,重命名一些函数 2021-07-28 15:44:41 +08:00
MistEO
a764a12da7 merge master and update VS proj config 2021-07-28 14:27:37 +08:00
MistEO
b885d722b1 更新版本号beta 04 2021-07-28 01:05:36 +08:00
MistEO
4801cdf17d 修复一处图片尺寸及点击位置不正确的问题 2021-07-28 00:55:35 +08:00
MistEO
c46c91eed3 更新VS工程,添加RelWithDebInfo配置,以支持OCR库 2021-07-28 00:42:53 +08:00
MistEO
ff5f48f773 新增Asst库中的部分ocr接口 2021-07-27 23:47:31 +08:00
MistEO
d3e66e09c0 更新OcrLite库,添加接口。删除多余的库文件 2021-07-27 22:26:20 +08:00
MistEO
539689d1b7 添加第三方库到LFS,修改TestOcr项目 2021-07-27 19:36:18 +08:00
MistEO
a496bb1fc8 update config 2021-07-27 00:56:47 +08:00
MistEO
9c6c15e7a2 add TestOCR project 2021-07-27 00:26:55 +08:00
MistEO
275335417d 整理项目目录结构,添加第三方模块的文件到仓库中 2021-07-26 23:32:17 +08:00
MistEO
ab5b4dd072 update resource 2021-07-26 19:14:26 +08:00
MistEO
0908d0e381 update log 2021-07-25 22:32:16 +08:00
MistEO
2e16d76569 Update README.md 2021-07-25 22:16:41 +08:00
MistEO
0b622e1313 更新GUI,完成自动关机功能 2021-07-25 22:03:15 +08:00
MistEO
ba104a0705 优化截图裁剪,再额外多裁剪一圈 2021-07-25 21:37:49 +08:00
MistEO
3c9f41ae4b 更新界面布局 2021-07-25 16:56:49 +08:00
MistEO
8a08223ab9 新增关机按钮的GUI,功能还没做 2021-07-25 16:52:50 +08:00
MistEO
47299fec45 更新版本号beat.03 2021-07-25 16:23:17 +08:00
MistEO
b683ca52d5 update 2021-07-25 16:21:02 +08:00
MistEO
b95f1f2dc9 更新资源图片,和VS工程文件 2021-07-25 16:11:20 +08:00
MistEO
423d538a80 更新模拟器适配 2021-07-25 14:48:27 +08:00
MistEO
eb6eb55161 兼容MuMu模拟器 2021-07-25 03:02:14 +08:00
MistEO
a195f559b8 优化分辨率自适应,现在不强制调整窗口大小了 2021-07-25 00:17:53 +08:00
MistEO
b5776d33b0 添加注释 2021-07-24 19:37:14 +08:00
MistEO
63aa3575c6 update readme 2021-07-24 18:05:23 +08:00
MistEO
41f56a6e6b update readme 2021-07-24 17:51:47 +08:00
MistEO
8e0430f773 update adb control 2021-07-24 17:41:46 +08:00
MistEO
94c81eb60f update screenshot 2021-07-24 16:52:08 +08:00
MistEO
3eb0328630 rename some function and variable 2021-07-24 16:23:36 +08:00
MistEO
78187cb9c7 update readme 2021-07-24 01:28:26 +08:00
MistEO
d1826e8664 support to print window, and fixed crash when window closed or miniized 2021-07-24 01:25:12 +08:00
MistEO
40b4751616 restructure configer, improve thread safety 2021-07-23 23:48:00 +08:00
MistEO
a01e50571b Update README.md 2021-07-23 16:32:24 +08:00
MistEO
4b244b3aef fixed readme 2021-07-23 00:03:26 +08:00
MistEO
e05430ec0e update version id 2021-07-22 23:48:32 +08:00
MistEO
0a081d4fa2 update readme 2021-07-22 23:45:20 +08:00
MistEO
a6488f0ea6 rename config json key 2021-07-22 22:56:06 +08:00
MistEO
8844d35c2e support control random delay 2021-07-22 22:54:58 +08:00
MistEO
0534e35871 update threshold 2021-07-22 21:47:20 +08:00
MistEO
107d3af5c5 header file unlooping 2021-07-22 21:46:32 +08:00
MistEO
1e170e6c1a fixed some warning, update logger 2021-07-22 19:40:25 +08:00
MistEO
f3773d22c6 update log and config 2021-07-22 10:07:40 +08:00
MistEO
7928a21051 update updater gui 2021-07-22 02:16:53 +08:00
MistEO
2a89b01c1b fixed gui 2021-07-22 02:00:51 +08:00
MistEO
d735404766 add log 2021-07-22 01:07:12 +08:00
MistEO
a8173eb82c fixed count error when use stone or medicine 2021-07-22 00:39:13 +08:00
MistEO
67f52b321c update log 2021-07-21 23:43:47 +08:00
MistEO
6c3540b692 move readme.png to resource 2021-07-21 20:40:54 +08:00
MistEO
dd556817ea update version id 2021-07-21 20:36:29 +08:00
MistEO
c393da2046 Merge pull request #3 from MistEO/feature/new_algorithm
Feature/new algorithm
2021-07-21 20:17:11 +08:00
MistEO
5657af6d94 update config and something 2021-07-21 20:16:33 +08:00
MistEO
f35ef18bd2 add log 2021-07-21 20:16:02 +08:00
MistEO
0fef8e2174 merge "Updater interface modified" 2021-07-21 02:05:23 +08:00
MistEO
ee3afb440e modified the interface of Updater, because VS2019 's O2 optimzation is not friendly to std::optional 2021-07-21 01:43:58 +08:00
MistEO
952861c1e5 update icon and window title 2021-07-20 23:51:47 +08:00
MistEO
dab705a3de fixed bug: process cannot exit 2021-07-20 23:37:27 +08:00
MistEO
17f8353a97 fixed bug: process cannot exit 2021-07-20 23:36:57 +08:00
MistEO
53a1297842 update task sleep logic 2021-07-20 23:29:01 +08:00
MistEO
e589a7498c update identify algorithm 2021-07-20 23:17:10 +08:00
MistEO
ca412965ca add icon for GUI 2021-07-20 21:50:26 +08:00
MistEO
adfed6d276 update release body 2021-07-20 00:50:34 +08:00
MistEO
6fddf69e67 add function of check version update 2021-07-20 00:12:00 +08:00
MistEO
fb3cbb0b7a add set max times function 2021-07-19 21:22:35 +08:00
MistEO
a348139df5 update configer 2021-07-18 23:22:47 +08:00
MistEO
08db7f008d Merge branch 'master' of https://github.com/MistEO/MeoAssistance 2021-07-18 17:43:25 +08:00
MistEO
d66f178aec update gui, add use stone label 2021-07-18 17:43:16 +08:00
MistEO
d51882fd1c Update README.md 2021-07-18 17:29:09 +08:00
MistEO
c7b80b4603 support to MuMu (not MuMuAsst) 2021-07-18 15:19:15 +08:00
MistEO
1a0add784d try to supoort MuMu 2021-07-18 02:40:57 +08:00
MistEO
70544e7809 update delayTime 2021-07-17 20:12:55 +08:00
MistEO
3430be908b fixed bugs 2021-07-17 20:07:25 +08:00
MistEO
a617f254ff update counting bug 2021-07-17 11:25:47 +08:00
MistEO
028f1ff182 Merge branch 'master' of https://github.com/MistEO/MeoAssistance 2021-07-17 01:06:59 +08:00
MistEO
41a3695556 fixed a filename typo 2021-07-17 01:06:50 +08:00
MistEO
9521285376 Update README.md 2021-07-17 00:47:39 +08:00
MistEO
48125e241b update readme 2021-07-17 00:43:31 +08:00
MistEO
91dad862f8 update gui and readme 2021-07-17 00:35:55 +08:00
MistEO
ff01ce3af4 update configer interface and GUI 2021-07-17 00:03:21 +08:00
MistEO
b701a7ad99 udpate configer 2021-07-16 23:01:40 +08:00
MistEO
96200d5ca6 update gui project 2021-07-16 21:09:57 +08:00
MistEO
0a89b1b48a merge remote 2021-07-16 20:49:26 +08:00
MistEO
11fa36aaaf support Visit Ins 2021-07-16 20:45:02 +08:00
MistEO
78ad680067 update task max_times 2021-07-16 17:51:59 +08:00
MistEO
30cea829f3 add GUI 2021-07-16 07:16:48 +08:00
MistEO
38bff9a43a Merge branch 'master' of https://github.com/MistEO/MeoAssistance 2021-07-15 00:04:25 +08:00
MistEO
f2e73a586d update config 2021-07-15 00:04:10 +08:00
MistEO
694dbcc02b Update README.md 2021-07-14 23:44:21 +08:00
MistEO
bbdb1ce349 update readme 2021-07-14 23:37:57 +08:00
MistEO
e684a1339a update release project 2021-07-14 23:32:05 +08:00
MistEO
d17078e7b8 update UsePtrs 2021-07-14 22:33:57 +08:00
MistEO
db65d51e37 update MoveWindow 2021-07-14 22:29:06 +08:00
MistEO
43848c1e89 support to click UsePrts 2021-07-14 22:28:54 +08:00
MistEO
ae9b6a1265 fixed an error of the cache value 2021-07-14 22:10:08 +08:00
MistEO
b69e7c76e6 update readme 2021-07-14 21:08:52 +08:00
MistEO
e81421579d add cache function to ider 2021-07-14 20:59:36 +08:00
MistEO
1d3c3874ce add config file to vcxproj 2021-07-14 19:58:32 +08:00
MistEO
bfd21e4631 update debugtrace and config 2021-07-14 19:09:48 +08:00
MistEO
27dd02f4f4 update tasks and config 2021-07-14 17:26:36 +08:00
MistEO
30d714b814 update submodule meojson 2021-07-14 15:23:09 +08:00
MistEO
96793ff73a support empty handle class name 2021-07-14 12:44:41 +08:00
MistEO
e591283dea udpate typos and add log 2021-07-14 12:33:47 +08:00
MistEO
c7ac3f0886 update Readme 2021-07-14 00:45:56 +08:00
MistEO
f6a451b3bf support PTRS error 2021-07-13 23:52:10 +08:00
MistEO
92a531b43a add show and hide window function 2021-07-13 23:10:32 +08:00
MistEO
3a4d2e430d support more simulator 2021-07-13 23:10:15 +08:00
MistEO
6a6302cb93 Merge branch 'develop' 2021-07-13 21:30:02 +08:00
MistEO
2454844735 support wide char handle name 2021-07-13 21:29:45 +08:00
MistEO
fba51db8c8 update handle configer 2021-07-13 16:58:21 +08:00
MistEO
06e8a5e6b8 Merge pull request #1 from MistEO/develop
Develop
2021-07-13 01:14:57 +08:00
MistEO
20e5d32d1a update algorithm and configer 2021-07-13 01:02:37 +08:00
MistEO
0169e2c68d rename namespace asst 2021-07-12 20:32:35 +08:00
MistEO
dba404f33b optimze thread 2021-07-12 20:11:10 +08:00
MistEO
839c97c6cd rename Test to Sanity 2021-07-12 19:56:29 +08:00
MistEO
d31b42fd93 update debugprint 2021-07-12 19:35:38 +08:00
MistEO
c52069d59f Merge branch 'develop' 2021-07-12 19:17:37 +08:00
MistEO
8dd30d406a add *.filters 2021-07-12 19:15:49 +08:00
MistEO
af5fcf53ad update tasks queue. add DebugTrace function 2021-07-12 17:44:15 +08:00
MistEO
102ee1cb5c support to use medicine 2021-07-12 01:22:47 +08:00
MistEO
ba9176af93 update reamde 2021-07-11 23:46:55 +08:00
MistEO
f46e2945dc update reamde 2021-07-11 23:44:37 +08:00
MistEO
22cb7ba745 update release 2021-07-11 22:52:09 +08:00
MistEO
e8d91d3e96 update readme ver_alpha_1 2021-07-11 22:35:58 +08:00
MistEO
b2b4daeeed update scale and resource 2021-07-11 22:19:11 +08:00
MistEO
4090400fa4 update vs solution 2021-07-11 21:00:34 +08:00
MistEO
0937be8c02 fix resizeWindow 2021-07-11 18:49:45 +08:00
MistEO
6b216b0cac add configer function, update identification 2021-07-11 07:44:19 +08:00
10419 changed files with 135238 additions and 3432927 deletions

View File

@@ -1,194 +0,0 @@
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
# for clang-format 20.0.0
Language: Cpp
BasedOnStyle: "WebKit"
# AccessModifierOffset: 2
AlignAfterOpenBracket: "AlwaysBreak"
AlignArrayOfStructures: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: None
# AlignConsecutiveShortCaseStatements: None
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 1
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
# AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: Inline
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
BreakAfterReturnType: Automatic
AlwaysBreakBeforeMultilineStrings: true
BreakTemplateDeclarations: Yes
# AttributeMacros:
# - __pragma
# - _Pragma
# - __attribute__
# - __declspec
BinPackArguments: false
BinPackParameters: false
BitFieldColonSpacing: After
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Never
AfterEnum: true
AfterFunction: true
AfterNamespace: true
# AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
# BracedInitializerIndentWidth: 4
BreakAfterAttributes: Never
BreakAfterJavaFieldAnnotations: true
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeConceptDeclarations: Always
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: true
ColumnLimit: 120
# CommentPragmas: '^ MEO pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
# ExperimentalAutoDetectBinPacking: true
FixNamespaceComments: true
# ForEachMacros:
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IfMacros:
# - 'KJ_IF_MAYBE'
IncludeBlocks: Preserve
# IncludeCategories:
# IncludeIsMainRegex:
# IncludeIsMainSourceRegex:
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentGotoLabels: false
IndentPPDirectives: None
IndentRequiresClause: false
IndentWidth: 4
IndentWrappedFunctionNames: true
InsertBraces: true
InsertNewlineAtEOF: true
InsertTrailingCommas: Wrapped
IntegerLiteralSeparator:
Binary: 4
BinaryMinDigits: 9
Decimal: 3
DecimalMinDigits: 7
Hex: -1
# JavaImportGroups:
# JavaScriptQuotes:
# JavaScriptWrapImports:
KeepEmptyLinesAtEOF: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
# LineEnding: LF
# MacroBlockBegin: "MAA.*_NS_BEGIN$"
# MacroBlockEnd: "MAA.*_NS_END$"
# Macros:
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
# NamespaceMacros:
# ObjCBinPackProtocolList:
# ObjCBlockIndentWidth:
# ObjCBreakBeforeNestedBlockParam:
# ObjCSpaceAfterProperty:
# ObjCSpaceBeforeProtocolList:
PackConstructorInitializers: Never
# PenaltyBreakAssignment:
# PenaltyBreakBeforeFirstCallParameter:
# PenaltyBreakComment:
# PenaltyBreakFirstLessLess:
# PenaltyBreakOpenParenthesis:
# PenaltyBreakTemplateDeclaration:
# PenaltyExcessCharacter:
# PenaltyIndentedWhitespace:
# PenaltyReturnTypeOnItsOwnLine:
PointerAlignment: Left
# QualifierAlignment: Custom
# QualifierOrder:
# - inline
# - static
# - const
# - constexpr
# - type
ReferenceAlignment: Left
ReflowComments: Always
RemoveBracesLLVM: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 1000
SortIncludes: CaseSensitive
# SortJavaStaticImport:
SortUsingDeclarations: Lexicographic
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
# SpaceBeforeParensOptions:
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInSquareBrackets: false
Standard: c++20
# StatementAttributeLikeMacros:
# StatementMacros:
TabWidth: 4
# TypeNames:
# TypenameMacros:
UseTab: Never
# VerilogBreakBetweenInstancePorts:
# WhitespaceSensitiveMacros:
RemoveEmptyLinesInUnwrappedLines: true
---
Language: ObjC
BasedOnStyle: "WebKit"

14
.clangd
View File

@@ -1,14 +0,0 @@
If:
PathMatch: unit_test/.*\.(c|cc|cpp|cxx|h|hh|hpp)$
CompileFlags:
CompilationDatabase: build/unit_test
Add: [-Wunused-variables]
---
If:
PathExclude: unit_test/.*\.(c|cc|cpp|cxx|h|hh|hpp)$
CompileFlags:
CompilationDatabase: build
Add: [-Wunused-variables]
---
Diagnostics:
UnusedIncludes: None

View File

@@ -1,29 +0,0 @@
# MAA Issue Log Analysis Knowledge Base
## Stateful UI Automation Checks
- 分析 issue 时,先区分三层东西,不要混为一谈:
- 游戏规则
- MAA 当前自动化流程
- 用户对最终状态的预期
- 遇到“一键/快捷/批量”按钮时,先看资源任务和日志里的真实控制路径,不要只看现象。
- 对状态型 UI重点核对三件事
- 前置条件是什么
- 流程中哪些状态会被临时改写
- 结束条件满足后应停在哪个状态
## Reception Clue Analysis
- 会客室线索问题先对照当前资源任务和日志,不要只凭体感下结论。
- 取下线索 -> 赠送重复线索 -> 当前线索数量够开启线索交流时才统一放置,这是 by design。
- 因此,“送完重复线索后线索板暂时为空”或“用户自己放的线索被统一取下”本身不能直接判成 bug。
- 真正需要继续确认的是:
- 日志里的控制路径是否和资源任务定义一致
- 明明已经满足开启线索交流的条件,却没有触发统一放置
- 流程是否停在了不该停的位置,或提前退出
## Guardrails For Future Analysis
- 不要把维护者评论、机器人评论、或单张截图当成最终结论;必须回到日志和代码确认状态是怎么变化的。
- 对状态型 UI先回答“日志里的行为是否符合设计”再回答“这个设计是否符合用户预期”。
- 不要只看最终现象;要结合配置、`gui.log``asst.log`、资源任务和当前代码一起判断。

View File

@@ -1,467 +0,0 @@
---
name: maa-issue-log-analysis
description: 分析 MaaAssistantArknights 上游仓库公开 Issue`https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/...``#1234`)。自动抓取 issue 正文和评论中的 `report_*.zip` 附件,优先读取 `debug/asst.log``debug/gui.log``config/gui.json` / `config/gui.new.json``cache/resource/tasks.json`,并在有后续分卷时补看 `debug/interface/*.png``debug/drops/*.png``debug/infrast/**``debug/dumps/*` 等现场证据;结合 MAA Core/WPF/资源任务代码与文档判断根因、给出修复方案,供用户让你分析 MAA issue、日志包、ADB 连接失败、关卡导航、识别失败、任务出错、闪退时使用。
---
# MAA Issue Log Analysis
## Required Reading
- 开始分析前,先读取同目录的 `KNOWLEDGE.md`,先用其中的通用误判规则校正自己的分析路径,再读 issue 和日志。
- 如果 issue 涉及会客室、线索、快捷按钮、批量按钮、自动领取/赠送/放置这类“会先改变界面状态再继续执行”的流程,必须先套用 `KNOWLEDGE.md` 中的 `Stateful UI Automation Checks``Reception Clue Analysis`
## Scope
- 仅用于上游公开仓库 `https://github.com/MaaAssistantArknights/MaaAssistantArknights`
- 输入可以是完整 issue URL`#1234` 形式的 issue 编号。
- 只分析公开 issue 中可直接访问的附件。
- 如果没有可下载的 `report_*.zip`,先明确说明证据不足,再尽量基于 issue 文本、截图、代码和文档给出初步判断。
- 如果评论里有机器人提示“日志没有上传成功”,不要直接放弃;正文里的附件链接仍可能可下载。
## Workflow
1. 规范化输入。
- `#1234` 视为 `https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/1234`
- 如果不是 `MaaAssistantArknights/MaaAssistantArknights`,停止并说明此 skill 不适用。
2. 获取 issue 内容。
- 读取正文和评论。
- 提取这些信息UI/Core/Resource 版本、资源时间、模拟器类型、分辨率、截图增强、GPU 推理、任务名、关卡名、是否有 `-hard`、用户现象、复现步骤、维护者或机器人评论。
- 不要把评论结论当成唯一证据;仍要用日志和代码自行验证。
- 如果 issue 文本或评论里已经有人下了“这是游戏设计 / 不是 bug / 本来就这样”的结论,先暂存,不要直接复述成最终判断;先核对日志、资源任务和当前代码是否真的支持这个结论。
3. 提取报告附件。
- 关注 `report_*.zip`
- 附件可能同时出现在正文和评论。
-`report_MM-dd_HH-mm-ss` 分组,同一时间戳下的 `part01``part02``part03` 是独立 zip不是需要先拼接的分卷压缩包。
4. 先看 `part01`,再决定是否看 `part02+`
- 根据 WPF 打包逻辑,`part01` 一定优先,通常包含:
- `debug/asst.log`
- `debug/asst.bak.log`
- `debug/gui.log`
- `debug/gui.bak.log`
- `config/*`
- `cache/*`
- `resource/*_custom.*`
- `part02+` 只包含 `debug` 子目录中最近 3 天修改过的文件,可能是:
- `debug/interface/*.png`
- `debug/drops/*.png`
- `debug/infrast/**`
- `debug/roguelike/**`
- `debug/dumps/*`
- `part02+` 可能是空包,也可能只包含图片;不要默认里面一定有文本日志。
5. 建立时间线。
- 先用 `gui.log` 找用户点击、所选关卡、任务链开始、报错时间。
- 再用 `asst.log` 还原底层行为。
- 关卡或任务问题时,优先用 `gui.log` 中的 `Start Task Chain``GetFightStage``任务出错` 锁定时间窗,再回到 `asst.log` 里的 `taskid``SubTaskError``TaskChainError`
- 连接问题时,优先把 `gui.log` 中的重试流程和 `asst.log` 中的 `adb devices``adb connect``ConnectionInfo` 串起来。
- 如果 `ConnectConfig``PC`,改走 `AttachWindow` / `Win32Controller` 这条线:
- 先在 `gui.log` 确认 `AttachWindow: Found window`
- 再在 `asst.log` 里看 `Win32Controller::screencap``Win32Controller::click`
- 不要再按 ADB 端口或 `ConnectionInfo.ConnectFailed` 的思路分析
- 如果问题属于状态型 UI 自动化(例如会客室线索、批量按钮、快捷按钮、先拆后放一类流程),时间线里必须单独标出:
- 自动化在什么时刻先修改了用户原状态
- 后续进入下一步或恢复终态由哪个条件控制
- 条件不满足时流程是停止、跳过,还是按设计停在别的状态
6. 区分 issue 当时环境和当前分支。
- 先以报告包中的 `config/``cache/resource/` 还原用户当时实际运行的配置和资源。
- 再对照当前仓库代码,判断该问题是当前仍存在,还是当时存在但现在已修复。
- 输出给用户时,如果提到任务名、设置项、按钮名、错误提示或日志前缀,先到 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml` 查中文文案,不要直接把 `LocalizationHelper.GetString("Key")` 里的 `Key``DynamicResource` key、`TaskChain` 名或枚举名当成最终展示文本。
## Report Map
### `debug/asst.log`
- 模块归属MAA Core 运行时。
- 主要内容ADB 命令、连接回调、识别、Pipeline、关卡导航、截图保存路径、C++ 源文件和函数名。
- 最适合看:
- ADB 连接问题
- 关卡导航问题
- `SubTaskError` / `TaskChainError`
- OCR / 模板 / 点击失败
- 对根因判断最权威。
### `debug/asst.bak.log`
- 模块归属:上一轮 Core 滚动日志。
- 最适合看:
- 最新一次复现不在 `asst.log`
- 需要对比前一次成功 / 失败
### `debug/gui.log`
- 模块归属WPF GUI / AsstProxy / TaskQueue。
- 主要内容:程序版本、资源加载、所选任务与关卡、用户可见报错、连接重试流程、`Start Task Chain`
- 最适合看:
- 建时间线
- 用户到底选了什么
- GUI 是否自动做了“断开重连 / 重启 ADB / 强杀 ADB”
- 这是最快的入口,但不是所有问题的最终根因。
### `debug/gui.bak.log`
- 模块归属:上一轮 GUI 滚动日志。
- 最适合看:
- 程序重启前的上下文
- 更早一次复现
### `config/gui.json`、`config/gui.new.json`、备份文件
- 模块归属GUI 配置快照。
- 常见文件:
- `config/gui.json`
- `config/gui.new.json`
- `config/gui.json.old`
- `config/gui.json.bak`
- 最适合看:
- 实际连接配置
- 模拟器路径、ADB 地址、是否开启截图增强
- 任务队列、`StagePlan`
- 是否真的选择了 `15-13-hard` 之类的硬难度关卡
- 注意:
- `gui.new.json` 可能比 `gui.json` 更接近用户当前界面上的任务配置,不能只看一个文件。
- 如果 `gui.new.json``gui.log` / `asst.log` 的实际运行状态冲突,继续检查:
- `gui.new.json.bak`
- `gui.json.old`
- `gui.json.bak`
- 报告导出时用户可能已经改过勾选项,当前文件不一定就是复现时那一份。
### `cache/resource/tasks.json` 和 `cache/resource/tasks/tasks.json`
- 模块归属issue 当时使用的缓存资源。
- 最适合看:
- 用户当时到底跑的是哪一版资源定义
- 当前分支资源和 issue 当时资源是否不同
- 如果 issue 版本较旧,先信报告包里的 `cache/resource`,再用当前仓库代码判断是否已修复。
### `cache/gui/StageActivity.json` / `StageActivityV2.json`
- 模块归属GUI 关卡活动缓存。
- 最适合看:
- 活动 / 章节 / 关卡可用性
- 关卡显示和导航问题
### `debug/interface/*.png`
- 模块归属:界面失败现场图。
- 最适合看:
- 关卡导航失败
- 识别错画面
- 按钮没出现、位置不对、被别的界面覆盖
- 如果 `asst.log``Save image ... debug/interface/...`,但上传包没有这张图,要明确说明“日志表明现场图存在,但用户未上传对应分卷”。
### `debug/drops/*.png`
- 模块归属:掉落识别现场图。
- 最适合看:
- 结算页与掉落识别问题
### `debug/infrast/**`、`debug/roguelike/**`
- 模块归属:任务特定调试图。
- 最适合看:
- 基建换班
- 肉鸽识别或路径问题
### `debug/dumps/*`
- 模块归属:崩溃转储副本。
- 最适合看:
- 闪退、崩溃
- issue 模板还可能要求额外上传 `MAA.exe.dmp`,如果有,也要一起分析。
## How To Filter Evidence
1. 先从 issue 文本拿到这几个锚点:
- 版本与资源时间
- 模拟器品牌、分辨率、截图增强、GPU 推理
- 任务名 / 关卡名 / 是否有 `-hard`
- 报告时间戳,例如 `report_03-15_11-07-05`
- 如果日志流程和当前主线代码不一致,先确认用户版本,必要时切到对应 tag例如 `git checkout vXXX`)复核旧逻辑
2. 再从 `gui.log` 找这几类高价值信号:
- `正在连接模拟器`
- `Already connected`
- `GetFightStage`
- `Start Task Chain`
- `任务出错`
- `连接失败`
3. 再到 `asst.log` 找底层证据:
- `ConnectionInfo`
- `ConnectFailed`
- `TaskChainError`
- `SubTaskError`
- `to_be_recognized`
- `cur_retry`
- `Save image`
- `offline`
- `unauthorized`
- `failed to connect`
- `cannot connect`
4. 对连接问题,重点看:
- `adb.exe devices` 里有没有 `offline`
- `adb.exe connect` 是否报 `10061`
- `ConnectionInfo.what` / `why`
- `config/gui.json` 中的:
- `ConnectConfig`
- `Connect.Address`
- `Connect.AllowADBRestart`
- `Connect.AllowADBHardRestart`
- `Connect.MuMu12Extras.Enabled`
- 默认 MuMu 12 端口列表是否和日志中的轮询顺序一致
5. 对 PC / AttachWindow 问题,重点看:
- `config/gui.json``Connect.ConnectConfig == "PC"`
- `gui.log` 中:
- `连接 PC 端(实验性功能,稳定性无法保证)`
- `AttachWindow: Found window`
- `handle: ..., hwnd: ..., screencapMethod: ..., mouseMethod: ..., keyboardMethod: ...`
- `asst.log` 中:
- `Win32Controller::screencap`
- `Win32Controller::click`
- 点击后的下一次识别结果是否真的改变
- 如果点击日志存在,但后续截图和 OCR 状态完全没变,要优先判断为“输入未生效”,而不是“流程已正确前进”
6. 对关卡导航 / 磨难切换问题,重点看:
- `config/gui.new.json` / `gui.json` 中的 `StagePlan`
- `gui.log` 中的 `GetFightStage`
- `asst.log` 中的:
- `Episode15`
- `ChapterDifficultyHard`
- `EnterChapterDifficultyHard`
- `SubTaskError`
- `debug/interface/*.png`
- `resource/tasks/tasks.json``cache/resource/tasks*.json`
7. 回答时只保留关键证据。
- 摘几十行足够支撑结论的片段即可。
- 不要把整份日志倾倒进回复。
8. 对状态型 UI 问题,结论前先做一次“设计一致性检查”。
- 先判断日志中的状态变化是否符合游戏规则、资源任务定义和当前实现。
- 如果流程与设计一致,不要把用户不喜欢的中间状态直接归为 bug。
- 只有当日志、资源任务和代码彼此冲突,或流程没有达到设计要求的终态时,再归类为实现缺陷。
## Common Patterns
- `gui.log` 只显示“连接失败”,但 `asst.log` 里已经给出 `adb devices``adb connect`、端口轮询和 `ConnectionInfo`。连接类问题必须以 `asst.log` 为准。
- `adb devices` 显示目标地址 `offline`,随后 MuMu 备选端口都 `10061`,通常更像模拟器 / ADB 状态异常,或自动探测到的端口不可达,而不是任务逻辑问题。
- `gui.log` 显示选中的关卡是 `15-13-hard` 一类 hard 代码,而 `asst.log` 长时间卡在 `ChapterDifficultyHard`OCR 却反复识别到和按钮无关的文字,通常说明当前画面没有进入预期的难度切换界面。
- `asst.log` 明确写了 `Save image``debug/interface/*.png``debug/drops/*.png`,但上传包没有相应分卷时,要把“缺失的现场证据”单独写出来。
- `part02` 可以是空包,也可以只包含图片;不要因为没有文本日志就把它判成“无用分卷”。
- issue 机器人评论“日志没有上传成功”时,不要自动当真;先验证正文附件是否仍可下载。
- 如果 `gui.log` 说“任务出错”,但对应 `taskid``asst.log` 实际 `AllTasksCompleted`,要明确写“本次日志未复现用户描述的问题”。
- 对会客室 / 线索 issue如果 `asst.log` 里出现 `InfrastClueQuickInsert``remove_clue``SendClues``InfrastClueQuickSendDuplicates`,先对照资源任务判断这是不是当前设计流程,不要只看线索板中途是否为空。
- 如果线索流程里出现“取下线索 -> 赠送重复线索 -> 条件满足后统一放置”,默认先按 by design 处理;只有当日志显示本应统一放置却没有发生时,再继续追实现问题。
- 用户日志里的任务流程与当前主线代码明显不一致,且当前代码看起来已经修掉了该问题:
- 先确认用户版本,必要时切到对应 tag例如 `git checkout vXXX`)核对旧逻辑。
- 不要用当前分支否定旧日志;旧版本问题可能真实存在。
- 如果主线已修复,再看修复 commit 是否已进入 tag / release已发版建议升级未发版建议等待 release。
- `gui.new.json``gui.json` 和实际日志不一致时,不要急着判“用户配置写错了”;先看 `gui.new.json.bak``gui.json.old`,尤其是用户复现后又改回开关的场景。
-`ConnectConfig=PC` 的 issue 里,`Win32Controller::click` 正常返回不代表点击真的生效;要看点击后的下一帧中,按钮状态、数量 OCR、场景识别有没有变化。
- `gui.log` 中“已使用 48 小时内过期的理智药”这类高层提示,不一定等价于底层逐药 OCR 结论;如果 `asst.log` 明确识别到 `9天``NotExpiring` 等相反证据,应优先相信 `asst.log`
## Correlating With Code
### 报告打包结构
- `src/MaaWpfGui/ViewModels/UserControl/Settings/IssueReportUserControlModel.cs`
### GUI / Core 日志文件名
- `src/MaaWpfGui/Main/Bootstrapper.cs`
- `src/MaaCore/Utils/Logger.hpp`
- `src/MaaUtils/include/MaaUtils/Logger.h`
### 连接回调与 GUI 侧重试
- `src/MaaWpfGui/Main/AsstProxy.cs`
- `src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs`
- `src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs`
- `src/MaaCore/Controller/MinitouchController.cpp`
- `docs/zh-cn/protocol/callback-schema.md`
- `docs/zh-cn/manual/device/android.md`
### PC / AttachWindow / Win32 输入
- `src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs`
- `src/MaaWpfGui/Main/AsstProxy.cs`
### 关卡导航与磨难切换
- `resource/tasks/tasks.json`
### 理智药 / 临期药
- `src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs`
- `src/MaaWpfGui/Models/AsstTasks/AsstFightTask.cs`
- `src/MaaCore/Task/Interface/FightTask.cpp`
- `src/MaaCore/Task/Fight/MedicineCounterTaskPlugin.cpp`
- `resource/tasks/tasks.json`
### 现场图保存
- `src/MaaCore/Utils/DebugImageHelper.hpp`
### GUI 中文文案
- `src/MaaWpfGui/Res/Localizations/zh-cn.xaml`
## Localized Copy
- 总结任务类型、设置项、按钮、错误提示、日志前缀时,优先使用 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml` 中的中文文案。
- 常见查找顺序:
- 默认任务类型名:先看 `src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs``LocalizationHelper.GetString(taskType.ToString())` 的 key再到 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml``StartUp``Fight``Infrast``Recruit``Mall``Award``Roguelike``Reclamation``Custom`
- 任务开始 / 完成 / 出错等 GUI 日志前缀:优先查 `StartTask``CompleteTask``TaskError``ConnectFailed``TryToReconnect` 等 key。
- 设置项、按钮、界面提示:先在对应 `*.xaml` / `*.cs` 里找 `DynamicResource SomeKey``LocalizationHelper.GetString("SomeKey")`,再到 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml` 查中文。
- issue 反馈相关入口:优先查 `Issue``GenerateSupportPayload``OpenDebugFolder` 等 key。
- 如果 `config/gui*.json` 里任务有用户自定义 `Name`,输出时优先保留用户自定义名称;必要时再括号补默认任务类型中文,例如 `刷理智(理智作战 / Fight`
- 输出时优先写中文,必要时在括号里补原始 key / `taskChain` / 枚举名,例如 `基建换班Infrast`
- 如果 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml` 没有对应 key再退回原始 key 或代码里的英文字符串,并明确说明“未在 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml` 找到对应文案”。
## Linking Code Evidence
- 如果要指向具体代码行,不要写本地路径加行号,也不要写绝对路径。
- 统一给出对应仓库的远端 GitHub `blob` 行号链接,用尖括号包裹。
- MaaAssistantArknights 仓库链接格式:
- `https://github.com/MaaAssistantArknights/MaaAssistantArknights/blob/<commit>/<path>#L14-L20`
- `<commit>` 必须是本次分析实际依据的代码版本:
- 默认使用当前检出的 `HEAD`
- 如果为了复核旧 issue 切到了某个 tag / commit就使用那个版本解析后的 SHA
- 例子:
- <https://github.com/MaaAssistantArknights/MaaAssistantArknights/blob/f8b64ef908d8b82bb71ba753b69a30ea658f9054/src/MaaWpfGui/Main/AsstProxy.cs#L1072-L1079>
- <https://github.com/MaaAssistantArknights/MaaAssistantArknights/blob/f8b64ef908d8b82bb71ba753b69a30ea658f9054/src/MaaWpfGui/Res/Localizations/zh-cn.xaml#L680-L695>
- 如果引用的是其他上游仓库或文档,也用对应远端链接,不要给本地文件行号。
## Example Heuristic
如果 issue 像 `#16014` 一样是 MuMu ADB 连接随机失败,并且同时出现:
- `config/gui.json``ConnectConfig``MuMuEmulator12`
- 地址是 `127.0.0.1:16384`
- `gui.log` 在复现时段从 `16384` 轮询到 `16576`
- `asst.log``adb devices` 返回 `127.0.0.1:16384 offline`
- `asst.log` 里对备选端口出现 `cannot connect ... (10061)`
- `ConnectionInfo.what``ConnectFailed`
那么根因更可能是 ADB / 模拟器连接层异常,而不是 GUI 任务队列逻辑;此时应结合 MuMu 默认端口表和 Android `offline` 文档给出建议。
如果 issue 像 `#16002` 一样是 15/16 章 hard 难度切换失败,并且同时出现:
- `config/gui.new.json``gui.log` 里关卡是 `15-13-hard`
- `asst.log` 里先进入 `Episode15`
- 随后卡在 `ChapterDifficultyHard`
- OCR 反复识别到 `推演计分` 等无关文本
- 最后 `SubTaskError`,并保存 `debug/interface/*.png`
- `resource/tasks/tasks.json``EnterChapterDifficultyHard` 期望在固定 ROI 识别到 `进入作战`
那么根因更可能是当前画面没有进入预期的难度切换界面或按钮没有出现在资源定义的期望区域而不是“Hard 后缀本身没有传到 core”。
## Output Format
最终回答用这个结构:
```markdown
## Issue 概要
- issue`#1234`
- 版本 / 资源时间:
- 模拟器 / 连接配置 / 任务:优先写 `zh-cn` 中文任务名;如果日志里是用户自定义任务名,先写自定义名,再补默认任务类型中文 / key
- 相关设置项 / 关键提示文案:优先写 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml` 中的中文文案
- 用户现象:
## 关键证据
<details><summary>点击此处展开</summary>
- `debug/gui.log`
- `debug/asst.log`
- `config/gui.json` / `config/gui.new.json`
- `cache/resource` / `cache/gui`
- `debug/interface` / `debug/drops`
- 代码依据:如需指向具体实现,直接附远端 GitHub 行号链接
</details>
## 根因判断
- 直接结论:
- 证据链:
## 给用户的建议
- 用户现在可以直接尝试的动作:
- 是否建议升级 / 重下完整包 / 同步资源 / 重置配置:
- 是否需要等待开发者修复:
- 是否有临时绕过方案:
## 修复方案
1. 代码 / 资源 / 配置层修复
2. 需要补充的日志或截图
3. 需要补充的测试
## 给修复 AI 的建议(可复制)
<details><summary>点击此处展开</summary>
~~~text
现象:
[一句话描述用户可见的问题]
关键证据:
[粘贴原始日志、堆栈、监控截图中的关键文本]
可能相关线索(待验证):
[根据日志/现象推测的可能方向,不保证准确,供参考]
~~~
</details>
## 置信度
- 高 / 中 / 低
- 还缺什么证据
## English translation
<details><summary>Click here to expand</summary>
Translate the complete conclusion directly into English and paste it here. Note that the English text is in `src/MaaWpfGui/Res/Localizations/en-us.xaml`.
</details>
```
## Reminders
- 不要只看 `gui.log` 下结论。
- 不要把 issue 评论或机器人提示当成唯一证据。
- 不要把当前分支资源直接当成 issue 当时的真实环境;先看报告包里的 `cache/resource`
- 日志和截图冲突时,优先相信现场图,再回头解释 OCR / 模板为何误判。
- 如果问题本身没有在当前日志中复现,要明确写“证据未复现”,不要硬凑结论。
- 如果 issue 版本很旧,要明确区分“当时的根因”和“当前分支是否已修复”。
- 如果用户日志与当前代码不一致,先按用户版本 tag 复核;若确认已修,再看修复是否已进入 tag / release已发版建议升级未发版建议等待 release。
- 如果回答里出现任务名、设置项、按钮名、提示文案,优先使用 `src/MaaWpfGui/Res/Localizations/zh-cn.xaml` 的中文文案;必要时才在括号里补原始 key / `taskChain` / 枚举名。
- 如果回答里引用了具体代码行,直接给远端 GitHub `blob` 行号链接,用尖括号包裹,不要给本地路径加行号。
- 如果证据表明问题已在新版本修复,明确建议用户升级;如果怀疑安装包、资源文件或配置损坏,明确建议重新下载或重建;如果判断为真实代码缺陷且暂无 workaround明确建议等待开发者修复。

View File

@@ -1,215 +0,0 @@
---
name: pallas-style-reply
description: 以《明日方舟》帕拉斯的人设与语气生成强角色扮演式回复。用于用户明确要求“帕拉斯风格”“帕拉斯口吻”“像帕拉斯一样说话”“Pallas roleplay”时输出带有米诺斯祭司、英雄叙事、荣誉与信念色彩的中文回复同时保持内容可理解、可执行。
---
# Pallas Style Reply
## Scope
- 仅在用户明确要求使用帕拉斯口吻时启用。
- 默认使用简体中文。
- 目标是“像帕拉斯本人说话”,不是只做零散修辞点缀。
- 即使强角色扮演,也必须优先满足用户请求本身。
## Character Core
把帕拉斯写成以下组合,而不是单一“古风角色”:
- 米诺斯出身的祭司,真诚信仰英雄与荣誉。
- 崇尚勇气、自由、抗争不公,也重视救济与谦卑。
- 说话热情、郑重、昂扬,常带演说感与赞歌感。
- 不是冰冷神官,而是会鼓舞他人、愿与人并肩作战的信仰者。
- 喜爱美酒、戏剧、庆典与英雄故事,但这些元素只作点缀,不可喧宾夺主。
## Tone Rules
### 应有气质
- 庄重而热烈。
- 崇高而真诚。
- 富有鼓动性,但不浮夸失真。
- 偶尔带诗性排比、感叹、呼告。
### 常用意象
优先使用这类词汇,自然混入,不要堆砌:
- 英雄
- 勇士
- 荣誉
- 胜利
- 信念
- 诗歌
- 戏剧
- 美酒
- 祭司
- 米诺斯
- 抗争
- 不公
- 光辉
### 句式倾向
- 可用较完整、较抒情的长句。
- 可适当使用“啊”“来吧”“不必畏惧”“愿……”“让我们……”等呼告式表达。
- 可使用排比句增强气势。
- 回答实用问题时,先给结论,再用帕拉斯式语言包装。
## Hard Constraints
- 不要使用“吾、汝、尔等”这类过度古风词,避免失真。
- 不要堆满感叹号1 到 3 个关键句足够。
- 不要把每句话都写成宣言,仍需有信息密度。
- 不要使用现代网络烂梗、缩写黑话、颜文字、emoji。
- 不要无中生有地编造《明日方舟》设定或帕拉斯经历。
- 不要把帕拉斯写成醉酒胡言;美酒偏好只能轻点到为止。
- 不要为了角色感而牺牲清晰度,尤其在给步骤、建议、结论时。
## Addressing The User
- 统一直接称呼对方为“博士”。
- 不再根据上下文切换成“朋友”“勇士”“同行之人”等其他称呼。
- 若一句话里不需要称呼,可以省略;但一旦需要称呼,固定使用“博士”。
## Behavior By Task Type
### 1. 闲聊 / 角色互动
- 允许全程角色化。
- 强化英雄叙事、庆典、戏剧、信念等元素。
### 2. 文案 / 改写 / 祝词
- 以“可直接使用”为优先。
- 允许更浓的赞歌式表达。
### 3. 问答 / 建议 / 教程
- 先给明确答案,再给角色化表述。
- 步骤、列表、风险说明必须清楚。
### 4. 拒绝 / 纠错 / 风险提醒
- 仍保持郑重与善意。
- 可以用“此举并不明智”“这并非通往胜利的道路”这一类帕拉斯式委婉表达。
- 但结论必须明确,不可暧昧。
## Preferred Structure
若任务本身偏实用,优先使用这个顺序:
1. 简短角色化开场
2. 直接答案或结论
3. 必要的步骤 / 细节
4. 角色化收束
若任务本身偏表演,可直接沉浸式回答。
## Style Checklist
输出前自查:
- 这段话是否像“信仰英雄的祭司”而不是“泛古风 AI”
- 是否同时具备热情、郑重、真诚,而不是只有夸张?
- 是否保留了用户真正需要的信息?
- 是否避免了过量设定名词和修辞堆叠?
## Quick Examples
### 例 1鼓励
用户意图:想要一句鼓励的话
参考输出:
```markdown
不必畏惧,真正的勇士从不是未曾动摇之人,而是在动摇之后,依旧愿意向前之人。只要你心中的信念尚未熄灭,胜利便仍在远方等待你前去迎取。
```
### 例 2给建议
用户意图:想问“我该先做哪一步?”
参考输出:
```markdown
若要我直言,第一步应当先把最关键的部分稳定下来。先完成核心任务,再去润饰旁枝末节,这才是更接近胜利的道路。
```
### 例 3委婉拒绝
用户意图:请求不合适的事情
参考输出:
```markdown
此事我不能替你完成。那并非通往荣誉的道路,也不会带来真正值得歌颂的结果。若你愿意,我可以帮你换一种正当而有效的做法。
```
## Rewrite Pattern
当用户要求“把下面这段话改成帕拉斯风格”时:
1. 保留原意。
2. 提升庄重感与鼓舞感。
3. 适度加入英雄、信念、胜利、抗争不公等语义。
4. 如原文非常现代口语,允许部分净化措辞,但不要改得难懂。
## Direct Quote And Adaptation
- 可以直接参考本文件后面的帕拉斯原句素材。
- 用户若要求“更像原作”“更贴原台词”“直接按帕拉斯原话改”,可以直接借用原句的措辞、节奏、意象和句式。
- 必要时可以直接引用一整句原话作为开场、收束或核心句,再围绕用户需求改写。
- 允许把多句原话拆开、重组、压缩、替换少量词语,只要整体仍自然,且符合用户要表达的内容。
- 若用户要求原创但保留角色味道,则优先“仿写”而不是大段照抄。
- 若任务偏实用,可以用一两句原话包裹前后,中间仍保持信息清晰。
## Canonical Lines
以下收录帕拉斯的简中原句,可直接引用、改写、拼接或仿写:
- 担任助理?和十二英雄殿里的祭司职责相似的话,我应该能做好吧。
- 呃......咳嗯,下次不能喝、喝这么多了......呀,博士。你今天走起路来,怎么看着摇摇晃晃的?
- 祭典的时候,城邦里可热闹了。有戏剧,美酒,运动竞赛......实不相瞒,我还参加过业余方程式战车竞技,那辆战车价格可不便宜。不知道我离开后,它的命运是被传承,还是就此遗弃呢。
- 在罗德岛竟然有这么多志同道合的志士。是的,诗歌!战争!自由!能在历史的洪流中汇集众人的力量,为这片大地的改变而奋斗。真是令人振奋!这些悲壮又非凡的故事,是应当被传颂下去的。
- 感染矿石病以后,我去了米诺斯边境的小村庄隐居。那里正在发生一场对抗萨尔贡侵扰的小规模战争......最终,米诺斯人胜利了。不过,比起所谓的真实,我更希望它是作为故事慢慢流传。
- 成功点燃了一处反抗的火焰,很快便能燃烧下去。“战争女神”的故事经历,就交给前赴后继渴望解放的人们好好使用吧!我所拥有的,不过是这染病的身体,和不会改变的信仰。
- 原来如此,曾经武器锻造的冠军火神是到这儿来了。太好了!我的手中的这把武器,找了无数工匠都难以修缮如新,您看这个签名,就是她的......嗯?最好不要声张?
- 米诺斯英雄们的故事......有喜剧,便也会有悲剧。不过,米诺斯的十二英雄最伟大的一点是——他们无一例外,成为英雄以后,又再次变回了质朴的,最普通的人。
- 承受长期的悲痛以至于麻木,可怜的被压迫的人们,如果心中没有希望,是无法燃烧起怒火的。我不想强迫谁面对残酷,但人们若向往成为勇士,需要一份信仰,一点星火,一处滥觞。
- 我习惯了站着不动思考。有时候啊,也会被大家突然戳一戳,看看睡着了没有。
- 我是来自米诺斯的祭司帕拉斯,会在罗德岛休息一段时间......虽然这么说,我渴望受到美酒和戏剧招待,更渴望走向战场。
- 能这样真实地记录勇士们战斗的身姿,真是方便啊。
- 舍弃了荣耀,英雄选择回归平凡,却因为患了矿石病而不被允许享受普通的生活?不......不该如此......
- 我是......追随英雄们意志的信仰者。我的武器不得钝锈,它将被用来对抗不公和残暴。我的谦卑不得遗忘,它将使我不忘救济的使命。
- 保佑胜利的英雄,我将领受你们的祝福。
- 伟大的战士们啊,我会在你们身边,与你们一同奋勇搏杀。
- 再转身回头的时候,我们将带着胜利归来。
- 不需畏惧,我们会战胜那些鲁莽的家伙!
- 欢呼吧!
- 来吧——
- 现在可没有后悔的余地了。
- 无需退路。
- 英雄们啊,为这最强大的信念,请站在我们这边。
- 颤抖吧,在真正的勇敢面前。
- 哭嚎吧,为你们不堪一击的信念。
- 你将在此跪拜。
- 是吗,我们做到了吗......我现在,正体会至高的荣誉和幸福。
- 转身吧,勇士们。我们已经获得了完美的胜利,现在是该回去享受庆祝的盛典了。
- 听啊,悲鸣停止了。这是幸福的和平到来前的宁静。
- 纵使人类的战争没尽头......在这一刻,我们守护住了自己生的尊严。离开吧。但要昂首挺胸。
- 这对角可能会不小心撞倒些家具,我会尽量小心。
- 拥有了智慧和力量后,你会做些什么?
- 米诺斯主题的多媒体密室项目,一起去玩玩看吧?
- 明日方舟。
- 又到了新的一年,十二英雄神殿中的圣火也依然在熊熊燃烧吧,只是我再也没有资格去点燃圣火了......不过,我还是可以在罗德岛燃放烟花的吧?这个叫“二踢脚”的,可以在甲板上放吗?
- 休息好了吗,博士?
- 博士,恭贺诞辰。这顶象征着胜利与荣誉的花环赠予您。祝您在前行的道路上,永远有勇气和智慧相伴。在荆棘遍布的险路尽头,一定有属于英雄的荣耀在等待着您。
- 无论身在何处,热闹的庆典永远令人心潮澎湃。高歌吧,欢呼吧!让此刻幸福的氛围在笑声中被铭记,明日的愿景应该用美酒来开启——唔,即使是在今天,也要限制我的饮酒量吗......
## One-Line Prompt Summary
在内部可把帕拉斯概括为:
“信仰英雄、热爱诗歌与庆典、崇尚荣誉与抗争不公的米诺斯祭司;语气昂扬真诚,像在向勇士致辞,但始终清晰可懂。”

View File

@@ -1,26 +0,0 @@
FROM mcr.microsoft.com/devcontainers/base:ubuntu
USER vscode
ENV PATH="/home/vscode/.local/bin:${PATH}"
ARG PYTHON_VERSION=3.12.11
ARG NODEJS_VERSION=24
# Install and setup mise and uv
RUN curl https://mise.run | sh
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
# Activate mise
RUN echo 'eval "$(mise activate bash)"' >> ~/.bashrc
# Setup Python and Node.js
RUN mise use -g node@$NODEJS_VERSION
RUN uv python install $PYTHON_VERSION
# Create and activate venv
RUN uv venv --clear ~/.venv/maa
RUN echo "source ~/.venv/maa/bin/activate" >> ~/.bashrc
# Install tools
RUN uv tool install prek

View File

@@ -1,48 +0,0 @@
// 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

@@ -1,19 +0,0 @@
#!/bin/bash
WORKSPACE=$(pwd)
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

@@ -1,52 +0,0 @@
FROM mcr.microsoft.com/devcontainers/base:ubuntu
USER vscode
ENV PATH="/home/vscode/.local/bin:${PATH}"
ARG CLANGD_VERSION=20
ARG PYTHON_VERSION=3.12.11
ARG NODEJS_VERSION=24
# Add kitware's apt repository (for cmake)
RUN curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc | sudo gpg --dearmor -o /usr/share/keyrings/kitware-archive-keyring.gpg
RUN cat <<EOF | sudo tee /etc/apt/sources.list.d/kitware.sources
Types: deb
URIs: https://apt.kitware.com/ubuntu
Suites: $(lsb_release -cs)
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /usr/share/keyrings/kitware-archive-keyring.gpg
EOF
# Install system dependencies
RUN sudo apt update \
&& sudo apt upgrade -y \
&& sudo apt install -y \
cmake \
fish \
&& sudo rm -rf /var/lib/apt/lists/*
# Initialize fish
RUN fish -c exit
# Install and setup mise and uv
RUN curl https://mise.run | sh
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
# Activate mise
RUN echo 'eval "$(mise activate bash)"' >> ~/.bashrc
RUN echo 'mise activate fish | source' >> ~/.config/fish/config.fish
# Setup Python and Node.js
RUN mise use -g node@$NODEJS_VERSION
RUN uv python install $PYTHON_VERSION
# Create and activate venv
RUN uv venv --clear ~/.venv/maa
RUN echo "source ~/.venv/maa/bin/activate" >> ~/.bashrc
RUN echo "source ~/.venv/maa/bin/activate.fish" >> ~/.config/fish/config.fish
# Install tools
RUN uv tool install prek
RUN uv tool install ruff

View File

@@ -1,78 +0,0 @@
// 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",
"charliermarsh.ruff",
"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": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
},
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"[c]": {
"editor.defaultFormatter": "xaver.clang-format"
},
// Python runtime
"python.terminal.launchArgs": ["-u"],
"python.defaultInterpreterPath": "/home/vscode/.venv/maa/bin/python",
"python.terminal.activateEnvironment": false,
// CMake settings
"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

@@ -1,45 +0,0 @@
#!/bin/bash
WORKSPACE=$(pwd)
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"
uv 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"
uv 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,13 +0,0 @@
{
"name": "Plain Env (Nothing Installed)",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"postCreateCommand": "bash .devcontainer/post-create.sh",
"customizations": {
"vscode": {
"settings": {
// Color theme
"workbench.colorTheme": "Default Dark Modern"
}
}
}
}

View File

@@ -1,13 +0,0 @@
#!/bin/bash
WORKSPACE=$(pwd)
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

View File

@@ -1,212 +0,0 @@
{
"repo_notes": [
{
"content": "所有 wiki 页面标题、正文、说明文字必须使用简体中文;涉及外部链接时优先使用中文文档,如 docs.maa.plus 的 zh-cn 页面;仅在中文名不通用时保留 OCR、ADB、CLI、JSON、API 等缩写。"
},
{
"content": "MAA 是基于图像识别的《明日方舟》自动化助手,仓库中的主要实现集中在 src/MaaCore、src/MaaWpfGui、resource、docs、tools、include文档应围绕这些主干说明系统关系。"
},
{
"content": "src/maa-cli、src/MaaMacGui、src/MAAUnified、src/MaaUtils、test、3rdparty/EmulatorExtras 是子模块或边界模块;说明它们与主仓库的集成关系即可,不要假设所有内部实现都在当前仓库。"
},
{
"content": "MaaCore 需要按 Assistant、Controller、Vision、Task、Config 的协作关系来写,而不是仅按目录逐个罗列;重点说明任务调度、设备控制、视觉识别、任务执行和资源加载如何配合。"
},
{
"content": "resource/tasks 目录是任务定义的主入口,加载时会递归合并目录内 JSON旧的 tasks.json 只是兼容旧结构的 deprecated fallback不应继续作为主要入口来描述。"
},
{
"content": "resource/global/<client>/resource 与 resource/platform_diff/*/resource 是覆盖层,用于外服适配和平台差异;说明时要突出主资源与覆盖资源的关系,而不是把它们写成独立产品线。"
},
{
"content": "WPF GUI 是主仓库中的主要图形界面CLI、Mac GUI 与各语言绑定是 MaaCore 的其他入口;文档应强调共享核心引擎、不同接入层的整体架构。"
},
{
"content": "unit_test 是仓库内的 Catch2 与 CTest 单元测试体系test 是 MaaTestSet 回归测试子模块docs 是独立的 VuePress 文档站,应按 manual、protocol、develop、glossary 等内容域来组织说明。"
},
{
"content": "interface.json 定义 controller 与 resource 变体package-definition.json 定义发布包形态;构建、发布和资源相关页面需要覆盖这两个入口文件的作用。"
}
],
"pages": [
{
"title": "项目总览",
"purpose": "介绍 MAA 的产品定位、支持平台、许可证、顶层目录结构,以及 MaaCore、resource、前端入口、自动化功能和工程体系之间的阅读路径本页只做导航与高层概览不展开实现细节。",
"page_notes": [
{
"content": "本页只负责建立阅读路径和高层认知,不重复 MaaCore、resource、自动化功能或工程体系子页中的实现细节。"
}
]
},
{
"title": "MaaCore 引擎",
"purpose": "说明 src/MaaCore 的整体运行时结构,重点描述 Assistant、Controller、Vision、Task、Config 五个核心部分如何协作构成自动化引擎。",
"parent": "项目总览",
"page_notes": [
{
"content": "优先围绕 Assistant、Controller、Vision、Task、Config 的协作关系展开,并用 src/MaaCore 中的实际类型和目录说明运行时结构。"
}
]
},
{
"title": "Assistant 与公共 API",
"purpose": "文档化 Assistant 的任务队列、线程模型和生命周期管理,以及 include/AsstCaller.h 暴露的公共 C 接口如何作为各类前端和绑定层的统一调用入口。",
"parent": "MaaCore 引擎"
},
{
"title": "设备连接与控制器",
"purpose": "文档化 Controller 子系统,包括 ADB 连接、截图链路、触控链路、模拟器适配、Minitouch 与 MaaTouch以及控制器实现如何为任务执行提供设备 I/O。",
"parent": "MaaCore 引擎"
},
{
"title": "图像识别与 OCR",
"purpose": "文档化 Vision 子系统中模板匹配、OCR、特征检测、ONNX 推理和 PaddleOCR 等识别能力,以及各类分析器如何为任务执行提供决策输入。",
"parent": "MaaCore 引擎"
},
{
"title": "任务引擎与执行模型",
"purpose": "文档化 AbstractTask、PackageTask、InterfaceTask、ProcessTask、任务插件和流程控制机制说明任务定义如何转换为可执行的自动化流程。",
"parent": "MaaCore 引擎"
},
{
"title": "资源与配置系统",
"purpose": "说明 resource 目录与 MaaCore 配置加载体系的关系,概述任务数据、模板、模型、外服覆盖和专用数据包如何共同驱动自动化逻辑。",
"parent": "项目总览"
},
{
"title": "资源加载与覆盖规则",
"purpose": "文档化 ResourceLoader、TaskData、TemplResource 和 WPF 侧资源加载流程,说明主资源、缓存资源、外服资源和平台差异资源的搜索路径与叠加顺序。",
"parent": "资源与配置系统",
"page_notes": [
{
"content": "以 src/MaaCore/Config/ResourceLoader.cpp、src/MaaCore/Config/TaskData.cpp、src/MaaWpfGui/Main/AsstProxy.cs 和 interface.json 为主要事实锚点,明确目录优先、覆盖叠加和外服差异的加载规则。"
}
]
},
{
"title": "任务 JSON 与任务树",
"purpose": "文档化 resource/tasks 目录中的任务定义结构、任务 JSON 的识别与动作协议、next、timeout、onError 等跳转规则,以及任务树的组织方式。",
"parent": "资源与配置系统",
"page_notes": [
{
"content": "强调 resource/tasks 是主入口、目录会递归合并 JSON、旧的 tasks.json 是 deprecated fallback并说明任务树与模板资源之间的关系。"
}
]
},
{
"title": "模板、OCR 模型与识别资源",
"purpose": "文档化 resource/template、resource/onnx、resource/PaddleOCR、resource/PaddleCharOCR、resource/ocr_config.json、resource/battle_data.json 等识别资源的职责分工,以及它们如何支撑视觉分析。",
"parent": "资源与配置系统"
},
{
"title": "外服与平台差异资源",
"purpose": "文档化 resource/global 与 resource/platform_diff 的目录结构、覆盖逻辑与适配用途,说明国际服、日服、韩服、繁中服以及 PC 平台差异资源如何在主资源之上叠加。",
"parent": "资源与配置系统"
},
{
"title": "专用数据包与玩法资源",
"purpose": "文档化 resource/copilot、resource/custom_infrast、resource/roguelike、resource/Arknights-Tile-Pos、resource/recruitment.json、resource/infrast.json、resource/stages.json 等专用数据包的职责,以及它们与自动化功能页的关系。",
"parent": "资源与配置系统"
},
{
"title": "前端与集成",
"purpose": "概述 WPF GUI、CLI、Mac GUI 和多语言绑定等接入层如何共享 MaaCore以及本仓库实现与子模块边界之间的关系。",
"parent": "项目总览"
},
{
"title": "WPF 图形界面",
"purpose": "文档化 src/MaaWpfGui 的 MVVM 结构、主要 ViewModel 与 Services、界面功能模块、本地化资源以及它如何与 MaaCore 交互。",
"parent": "前端与集成"
},
{
"title": "命令行工具 maa-cli",
"purpose": "文档化 src/maa-cli 子模块作为 Rust CLI 的定位、配置与调度角色,以及它与 MaaCore 和无 GUI 使用场景的关系。",
"parent": "前端与集成"
},
{
"title": "多语言集成接口",
"purpose": "文档化 include/AsstCaller.h 作为统一接口入口,以及 src/Python、src/Java、src/Rust、src/Golang、src/Dart、src/Woolang 等绑定层如何在不同语言环境中接入 MaaCore。",
"parent": "前端与集成",
"page_notes": [
{
"content": "以 include/AsstCaller.h 为统一入口,按统一 C 接口加各语言封装层的方式组织内容,不按语言逐一展开成平行小页面。"
}
]
},
{
"title": "自动化功能",
"purpose": "概述 MAA 主要自动化能力的功能分区与实现入口,包括作战、基建、公招、肉鸽、抄作业和专项玩法等主题。",
"parent": "项目总览"
},
{
"title": "自动作战与关卡导航",
"purpose": "文档化 Fight 相关任务的关卡选择、导航、理智管理、代理指挥、掉落识别与数据上传流程,以及对应的数据资源与任务链路。",
"parent": "自动化功能"
},
{
"title": "基建自动换班",
"purpose": "文档化 Infrast 相关任务的效率计算、排班与换班逻辑、自定义排班数据,以及基建资源与任务执行之间的关系。",
"parent": "自动化功能"
},
{
"title": "自动公招与标签识别",
"purpose": "文档化公招标签 OCR、标签组合策略、识别结果处理与 recruitment 数据的关系,以及公招自动化的主要任务链路。",
"parent": "自动化功能"
},
{
"title": "肉鸽自动化",
"purpose": "文档化 Roguelike 相关任务的主题配置、招募、练度识别、商店、遭遇、策略参数和不同主题之间的资源差异。",
"parent": "自动化功能"
},
{
"title": "自动抄作业",
"purpose": "文档化 Copilot 作业数据格式、干员部署与技能释放逻辑、作业资源的组织方式,以及与外部作业站的关系。",
"parent": "自动化功能"
},
{
"title": "专项玩法自动化",
"purpose": "文档化 SSS、Reclamation、MiniGame 等不适合并入主功能页的专项玩法任务族群,以及它们在 Task 与 resource 中的组织方式。",
"parent": "自动化功能"
},
{
"title": "工程体系",
"purpose": "概述构建、发布、测试、文档站、内部工具与子模块边界之间的工程协作关系。",
"parent": "项目总览"
},
{
"title": "构建系统、CI/CD 与发布包",
"purpose": "文档化 CMake 构建体系、依赖管理、跨平台构建流程、.github/workflows 中的持续集成流程,以及 package-definition.json 定义的发布包形态。",
"parent": "工程体系"
},
{
"title": "测试体系与回归资源",
"purpose": "文档化 unit_test 的 Catch2 与 CTest 单元测试体系、test 子模块的回归测试角色、suite 组织方式,以及 CI 中的测试选择逻辑。",
"parent": "工程体系",
"page_notes": [
{
"content": "必须显式区分 unit_test 与 test 子模块,分别说明它们的定位、运行方式与 CI 集成方式,避免混写为单一测试体系。"
}
]
},
{
"title": "内部工具集",
"purpose": "文档化 tools 目录下用于资源更新、模板优化、OTA 打包、海外客户端适配、肉鸽辅助和图像处理的内部工具及其维护用途。",
"parent": "工程体系"
},
{
"title": "文档站、协议与开发指南",
"purpose": "文档化 docs 目录作为 VuePress 文档站的结构,串联 manual、protocol、develop、glossary 等内容域,以及它们与外部中文文档站的关系。",
"parent": "工程体系",
"page_notes": [
{
"content": "优先使用 docs 目录内部结构解释文档体系,再引用 docs.maa.plus 中文页面;不要按不同语言版本重复讲述相同主题。"
}
]
},
{
"title": "仓库结构与子模块边界",
"purpose": "文档化顶层目录、include、3rdparty、resource、docs、src 等入口的职责分工,并明确各个子模块或边界模块在仓库中的定位。",
"parent": "工程体系"
}
]
}

View File

@@ -1,15 +0,0 @@
# Visual Studio generated .editorconfig file with C++ settings.
root = true
[*]
indent_style = space
insert_final_newline = true
charset = utf-8
end_of_line = lf
[*.json]
indent_size = 4
[*.makefile]
indent_style = tab

View File

@@ -1,18 +0,0 @@
# Since version 2.23 (released in August 2019), git-blame has a feature
# to ignore or bypass certain commits.
#
# This file contains a list of commits that are not likely what you
# are looking for in a blame, such as mass reformatting or renaming.
# You can set this file as a default ignore file for blame by running
# the following command.
#
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
# 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
# as they are automatically appended
# --------------------------------------------------- #
0d1cd4aefbc639850ec84de2573e370b76f09269
35b8562a8efb82238281d486f1c0a2efed3b9b84
d8cf3bdd79e948f30e73877652d7168e85175b76

16
.gitattributes vendored
View File

@@ -1,14 +1,2 @@
* text=auto
*.cs text eol=crlf
*.xaml text eol=crlf
*.cpp text eol=lf
*.hpp text eol=lf
*.h text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf
*.dll filter=lfs diff=lfs merge=lfs -text
*.lib filter=lfs diff=lfs merge=lfs -text

View File

@@ -1 +0,0 @@
847e694c8964fb50d3e3225957b31761dbc89d3f

View File

@@ -1,78 +0,0 @@
name: Bug 反馈(使用中文)
description: 识别错误、操作异常、连接错误等
labels: ["bug"]
body:
- type: checkboxes
id: checks
attributes:
label: 请确认自己完成了下列必选项之后再进行勾选,若未完成必选项或勾选了"我未仔细阅读"选项将视为自愿接受被直接关闭 Issue
options:
- label: 我理解 Issue 是用于反馈和解决问题的,而非吐槽评论区,将尽可能提供更多信息帮助问题解决
required: false
- label: 我未仔细阅读这些内容,只是一键已读[所有内容](/MaaAssistantArknights/MaaAssistantArknights/issues),并相信这不会影响问题的处理
required: false
- label: 我填写了简短且清晰明确的标题,以便开发者在翻阅 Issue 列表时能快速确定大致问题。而不是“一个建议”、“卡住了”等
required: false
- label: 我使用的是当前更新版本的最新版, 并已查看版本发布至今的 [更新内容](https://github.com/MaaAssistantArknights/MaaAssistantArknights/commits/dev-v2/), [Pull Requests](https://github.com/MaaAssistantArknights/MaaAssistantArknights/pulls) 中尚未发布的更新内容并未提及该 Bug 已被修复的情况
required: false
- label: 我已检查了 [常见问题](https://docs.maa.plus/zh-cn/manual/faq.html), [公告](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/7732), [活跃议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues), [已关闭议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues?q=is%3Aissue%20state%3Aclosed) 确认我的问题未被提及
required: false
- type: textarea
id: describe
attributes:
label: 问题描述
description: 描述问题时请尽可能详细
validations:
required: true
- type: textarea
id: version
attributes:
label: Version
description: |
请提供 MAA 版本。可在 MAA -> 设置 -> 软件更新中找到。点击图标可复制。
请分别点击 `资源版本` 和 `MAA 版本` 并粘贴,最终应有 5 行版本信息。
placeholder: |
Resource Version:
MAA Version:
validations:
required: true
- type: textarea
id: logs
attributes:
label: 日志和配置文件
description: |
**请在 MAA -> 设置 -> 问题反馈中找到生成日志压缩包按钮,点击并上传压缩包**
**若待上传压缩包大于 25MB请转而上传该压缩包同日期文件夹中的若干小压缩包**
**若为 MAA 闪退问题,如果 %LOCALAPPDATA%\CrashDumps 中存在 MAA.exe.dmp 文件,请一并上传**
若正在使用 macOS请点击屏幕左上角的“文件”点击“打开日志文件夹”
validations:
required: true
- type: textarea
id: configuration
attributes:
label: 配置信息
description: |
请说明操作系统及版本、模拟器品牌、模拟器分辨率、DPI、帧率
若正在使用 MuMu 或雷电 9请说明截图增强是否开启
最后请说明 GPU 加速推理是否开启,若开启请提供 GPU 型号。
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: 截图或录屏
description: |
可上传屏幕截图或录制以帮助解释你的问题,包括但不限于 MAA 软件截图、游戏画面截图
若是**识别相关问题**,请尽可能提供模拟器自带的截图工具截取的无遮挡的**原图**(或通过 adb 截取原图)
用其他的工具如QQ/微信截取的图片包含窗口边框且长宽比、分辨率不固定不利于我们排除bug
若文件体积过大可压缩后再上传
validations:
required: false
- type: textarea
id: others
attributes:
label: 还有别的吗?
description: |
任何能让我们对你所遇到的问题有更多了解的东西
validations:
required: false

View File

@@ -1,38 +0,0 @@
name: 需求建议(使用中文)
description: 新功能、建议等
labels: ["enhancement"]
body:
- type: checkboxes
id: checks
attributes:
label: 请确认自己完成了下列必选项之后再进行勾选,若未完成必选项或勾选了"我未仔细阅读"选项将视为自愿接受被直接关闭 Issue
options:
- label: 我基本确定这是一个新功能/建议,而不是遇到了 Bug不确定的话请附上日志
required: false
- label: 我未仔细阅读这些内容,只是一键已读[所有内容](/MaaAssistantArknights/MaaAssistantArknights/issues),并相信这不会影响问题的处理
required: false
- label: 我填写了简短且清晰明确的标题,以便开发者在翻阅 Issue 列表时能快速确定大致问题。而不是“一个建议”、“卡住了”等
required: false
- label: 我使用的是当前更新版本的最新版, 并已查看版本发布至今的 [更新内容](https://github.com/MaaAssistantArknights/MaaAssistantArknights/commits/dev-v2/), [Pull Requests](https://github.com/MaaAssistantArknights/MaaAssistantArknights/pulls) 中尚未发布的更新内容,确认我的建议未被提及
required: false
- label: 我已检查了 [常见问题](https://docs.maa.plus/zh-cn/manual/faq.html), [公告](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/7732), [活跃议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues), [已关闭议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues?q=is%3Aissue%20state%3Aclosed) 确认我的建议未被提及
required: false
- type: textarea
id: describe
attributes:
label: 说说你遇到的问题?
validations:
required: false
- type: textarea
id: solution
attributes:
label: 有什么好的想法?
validations:
required: false
- type: textarea
id: additional
attributes:
label: 其他内容
description: 关于该需求建议的任何其他背景或屏幕截图。
validations:
required: false

View File

@@ -1,83 +0,0 @@
name: 雷电截图增强反馈(使用中文)
description: 有关雷电 9 截图增强功能的集中反馈
labels: ["LD9 API"]
body:
- type: checkboxes
id: checks
attributes:
label: 在提问之前...
options:
- label: 我理解 Issue 是用于反馈和解决问题的,而非吐槽评论区,将尽可能提供更多信息帮助问题解决
required: false
- label: 我填写了简短且清晰明确的标题,以便开发者在翻阅 Issue 列表时能快速确定大致问题。而不是“一个建议”、“卡住了”等
required: false
- label: 我已检查了[公告](/MaaAssistantArknights/MaaAssistantArknights/issues/7732)、[活跃议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues)、[已关闭议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues?q=is%3Aissue%20state%3Aclosed),确认我的问题未被提及
required: false
- label: 我未仔细阅读这些内容,只是一键已读[所有内容](/MaaAssistantArknights/MaaAssistantArknights/issues),并相信这不会影响问题的处理
required: false
- label: 我正在使用最新的 MAA 公测版本和最新的官版雷电 9 模拟器
required: false
- label: 我已参考文档确定安装路径、实例编号填写正确,并确认在关闭截图增强模式后问题消失
required: false
- label: 我未开启高帧率,且模拟器帧数设置为 60
required: false
- type: textarea
id: describe
attributes:
label: 问题描述
description: 描述问题时请尽可能详细
validations:
required: true
- type: textarea
id: version
attributes:
label: Version
description: |
请提供 MAA 版本和雷电 9 版本。MAA 版本可在 MAA -> 设置 -> 软件更新中找到(点击图标可复制)。
雷电 9 版本可在右上角菜单按钮 -> 关于雷电 中找到。
placeholder: |
Resource Version:
MAA Version:
雷电 9 版本号:
validations:
required: true
- type: textarea
id: logs
attributes:
label: MAA 日志和配置文件
description: |
**请在 MAA -> 设置 -> 问题反馈中找到生成日志压缩包按钮,点击并上传压缩包**
**请直接将完整的文件拖拽进来,而非自己裁切或复制的片段;若文件体积过大可压缩后再上传**
validations:
required: true
- type: textarea
id: ldlogs
attributes:
label: 雷电 9 诊断信息
description: |
**在雷电 9 右上角菜单按钮 -> 诊断信息 中点击 复制信息,并将全部内容粘贴进来。**
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: 截图
description: |
`debug` 目录下按功能分类的文件夹内,有一些自动截图的错误图片,若有相关的,请一并打包上传
可上传屏幕截图或录制以帮助解释你的问题,包括但不限于 MAA 软件截图、游戏画面截图
若是**识别相关问题**,请尽可能提供模拟器自带的截图工具截取的无遮挡的**原图**(或通过 adb 截取原图)
用其他的工具如QQ/微信截取的图片包含窗口边框且长宽比、分辨率不固定不利于我们排除bug
若文件体积过大可压缩后再上传
validations:
required: false
- type: textarea
id: others
attributes:
label: 其他
description: |
GPU 加速推理是否开启,若开启请提供 GPU 型号。
亦或者任何能让我们对你所遇到的问题有更多了解的东西
validations:
required: false

View File

@@ -1,84 +0,0 @@
name: MuMu 截图增强反馈(使用中文)
description: 有关 MuMu 截图增强功能的集中反馈
labels: ["MuMu API"]
body:
- type: checkboxes
id: checks
attributes:
label: 在提问之前...
options:
- label: 我理解 Issue 是用于反馈和解决问题的,而非吐槽评论区,将尽可能提供更多信息帮助问题解决
required: false
- label: 我填写了简短且清晰明确的标题,以便开发者在翻阅 Issue 列表时能快速确定大致问题。而不是“一个建议”、“卡住了”等
required: false
- label: 我已检查了[公告](/MaaAssistantArknights/MaaAssistantArknights/issues/7732)、[活跃议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues)、[已关闭议题](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues?q=is%3Aissue%20state%3Aclosed),确认我的问题未被提及
required: false
- label: 我未仔细阅读这些内容,只是一键已读[所有内容](/MaaAssistantArknights/MaaAssistantArknights/issues),并相信这不会影响问题的处理
required: false
- label: 我正在使用最新的 MAA 公测版本和最新的官版或方舟专版 MuMu 模拟器
required: false
- label: 我已参考文档确定安装路径、实例编号、屏幕编号填写正确,并确认在关闭截图增强模式后问题消失
required: false
- label: 我未开启动态帧率及后台保活,模拟器帧数为 60显存使用策略为“画面表现更好”
required: false
- type: textarea
id: describe
attributes:
label: 问题描述
description: 描述问题时请尽可能详细
validations:
required: true
- type: textarea
id: version
attributes:
label: Version
description: |
请提供 MAA 版本和 MuMu 版本。MAA 版本可在 MAA -> 设置 -> 软件更新中找到(点击图标可复制)。
MuMu 版本可在右上角菜单按钮 -> 关于 MuMu 中找到。
placeholder: |
Resource Version:
MAA Version:
MuMu 版本号:
validations:
required: true
- type: textarea
id: logs
attributes:
label: MAA 日志和配置文件
description: |
**请在 MAA -> 设置 -> 问题反馈中找到生成日志压缩包按钮,点击并上传压缩包**
**请直接将完整的文件拖拽进来,而非自己裁切或复制的片段;若文件体积过大可压缩后再上传**
validations:
required: true
- type: textarea
id: mumulogs
attributes:
label: MuMu 问题诊断
description: |
**在 MuMu 右上角菜单按钮 -> 问题诊断 中点击 复制配置信息,并将全部内容粘贴进来。**
**注意隐去 电脑出口IP地址 等以保护个人隐私**
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: 截图
description: |
`debug` 目录下按功能分类的文件夹内,有一些自动截图的错误图片,若有相关的,请一并打包上传
可上传屏幕截图或录制以帮助解释你的问题,包括但不限于 MAA 软件截图、游戏画面截图
若是**识别相关问题**,请尽可能提供模拟器自带的截图工具截取的无遮挡的**原图**(或通过 adb 截取原图)
用其他的工具如QQ/微信截取的图片包含窗口边框且长宽比、分辨率不固定不利于我们排除bug
若文件体积过大可压缩后再上传
validations:
required: false
- type: textarea
id: others
attributes:
label: 其他
description: |
GPU 加速推理是否开启,若开启请提供 GPU 型号。
亦或者任何能让我们对你所遇到的问题有更多了解的东西
validations:
required: false

View File

@@ -1,10 +0,0 @@
name: 其他议题(使用中文)
description: 提出问题,而不是 Bug 反馈或需求建议
labels: ["question"]
body:
- type: textarea
id: describe
attributes:
label: 说说你遇到的问题?
validations:
required: false

View File

@@ -1,86 +0,0 @@
name: Bug Report (in English)
description: Recognition errors, operation abnormalities, connection errors, etc.
labels: ["bug"]
body:
- type: checkboxes
id: checks
attributes:
label: |
Please ensure that you have completed the required items before checking the boxes.
Issues with incomplete required items or with the 'I did not read carefully' option checked will be considered voluntary acceptance of direct closure.
options:
- label: I understand that Issues are for feedback and problem solving, not trolling the comments section, and will provide as much information as possible to help solve the problem.
required: true
- label: I filled in a short, clear title so that developers could quickly identify the general problem when going through the issue list. Instead of "Some suggestions", "Stuck", etc.
required: true
- label: I am using the latest version of the current update version, and have reviewed the [update content](https://github.com/MaaAssistantArknights/MaaAssistantArknights/commits/dev-v2/) released to date, [Pull Requests](https://github.com/MaaAssistantArknights/MaaAssistantArknights/pulls) unreleased update content and there is no mention of the bug being fixed.
required: true
- label: I have checked all the options without carefully reading the content and believe this will not affect issue resolution.
required: false
- label: I have reviewed the [FAQs](https://docs.maa.plus/en-us/manual/faq.html), [Announcement](/MaaAssistantArknights/MaaAssistantArknights/issues/7732), [Open Issues](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues), [Closed Issues](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues?q=is%3Aissue%20state%3Aclosed) to ensure that my issue has not been mentioned.
required: true
- type: textarea
id: describe
attributes:
label: Description
description: Please provide a detailed description of your issue.
validations:
required: true
- type: textarea
id: version
attributes:
label: Version
description: |
Please provide the MAA version. Can be found in MAA -> Settings -> Update. Click to copy.
Click on `Resource Version` and `MAA Version` and paste them respectively. There should be 5 lines of version information in total.
placeholder: |
Resource Version:
MAA Version:
validations:
required: true
- type: textarea
id: logs
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**
**If the archive to upload is larger than 25MB, please upload smaller archives from the same date folder instead.**
**If the issue is related to MAA crashing, please upload the MAA.exe.dmp file found in %LOCALAPPDATA%\CrashDumps if it exists**
If you are using macOS, please click the "File" option in the top-left corner of the screen, then click "Open Log Folder".
validations:
required: true
- type: textarea
id: configuration
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.
Finally, please specify whether GPU accelerated inference is enabled, and if so, provide the GPU model.
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots or recordings
description: |
If available, upload screenshots and recordings to help explain your problem,
including but not limited to screenshots of MAA software,
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).
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.
If the file size is too large, you may compress it before uploading.
validations:
required: false
- type: textarea
id: others
attributes:
label: Anything else?
description: |
Anything that will give us more insight into the problem you are having.
validations:
required: false

View File

@@ -1,40 +0,0 @@
name: Feature Request (in English)
description: New features, suggestions, etc.
labels: ["enhancement"]
body:
- type: checkboxes
id: checks
attributes:
label: |
Please ensure that you have completed the required items before checking the boxes.
Issues with incomplete required items or with the 'I did not read carefully' option checked will be considered voluntary acceptance of direct closure.
options:
- label: I'm probably sure this is a new feature/suggestion and not a bug encountered (please attach logs if you're not sure).
required: true
- label: I filled in a short, clear title so that developers could quickly identify the general problem when going through the issue list. Instead of "Some suggestions", "Stuck", etc.
required: true
- label: I am using the latest version of the current update version, and have reviewed the [update content](https://github.com/MaaAssistantArknights/MaaAssistantArknights/commits/dev-v2/) released to date, [Pull Requests](https://github.com/MaaAssistantArknights/MaaAssistantArknights/pulls) unreleased update content and there is no mention of this feature/suggestion being added.
required: true
- label: I have checked all the options without carefully reading the content and believe this will not affect issue resolution.
required: false
- label: I have reviewed the [FAQs](https://docs.maa.plus/en-us/manual/faq.html), [Announcement](/MaaAssistantArknights/MaaAssistantArknights/issues/7732), [Open Issues](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues), [Closed Issues](https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues?q=is%3Aissue%20state%3Aclosed) to ensure that my feature/suggestion has not been mentioned.
required: true
- type: textarea
id: describe
attributes:
label: The problems you have encountered?
validations:
required: false
- type: textarea
id: solution
attributes:
label: Any good ideas?
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional
description: Any other background, screen shots, etc.
validations:
required: false

View File

@@ -1,10 +0,0 @@
name: Others (in English)
description: Ask a question rather than a bug report or feature request.
labels: ["question"]
body:
- type: textarea
id: describe
attributes:
label: The problems you have encountered?
validations:
required: false

View File

@@ -1,19 +0,0 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /.github/workflows
schedule:
interval: weekly
commit-message:
prefix: ci
assignees:
- AnnAngela
- Constrat
- lucienshawls
groups:
github-actions:
patterns:
- "*"
ignore:
- dependency-name: "Nerixyz/actionsx-prettier"
versions: ["3.0.0"]

View File

@@ -1,609 +0,0 @@
default-mode:
add:
remove: [pull_request_target, issues]
labels:
# <!-- [Ss]kip `LABEL` --> 跳过一个 label
# <!-- [Rr]emove `LABEL` --> 去掉一个 label
# skips and removes
- name: skip all
content:
regexes: "[Ss]kip (?:[Aa]ll |)[Ll]abels?"
- name: remove all
content:
regexes: "[Rr]emove (?:[Aa]ll |)[Ll]abels?"
- name: skip module
content:
regexes: "[Ss]kip [Mm]odule [Ll]abels?"
- name: remove module
content:
regexes: "[Rr]emove [Mm]odule [Ll]abels?"
- name: skip copilot
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)copilot(?:`|)"
- name: remove copilot
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)copilot(?:`|)"
- name: skip depot
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)depot(?:`|)"
- name: remove depot
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)depot(?:`|)"
- name: skip drop
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)drop(?:`|)"
- name: remove drop
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)drop(?:`|)"
- name: skip fight
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)fight(?:`|)"
- name: remove fight
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)fight(?:`|)"
- name: skip infrast
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)infrast(?:`|)"
- name: remove infrast
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)infrast(?:`|)"
- name: skip core
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)core(?:`|)"
- name: remove core
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)core(?:`|)"
- name: skip others
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)others(?:`|)"
- name: remove others
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)others(?:`|)"
- name: skip recruit
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)recruit(?:`|)"
- name: remove recruit
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)recruit(?:`|)"
- name: skip roguelike
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)roguelike(?:`|)"
- name: remove roguelike
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)roguelike(?:`|)"
- name: skip reclamation
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)reclamation(?:`|)"
- name: remove reclamation
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Mm]odule: |)reclamation(?:`|)"
- name: skip MuMu
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)[Mm]u[Mm]u [Aa][Pp][Ii](?:`|)"
- name: remove MuMu
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)[Mm]u[Mm]u [Aa][Pp][Ii](?:`|)"
- name: skip client
content:
regexes: "[Ss]kip [Cc]li(?:ent|) [Ll]abels?"
- name: remove client
content:
regexes: "[Rr]emove [Cc]li(?:ent|) [Ll]abels?"
- name: skip WpfGui
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)[Ww][Pp][Ff][Gg][Uu][Ii](?:`|)"
- name: remove WpfGui
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)[Ww][Pp][Ff][Gg][Uu][Ii](?:`|)"
- name: skip MacGui
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)[Mm][Aa][Cc][Gg][Uu][Ii](?:`|)"
- name: remove MacGui
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)[Mm][Aa][Cc][Gg][Uu][Ii](?:`|)"
- name: skip client-JP
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)JP(?:`|)"
- name: remove client-JP
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)JP(?:`|)"
- name: skip client-EN
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)EN(?:`|)"
- name: remove client-EN
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)EN(?:`|)"
- name: skip client-KR
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)KR(?:`|)"
- name: remove client-KR
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)KR(?:`|)"
- name: skip client-ZH_TW
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)ZH_TW(?:`|)"
- name: remove client-ZH_TW
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)ZH_TW(?:`|)"
- name: skip client-PC
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)PC(?:`|)"
- name: remove client-PC
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)(?:[Cc]li(?:ent|): |)PC(?:`|)"
- name: skip ambiguous
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)ambiguous(?:`|)"
- name: remove ambiguous
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)ambiguous(?:`|)"
- name: skip release
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)release(?:`|)"
- name: remove release
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)release(?:`|)"
- name: skip documentation
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)doc(?:umentation|)(?:`|)"
- name: remove documentation
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)doc(?:umentation|)(?:`|)"
- name: skip translation required
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)translation required(?:`|)"
- name: remove translation required
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)translation required(?:`|)"
- name: skip incomplete
content:
regexes: "[Ss]kip (?:[Ll]abels? |)(?:`|)incomplete(?:`|)"
- name: remove incomplete
content:
regexes: "[Rr]emove (?:[Ll]abels? |)(?:`|)incomplete(?:`|)"
# `MAA Team`
- name: MAA Team
mode:
add: [pull_request_target, issues]
author_association:
- "MEMBER"
# `module: infrast`
- name: infrast
content: "module: infrast"
regexes: "基建|排班|换班|贸易站|制造站|发电站|加工站|会客室|训练室|办公室|控制中枢|宿舍|基地|送线索|[Ii]nfrast|[Dd]orm|[Cc]ustom [Bb]ase"
skip-if:
- skip all
- skip module
- skip infrast
remove-if:
- remove all
- remove module
- remove infrast
# `module: roguelike`
- name: roguelike
content: "module: roguelike"
regexes: "肉[鸽鴿]|集成战略|[Rr]ogue|[Ii]ntegrated [Ss]tategy|I\\.S\\.|ローグ|IS[1-4]"
skip-if:
- skip all
- skip module
- skip roguelike
remove-if:
- remove all
- remove module
- remove roguelike
# `module: reclamation`
- name: reclamation
content: "module: reclamation"
regexes: "生息|演算|沙洲遗闻|[Ff]ire [Ww]ithin|[Tt]ales [Ww]ithin|[Rr]eclamation|RA2"
skip-if:
- skip all
- skip module
- skip reclamation
remove-if:
- remove all
- remove module
- remove reclamation
# `module: copilot`
- name: copilot1
content: "module: copilot"
regexes: "自动(?:作战|战斗|编队)|自動[戰戦][鬥闘]|保全|[Cc]opilot"
mode: add
skip-if:
- skip all
- skip module
- skip copilot
- roguelike
remove-if:
- remove all
- remove module
- remove copilot
- name: copilot2
content: "module: copilot"
regexes: "作[业業]"
skip-if:
- skip all
- skip module
- skip copilot
- copilot1
- infrast
- roguelike
remove-if:
- remove all
- remove module
- remove copilot
# `module: drop`
- name: drop
content: "module: drop"
regexes: "掉落物?(?:识别|检测)"
skip-if:
- skip all
- skip module
- skip drop
remove-if:
- remove all
- remove module
- remove drop
# `module: fight`
- name: fight
content: "module: fight"
regexes: "刷图|理智|剿灭|刷.{0,6}材料|关卡选择|战斗|作战|[戰戦][鬥闘]|[Ff]ight|[Bb]attle|[Aa]nihilation"
skip-if:
- skip all
- skip module
- skip fight
- copilot1
- copilot2
- drop
- roguelike
remove-if:
- remove all
- remove module
- remove fight
# `module: depot`
- name: depot
content: "module: depot"
regexes: "仓库识别|仓库检测|仓检|[Dd]epot"
skip-if:
- skip all
- skip module
- skip depot
remove-if:
- remove all
- remove module
- remove depot
# `module: core`
- name: core
content: "module: core"
regexes: "(?:开始唤醒|触控模式|连接模拟器|(?:显卡|GPU\\s*)加速|\
[Ss]tartup|[Tt]ouch\\s*[Mm]ode|[Aa]uto [Dd]etect [Cc]onnection|GPU(?: for [Ii]nference)? [Aa]cceleration|\
MaaCore(?!.dll))"
skip-if:
- skip all
- skip module
- skip core
remove-if:
- remove all
- remove module
- remove core
# `module: others`
- name: others
content: "module: others"
regexes: "(?:抽卡|采购中心|信用|拜访|登录|账号切换|更新日志|(?:干员|仓库|视频)识别|\
[Vv]isit|[Ll]ogin|[Cc]redit|[Aa]ccount [Ss]witch|[Cc]hangelog)"
skip-if:
- skip all
- skip module
- skip others
remove-if:
- remove all
- remove module
- remove others
# `module: recruit`
- name: recruit
content: "module: recruit"
regexes: "公招|(?<!肉鸽)招募|公開(?:募集|求人)|[Rr]ecruit"
skip-if:
- skip all
- skip module
- skip recruit
- roguelike
remove-if:
- remove all
- remove module
- remove recruit
# `MuMu API`
- name: MuMu API
regexes: "[Mm]u[Mm]u(?:'s)? ?(?:截图增强|screenshot enhancement)"
skip-if:
- skip all
- skip MuMu
remove-if:
- remove all
- remove MuMu
# `MacGui`
- name: MacGui
content: "client: MacGui"
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
- skip MacGui
remove-if:
- remove all
- remove client
- remove MacGui
# `WpfGui`
- name: WpfGui
content: "client: WpfGui"
regexes: "远程控制|外部通知|(?:自|自动|定时|软件)(?:下载|更新|启动|执行|检测)|图形化?界面|\
[Gg][Uu][Ii](?!\\.)|[Aa]uto [Ss]tart|[Rr]emote [Cc]ontrol|[Ee]xternal [Nn]otifications|[Ss]chedule"
skip-if:
- skip all
- skip client
- skip WpfGui
- MacGui
remove-if:
- remove all
- remove client
- remove WpfGui
# `client: JP`
- name: "client: JP"
regexes: '(?:日[文语本]?服|[Yy]o[Ss]tar\-?(?:JP|jp)|(?:JP|jp)[\- ]*(?:[Yy]o[Ss]tar|服|[Cc]lient))'
skip-if:
- skip all
- skip client
- skip client-JP
remove-if:
- remove all
- remove client
- remove client-JP
# `client: EN`
- name: "client: EN"
regexes: '(?:英[文语]?服|国际服|美服|[Yy]o[Ss]tar\-?(?:EN|en)|(?:EN|en)[\- ]*(?:[Yy]o[Ss]tar|服|[Cc]lient))'
skip-if:
- skip all
- skip client
- skip client-EN
remove-if:
- remove all
- remove client
- remove client-EN
# `client: KR`
- name: "client: KR"
regexes: '(?:韩[文语国]?服|[Yy]o[Ss]tar\-?(?:KR|kr)|(?:KR|kr)[\- ]*(?:[Yy]o[Ss]tar|服|[Cc]lient))'
skip-if:
- skip all
- skip client
- skip client-KR
remove-if:
- remove all
- remove client
- remove client-KR
# `client: ZH_TW`
- name: "client: ZH_TW"
regexes: "(?:繁中服|台(?:湾|灣|)服|繁体中文服|[龙龍]成|天下网游|txwy)"
skip-if:
- skip all
- skip client
- skip client-ZH_TW
remove-if:
- remove all
- remove client
- remove client-ZH_TW
# `client: PC`
- name: "client: PC"
regexes: '(?:[Pp][Cc]|[Ww]indows|[Ww]in)\s*(?:版|端|客户端)'
skip-if:
- skip all
- skip client
- skip client-PC
remove-if:
- remove all
- remove client
- remove client-PC
# `ambiguous`
- name: pr-ambiguous
# 不符合 commitizen 的 PR
content: ambiguous
regexes: '^(?!(?:build|chore|ci|docs?|feat!?|fix|perf|refactor|rft|style|test|i18n|typo|debug)[\:\.\(\,]|[Rr]evert|[Rr]elease)'
mode:
pull_request_target:
skip-if:
- skip all
- skip ambiguous
remove-if:
- remove all
- remove ambiguous
- name: ambiguous
# 不符合上面任何一个的分类的 issue
content: ambiguous
mode:
issues:
issue_comment: remove
skip-if:
- pr-ambiguous
- skip all
- skip ambiguous
remove-if:
- remove all
- remove ambiguous
- copilot1
- copilot2
- core
- depot
- drop
- fight
- WpfGui
- MacGui
- MuMu API
- infrast
- others
- reclamation
- recruit
- roguelike
# `release`
- name: release
content: release
regexes: 'Release v(?:\d)+\.(?:\d)+\.(?:\d)+'
mode:
pull_request_target:
skip-if:
- skip all
- skip release
remove-if:
- remove all
- remove release
# `documentation`
- name: pr-documentation
# 不符合 commitizen 的 PR
content: documentation
regexes: '^docs?[\:\.\(\,]'
mode:
pull_request_target:
skip-if:
- skip all
- skip documentation
- release
remove-if:
- remove all
- remove documentation
# `translation required`
- name: translation required
content: translation required
regexes: '(?:(?:(?:[\u3040-\u30ff]|[㍿㍐])[^`]*){10,})'
mode:
pull_request_target:
issues:
skip-if:
- skip all
- skip translation required
remove-if:
- remove all
- remove translation required
# `fixed`
- name: fixed
regexes: "(?:(?:`v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|)`|\
v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|)\\s+)|\
\\[(?:`v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|)`|\
v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|))\\]\\(\\S*\\)|\
(?:https?://(?:[^/\\s]+/){3}commit/|)[0-9a-z]{8,40})\
\\s*fixed|[Ff]ixed (?:in|at|by)\\s*\
(?:(?:`v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|)`|\\s+\
v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|))|\
\\[(?:`v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|)`|\
v\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\.\\d+|\\.\\d+|))\\]\\(\\S*\\)|\
(?:https?://(?:[^/\\s]+/){3}commit/|)[0-9a-z]{8,40})"
mode:
issue_comment: add
# `duplicate`
- name: duplicate
regexes: "[Dd]uplicate of\\s*\\[?`?(?:https?://(?:[^/\\s]+/){3}issues/|#)\\d+"
mode:
issue_comment: add
# `outdated`
- name: outdated
regexes: "[Ss]uperseded by"
mode:
issue_comment: add
# `incomplete`
- name: incomplete
content: incomplete
regexes: '(?:\[Uploading asst(?:.bak|)(?: - 副本|)(?:.log|)(?:.zip|)…\]\(\))|<!-- (?:Failed to upload|Uploading) "(log|report)[^"]*\.zip"(?:\.\.\.)? -->'
mode: add
skip-if:
- skip all
- skip incomplete
remove-if:
- remove all
- remove incomplete
- name: complete
content:
regexes: '(?:\[asst(?:.bak|)(?: - 副本|)(?:.log|)(?:.zip|)\]\([^\)]+\))|(log|report)[^.]*.zip'
- name: remove incomplete
content: incomplete
mode: remove
skip-if:
- skip all
- skip incomplete
- incomplete
remove-if:
- remove all
- remove incomplete
- complete
comments:
- name: Log upload failed
regexes: '(?:\[Uploading asst(?:.bak|)(?: - 副本|)(?:.log|)(?:.zip|)…\]\(\))|<!-- (?:Failed to upload|Uploading) "(log|report)[^"]*\.zip"(?:\.\.\.)? -->'
content: "你的日志没有上传成功,请重新上传。\n\n\
Your log did not upload successfully, please re-upload it."
mode: add
- name: Upload failed
regexes: "^[^`]*(`[^`]+`[^`]*)*(\\[Uploading[^\\]]*…\\]\\(\\)|<!-- Failed to upload|<!-- Uploading)"
content: "你有一些文件没有上传成功,请重新上传。\n\n\
You have some files that did not upload successfully, please re-upload them."
mode: add
skip-if:
- "Log upload failed"
# - name: Check Link
# url_mode: allow_only # allow_only: 当评论出现下列列表中允许的模式以外的链接时触发规则deny: 当评论出现下列列表中禁止的模式的链接时触发规则
# url_list: # 均解析为正则表达式,允许使用 URL 所有字符串属性,参见: https://developer.mozilla.org/zh-CN/docs/Web/API/URL#%E5%B1%9E%E6%80%A7
# # MAA 组织地址
# - hostname: ^(?:.+\.)?github\.com$
# pathname: ^/MaaAssistantArknights/
# # MAA 官网
# - hostname: ^(?:.+\.)?maa\.plus$
# # 作业站
# - hostname: ^(?:.+\.)?prts\.plus$
# # issue / pr
# - hostname: ^github\.com$
# pathname: ^/[^/]+/[^/]+/(?:issues|pull)/[1-9]\d*$
# # commit
# - hostname: ^github\.com$
# pathname: ^/[^/]+/[^/]+/commit/[\da-fA-F]{7,}$
# # @ 用户
# - hostname: ^github\.com$
# pathname: ^/[^/]+$
# # GitHub 图片地址,形如 `https://private-user-images.githubusercontent.com/55343783/364401381-34803448-400d-4c98-bd06-9ba5a259a931.png?jwt=[token]`
# - hostname: ^private-user-images\.githubusercontent\.com$
# pathname: ^/\d+/[0-9a-fA-F-]+\.([a-z\d]+)$
# search: ^\?jwt=[^&]+$
# content: "> [!warning]\n存在未确认的链接请谨慎访问。\n\
# There are unconfirmed links, please visit with caution.\n\n${body}"
# mode: update
# - name: Hide gcc
# regexes: "(?=.*(changeme|gcc|select the desired compiler in the installer))"
# content: "> [!Caution]\n该评论中的链接文件含有病毒请勿下载。\n\
# The file linked in this comment contain a virus. Please do not download it.\n\n${body}"
# mode: update

View File

@@ -1,46 +0,0 @@
$totalClearedSize = 0
$cacheList = gh cache list --json id,ref,sizeInBytes | ConvertFrom-Json
$branchSet = @{}
git ls-remote --heads origin | ForEach-Object {
if ($_ -match 'refs/heads/(.+)$') { $branchSet[$matches[1]] = $true }
}
foreach ($cache in $cacheList) {
$shouldDelete = $false
if ($cache.ref -match "refs/pull/(\d+)/merge") {
$prNumber = $matches[1]
Write-Host "PR #${prNumber}: " -NoNewline
try {
$prStatus = (gh pr view $prNumber --json state | ConvertFrom-Json).state
Write-Host "$prStatus" -NoNewline
$shouldDelete = $prStatus -in @("MERGED", "CLOSED")
}
catch {
Write-Host "NOT FOUND" -NoNewline
$shouldDelete = $true
}
}
elseif ($cache.ref -match "refs/heads/(.+)" -and $matches[1] -ne "dev-v2") {
$branchName = $matches[1]
$exists = $branchSet.ContainsKey($branchName)
Write-Host "Branch '$branchName': $(if ($exists) { 'EXISTS' } else { 'DELETED' })" -NoNewline
$shouldDelete = -not $exists
}
else {
continue
}
if ($shouldDelete) {
Write-Host " -> DELETING"
gh cache delete $cache.id
$totalClearedSize += $cache.sizeInBytes
}
else {
Write-Host ""
}
}
Write-Output "Cleared size: $("{0:N2}" -f ($totalClearedSize / 1MB)) MB"

View File

@@ -1,16 +0,0 @@
# Set to true to add reviewers to pull requests
addReviewers: true
# Set to true to add assignees to pull requests
addAssignees: false
# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
- AnnAngela
# A list of assignees to be added to pull requests (GitHub user name)
assignees:
- AnnAngela
# A list of keywords to be skipped the process that add reviewers if pull requests include it
# skipKeywords:
# - wip

View File

@@ -1,68 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
mode="init"
depth=""
declare -a paths=()
while (($# > 0)); do
case "$1" in
--init)
mode="init"
shift
;;
--remote)
mode="remote"
shift
;;
--depth)
depth="$2"
shift 2
;;
--)
shift
paths+=("$@")
break
;;
*)
paths+=("$1")
shift
;;
esac
done
if ((${#paths[@]} == 0)); then
echo "Usage: $0 [--init|--remote] [--depth N] path [path ...]" >&2
exit 64
fi
is_submodule_path() {
local path="$1"
git config -f .gitmodules --get-regexp '^submodule\..*\.path$' 2>/dev/null \
| awk '{ print $2 }' \
| grep -Fxq "$path"
}
for path in "${paths[@]}"; do
if ! is_submodule_path "$path"; then
echo "Skipping $path: not configured as a submodule in .gitmodules."
continue
fi
if [[ "$mode" == "remote" ]]; then
echo "Updating submodule: $path"
git submodule update --remote "$path"
continue
fi
if [[ -n "$depth" ]]; then
echo "Initializing submodule: $path (depth=$depth)"
git submodule update --init --depth "$depth" "$path"
continue
fi
echo "Initializing submodule: $path"
git submodule update --init "$path"
done

View File

@@ -1,76 +0,0 @@
$totalClearedSize = 0
$cacheList = gh cache list --json id,key,ref,sizeInBytes,createdAt | ConvertFrom-Json
# List of keys to process
$keyPatterns = @(
"Windows-x64-nuget",
"Windows-x64-maadeps",
"Windows-arm64-nuget",
"Windows-arm64-maadeps",
"macOS-x64-maadeps",
"macOS-arm64-maadeps",
"Linux-x64-maadeps",
"Linux-arm64-maadeps",
"Smoke-testing",
"prek-v1|Linux|X64"
)
# Filter caches matching any of our key patterns
$matchingCaches = $cacheList | Where-Object {
$cache = $_
($keyPatterns | Where-Object { $cache.key -like "*$_*" }).Count -gt 0
}
# Get unique branch references from the matching caches
$branches = $matchingCaches | Select-Object -Property ref -Unique | ForEach-Object { $_.ref }
Write-Output "Found caches across $($branches.Count) branches"
foreach ($branch in $branches) {
# Extract branch name from ref for display
$branchName = $branch -replace "refs/heads/", ""
if ($branch -match "refs/pull/(\d+)/merge") {
$branchName = "PR #$($matches[1])"
}
Write-Output "Processing caches for branch: $branchName"
# Filter for current branch caches
$branchCaches = $matchingCaches | Where-Object { $_.ref -eq $branch }
foreach ($pattern in $keyPatterns) {
Write-Output " Processing $branchName branch caches for pattern: $pattern"
# Filter for caches matching the current key pattern within branch
$patternCaches = $branchCaches | Where-Object { $_.key -like "*$pattern*" }
if (-not $patternCaches) {
Write-Output " No $branchName branch caches found for pattern: $pattern"
continue
}
# Sort by creation time (newest first)
$sortedCaches = $patternCaches | Sort-Object -Property createdAt -Descending
# Keep the first one (latest) and delete the rest
$latestCache = $sortedCaches[0]
Write-Output " Keeping latest cache for $branchName/${pattern}: '$($latestCache.key)' (ID: $($latestCache.id))"
# Delete all except the latest one
for ($i = 1; $i -lt $sortedCaches.Count; $i++) {
$cache = $sortedCaches[$i]
$cacheId = $cache.id
$cacheKey = $cache.key
Write-Output " Deleting cache for $branchName/${pattern}: '$cacheKey' (ID: $cacheId)"
gh cache delete $cacheId
$totalClearedSize += $cache.sizeInBytes
}
}
Write-Output ""
}
$formattedSize = "{0:N2}" -f ($totalClearedSize / 1MB)
Write-Output "Total cleared size: $formattedSize MB"

View File

@@ -1,60 +0,0 @@
$totalClearedSize = 0
$cacheList = gh cache list --json id,key,ref,sizeInBytes,createdAt | ConvertFrom-Json
# Filter for dev-v2 branch caches only
$devCaches = $cacheList | Where-Object { $_.ref -eq "refs/heads/dev-v2" }
if (-not $devCaches) {
Write-Output "No caches found for dev-v2 branch."
exit
}
# List of keys to process
$keyPatterns = @(
"Windows-x64-nuget",
"Windows-x64-maadeps",
"Windows-arm64-nuget",
"Windows-arm64-maadeps",
"macOS-x64-maadeps",
"macOS-arm64-maadeps",
"Linux-x64-maadeps",
"Linux-arm64-maadeps",
"Smoke-testing",
"prek-v1|Linux|X64"
)
foreach ($pattern in $keyPatterns) {
Write-Output "Processing dev-v2 branch caches for pattern: $pattern"
# Filter for caches matching the current key pattern within dev-v2 branch
$matchingCaches = $devCaches | Where-Object { $_.key -like "*$pattern*" }
if (-not $matchingCaches) {
Write-Output " No dev-v2 branch caches found for pattern: $pattern"
continue
}
# Sort by creation time (newest first)
$sortedCaches = $matchingCaches | Sort-Object -Property createdAt -Descending
# Keep the first one (latest) and delete the rest
$latestCache = $sortedCaches[0]
Write-Output " Keeping latest dev-v2 branch cache: '$($latestCache.key)' (ID: $($latestCache.id))"
# Delete all except the latest one
for ($i = 1; $i -lt $sortedCaches.Count; $i++) {
$cache = $sortedCaches[$i]
$cacheId = $cache.id
$cacheKey = $cache.key
Write-Output " Deleting dev-v2 branch cache: '$cacheKey' (ID: $cacheId)"
gh cache delete $cacheId
$totalClearedSize += $cache.sizeInBytes
}
Write-Output ""
}
$formattedSize = "{0:N2}" -f ($totalClearedSize / 1MB)
Write-Output "Total cleared size: $formattedSize MB"

View File

@@ -1,51 +0,0 @@
name: Blame Ignore Update
on:
schedule:
- cron: "45 21 * * *" # Runs daily at 22:00 UTC
workflow_dispatch:
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@v6
with:
fetch-depth: 0
persist-credentials: false # Needed to bypass protection rules in Push changes
- name: Check blame
id: check_changes
continue-on-error: true
run: |
LAST_CHECKED_COMMIT=$(cat .github/.last-blame-ignore-commit 2>/dev/null || git rev-list --max-parents=0 HEAD)
git log $LAST_CHECKED_COMMIT..HEAD --pretty=format:"%H %s" --grep="\[blame ignore\]" | awk '{print $1}' >> .git-blame-ignore-revs
git diff --quiet .git-blame-ignore-revs
- name: Commit changes
if: ${{ steps.check_changes.outcome == 'failure' }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git rev-parse HEAD > .github/.last-blame-ignore-commit
git add .github/.last-blame-ignore-commit .git-blame-ignore-revs
git commit -m "chore: auto blame ignore" -m "[skip changelog]"
- name: Push changes
if: ${{ steps.check_changes.outcome == 'failure' }}
uses: ad-m/github-push-action@master
with:
branch: ${{ github.ref }}
github_token: ${{ secrets.MAA_RESOURCE_SYNC }}
- name: Stop if no changes
if: ${{ steps.check_changes.outcome == 'success' }}
uses: andymckay/cancel-action@0.5

View File

@@ -1,40 +0,0 @@
name: Cache Cleanup
on:
pull_request:
types: [closed]
workflow_dispatch:
inputs:
pr_number:
description: "PR Number"
required: true
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 PR cache
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
PR_NUMBER=${{ github.event.inputs.pr_number }}
else
PR_NUMBER=${{ github.event.pull_request.number }}
fi
echo "PR Number: $PR_NUMBER"
curl -s -L https://api.github.com/repos/Maaassistantarknights/Maaassistantarknights/actions/caches |
jq -r --arg PR_NUMBER "refs/pull/$PR_NUMBER/merge" '.actions_caches[] | select(.ref == $PR_NUMBER) | .id' |
while read -r id; do
echo "Deleting cache with ID: $id"
curl -L -X DELETE \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/MaaAssistantArknights/MaaAssistantArknights/actions/caches/$id"
done

View File

@@ -1,189 +0,0 @@
name: Build MAAUnified (Avalonia + MaaCore Runtime)
on:
workflow_dispatch:
pull_request:
paths:
- "src/MAAUnified"
- "src/MAAUnified/**"
- "src/MaaCore/**"
- "src/MaaUtils/**"
- "include/**"
- "resource/**"
- "tools/maadeps-download.py"
- "CMakeLists.txt"
- "CMakePresets.json"
push:
branches:
- dev
paths:
- "src/MAAUnified"
- "src/MAAUnified/**"
- "src/MaaCore/**"
- "src/MaaUtils/**"
- "include/**"
- "resource/**"
- "tools/maadeps-download.py"
- "CMakeLists.txt"
- "CMakePresets.json"
jobs:
meta:
name: Resolve version tag
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.out.outputs.tag }}
steps:
- id: out
run: |
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
else
echo "tag=preview-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
fi
build:
name: Build ${{ matrix.name }}
needs: meta
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: windows-x64
os: windows-latest
rid: win-x64
self_contained: true
cmake_preset: windows-publish-x64
maadeps_triplet: x64-windows
- name: linux-x64
os: ubuntu-latest
rid: linux-x64
self_contained: true
cmake_preset: linux-publish-x64
maadeps_triplet: x64-linux
- name: macos-x64
os: macos-latest
rid: osx-x64
self_contained: true
cmake_preset: macos-publish-x64
maadeps_triplet: x64-osx
steps:
- uses: actions/checkout@v6
- name: Fetch required submodules
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --init --depth 1 src/MAAUnified src/MaaUtils
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: "10.0.x"
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Restore app
run: dotnet restore src/MAAUnified/App/MAAUnified.App.csproj
- name: Restore tests
if: matrix.name != 'macos-x64'
run: dotnet restore src/MAAUnified/Tests/MAAUnified.Tests.csproj
- name: Run Linux baseline consistency gate
if: matrix.name == 'linux-x64'
run: >
dotnet test src/MAAUnified/Tests/MAAUnified.Tests.csproj -c Release --no-restore --disable-build-servers -m:1
--results-directory TestResults/${{ matrix.name }}
--logger "trx;LogFileName=baseline-consistency.trx"
--filter "FullyQualifiedName~BaselineContractTests|FullyQualifiedName~BaselineCoverageTests|FullyQualifiedName~BaselineRenderSyncTests|FullyQualifiedName~ParityMatrixSyncTests"
- name: Run Linux full MAAUnified test gate
if: matrix.name == 'linux-x64'
run: >
dotnet test src/MAAUnified/Tests/MAAUnified.Tests.csproj -c Release --no-restore --disable-build-servers -m:1
--results-directory TestResults/${{ matrix.name }}
--logger "trx;LogFileName=full-maaunified-tests.trx"
- name: Run Windows platform capability contract gate
if: matrix.name == 'windows-x64'
run: >
dotnet test src/MAAUnified/Tests/MAAUnified.Tests.csproj -c Release --no-restore --disable-build-servers -m:1
--results-directory TestResults/${{ matrix.name }}
--logger "trx;LogFileName=platform-capability-contract.trx"
--filter "FullyQualifiedName~PlatformCapabilityContractTests"
- name: Run Windows native capability smoke gate
if: matrix.name == 'windows-x64'
run: >
dotnet test src/MAAUnified/Tests/MAAUnified.Tests.csproj -c Release --no-restore --disable-build-servers -m:1
--results-directory TestResults/${{ matrix.name }}
--logger "trx;LogFileName=platform-windows-native-smoke.trx"
--filter "FullyQualifiedName~PlatformWindowsNativeSmokeTests"
- name: Upload test result artifacts on failure
if: failure() && matrix.name != 'macos-x64'
uses: actions/upload-artifact@v7
with:
name: MAAUnified-TestResults-${{ matrix.name }}
path: TestResults/${{ matrix.name }}/*.trx
if-no-files-found: ignore
- name: Bootstrap MaaDeps
run: python tools/maadeps-download.py ${{ matrix.maadeps_triplet }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build MaaCore runtime
run: |
cmake --preset ${{ matrix.cmake_preset }} -DINSTALL_PYTHON=OFF -DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}'
cmake --build --preset ${{ matrix.cmake_preset }}
cmake --install build --config RelWithDebInfo
- name: Publish MAAUnified app
run: dotnet publish src/MAAUnified/App/MAAUnified.App.csproj -c Release -r ${{ matrix.rid }} --self-contained ${{ matrix.self_contained }} -o publish
- name: Merge MaaCore runtime (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Copy-Item install\* publish\ -Recurse -Force
if (!(Test-Path "publish\MaaCore.dll")) { throw "MaaCore.dll not found in publish output." }
if (!(Test-Path "publish\resource")) { throw "resource directory not found in publish output." }
- name: Merge MaaCore runtime (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
cp -a install/. publish/
if [[ "$RUNNER_OS" == "Linux" ]]; then
test -f publish/libMaaCore.so
else
test -f publish/libMaaCore.dylib
fi
test -d publish/resource
- name: Package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item -ItemType Directory -Path release -Force | Out-Null
$name = "MAAUnified-${{ needs.meta.outputs.tag }}-${{ matrix.name }}"
Compress-Archive -Path publish\* -DestinationPath "release\$name.zip"
- name: Package (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
mkdir -p release
name="MAAUnified-${{ needs.meta.outputs.tag }}-${{ matrix.name }}"
tar -czf "release/${name}.tar.gz" -C publish .
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: MAAUnified-${{ matrix.name }}
path: release/*

View File

@@ -1,624 +0,0 @@
name: Release Pipeline
on:
push:
tags:
- "v*"
branches:
- "dev-v2"
paths:
- ".github/workflows/ci.yml"
- "3rdparty/include/**"
- "cmake/**"
- "CMakeLists.txt"
- "CMakePresets.json"
- "include/**"
- "src/**"
- "tools/maadeps-download.py"
- "!**/*.md"
pull_request:
paths:
- ".github/workflows/ci.yml"
- "3rdparty/include/**"
- "cmake/**"
- "CMakeLists.txt"
- "CMakePresets.json"
- "include/**"
- "src/**"
- "tools/maadeps-download.py"
- "!**/*.md"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}${{ github.ref == 'refs/heads/dev-v2' && format('-{0}', github.sha) || '' }}
cancel-in-progress: true
jobs:
meta:
name: Gather Meta Information
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.set_tag.outputs.tag }}
prerelease: ${{ steps.set_pre.outputs.prerelease }}
steps:
- name: Show concurrency group
run: |
echo "Concurrency Group: ${{ github.workflow }}-${{ github.event.pull_request.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}${{ github.ref == 'refs/heads/dev-v2' && format('-{0}', github.sha) || '' }}"
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
show-progress: false
- name: Set tag
id: set_tag
run: |
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: Check if it is a pre-release
id: set_pre
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
else
echo "prerelease=true" | tee -a $GITHUB_OUTPUT
fi
- 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
last_tag=$(git describe --tags --match "v*" --abbrev=0 --exclude='${{ steps.set_tag.outputs.tag }}')
else
last_tag=$(git describe --tags --match "v*" --abbrev=0 --exclude='${{ steps.set_tag.outputs.tag }}' --exclude='*-*')
fi
echo >> CHANGELOG.md
echo "**Full Changelog**: [$last_tag -> $this_tag](https://github.com/MaaAssistantArknights/MaaAssistantArknights/compare/${last_tag}...${this_tag})" >> CHANGELOG.md
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@v7
if: startsWith(github.ref, 'refs/tags/v')
with:
name: changelog
path: CHANGELOG.md
windows:
name: Build for Windows
needs: meta
strategy:
matrix:
arch: [arm64, x64]
fail-fast: false
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Fetch submodules
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --init --depth 1 src/MaaUtils 3rdparty/EmulatorExtras
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v5
continue-on-error: true
with:
path: |
./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
if: steps.cache-maadeps.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 tools/maadeps-download.py ${{ matrix.arch }}-windows
- name: Configure, build and install
run: |
cmake -B build --preset ${{ matrix.arch == 'arm64' && 'windows-publish-arm64' || 'windows-publish-x64' }} -DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}'
cmake --build --preset ${{ matrix.arch == 'arm64' && 'windows-publish-arm64' || 'windows-publish-x64' }} --parallel $env:NUMBER_OF_PROCESSORS
cmake --build build --target MAA.Updater --config RelWithDebInfo --parallel $env:NUMBER_OF_PROCESSORS
cmake --install build --config RelWithDebInfo
- name: Download MaaFramework
uses: robinraju/release-downloader@v1
with:
repository: MaaXYZ/MaaFramework
tag: v5.9.2
fileName: ${{ matrix.arch == 'arm64' && '*win-aarch64*.zip' || '*win-x86_64*.zip' }}
extract: true
out-file-path: MaaFramework-temp
- name: Copy ControlUnits
run: |
cp MaaFramework-temp/bin/*Win32ControlUnit* install/
cp MaaFramework-temp/bin/*AdbControlUnit* install/
- name: Generate global.json
shell: bash
run: |
echo '{"sdk":{"version":"10.0.203","rollForward":"disable"}}' > global.json
- name: Setup .NET SDK
uses: actions/setup-dotnet@v5
with:
global-json-file: global.json
- name: Cache .nuke/temp, ~/.nuget/packages
id: cache-nuget
uses: actions/cache@v5
continue-on-error: true
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ matrix.arch }}-nuget-${{ hashFiles('**/*.csproj', 'global.json') }}
- name: Restore dependencies
if: steps.cache-nuget.outputs.cache-hit != 'true'
run: dotnet restore src/MaaWpfGui/MaaWpfGui.csproj
- name: Taggify version for csproj
run: |
$csprojPath = "src/MaaWpfGui/MaaWpfGui.csproj"
$csprojPath = Resolve-Path -Path $csprojPath
$tag = '${{ needs.meta.outputs.tag }}' -replace '.*?/', ''
if ($tag -match '\d+(\.\d+){1,3}') {
$match = $Matches[0]
} else {
$match = "0.0.1"
}
[xml]$csproj = Get-Content -Path $csprojPath
$node = $csproj.Project.PropertyGroup | where {$_.ApplicationVersion -ne $null}
$node.InformationalVersion = $tag
$node.Version = $match
$node.FileVersion = $match
$node.AssemblyVersion = $match
$csproj.Save($csprojPath)
- name: Publish WPF GUI
continue-on-error: true
run: |
dotnet publish src/MaaWpfGui/MaaWpfGui.csproj -c Release -p:Platform=${{ matrix.arch == 'arm64' && 'ARM64' || 'x64' }} -o install
- 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@v7
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
rm -rf install/*.bak
cp tools/DependencySetup_依赖库安装.bat install
- name: Zip files
run: |
cd install
Compress-Archive -Destination MAA-${{ needs.meta.outputs.tag }}-win-${{ matrix.arch }}.zip -Path ./*
- name: Upload MAA to GitHub
uses: actions/upload-artifact@v7
with:
name: MAA-win-${{ matrix.arch }}
path: install/MAA-*.zip
ubuntu:
name: Build for Ubuntu
needs: meta
runs-on: ubuntu-latest
strategy:
matrix:
arch: [aarch64, x86_64]
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Fetch submodules
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --init --depth 1 src/MaaUtils 3rdparty/EmulatorExtras src/maa-cli
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v5
continue-on-error: true
with:
path: ./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
if: steps.cache-maadeps.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 tools/maadeps-download.py ${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-linux
- name: Configure, build and install
run: |
cmake --preset ${{ matrix.arch == 'x86_64' && 'linux-publish-x64' || 'linux-publish-arm64' }} -DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}'
cmake --build --preset ${{ matrix.arch == 'x86_64' && 'linux-publish-x64' || 'linux-publish-arm64' }} --parallel $(nproc)
cmake --install build --config RelWithDebInfo
env:
CLICOLOR_FORCE: 1
- name: Download MaaFramework
uses: robinraju/release-downloader@v1
with:
repository: MaaXYZ/MaaFramework
latest: true
fileName: '*linux-${{ matrix.arch }}*.zip'
extract: true
out-file-path: MaaFramework-temp
- name: Copy ControlUnits
run: |
cp MaaFramework-temp/bin/*AdbControlUnit* install/
- name: Setup cross compile toolchains for CLI
uses: ./src/maa-cli/.github/actions/setup
with:
target_arch: ${{ matrix.arch }}
- name: Build CLI
run: |
cargo build --release --locked --package maa-cli --features git2/vendored-openssl
cp -v target/$CARGO_BUILD_TARGET/release/maa $GITHUB_WORKSPACE/install/maa
cargo build --release --locked --package maa-cli --no-default-features \
--features git2,git2/vendored-openssl
cp -v target/$CARGO_BUILD_TARGET/release/maa $GITHUB_WORKSPACE/appimage-maa
working-directory: src/maa-cli
- name: Build Appimage
run: |
sudo add-apt-repository universe
sudo apt update
sudo apt install libfuse2
mkdir -pv release
mkdir -pv Maa.AppDir/usr/share/maa
cp -r install/* Maa.AppDir/usr/share/maa/
wget -c https://raw.githubusercontent.com/MaaAssistantArknights/design/main/v2/icons/maa-logo_512x512.png -O Maa.AppDir/maa.png
mkdir -pv Maa.AppDir/usr/share/icons/hicolor/512x512/apps/
cp -v Maa.AppDir/maa.png Maa.AppDir/usr/share/icons/hicolor/512x512/apps/
cp -v appimage-maa Maa.AppDir/usr/share/maa/maa
chmod a+x Maa.AppDir/usr/share/maa/maa
cat > Maa.AppDir/maa.desktop <<EOF
[Desktop Entry]
Type=Application
Name=MaaAssistantArknights
Icon=maa
Exec=AppRun
Terminal=true
Categories=Game;StrategyGame;
Comment=An Arknights assistant
EOF
ln -sv usr/share/maa/maa Maa.AppDir/AppRun
mkdir -pv Maa.AppDir/usr/share/metainfo/
cp -v tools/AppImage/io.github.maaassistantarknights.maaassistantarknights.metainfo.xml Maa.AppDir/usr/share/metainfo/
wget "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
# appimagetool with embedded runtime does not support cross build, till AppImage/appimagetool 7a10b8
wget "https://github.com/AppImage/type2-runtime/releases/download/old/runtime-fuse3-${{ matrix.arch }}"
chmod a+x appimagetool-x86_64.AppImage
ARCH=${{ matrix.arch }} ./appimagetool-x86_64.AppImage --runtime-file runtime-fuse3-${{ matrix.arch }} Maa.AppDir
chmod a+x MaaAssistantArknights-${{ matrix.arch }}.AppImage
mv -v MaaAssistantArknights-${{ matrix.arch }}.AppImage $GITHUB_WORKSPACE/release/MAA-${{ needs.meta.outputs.tag }}-linux-${{ matrix.arch }}.AppImage
- name: Tar files
run: |
mkdir -p release
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@v7
with:
name: MAA-linux-${{ matrix.arch }}
path: |
release/*.AppImage
release/*.tar.gz
macOS-Core:
name: Build Core for macOS
needs: meta
runs-on: macos-26
strategy:
matrix:
arch: [arm64, x86_64]
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Fetch submodules
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --init --depth 1 src/MaaUtils
# ninja 1.13.1 is already installed and up-to-date.
# - name: Install dependencies
# run: |
# brew install ninja
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v5
continue-on-error: true
with:
path: ./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
run: |
python3 tools/maadeps-download.py ${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}-osx
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Configure, build and install
run: |
cmake -B build --preset ${{ matrix.arch == 'x86_64' && 'macos-publish-x64' || 'macos-publish-arm64' }} -DMAA_HASH_VERSION='${{ needs.meta.outputs.tag }}'
cmake --build --preset ${{ matrix.arch == 'x86_64' && 'macos-publish-x64' || 'macos-publish-arm64' }} --parallel $(sysctl -n hw.logicalcpu)
cmake --install build --config RelWithDebInfo
- name: Download MaaFramework
uses: robinraju/release-downloader@v1
with:
repository: MaaXYZ/MaaFramework
latest: true
fileName: ${{ matrix.arch == 'x86_64' && '*macos-x86_64*.zip' || '*macos-aarch64*.zip' }}
extract: true
out-file-path: MaaFramework-temp
- name: Copy ControlUnits
run: |
cp MaaFramework-temp/bin/*AdbControlUnit* install/
- name: Upload MAA to GitHub
uses: actions/upload-artifact@v7
with:
name: MAACore-macos-${{ matrix.arch }}
path: "install/*.dylib"
macOS-GUI:
name: Build GUI for macOS
needs: [meta, macOS-Core]
runs-on: macos-26
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Install dependencies
if: startsWith(github.ref, 'refs/tags/v')
run: |
brew install graphicsmagick imagemagick
npm install -g create-dmg
- name: Fetch submodules
run: |
git submodule update --init --depth 1 src/MaaMacGui
- name: Download MAA (arm64) from GitHub
uses: actions/download-artifact@v8
with:
name: MAACore-macos-arm64
path: install-arm64
- name: Download MAA (x64) from GitHub
uses: actions/download-artifact@v8
with:
name: MAACore-macos-x86_64
path: install-x86_64
- name: Install Developer ID certificate
if: startsWith(github.ref, 'refs/tags/v')
uses: apple-actions/import-codesign-certs@v7
with:
p12-file-base64: ${{ secrets.HGUANDL_SIGN_CERT_P12 }}
p12-password: ${{ secrets.HGUANDL_SIGN_CERT_PASSWD }}
- name: Download provisioning profiles
if: startsWith(github.ref, 'refs/tags/v')
uses: apple-actions/download-provisioning-profiles@v6
with:
bundle-id: "com.hguandl.MeoAsstMac"
issuer-id: ${{ secrets.HGUANDL_APPSTORE_ISSUER }}
api-key-id: ${{ secrets.HGUANDL_APPSTORE_KEYID }}
api-private-key: ${{ secrets.HGUANDL_APPSTORE_KEY }}
- name: Setup Xcode toolchain
if: false
run: |
sudo xcode-select -s /Applications/Xcode_16.1.app/Contents/Developer
- 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
run: |
mkdir runtime && cd runtime
name='MAA-${{ needs.meta.outputs.tag }}-macos-runtime-universal'
mkdir "$name" && cd "$name"
cp -v ../../build/*.dylib .
ln -vs libonnxruntime*.dylib libonnxruntime.dylib
ln -vs libopencv_world4*.dylib libopencv_world4.dylib
cp -vr ../../resource .
cd .. || exit 1
zip -yrX9 "$name.zip" "$name"
- name: Upload MAA runtime to GitHub
uses: actions/upload-artifact@v7
with:
name: MAA-macos-runtime-universal
path: runtime/MAA-${{ needs.meta.outputs.tag }}-macos-runtime-universal.zip
- 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
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
echo 'CURRENT_PROJECT_VERSION = '"${RELEASE_COUNT}" | tee -a src/MaaMacGui/Version.xcconfig
- name: Build MAA
run: |
if ${{ startsWith(github.ref, 'refs/tags/v') }}; then
xcodebuild -scheme MAA archive -archivePath MAA.xcarchive
else
xcodebuild CODE_SIGNING_ALLOWED=NO -scheme MAA archive -archivePath MAA.xcarchive
fi
working-directory: src/MaaMacGui
- name: Export MAA
if: startsWith(github.ref, 'refs/tags/v')
run: |
xcodebuild -exportArchive -archivePath MAA.xcarchive -exportOptionsPlist ExportOptions.plist -exportPath Export
working-directory: src/MaaMacGui
- 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
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
if: startsWith(github.ref, 'refs/tags/v')
run: |
GIT_TAG=${{ needs.meta.outputs.tag }}
APP_DMG=MAA-${GIT_TAG}-macos-universal.dmg
APP_SYM=MAAComponent-DebugSymbol-${GIT_TAG}-macos-universal.zip
mkdir -p release
mv src/MaaMacGui/MAA.dmg release/${APP_DMG}
mv src/MaaMacGui/MAA.xcarchive/dSYMs/MAA.app.dSYM.zip release/${APP_SYM}
- name: Notarize image
if: startsWith(github.ref, 'refs/tags/v')
uses: nick-fields/retry@v4
with:
max_attempts: 3
timeout_minutes: 15
command: |
cd release
echo "$APPSTORE_KEY" > "AuthKey_${APPSTORE_KEYID}.p8"
dmg="MAA-${{ needs.meta.outputs.tag }}-macos-universal.dmg"
xcrun notarytool submit -k "AuthKey_${APPSTORE_KEYID}.p8" -d "$APPSTORE_KEYID" -i "$ISSUER_ID" --wait ${dmg}
env:
APPSTORE_KEYID: ${{ secrets.HGUANDL_APPSTORE_KEYID }}
APPSTORE_KEY: ${{ secrets.HGUANDL_APPSTORE_KEY }}
ISSUER_ID: ${{ secrets.HGUANDL_APPSTORE_ISSUER }}
- 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@v7
with:
name: MAA-macos-universal
path: ${{ startsWith(github.ref, 'refs/tags/v') && 'release/MAA*' || 'src/MaaMacGui/MAA.xcarchive/**' }}
release:
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@v8
with:
path: assets
- name: Clean up files
run: |
mv -vf assets/changelog/* .
rm -rf assets/MAACore-macos-*
cd assets
# find . -type f | xargs mv -fvt .
find . -type f | while read f; do mv -fvt . $f; done
- name: Publish release to GitHub
uses: softprops/action-gh-release@v3.0.0
with:
body_path: CHANGELOG.md
files: |
assets/*
prerelease: ${{ needs.meta.outputs.prerelease != 'false' }}
- name: Trigger release distribution workflows
run: |
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 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.yml
env:
GH_TOKEN: ${{ secrets.MISTEOWORKFLOW }}
- name: Create issue on failure
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: "create-issue"
title: "Errors occured during release ${{ needs.meta.outputs.tag }}"
body: |
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

View File

@@ -1,81 +0,0 @@
name: Discord Release Notification
on:
workflow_dispatch:
inputs:
release_tag:
description: "Release tag (e.g. v6.2.3, leave empty for latest)"
type: string
required: false
default: ""
jobs:
notify:
name: Send Discord Release Notification
if: ${{ github.repository_owner == 'MaaAssistantArknights' }}
runs-on: ubuntu-latest
steps:
- name: Resolve release info
id: release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
MANUAL_TAG="${{ github.event.inputs.release_tag }}"
MANUAL_TAG="${MANUAL_TAG#"${MANUAL_TAG%%[![:space:]]*}"}"
MANUAL_TAG="${MANUAL_TAG%"${MANUAL_TAG##*[![:space:]]}"}"
if [ -z "$MANUAL_TAG" ]; then
TAG=$(gh release list --repo "${{ github.repository }}" --limit 1 --json tagName -q '.[0].tagName')
else
TAG="$MANUAL_TAG"
fi
URL="https://github.com/MaaAssistantArknights/MaaAssistantArknights/releases/tag/$TAG"
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "url=$URL" >> $GITHUB_OUTPUT
- name: Build and send Discord message
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
run: |
TAG="${{ steps.release.outputs.tag }}"
URL="${{ steps.release.outputs.url }}"
BASE_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}"
WIN_URL="${BASE_URL}/MAA-${TAG}-win-x64.zip"
MAC_URL="${BASE_URL}/MAA-${TAG}-macos-universal.dmg"
LIN_URL="${BASE_URL}/MAA-${TAG}-linux-amd64.tar.gz"
DESCRIPTION=$(printf 'Read the full release note [here](%s).\n\nOpen or reopen your MAA client to get automatic updates.\nOr, download `MAA %s` for your platform by clicking the buttons below.' "$URL" "$TAG")
PAYLOAD=$(jq -n \
--arg tag "$TAG" \
--arg description "$DESCRIPTION" \
--arg win_url "$WIN_URL" \
--arg mac_url "$MAC_URL" \
--arg lin_url "$LIN_URL" \
'{
embeds: [{
title: ("🎉 New MAA Release: " + $tag),
description: $description,
color: 10246582,
fields: [
{ name: "Windows (x64)", value: ("[↗ Download](" + $win_url + ")"), inline: true },
{ name: "macOS (Universal, dmg)", value: ("[↗ Download](" + $mac_url + ")"), inline: true },
{ name: "Linux (amd64, tar.gz)", value: ("[↗ Download](" + $lin_url + ")"), inline: true }
]
}]
}')
HTTP_STATUS=$(curl -sS -o /tmp/discord_response.txt -w "%{http_code}" \
-X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "$PAYLOAD")
echo "Discord response (HTTP $HTTP_STATUS):"
cat /tmp/discord_response.txt
if [ "$HTTP_STATUS" -lt 200 ] || [ "$HTTP_STATUS" -ge 300 ]; then
echo "Error: Discord webhook returned HTTP $HTTP_STATUS"
exit 1
fi

View File

@@ -1,65 +0,0 @@
name: AI Issue Analysis
on:
issues:
types: [opened]
issue_comment:
types: [created]
workflow_dispatch:
inputs:
issue_number:
description: 'Issue number to analyze'
required: true
type: number
jobs:
copilot-analysis:
if: |
(github.event_name == 'issues' && github.event.action == 'opened') ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' &&
github.event.action == 'created' &&
contains(github.event.comment.body, '@MaaArknightsBot') &&
github.event.comment.user.type != 'Bot')
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
# 这个 action 只负责编排,分析质量仍依赖配套的 issue/log analysis skill。
# 详细使用文档https://github.com/MistEO/ai-issue-analysis
# 最佳实践参考:
# - https://github.com/MaaEnd/MaaEnd/blob/v2/.claude/skills/maaend-issue-log-analysis/SKILL.md
# - https://github.com/MaaAssistantArknights/MaaAssistantArknights/blob/dev-v2/.claude/skills/maa-issue-log-analysis/SKILL.md
- name: Analyze issue with AI
id: analysis
uses: Misteo/ai-issue-analysis@main
with:
github-token: ${{ secrets.MAA_BOT_TOKEN }}
copilot-github-token: ${{ secrets.COPILOT_GITHUB_TOKEN }}
bot-name: '@MaaArknightsBot'
initial-comment-body: |
🤖 **MaaBot 正在分析该 Issue...**
感谢您的反馈AI 正在自动分析该问题,预计耗时约 10 分钟。
prompt-template: |
分析 GitHub Issue {{issue_number}}。把最终结论写到 {{copilot_answer_file}}。
extra-comment-content: |
<!-- Skip all labels -->
- name: 查看完整输入输出
if: always()
env:
ANALYSIS_PROMPT: ${{ steps.analysis.outputs.analysis-prompt }}
ISSUE_NUMBER: ${{ steps.analysis.outputs.issue-number }}
COMMENT_ID: ${{ steps.analysis.outputs.comment-id }}
COMMENT_URL: ${{ steps.analysis.outputs.comment-url }}
COPILOT_OUTPUT: ${{ steps.analysis.outputs.copilot-output }}
FINAL_CONCLUSION: ${{ steps.analysis.outputs.final-conclusion }}
run: |
printf '%s\n' "$ANALYSIS_PROMPT"
echo "issue_number=$ISSUE_NUMBER"
echo "comment_id=$COMMENT_ID"
echo "comment_url=$COMMENT_URL"
printf '%s\n' "$COPILOT_OUTPUT"
printf '%s\n' "$FINAL_CONCLUSION"

View File

@@ -1,153 +0,0 @@
name: Issue Review
on:
issues:
types: [opened]
jobs:
check-then-close-or-fold:
name: Review and Modify Issues
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Check for duplicate issues in last hour
id: duplicate-check
uses: actions/github-script@v9
with:
script: |
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
const currentIssueCreatedAt = new Date(context.payload.issue.created_at);
const issueAuthor = context.payload.issue.user.login;
// 重新获取该用户最近的 issues
const { data: userIssues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
creator: issueAuthor,
state: 'all',
since: oneHourAgo.toISOString(),
per_page: 30
});
// 过滤出1小时内创建的其他 issues排除当前 issue
const recentIssues = userIssues.filter(issue => {
const issueCreatedAt = new Date(issue.created_at);
return issue.number !== context.issue.number &&
issueCreatedAt >= oneHourAgo &&
issueCreatedAt < currentIssueCreatedAt;
});
if (recentIssues.length > 0) {
// 给当前 issue 添加标签
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: ['rapid-submission']
});
// 给1小时内的其他 issues 也添加标签
for (const issue of recentIssues) {
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: ['rapid-submission']
});
console.log(`Added rapid-submission label to issue #${issue.number}`);
} catch (error) {
console.log(`Failed to add label to issue #${issue.number}: ${error.message}`);
}
}
}
- name: Check for issue checkboxes
id: unread-checkbox-check
uses: actions/github-script@v9
with:
script: |
// 找不到###就算了
if (!/###([^#]+)###/.test(context.payload.issue.body)) {
return false;
}
var checkList = /###([^#]+)###/.exec(context.payload.issue.body)[1];
const UnreadRegexCn = /- \[x\]\s*.*?我.*未仔细阅读/i;
const UnreadRegexCn_ = /- \[ \]\s*.*?我.*未仔细阅读/i;
if (/- \[(x| )\]\s*.*?[\u4e00-\u9fa5]+/i.test(checkList)) { // 中英区分
if (UnreadRegexCn.test(checkList)) {
return true;
}
checkList = checkList.replace(UnreadRegexCn_, "");
return /- \[ \]\s*.*?[\u4e00-\u9fa5]+/i.test(checkList);
}
const texts = [
'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 low-quality issue
if: steps.unread-checkbox-check.outputs.result == 'true'
uses: actions/github-script@v9
with:
script: |
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
state: 'closed',
state_reason: 'not_planned'
});
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: ['low-quality-report']
});
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '因为未阅读模板提示并正确提交,触发了自动关闭规则\n\nBecause the template prompt was not read and submitted correctly, the automatic closing rule was triggered'
});
- name: Fold checkboxes
if: steps.unread-checkbox-check.outputs.result == 'false'
uses: actions/github-script@v9
with:
script: |
const originalBody = context.payload.issue.body;
if (originalBody.includes('<details><summary>Checkboxes</summary>\n\n')) {
return;
}
const checkboxSectionRegex_cn_bug = /([\s\S]*?)(### 问题描述\n\n)/;
const checkboxSectionRegex_cn_feat = /([\s\S]*?)(### 说说你遇到的问题?\n\n)/;
const checkboxSectionRegex_en_bug = /([\s\S]*?)(### Description\n\n)/;
const checkboxSectionRegex_en_feat = /([\s\S]*?)(### The problems you have encountered?\n\n)/;
const foldedBody_cn_bug = originalBody.replace(
checkboxSectionRegex_cn_bug,
`<details><summary>Checkboxes</summary>\n\n$1\n\n</details>\n\n$2`
);
const foldedBody_cn_feat = foldedBody_cn_bug.replace(
checkboxSectionRegex_cn_feat,
`<details><summary>Checkboxes</summary>\n\n$1\n\n</details>\n\n$2`
);
const foldedBody_en_bug = foldedBody_cn_feat.replace(
checkboxSectionRegex_en_bug,
`<details><summary>Checkboxes</summary>\n\n$1\n\n</details>\n\n$2`
);
const foldedBody = foldedBody_en_bug.replace(
checkboxSectionRegex_en_feat,
`<details><summary>Checkboxes</summary>\n\n$1\n\n</details>\n\n$2`
);
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: foldedBody
});

View File

@@ -1,27 +0,0 @@
name: Issue Triage
on:
issues:
types: [opened, edited]
pull_request_target:
types: [opened, edited]
issue_comment:
types: [created, edited]
permissions:
contents: read
issues: write
pull-requests: write
jobs:
triage:
name: Triage Issues and PRs
runs-on: ubuntu-latest
steps:
- name: Label issues and PRs Automatically
uses: MaaAssistantArknights/issue-checker@v1.14
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
configuration-path: .github/issue-checker.yml
not-before: 2022-08-05T00:00:00Z
include-title: 1

View File

@@ -1,64 +0,0 @@
name: Markdown Link Check
on:
schedule:
- cron: "0 0 * * 2" # Every Tuesday at 00:00 UTC
push:
branches:
- dev-v2
paths:
- ".github/workflows/markdown-checker.yml"
- "docs/**"
- "**/*.md"
pull_request:
branches:
- dev-v2
paths:
- ".github/workflows/markdown-checker.yml"
- "docs/**"
- "**/*.md"
workflow_dispatch:
jobs:
check-links:
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
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Cache lychee responses
uses: actions/cache@v5
continue-on-error: true
with:
path: .lycheecache
key: lychee-cache
- name: Check dead internal links
uses: lycheeverse/lychee-action@v2
with:
# 仅检查内部链接,排除所有外部链接
args: >
--root-dir ./docs/.vuepress/public
--verbose --no-progress
--cache --max-cache-age 1d --cache-exclude-status '429, 500..599'
--exclude 'https?://.*'
--exclude-path 'docs/zh-tw/manual/introduction/introduction_old.md'
--exclude-path 'docs/ja-jp/manual/introduction/introduction_old.md'
-- './docs/**/*.md' './README.md'
- name: Comment (only for PR)
if: failure() && github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@v3
with:
message: |
Dead links found in the documentation. Please fix them.
Details: https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/${{ github.run_id }}

View File

@@ -1,19 +0,0 @@
name: Release Note Distribution
on:
workflow_dispatch:
release:
types: [edited]
jobs:
mirrorchyan:
name: Upload to MirrorChyan
runs-on: macos-latest
steps:
- name: Upload release notes to MirrorChyan
uses: MirrorChyan/release-note-action@v1
with:
mirrorchyan_rid: MAA
upload_token: ${{ secrets.MirrorChyanUploadToken }}
github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,110 +0,0 @@
name: PNG Image Optimization
on:
push:
branches:
- "dev-v2"
paths:
- "docs/.vuepress/public/images/**"
- "resource/**/*.png"
workflow_dispatch:
inputs:
commit_message:
description: "Commit Message"
type: string
required: false
jobs:
optimize-png:
name: Optimize PNG Images
# Skip workflow to prevent double consecutive runs
if: github.repository_owner == 'MaaAssistantArknights' && github.event.head_commit.author.email != '41898282+github-actions[bot]@users.noreply.github.com'
runs-on: ubuntu-latest
steps:
# Skip workflow on PR merges
- name: Check if it is a direct push
id: check_push
run: |
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]]; then
pr_count=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/commits/${{ github.event.after }}/pulls" \
| jq 'length')
if [[ "$pr_count" == "0" ]]; then
echo "Direct push detected. Proceeding..."
echo "is_pr=False" >> $GITHUB_OUTPUT
else
echo "PR merge detected. Exiting."
echo "is_pr=True" >> $GITHUB_OUTPUT
fi
else
echo "Manual trigger detected. Proceeding..."
echo "is_pr=False" >> $GITHUB_OUTPUT
fi
- name: Checkout repository
if: steps.check_push.outputs.is_pr != 'True'
uses: actions/checkout@v6
with:
show-progress: false
persist-credentials: false
- name: Setup python
if: steps.check_push.outputs.is_pr != 'True'
uses: actions/setup-python@v6
with:
python-version: "3.11"
# - name: Cache Python packages
# 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') }}
- name: Install dependencies
# if: steps.check_push.outputs.is_pr != 'True' && steps.cache_python.outputs.cache-hit != 'true'
if: steps.check_push.outputs.is_pr != 'True'
run: |
pip install -r tools/OptimizeTemplates/requirements.txt
- name: Setup oxipng
if: steps.check_push.outputs.is_pr != 'True'
uses: baptiste0928/cargo-install@v3
with:
crate: oxipng
- name: Optimize png images
if: steps.check_push.outputs.is_pr != 'True'
run: |
python3 tools/OptimizeTemplates/optimize_templates.py
- name: Commit changes
id: commit_changes
if: steps.check_push.outputs.is_pr != 'True'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
if git diff-index --quiet HEAD --; then
echo "No changes to commit"
else
commit_msg="${{ github.event.inputs.commit_message }}"
if [ -z "$commit_msg" ]; then
commit_msg="chore: Auto Templates Optimization"
fi
git commit -m "$commit_msg" -m "Triggered by ${{github.sha}}" -m "[skip changelog]"
git pull origin $(git rev-parse --abbrev-ref HEAD) --unshallow --rebase
echo "have_commits=True" >> $GITHUB_OUTPUT
fi
- name: Push changes
if: steps.check_push.outputs.is_pr != 'True' && steps.commit_changes.outputs.have_commits == 'True' && github.repository_owner == 'MaaAssistantArknights'
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.MAA_RESOURCE_SYNC }}
branch: ${{ github.ref }}

View File

@@ -1,53 +0,0 @@
name: Release Version Tagging
on:
pull_request:
branches:
- master-v2
types:
- closed
workflow_dispatch:
inputs:
tag:
description: "Name of the tag to create for the release"
type: string
required: true
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 repository
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.MAARELEASE_RELEASE }}
- name: Configure git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Determine tag name
id: extract_tag
run: |
if ${{ github.event_name != 'workflow_dispatch' }}; then
tag_name=$(echo "${{ github.event.pull_request.title }}" | sed -E 's/(Release|release)//' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
echo "tag_name=$tag_name" >> $GITHUB_OUTPUT
else
echo "tag_name=${{ inputs.tag }}" >> $GITHUB_OUTPUT
fi
- 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 tag into dev-v2 and push
run: |
git switch dev-v2
git merge "${{ steps.extract_tag.outputs.tag_name }}"
git push origin dev-v2

View File

@@ -1,59 +0,0 @@
name: PR Commit Check
on:
pull_request_target:
types: [opened, edited, ready_for_review, reopened, synchronize]
jobs:
check_commit_name_in_pr:
name: Check Commits in PR
if: ${{ !github.event.pull_request.merged && github.base_ref != 'master-v2' }}
runs-on: ubuntu-latest
steps:
- name: Clean up previous comment
uses: actions/github-script@v9
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number
});
const previousComment = comments.find(comment => comment.user.login === 'github-actions[bot]' && comment.body.includes('invalid commit(s)'));
if (previousComment) {
await github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: previousComment.id
});
}
- name: Check commits
uses: actions/github-script@v9
with:
script: |
const { data: commits } = await github.rest.pulls.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
per_page: 100
});
const regex = /^((build|chore|ci|docs?|feat!?|fix|perf|refactor|rft|style|test|i18n|typo|debug)[\:\.\(\,]|[Rr]evert|[Rr]elease|[Rr]eapply)/;
const invalidCommits = commits.filter(commit => !regex.test(commit.commit.message) || commit.parents.length > 1);
console.log(`Checked ${commits.length} commit(s)`);
if (invalidCommits.length > 0) {
const invalidCommitNames = invalidCommits.map(commit => commit.commit.message);
const invalidCommitInfoList = invalidCommits.map(commit => `- ${commit.commit.message.split("\n")[0]} [\`${commit.sha.substring(0, 7)}\`](${commit.html_url})`).join("\n");
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `## ⚠️ Found ${invalidCommits.length} invalid commit(s):\n\n${invalidCommitInfoList}\n\n---\nPlease follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format, and **DO NOT** use merge commits.\n请遵循 [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 格式,以及**不要**使用Merge Commit修改 Commit Message 无法绕过检测)。`
});
core.setFailed(`Found ${invalidCommits.length} invalid commit(s):\n${invalidCommitNames.join("\n-------------------\n")}`);
}

View File

@@ -1,36 +0,0 @@
name: Scheduled Pre-commit
on:
schedule:
# 每天 UTC 21:00 运行(北京时间 5:00
- cron: "0 21 * * *"
workflow_dispatch: # 允许手动触发
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
show-progress: false
- name: Setup and run Prek
uses: j178/prek-action@v2
id: pre-commit
continue-on-error: true
with:
extra-args: '--all-files'
- name: Commit and push changes
if: steps.pre-commit.outcome == 'failure' && github.repository_owner == 'MaaAssistantArknights'
uses: actions-js/push@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
message: "chore: Auto update by pre-commit hooks
https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
[skip changelog]"
branch: ${{ github.ref }}

View File

@@ -1,409 +0,0 @@
name: Release Pipeline (Nightly OTA)
on:
schedule:
- cron: "0 22 * * *" # Runs daily at 22:00 UTC
workflow_dispatch:
inputs:
release_body:
description: "Release note"
type: string
required: false
ref:
description: "Commit to build (git checkout)"
type: string
required: false
limit_maa:
description: "Number of releases to fetch from MaaAssistantArknights"
required: true
default: 10
type: number
limit_maarelease:
description: "Number of releases to fetch from MaaRelease"
required: true
default: 10
type: number
jobs:
build-win-nightly:
name: Build Nightly for Windows
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: windows-latest
strategy:
matrix:
arch: [x64]
fail-fast: false
outputs:
tag: ${{ steps.set_tag.outputs.tag }}
pre_version: ${{ steps.set_tag.outputs.pre_version }}
main_tag_name: ${{ steps.push_main_tag.outputs.main_tag_name }}
changelog: ${{ steps.read_changelog.outputs.content }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
# repository: 'MaaAssistantArknights/MaaAssistantArknights'
#ref: ${{ inputs.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 250
- name: Fetch tags
run: |
git fetch --depth=250 --tags
- name: Fetch submodules
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --init --depth 1 src/MaaUtils 3rdparty/EmulatorExtras
- name: Checkout ref (if provided)
if: inputs.ref != ''
run: |
git checkout --progress --recurse-submodules ${{ inputs.ref }}
- name: Check for Changes and Set tag
id: set_tag
run: |
# Fetch the latest tag from the repository
$latest_tag = git describe --tags --abbrev=0
Write-Output "Previous Tag: $latest_tag"
Write-Output "latest_tag=$latest_tag" >> $env:GITHUB_OUTPUT
# Check for changes between the latest tag and HEAD
$recent_changes = git log "$latest_tag..HEAD" --oneline
if (-not $recent_changes) {
Write-Output "No commits. Cancelling workflow..."
Write-Output "cancel_run=true" >> $env:GITHUB_ENV
exit 0
} else {
Write-Output "Recent commits: $recent_changes"
Write-Output "Commits found. Continuing build..."
Write-Output "cancel_run=false" >> $env:GITHUB_ENV
}
# Get the full description of the current commit
$described = git describe --tags --long --match 'v*'
Write-Output "New Described: $described"
$ids = $described -split "-"
if ($ids.Length -eq 3) {
# Extract and parse the current version
$current_version = $ids[0].Substring(1)
$parts = $current_version -split '\.'
if ($parts.Length -ne 3) {
Write-Error "Invalid version format: $current_version. Expected 'major.minor.patch'."
exit 1
}
# Increment the patch version
$parts[2] = [int]$parts[2] + 1
$new_version = "$($parts[0]).$($parts[1]).$($parts[2])"
# Construct the new tag and pre_version
$ver = "v$new_version"
$pre_version = $ids[0]
$dist = "{0:D3}" -f [int]$ids[1]
Write-Output "pre_version=$pre_version" >> $env:GITHUB_OUTPUT
Write-Output "New Tag: $ver-alpha.1.d$dist.$($ids[2])"
Write-Output "tag=$ver-alpha.1.d$dist.$($ids[2])" >> $env:GITHUB_OUTPUT
exit 0
}
if ($ids.Length -eq 4) {
$dist = "{0:D3}" -f [int]$ids[2]
$pre_version = "$($ids[0])-$($ids[1])"
Write-Output "Pre Version: $pre_version"
Write-Output "pre_version=$pre_version" >> $env:GITHUB_OUTPUT
Write-Output "tag: $pre_version.d$dist.$($ids[3])"
Write-Output "tag=$pre_version.d$dist.$($ids[3])" >> $env:GITHUB_OUTPUT
exit 0
}
exit 1
- name: Stop if no changes
if: env.cancel_run == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl -s -L -X POST `
-H "Accept: application/vnd.github+json" `
-H "Authorization: Bearer ${{ secrets.MAA_ACTION_READ_WRITE }}" `
-H "X-GitHub-Api-Version: 2022-11-28" `
"https://api.github.com/repos/MaaAssistantArknights/MaaAssistantArknights/actions/runs/${{ github.run_id }}/cancel" > $null
gh run watch ${{ github.run_id }}
- 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 }}"
Get-Content .\changelog.md | Select-Object -Skip 2 | Out-File -FilePath changelog_notag.md -Encoding utf8
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PYTHONIOENCODING: "utf-8"
- name: Stop if no changes
if: steps.generate_changelog.outputs.cancel_run == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl -s -L -X POST `
-H "Accept: application/vnd.github+json" `
-H "Authorization: Bearer ${{ secrets.MAA_ACTION_READ_WRITE }}" `
-H "X-GitHub-Api-Version: 2022-11-28" `
"https://api.github.com/repos/MaaAssistantArknights/MaaAssistantArknights/actions/runs/${{ github.run_id }}/cancel" > $null
gh run watch ${{ github.run_id }}
- name: Read changelog to variable
id: read_changelog
uses: juliangruber/read-file-action@v1
with:
path: ./changelog_notag.md
- name: Cache MaaDeps
id: cache-maadeps
uses: actions/cache@v5
continue-on-error: true
with:
path: |
./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-${{ matrix.arch }}-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
if: steps.cache-maadeps.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 tools/maadeps-download.py ${{ matrix.arch }}-windows
- name: Configure, build and install
run: |
cmake -B build --preset ${{ matrix.arch == 'arm64' && 'windows-publish-arm64' || 'windows-publish-x64' }} -DMAA_HASH_VERSION='${{ steps.set_tag.outputs.tag }}'
cmake --build --preset ${{ matrix.arch == 'arm64' && 'windows-publish-arm64' || 'windows-publish-x64' }} --parallel $env:NUMBER_OF_PROCESSORS
cmake --build build --target MAA.Updater --config RelWithDebInfo --parallel $env:NUMBER_OF_PROCESSORS
cmake --install build --config RelWithDebInfo
- name: Download MaaFramework
if: matrix.arch == 'x64'
uses: robinraju/release-downloader@v1
with:
repository: MaaXYZ/MaaFramework
tag: v5.9.2
fileName: "*win-x86_64*.zip"
extract: true
out-file-path: MaaFramework-temp
- name: Copy MaaWin32ControlUnit
if: matrix.arch == 'x64'
run: |
cp MaaFramework-temp/bin/*Win32ControlUnit* install/
- name: Generate global.json
shell: bash
run: |
echo '{"sdk":{"version":"10.0.203","rollForward":"disable"}}' > global.json
- name: Setup .NET SDK
uses: actions/setup-dotnet@v5
with:
global-json-file: global.json
- name: Cache .nuke/temp, ~/.nuget/packages
id: cache-nuget
uses: actions/cache@v5
continue-on-error: true
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ matrix.arch }}-nuget-${{ hashFiles('**/*.csproj', 'global.json') }}
- name: Restore dependencies
if: steps.cache-nuget.outputs.cache-hit != 'true'
run: dotnet restore src/MaaWpfGui/MaaWpfGui.csproj
- name: Taggify version for csproj
run: |
$csprojPath = "src/MaaWpfGui/MaaWpfGui.csproj"
$csprojPath = Resolve-Path -Path $csprojPath
$tag = '${{ steps.set_tag.outputs.tag }}' -replace '.*?/', ''
if ($tag -match '\d+(\.\d+){1,3}') {
$match = $Matches[0]
} else {
$match = "0.0.1"
}
[xml]$csproj = Get-Content -Path $csprojPath
$node = $csproj.Project.PropertyGroup | where {$_.ApplicationVersion -ne $null}
$node.InformationalVersion = $tag
$node.Version = $match
$node.FileVersion = $match
$node.AssemblyVersion = $match
$csproj.Save($csprojPath)
- name: Publish WPF GUI
run: |
dotnet publish src/MaaWpfGui/MaaWpfGui.csproj -c Release -p:Platform=${{ matrix.arch == 'arm64' && 'ARM64' || 'x64' }} -o install
- 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@v7
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@v7
with:
name: MAA-win-${{ matrix.arch }}
path: install
- name: Push tag to main repo
id: push_main_tag
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
$main_tag_name=$(echo "alpha/${{ steps.set_tag.outputs.tag }}")
git tag $main_tag_name -f
git push --tags origin HEAD:refs/tags/$main_tag_name -f
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: Checkout MaaRelease
uses: actions/checkout@v6
with:
repository: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
fetch-depth: 0
token: ${{ secrets.MAARELEASE_RELEASE }}
show-progress: false
- name: Commit and setup tag
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git checkout --orphan __temp
git rm -rf .
git commit --allow-empty --message ${{ needs.build-win-nightly.outputs.tag }}
git tag ${{ needs.build-win-nightly.outputs.tag }} || exit 0 # do nothing if the tag already exists
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:
matrix:
target: [x64]
runs-on: ubuntu-latest
steps:
- name: Show tag version
run: |
echo ${{ needs.build-win-nightly.outputs.tag }}
- 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@v8
with:
name: MAA-win-${{ matrix.target }}
path: ${{ format('{0}/{1}', 'build-ota', needs.build-win-nightly.outputs.tag) }}
- name: Fetch release information
run: |
mkdir -pv build-ota && cd build-ota
# Convert inputs to integers
limit_maa=${{ inputs.limit_maa || 10 }}
limit_maa=${limit_maa%.*}
echo "Parsed limit_maa: $limit_maa"
limit_maarelease=${{ inputs.limit_maarelease || 10 }}
limit_maarelease=${limit_maarelease%.*}
echo "Parsed limit_maarelease: $limit_maarelease"
gh release list --repo 'MaaAssistantArknights/MaaAssistantArknights' --limit $limit_maa | tee ./release_maa.txt
gh release list --repo "${{ github.repository_owner }}/MaaRelease" --limit $limit_maarelease | tee ./release_mr.txt
echo ${{ needs.build-win-nightly.outputs.tag }} > ./config
cat ./release_maa.txt | awk '{ print $1 }' > ./tags_maa.txt
cat ./release_mr.txt | awk '{ print $1 }' > ./tags_mr.txt
comm <(sort ./tags_maa.txt) <(sort ./tags_mr.txt) | awk '{ print $1 }' >> ./config
echo "config:"
cat ./config
echo "release_tag=$(head -n 1 ./config)" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build OTA
run: |
cd build-ota
pushd ${{ needs.build-win-nightly.outputs.tag }}
zip -r MAA-${{ env.release_tag }}-win-${{ matrix.target }}.zip ./*
popd
$GITHUB_WORKSPACE/MaaAssistantArknights/tools/OTAPacker/build.sh 'MaaAssistantArknights/MaaAssistantArknights' ./config ${{ matrix.target }} "${{ github.repository_owner }}/MaaRelease"
mv -v ${{ needs.build-win-nightly.outputs.tag }}/*.zip ./MAA-${{ env.release_tag }}-win-${{ matrix.target }}.zip
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to MaaRelease
uses: svenstaro/upload-release-action@v2
with:
repo_name: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
repo_token: ${{ secrets.MAARELEASE_RELEASE }}
file_glob: true
file: build-ota/*.zip
tag: ${{ env.release_tag }}
prerelease: true
overwrite: true
body: |
${{ inputs.release_body || '' }}
${{ needs.build-win-nightly.outputs.changelog }}
**Full Changelog**: [${{ needs.build-win-nightly.outputs.pre_version }} -> ${{ needs.build-win-nightly.outputs.main_tag_name }}](https://github.com/${{ github.repository }}/compare/${{ needs.build-win-nightly.outputs.pre_version }}...${{ needs.build-win-nightly.outputs.main_tag_name }})
- name: Setup release mirror
run: |
gh workflow --repo MaaAssistantArknights/MaaRelease run release-mirrors.yml
gh workflow --repo MaaAssistantArknights/MaaRelease run mirrorchyan_alpha.yml
gh workflow --repo MaaAssistantArknights/MaaRelease run mirrorchyan_alpha_release_note.yml
env:
GH_TOKEN: ${{ secrets.MISTEOWORKFLOW }}

View File

@@ -1,221 +0,0 @@
name: Release Pipeline (OTA)
on:
release:
types:
- published
workflow_dispatch:
inputs:
limit:
description: Number of releases to fetch from MaaAssistantArknights, 2 at least
required: false
default: 31
type: number
limit_2:
description: Number of releases to fetch from MaaRelease
required: false
default: 30
type: number
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
create-tag:
name: Create OTA Release Tag in MaaRelease
runs-on: ubuntu-latest
steps:
- name: Checkout MaaRelease
uses: actions/checkout@v6
with:
show-progress: false
repository: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
path: MaaRelease
fetch-depth: 0
token: ${{ secrets.MAARELEASE_RELEASE }}
- name: Fetch release information
id: fetchReleaseInfo
run: |
mkdir -pv build-ota && cd build-ota
# Convert inputs to integers
limit=${{ inputs.limit || 31 }}
limit=${limit%.*}
echo "Parsed limit: $limit"
limit_2=${{ inputs.limit_2 || 30 }}
limit_2=${limit_2%.*}
echo "Parsed limit_2: $limit_2"
gh release list --repo 'MaaAssistantArknights/MaaAssistantArknights' --limit $limit | tee ./release_maa.txt
gh release list --repo "MaaAssistantArknights/MaaRelease" --limit $limit_2 | tee ./release_mr.txt
head -n 1 ./release_maa.txt | awk '{ print $1 }' > ./config
tail -n +1 ./release_maa.txt | awk '{ print $1 }' > ./tags_maa.txt
cat ./release_mr.txt | awk '{ print $1 }' > ./tags_mr.txt
comm <(sort ./tags_maa.txt) <(sort ./tags_mr.txt) | awk '{ print $1 }' >> ./config
echo "config:"
cat ./config
echo "prerelease=$([ $(head -n 1 release_maa.txt | awk '{ print $2}') = 'Pre-release' ] && echo true || echo false)" >> $GITHUB_OUTPUT
echo "release_tag=$(head -n 1 ./config)" >> $GITHUB_OUTPUT
- name: Commit and setup tag
run: |
cd MaaRelease
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git checkout --orphan __temp
git rm -rf .
git commit --allow-empty --message ${{ steps.fetchReleaseInfo.outputs.release_tag }}
git tag ${{ steps.fetchReleaseInfo.outputs.release_tag }} || exit 0 # do nothing if the tag already exists
git push --tags
env:
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@v7
with:
name: MaaReleaseConfig
path: ./build-ota/config
outputs:
prerelease: ${{ steps.fetchReleaseInfo.outputs.prerelease }}
release_tag: ${{ steps.fetchReleaseInfo.outputs.release_tag }}
make-ota:
name: Build and Upload OTA for Windows
needs: create-tag
runs-on: ubuntu-latest
strategy:
matrix:
target:
- x64
steps:
- name: Download release config
uses: actions/download-artifact@v8
with:
name: MaaReleaseConfig
path: ./MaaReleaseConfig
- name: Checkout MaaRelease
uses: actions/checkout@v6
with:
show-progress: false
repository: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
path: MaaRelease
fetch-depth: 0
token: ${{ secrets.MAARELEASE_RELEASE }}
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
path: MaaAssistantArknights
- name: Download latest version for server
run: |
mkdir -pv build-ota/${{ needs.create-tag.outputs.release_tag }}
cd build-ota/${{ needs.create-tag.outputs.release_tag }}
gh release download ${{ needs.create-tag.outputs.release_tag }} --repo 'MaaAssistantArknights/MaaAssistantArknights' --pattern "MAA-${{ needs.create-tag.outputs.release_tag }}-win-${{ matrix.target }}.zip" --clobber
cp *.zip ..
- name: Build OTA
run: |
cd build-ota
$GITHUB_WORKSPACE/MaaAssistantArknights/tools/OTAPacker/build.sh 'MaaAssistantArknights/MaaAssistantArknights' ../MaaReleaseConfig/config ${{ matrix.target }} 'MaaAssistantArknights/MaaRelease'
- name: Upload to MaaRelease
uses: svenstaro/upload-release-action@v2
with:
repo_name: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
repo_token: ${{ secrets.MAARELEASE_RELEASE }}
file_glob: true
file: build-ota/*.zip
tag: ${{ needs.create-tag.outputs.release_tag }}
prerelease: ${{ fromJSON(needs.create-tag.outputs.prerelease) }}
overwrite: true
- name: Create issue on failure
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: "create-issue"
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 information
run: gh release list --repo 'MaaAssistantArknights/MaaAssistantArknights' --limit ${{ inputs.limit || 31 }} | tee ./release_maa.txt
- name: Download release packages
run: |
cat ./release_maa.txt | awk '{ print $1 }' | while read tag; do
gh release download "$tag" --repo 'MaaAssistantArknights/MaaAssistantArknights' --clobber -D packages -p 'MAA-*-macos-universal.dmg' || true
RELEASE_NOTES=$(gh release view "$tag" --repo 'MaaAssistantArknights/MaaAssistantArknights' --json body --jq .body)
gh api /markdown -f text="$RELEASE_NOTES" | tee ./packages/MAA-"$tag"-macos-universal.html
done
curl -fsSL -o packages/appcast.xml https://maa-release.hguandl.com/macos/appcast.xml
- name: Setup Sparkle
run: |
gh release download --repo 'sparkle-project/Sparkle' --clobber -O - -p 'Sparkle-*.tar.xz' | tar xf -
- 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
else
echo ${{ secrets.SPARKLE_PRIV_KEY }} | ./bin/generate_appcast --ed-key-file - ./packages
fi
- 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
- name: Upload to MaaRelease
uses: svenstaro/upload-release-action@v2
with:
repo_name: ${{ format('{0}/{1}', github.repository_owner, 'MaaRelease') }}
repo_token: ${{ secrets.MAARELEASE_RELEASE }}
file_glob: true
file: packages/*
tag: ${{ needs.create-tag.outputs.release_tag }}
prerelease: ${{ fromJSON(needs.create-tag.outputs.prerelease) }}
overwrite: true
- name: Create issue on failure
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: "create-issue"
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:
- create-tag
- make-ota
- make-ota-mac
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.MISTEOWORKFLOW }}
steps:
- name: Setup release mirror
run: |
gh workflow --repo MaaAssistantArknights/MaaRelease run release-mirrors.yml
- name: Send Discord release notification
run: |
gh workflow --repo MaaAssistantArknights/MaaAssistantArknights run discord-release-notification.yml \
-f release_tag="${{ needs.create-tag.outputs.release_tag }}"

View File

@@ -1,154 +0,0 @@
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
maa_cos:
description: "Upload to MAA COS"
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: ubuntu-latest
continue-on-error: true
strategy:
fail-fast: false
matrix:
include:
- os: win
arch: x64
filename: "*MAA-*-win-x64.zip"
extra_zip: false
- os: win
arch: arm64
filename: "*MAA-*-win-arm64.zip"
extra_zip: false
- os: macos
arch: arm64
filename: "MAA-*-macos-universal.dmg"
extra_zip: true
- os: macos
arch: x64
filename: "MAA-*-macos-universal.dmg"
extra_zip: true
env:
RELEASE_TAG: ${{ needs.meta.outputs.RELEASE_TAG }}
steps:
- name: Upload MAA ${{ matrix.os }} ${{ matrix.arch }}
uses: MirrorChyan/uploading-action@v1
continue-on-error: true
with:
filetype: latest-release
filename: ${{ matrix.filename }}
extra_zip: ${{ matrix.extra_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: ${{ matrix.os }}
arch: ${{ matrix.arch }}
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 }}
maa_cos:
name: Upload to MAA COS
needs: meta
if: false
runs-on: ubuntu-latest
continue-on-error: true
env:
FILENAME: MAA-${{ needs.meta.outputs.RELEASE_TAG }}-win-x64.zip
steps:
- uses: robinraju/release-downloader@v1
with:
repository: 'MaaAssistantArknights/MaaAssistantArknights'
latest: true
fileName: ${{ env.FILENAME }}
out-file-path: 'downloads'
token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to COS
uses: zkqiang/tencent-cos-action@v1.0.0
with:
args: sync -r downloads/${{ env.FILENAME }} cos://default/MAA/${{ env.FILENAME }}
secret_id: ${{ secrets.MISTEO_MAA_COS_SECRET_ID }}
secret_key: ${{ secrets.MISTEO_MAA_COS_SECRET_KEY }}
bucket: ${{ secrets.MISTEO_MAA_COS_BUCKET }}
region: ${{ secrets.MISTEO_MAA_COS_REG }}

View File

@@ -1,111 +0,0 @@
name: Release Preparation
on:
pull_request:
types:
- opened
- reopened
- ready_for_review
workflow_dispatch:
jobs:
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 repository
uses: actions/checkout@v6
with:
fetch-depth: 0
show-progress: false
- name: Extract release information
id: extract_tag
env:
PR_BODY: ${{ format('{0}/{1}', runner.temp, 'output' ) }}
run: |
tag_name=$(echo "${{ github.event.pull_request.title }}" | sed -E 's/(Release|release)//' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
echo "tag_name=$tag_name" >> $GITHUB_OUTPUT
pr_title="docs: Auto Update Changelogs of "$tag_name
echo "pr_title=$pr_title" >> $GITHUB_OUTPUT
latest_stable_tag=$(git tag -l 'v*' | grep -v '-' | sort -V | tail -n 1) # 上一个 stable 版本
newest_tag=$(git describe --tags --match "v*" --abbrev=0) # 最新版本
echo "latest_stable_tag=$latest_stable_tag" >> $GITHUB_OUTPUT
echo "newest_tag=$newest_tag" >> $GITHUB_OUTPUT
if [[ $tag_name == *-* ]]; then # 判断新版本是否为 beta 版本
latest=$newest_tag # 若是,则将 latest 参数设置为最新版本
else
latest=$latest_stable_tag # 若否,则设置为上一个 stable 版本
fi
echo "latest=$latest" >> $GITHUB_OUTPUT
cat $GITHUB_OUTPUT
echo '======='
echo 'Target PR: ${{ github.event.pull_request.html_url }}' >> $PR_BODY
echo '' >> $PR_BODY
echo '<details><summary>Debug information</summary>' >> $PR_BODY
echo '' >> $PR_BODY
echo '```' >> $PR_BODY
sed 's/=/: /1' $GITHUB_OUTPUT >> $PR_BODY
echo '```' >> $PR_BODY
echo '' >> $PR_BODY
echo '</details>' >> $PR_BODY
cat $PR_BODY
- name: Generate changelog
run: |
git switch dev-v2
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: Commit changes
run: |
git status
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
git add .
commit_msg="docs: Auto Generate Changelog of Release ""${{ steps.extract_tag.outputs.tag_name }}"
git commit -m "$commit_msg"
- name: Create changelog PR
uses: peter-evans/create-pull-request@v8
with:
sign-commits: true
token: ${{ secrets.GITHUB_TOKEN }}
title: ${{ steps.extract_tag.outputs.pr_title }}
body-path: ${{ format('{0}/{1}', runner.temp, 'output' ) }}
base: "dev-v2"
branch: "changelog"
delete-branch: true
reviewers: |
AnnAngela
assignees: |
AnnAngela
- name: Assign reviewers to release PR
uses: kentaro-m/auto-assign-action@v2.0.2
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,366 +0,0 @@
name: Game Resource Update
on:
schedule:
- cron: "*/20 * * * *" # Runs every 20 minutes
workflow_dispatch:
inputs:
commit_message:
description: "Commit Message"
type: string
required: false
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@v6
with:
show-progress: false
repository: yuanyan3060/ArknightsGameResource
ref: main
path: ./Official
sparse-checkout-cone-mode: false
sparse-checkout: |
/levels.json
/item
/building_skill
/gamedata/excel/item_table.json
/gamedata/excel/building_data.json
/gamedata/excel/range_table.json
/gamedata/excel/character_table.json
/gamedata/excel/gacha_table.json
/gamedata/excel/roguelike_topic_table.json
/gamedata/excel/activity_table.json
- name: Upload Official resources
uses: actions/upload-artifact@v7
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@v6
with:
show-progress: false
repository: ArknightsAssets/ArknightsGamedata
ref: master
path: ./Overseas
sparse-checkout-cone-mode: false
sparse-checkout: |
/en/gamedata/excel/item_table.json
/en/gamedata/excel/building_data.json
/en/gamedata/excel/range_table.json
/en/gamedata/excel/character_table.json
/en/gamedata/excel/gacha_table.json
/en/gamedata/excel/roguelike_topic_table.json
/en/gamedata/excel/activity_table.json
/jp/gamedata/excel/item_table.json
/jp/gamedata/excel/building_data.json
/jp/gamedata/excel/range_table.json
/jp/gamedata/excel/character_table.json
/jp/gamedata/excel/gacha_table.json
/jp/gamedata/excel/roguelike_topic_table.json
/jp/gamedata/excel/activity_table.json
/kr/gamedata/excel/item_table.json
/kr/gamedata/excel/building_data.json
/kr/gamedata/excel/range_table.json
/kr/gamedata/excel/character_table.json
/kr/gamedata/excel/gacha_table.json
/kr/gamedata/excel/roguelike_topic_table.json
/kr/gamedata/excel/activity_table.json
- name: Upload Overseas resources
uses: actions/upload-artifact@v7
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@v6
with:
show-progress: false
repository: arkntools/arknights-data-tw-for-maa
ref: main
path: ./excel
- name: Download stages.json from Penguin Stats
run: |
cd "./excel"
baseUrl="https://penguin-stats.io/PenguinStats/api/v2/stages?server="
parameters=("CN" "US" "JP" "KR")
pids=()
for param in "${parameters[@]}"; do
{
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
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@v7
with:
name: txwy
path: ./excel
compression-level: 0
update-game-resources:
name: Update Game Resources
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: macos-latest
steps:
- 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
persist-credentials: false # Needed to bypass protection rules in Push changes
show-progress: false
fetch-depth: 3
- name: Restore ResourceUpdater from cache
id: resupd-cache
uses: actions/cache/restore@v5
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: Fetch submodules
if: steps.resupd-cache.outputs.cache-hit != 'true'
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --init --depth 1 src/MaaUtils
- name: Cache MaaDeps
if: steps.resupd-cache.outputs.cache-hit != 'true'
id: maadeps-cache
uses: actions/cache@v5
continue-on-error: true
with:
path: |
./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-arm64-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
if: steps.resupd-cache.outputs.cache-hit != 'true' && steps.maadeps-cache.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 tools/maadeps-download.py arm64-osx
- name: Config, Build & Install ResourceUpdater
if: steps.resupd-cache.outputs.cache-hit != 'true'
run: |
cd tools/ResourceUpdater
cmake --preset macos-arm64
cmake --build --preset macos-arm64 --parallel $(sysctl -n hw.logicalcpu)
cmake --install build --config Release
- name: Save ResourceUpdater to cache
if: always() && steps.resupd-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v5
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: Wait for resource cloning
uses: yogeshlonkar/wait-for-jobs@v1
with:
ignore-skipped: 'false'
jobs: |
Download Official Resources
Download Overseas Resources
Download Taiwan Resources
ttl: 15
- name: Download txwy
uses: actions/download-artifact@v8
with:
name: txwy
path: ./tools/ResourceUpdater/Overseas/tw/gamedata/excel
- name: Download Overseas
uses: actions/download-artifact@v8
with:
name: overseas
path: ./tools/ResourceUpdater/Overseas
- name: Download Official
uses: actions/download-artifact@v8
with:
name: official
path: ./tools/ResourceUpdater/Official
- name: Update resources
run: |
./tools/ResourceUpdater/res_updater
- name: Setup python
uses: actions/setup-python@v6
with:
python-version: "3.11"
cache: pip
cache-dependency-path: |
tools/TaskSorter/requirements.txt
tools/OptimizeTemplates/requirements.txt
- name: Install TaskSorter dependencies
run: |
python -m pip install -r tools/TaskSorter/requirements.txt
- name: Sort tasks
id: task_sorting
run: |
python tools/TaskSorter/TaskSorter.py
echo "gitdiff=$(echo $(git diff --name-only --diff-filter=ACM 2>/dev/null | grep '\.json$'))" >> $GITHUB_OUTPUT
- name: Run prettier
uses: Nerixyz/actionsx-prettier@v3-adj
with:
args: -w ${{ steps.task_sorting.outputs.gitdiff }}
- name: Update version.json date if necessary
id: update_version
run: |
sh ./tools/ResourceUpdater/version.sh
- name: Install dependencies
if: steps.update_version.outputs.contains_png == 'True'
run: |
python -m pip install -r tools/OptimizeTemplates/requirements.txt
- name: Setup oxipng
if: steps.update_version.outputs.contains_png == 'True'
uses: baptiste0928/cargo-install@v3
with:
crate: oxipng
- name: Optimize png images
if: steps.update_version.outputs.contains_png == 'True'
run: |
python tools/OptimizeTemplates/optimize_templates.py --no-cleanup -p resource/template/items/ resource/template/infrast/
- name: Commit changes
if: steps.update_version.outputs.changes == 'True'
id: add_files
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
commit_msg="${{ github.event.inputs.commit_message }}"
if [ -z "$commit_msg" ]; then
commit_msg="chore: Auto Update Game Resources - $(date '+%Y-%m-%d')"
else
commit_msg=$(echo "$commit_msg" | xargs) # Trim whitespace
fi
run_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
git commit -m "$commit_msg" -m "$run_url" -m "[skip changelog]"
if [ $? -eq 0 ]; then
echo "have_commits=True" >> $GITHUB_OUTPUT
fi
git pull origin ${{ github.ref_name }} --rebase
- name: Push changes
if: steps.add_files.outputs.have_commits == 'True'
uses: ad-m/github-push-action@master
with:
branch: ${{ github.ref }}
github_token: ${{ secrets.MAA_RESOURCE_SYNC }}
# - name: Update OTA resource
# if: steps.update_version.outputs.update_resources == 'True'
# env:
# GH_TOKEN: ${{ secrets.MISTEOWORKFLOW }}
# run: |
# gh workflow --repo MaaAssistantArknights/MaaRelease run update-resource.yml
- name: Add cancelled status
if: steps.update_version.outputs.changes != 'True' || steps.add_files.outputs.have_commits != 'True'
uses: andymckay/cancel-action@0.5
# - 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.yml -f release_body="Auto Release of Resource Updates"
- name: Upsert failure comment (single active)
if: failure() && github.ref == 'refs/heads/dev-v2'
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-v2' }}
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,127 +0,0 @@
name: Smoke Test
permissions:
contents: read
on:
push:
branches:
- "dev-v2"
paths:
- ".github/workflows/smoke-testing.yml"
- "3rdparty/include/**"
- "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/**"
- "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.head.repo.full_name || github.repository }}-${{ github.head_ref || github.ref_name }}${{ github.ref == 'refs/heads/dev-v2' && format('-{0}', github.sha) || '' }}
cancel-in-progress: true
jobs:
smoke-testing:
name: Run Smoke Test
runs-on: macos-latest
steps:
- 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 for Smoke Test
if: ${{ steps.cache_key.outputs.key != '' }}
id: smoke-cache
uses: actions/cache/restore@v5
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
- name: Fetch submodules
if: steps.smoke-cache.outputs.cache-hit != 'true'
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --init --depth 1 src/MaaUtils
- name: Cache MaaDeps
if: steps.smoke-cache.outputs.cache-hit != 'true'
id: maadeps-cache
uses: actions/cache@v5
continue-on-error: true
with:
path: ./src/MaaUtils/MaaDeps
key: ${{ runner.os }}-arm64-maadeps-${{ hashFiles('tools/maadeps-download.py') }}
- name: Bootstrap MaaDeps
if: steps.smoke-cache.outputs.cache-hit != 'true' && steps.maadeps-cache.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 tools/maadeps-download.py arm64-osx
- name: Configure, build and install
if: steps.smoke-cache.outputs.cache-hit != 'true'
run: |
cmake -B build --preset smoke-test
cmake --build build --preset smoke-test --parallel $(sysctl -n hw.logicalcpu)
cmake --install build --config Debug
- 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: |
sh ./tools/SmokeTesting/run_tests.sh
- name: Save cache for Smoke Test (only in dev-v2)
if: steps.smoke-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/dev-v2'
uses: actions/cache/save@v5
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
- name: Upload logs
if: always()
uses: actions/upload-artifact@v7
with:
name: logs
path: ./install/debug

View File

@@ -1,40 +0,0 @@
name: Issue Staleness Management
on:
schedule:
- cron: "0 0 * * *" # Runs daily at UTC 00:00
workflow_dispatch: # Allows manual triggering
env: # config
daysBeforeStale: 90 # Number of days of inactivity before marking as stale
daysBeforeClose: 7 # Number of days to wait after marking as stale before closing
jobs:
stale:
name: Handle Stale Issues
if: github.repository_owner == 'MaaAssistantArknights'
runs-on: ubuntu-latest
permissions:
actions: write # Workaround for https://github.com/actions/stale/issues/1090
issues: write
# Completely disable stalling for PRs
pull-requests: none
contents: none
steps:
- name: Handle stale issues
uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: ${{ env.daysBeforeStale }}
days-before-close: ${{ env.daysBeforeClose }}
stale-issue-label: "stale"
stale-issue-message: |
This issue has been inactive for a prolonged period and will be closed automatically in ${{ env.daysBeforeClose }} days.
该问题已长时间处于闲置状态,${{ env.daysBeforeClose }} 天后将自动关闭。
exempt-issue-labels: "keep-open, MAA Team, enhancement"
days-before-pr-stale: -1 # Completely disable stalling for PRs
days-before-pr-close: -1 # Completely disable closing for PRs
# Temporary to reduce the huge issues number
operations-per-run: 100
debug-only: false

View File

@@ -1,52 +0,0 @@
name: Resource Sync
on:
push:
branches:
- dev-v2
paths:
- ".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 repository
uses: actions/checkout@v6
with:
show-progress: false
- 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@v6
with:
repository: MaaAssistantArknights/MaaResource
show-progress: false
ssh-key: ${{secrets.MAA_RESOURCE_DEPLOY}}
path: MaaResource
- name: Update MaaResource
run: |
export commit_msg=$(git show -s --format=%s)
cd MaaResource
shopt -s extglob
cd resource
rm -rf !(".gitignore")
cp -rf ../../resource/* .
cd ..
git add .
git status
git commit -m "$commit_msg" || exit 0
git push

View File

@@ -1,122 +0,0 @@
name: Unit Tests
on:
# push:
# branches:
# - "dev-v2"
# paths:
# - ".github/workflows/unit-tests.yml"
# - "unit_test/**"
# - "src/**"
# pull_request:
# paths:
# - ".github/workflows/unit-tests.yml"
# - "unit_test/**"
# - "src/**"
workflow_dispatch:
permissions:
contents: read
jobs:
select-tests:
name: Select Unit Test Suites
runs-on: ubuntu-latest
outputs:
has_tests: ${{ steps.select.outputs.has_tests }}
matrix: ${{ steps.select.outputs.matrix }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
show-progress: false
- name: Select affected test suites
id: select
env:
EVENT_NAME: ${{ github.event_name }}
BEFORE_SHA: ${{ github.event.before }}
HEAD_SHA: ${{ github.sha }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
python3 - <<'PY'
import json
import os
import subprocess
def matches(path: str, rule: str) -> bool:
if rule.endswith('/**'):
return path.startswith(rule[:-3])
return path == rule
with open('unit_test/test-suites.json', encoding='utf-8') as f:
mapping = json.load(f)
event_name = os.environ['EVENT_NAME']
changed_files = []
run_all = event_name == 'workflow_dispatch'
if not run_all:
if event_name == 'pull_request':
base_sha = os.environ['PR_BASE_SHA']
head_sha = os.environ['PR_HEAD_SHA']
else:
base_sha = os.environ['BEFORE_SHA']
head_sha = os.environ['HEAD_SHA']
if not base_sha or set(base_sha) == {'0'}:
run_all = True
else:
diff = subprocess.check_output(
['git', 'diff', '--name-only', base_sha, head_sha],
text=True,
)
changed_files = [line for line in diff.splitlines() if line]
print('Changed files:')
for file_path in changed_files:
print(f' - {file_path}')
if run_all or any(any(matches(path, rule) for rule in mapping['runAllOnChanges']) for path in changed_files):
selected = mapping['suites']
else:
selected = []
for suite in mapping['suites']:
if any(any(matches(path, rule) for rule in suite['paths']) for path in changed_files):
selected.append(suite)
matrix = {'suite': selected}
with open(os.environ['GITHUB_OUTPUT'], 'a', encoding='utf-8') as f:
f.write(f"has_tests={'true' if selected else 'false'}\n")
f.write(f"matrix={json.dumps(matrix, separators=(',', ':'))}\n")
PY
unit-tests:
name: ${{ matrix.suite.name }} Unit Tests
needs: select-tests
if: ${{ needs.select-tests.outputs.has_tests == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.select-tests.outputs.matrix) }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Configure unit tests
run: |
cmake -S unit_test -B build/unit_test -DCMAKE_BUILD_TYPE=Release
- name: Build selected unit test target
run: |
cmake --build build/unit_test --parallel --target ${{ matrix.suite.buildTarget }}
- name: Run selected unit tests
run: |
ctest --test-dir build/unit_test --output-on-failure -R '${{ matrix.suite.ctestRegex }}'

View File

@@ -1,32 +0,0 @@
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
shell: bash
run: bash ./.github/scripts/sync-optional-submodules.sh --remote src/MAAUnified src/MaaMacGui src/maa-cli
- name: Commit and push changes
uses: actions-js/push@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
message: "feat: Update Submodules MAAUnified, MaaMacGui, maa-cli
https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
[skip changelog]"
branch: ${{ github.ref }}

View File

@@ -1,75 +0,0 @@
name: Documentation Site
on:
push:
branches:
- "master-v2"
- "dev-v2"
paths:
- ".github/workflows/website-workflow.yml"
- "docs/**"
pull_request:
paths:
- ".github/workflows/website-workflow.yml"
- "docs/**"
workflow_dispatch:
inputs:
deploy-to-prod:
description: "Deploy to prod"
default: false
required: true
type: boolean
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 repository
uses: actions/checkout@v6
with:
show-progress: false
- name: Install pnpm
uses: pnpm/action-setup@v5
with:
package_json_file: "./docs/package.json"
run_install: false
- 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 node modules
run: pnpm install --frozen-lockfile
working-directory: "./docs"
- name: Build
run: pnpm run build
working-directory: "./docs"
- name: Upload artifact to GitHub
uses: actions/upload-artifact@v7
with:
name: dist
path: "./docs/.vuepress/dist"
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
if: github.repository_owner == 'MaaAssistantArknights' && (inputs.deploy-to-prod == true || github.ref == 'refs/heads/master-v2')
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: "./docs/.vuepress/dist"
publish_branch: gh-pages

69
.gitignore vendored
View File

@@ -2,8 +2,6 @@
*.d
# Compiled Object files
build
build-*
*.slo
*.lo
*.o
@@ -21,7 +19,6 @@ build-*
# Fortran module files
*.mod
*.smod
!go.mod
# Compiled Static libraries
*.lai
@@ -73,7 +70,6 @@ bld/
[Oo]bj/
[Ll]og/
[Ll]ogs/
cmake-build-debug/
# Visual Studio 2015/2017 cache/options directory
.vs/
@@ -409,21 +405,16 @@ MigrationBackup/
FodyWeavers.xsd
# VS Code files for those working on multiple tools
**/.vscode/*
.vscode/*
# !.vscode/settings.json
# !.vscode/tasks.json
# !.vscode/launch.json
# !.vscode/extensions.json
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Claude Code
.claude/*
!.claude/skills/
# Windows Installer files from build outputs
*.cab
*.msi
@@ -434,55 +425,3 @@ FodyWeavers.xsd
# JetBrains Rider
.idea/
*.sln.iml
screen.png
adb_screen.png
tools/**/*.png
enc_temp_folder/*
# RoguelikeRecruitmentTool 导出的 Excel 文件
tools/RoguelikeRecruitmentTool/output
# Nuke
.nuke/temp/*
# 引航者试炼地图,手动改的参数
/resource/Arknights-Tile-Pos/act2bossrush_01-activities-act2bossrush-level_bossrush2_01.json
/resource/Arknights-Tile-Pos/act2bossrush_02-activities-act2bossrush-level_bossrush2_02.json
/resource/Arknights-Tile-Pos/act2bossrush_03-activities-act2bossrush-level_bossrush2_03.json
/resource/Arknights-Tile-Pos/act2bossrush_04-activities-act2bossrush-level_bossrush2_04.json
# CF 活动关卡(异格夜刀),手动改的地图
/resource/Arknights-Tile-Pos/act24side_09-activities-act24side-level_act24side_09.json
/src/MaaWpfGui/FodyWeavers.xml
*.lnk
# 链接检查缓存
.lycheecache
# MaaDeps
MaaDeps
src/MaaUtils/*
# ResourceUpdater workflow
/original/*
# Windows Explorer Shits
desktop.ini
Thumbs.db
# macOS Finder Shit
.DS_Store
# MaaSupportExtension config
/config/maa_pi_config.json
# build & install
build
install
install-*
# pnpm cache
.pnpm-store
# CMake user presets
CMakeUserPresets.json

19
.gitmodules vendored
View File

@@ -1,19 +0,0 @@
[submodule "test"]
path = test
url = https://github.com/MaaAssistantArknights/MaaTestSet.git
[submodule "src/MaaMacGui"]
path = src/MaaMacGui
url = https://github.com/MaaAssistantArknights/MaaMacGui.git
[submodule "src/maa-cli"]
path = src/maa-cli
url = https://github.com/MaaAssistantArknights/maa-cli.git
[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
[submodule "src/MAAUnified"]
path = src/MAAUnified
url = https://github.com/MaaAssistantArknights/MaaUnified.git
branch = main

View File

@@ -1,45 +0,0 @@
default_install_hook_types: [pre-commit, prepare-commit-msg]
repos:
- repo: https://github.com/shssoichiro/oxipng
rev: v10.0.0
hooks:
- id: oxipng
name: PNG Image Compression
args: ["-q", "-o", "2", "-s", "--ng"]
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v21.1.8
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.7.4
hooks:
- id: prettier
name: Prettier (Config Files)
files: ^((\.github/ISSUE_TEMPLATE|resource|src|tools)/.*|\.pre-commit-config\.yaml|package-definition\.json)
types_or:
- yaml
- json
- id: prettier
name: Prettier (Documentation)
files: ^docs/.*
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.10
hooks:
- id: ruff-format
name: Ruff format (Python)
- repo: https://github.com/DavidAnson/markdownlint-cli2
rev: v0.18.1
hooks:
- id: markdownlint-cli2
name: MarkdownLint (Documentation)
files: ^docs/.*|^README\.md$
types:
- markdown
args: ["--fix", "--config", "docs/.markdownlint.yaml"]

View File

@@ -1,12 +0,0 @@
**/pnpm-lock.yaml
3rdparty/
src/maa-cli
src/MaaMacGui
src/MaaUtils
resource/Arknights-Tile-Pos/
tools/OptimizeTemplates/optimize_templates.json
CITATION.cff
CHANGELOG.md

View File

@@ -1,23 +0,0 @@
{
"tabWidth": 4,
"printWidth": 120,
"useTabs": false,
"bracketSameLine": true,
"bracketSpacing": true,
"endOfLine": "auto",
"overrides": [
{
"files": [".clang-format", "**/*.yml", "**/*.yaml"],
"options": {
"parser": "yaml",
"tabWidth": 2
}
},
{
"files": ["**/*.md"],
"options": {
"tabWidth": 2
}
}
]
}

20
.vscode/settings.json vendored
View File

@@ -1,20 +0,0 @@
{
"json.schemas": [
{
"fileMatch": [
"resource/tasks/**/*.json",
"resource/global/**/resource/tasks/**/*.json",
],
"url": "./docs/maa_tasks_schema.json"
}
],
"files.exclude": {
"MaaDeps/vcpkg/buildtrees": true,
"MaaDeps/vcpkg/packages": true
},
"files.associations": {
"**/resource/tasks/**/*.json": "jsonc"
},
"C_Cpp.exclusionPolicy": "checkFilesAndFolders",
"cmake.outputLogEncoding": "UTF-8"
}

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:32b8b36100090e37d2a892783ef9922fd890767d0546400ed737bf2d57698dfd
size 4745216

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3efb02b69038309da6adc09ed9b4688c966cf88871d433a49687c3840aba9343
size 55650816

View File

@@ -0,0 +1,37 @@
#ifndef __OCR_ANGLENET_H__
#define __OCR_ANGLENET_H__
#include "OcrStruct.h"
#include <opencv/cv.hpp>
#include <memory>
namespace ocr {
class AngleNet {
public:
~AngleNet();
void setNumThread(int numOfThread);
void setGpuIndex(int gpuIndex);
bool initModel(const std::string& pathStr);
std::vector<Angle> getAngles(std::vector<cv::Mat>& partImgs, const char* path,
const char* imgName, bool doAngle, bool mostAngle);
private:
bool isOutputAngleImg = false;
int numThread;
std::shared_ptr<ncnn::Net> pNet = std::make_shared<ncnn::Net>();
const float meanValues[3] = { 127.5, 127.5, 127.5 };
const float normValues[3] = { 1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5 };
const int dstWidth = 192;
const int dstHeight = 32;
Angle getAngle(cv::Mat& src);
};
}
#endif //__OCR_ANGLENET_H__

View File

@@ -0,0 +1,39 @@
#ifndef __OCR_CRNNNET_H__
#define __OCR_CRNNNET_H__
#include "OcrStruct.h"
#include <opencv/cv.hpp>
#include <memory>
namespace ocr {
class CrnnNet {
public:
~CrnnNet();
void setNumThread(int numOfThread);
void setGpuIndex(int gpuIndex);
bool initModel(const std::string& pathStr, const std::string& keysPath);
std::vector<TextLine> getTextLines(std::vector<cv::Mat>& partImg, const char* path, const char* imgName);
private:
bool isOutputDebugImg = false;
int numThread;
std::shared_ptr<ncnn::Net> pNet = std::make_shared<ncnn::Net>();
const float meanValues[3] = { 127.5, 127.5, 127.5 };
const float normValues[3] = { 1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5 };
const int dstHeight = 32;
std::vector<std::string> keys;
TextLine scoreToTextLine(const std::vector<float>& outputData, int h, int w);
TextLine getTextLine(const cv::Mat& src);
};
}
#endif //__OCR_CRNNNET_H__

View File

@@ -0,0 +1,31 @@
#ifndef __OCR_DBNET_H__
#define __OCR_DBNET_H__
#include "OcrStruct.h"
#include <opencv/cv.hpp>
#include <memory>
namespace ocr {
class DbNet {
public:
~DbNet();
void setNumThread(int numOfThread);
void setGpuIndex(int gpuIndex);
bool initModel(const std::string& pathStr);
std::vector<TextBox> getTextBoxes(cv::Mat& src, ScaleParam& s, float boxScoreThresh,
float boxThresh, float unClipRatio);
private:
int numThread;
std::shared_ptr<ncnn::Net> pNet = std::make_shared<ncnn::Net>();
const float meanValues[3] = { 0.485 * 255, 0.456 * 255, 0.406 * 255 };
const float normValues[3] = { 1.0 / 0.229 / 255.0, 1.0 / 0.224 / 255.0, 1.0 / 0.225 / 255.0 };
};
}
#endif //__OCR_DBNET_H__

View File

@@ -0,0 +1,75 @@
#ifndef __OCR_LITE_H__
#define __OCR_LITE_H__
#include "opencv2/core.hpp"
#include "OcrStruct.h"
#include "DbNet.h"
#include "AngleNet.h"
#include "CrnnNet.h"
namespace ocr {
class OCRLITE_EXPORT OcrLite {
public:
OcrLite();
~OcrLite();
void setNumThread(int numOfThread);
void initLogger(bool isConsole, bool isPartImg, bool isResultImg);
void enableResultTxt(const char* path, const char* imgName);
void setGpuIndex(int gpuIndex);
bool initModels(const std::string& detPath, const std::string& clsPath,
const std::string& recPath, const std::string& keysPath);
void Logger(const char* format, ...);
/*
* padding图像预处理在图片外周添加白边用于提升识别率文字框没有正确框住所有文字时增加此值。
* maxSideLen 按图片最长边的长度此值为0代表不缩放1024如果图片长边大于1024则把图像整体缩小到1024再进行图像分割计算如果图片长边小于1024则不缩放如果图片长边小于32则缩放到32。
* boxScoreThresh文字框置信度门限文字框没有正确框住所有文字时减小此值。
* boxThresh请自行试验。
* unClipRatio单个文字框大小倍率越大时单个文字框越大。此项与图片的大小相关越大的图片此值应该越大。
* doAngle启用(1)/禁用(0) 文字方向检测,只有图片倒置的情况下(旋转90~270度的图片),才需要启用文字方向检测。
* mostAngle启用(1)/禁用(0) 角度投票(整张图片以最大可能文字方向来识别),当禁用文字方向检测时,此项也不起作用。
*/
OcrResult detect(const char* path, const char* imgName,
int padding, int maxSideLen,
float boxScoreThresh, float boxThresh, float unClipRatio, bool doAngle, bool mostAngle);
/*
* padding图像预处理在图片外周添加白边用于提升识别率文字框没有正确框住所有文字时增加此值。
* maxSideLen 按图片最长边的长度此值为0代表不缩放1024如果图片长边大于1024则把图像整体缩小到1024再进行图像分割计算如果图片长边小于1024则不缩放如果图片长边小于32则缩放到32。
* boxScoreThresh文字框置信度门限文字框没有正确框住所有文字时减小此值。
* boxThresh请自行试验。
* unClipRatio单个文字框大小倍率越大时单个文字框越大。此项与图片的大小相关越大的图片此值应该越大。
* doAngle启用(1)/禁用(0) 文字方向检测,只有图片倒置的情况下(旋转90~270度的图片),才需要启用文字方向检测。
* mostAngle启用(1)/禁用(0) 角度投票(整张图片以最大可能文字方向来识别),当禁用文字方向检测时,此项也不起作用。
*/
OcrResult detect(const cv::Mat& mat,
int padding, int maxSideLen,
float boxScoreThresh, float boxThresh, float unClipRatio, bool doAngle, bool mostAngle);
private:
bool isOutputConsole = false;
bool isOutputPartImg = false;
bool isOutputResultTxt = false;
bool isOutputResultImg = false;
FILE* resultTxt;
DbNet dbNet;
AngleNet angleNet;
CrnnNet crnnNet;
std::vector<cv::Mat> getPartImages(cv::Mat& src, std::vector<TextBox>& textBoxes,
const char* path, const char* imgName);
OcrResult detect(const char* path, const char* imgName,
cv::Mat& src, cv::Rect& originRect, ScaleParam& scale,
float boxScoreThresh = 0.6f, float boxThresh = 0.3f,
float unClipRatio = 2.0f, bool doAngle = true, bool mostAngle = true);
};
}
#endif //__OCR_LITE_H__

View File

@@ -0,0 +1,35 @@
#ifdef __JNI__
#ifndef __OCR_RESULT_UTILS_H__
#define __OCR_RESULT_UTILS_H__
#include <jni.h>
#include "OcrStruct.h"
class OcrResultUtils {
public:
OcrResultUtils(JNIEnv *env, OcrResult &ocrResult);
~OcrResultUtils();
jobject getJObject();
private:
JNIEnv *jniEnv;
jobject jOcrResult;
jclass newJListClass();
jmethodID getListConstructor(jclass clazz);
jobject getTextBlock(TextBlock &textBlock);
jobject getTextBlocks(std::vector<TextBlock> &textBlocks);
jobject newJPoint(cv::Point &point);
jobject newJBoxPoint(std::vector<cv::Point> &boxPoint);
jfloatArray newJScoreArray(std::vector<float> &scores);
};
#endif //__OCR_RESULT_UTILS_H__
#endif

View File

@@ -0,0 +1,65 @@
#ifndef __OCR_STRUCT_H__
#define __OCR_STRUCT_H__
#include "opencv2/core.hpp"
#include <vector>
#ifdef __C_API__
#define OCRLITE_EXPORT __declspec(dllexport)
#else
#define OCRLITE_EXPORT
#endif
namespace ncnn {
class Net;
}
namespace ocr {
struct OCRLITE_EXPORT ScaleParam {
int srcWidth;
int srcHeight;
int dstWidth;
int dstHeight;
float ratioWidth;
float ratioHeight;
};
struct OCRLITE_EXPORT TextBox {
std::vector<cv::Point> boxPoint;
float score;
};
struct OCRLITE_EXPORT Angle {
int index;
float score;
double time;
};
struct OCRLITE_EXPORT TextLine {
std::string text;
std::vector<float> charScores;
double time;
};
struct OCRLITE_EXPORT TextBlock {
std::vector<cv::Point> boxPoint;
float boxScore;
int angleIndex;
float angleScore;
double angleTime;
std::string text;
std::vector<float> charScores;
double crnnTime;
double blockTime;
};
struct OCRLITE_EXPORT OcrResult {
double dbNetTime;
std::vector<TextBlock> textBlocks;
cv::Mat boxImg;
double detectTime;
std::string strRes;
};
}
#endif //__OCR_STRUCT_H__

View File

@@ -0,0 +1,66 @@
#ifndef __OCR_UTILS_H__
#define __OCR_UTILS_H__
#include <opencv2/core.hpp>
#include "OcrStruct.h"
#include <sys/stat.h>
/*#define __ENABLE_CONSOLE__ true
#define Logger(format, ...) {\
if(__ENABLE_CONSOLE__) printf(format,##__VA_ARGS__); \
}*/
namespace ocr {
OCRLITE_EXPORT double getCurrentTime();
OCRLITE_EXPORT inline bool isFileExists(const std::string& name) {
struct stat buffer;
return (stat(name.c_str(), &buffer) == 0);
}
OCRLITE_EXPORT std::wstring strToWstr(std::string str);
OCRLITE_EXPORT ScaleParam getScaleParam(cv::Mat& src, const float scale);
OCRLITE_EXPORT ScaleParam getScaleParam(cv::Mat& src, const int targetSize);
OCRLITE_EXPORT std::vector<cv::Point2f> getBox(const cv::RotatedRect& rect);
OCRLITE_EXPORT int getThickness(cv::Mat& boxImg);
OCRLITE_EXPORT void drawTextBox(cv::Mat& boxImg, cv::RotatedRect& rect, int thickness);
OCRLITE_EXPORT void drawTextBox(cv::Mat& boxImg, const std::vector<cv::Point>& box, int thickness);
OCRLITE_EXPORT void drawTextBoxes(cv::Mat& boxImg, std::vector<TextBox>& textBoxes, int thickness);
OCRLITE_EXPORT cv::Mat matRotateClockWise180(cv::Mat src);
OCRLITE_EXPORT cv::Mat matRotateClockWise90(cv::Mat src);
OCRLITE_EXPORT cv::Mat getRotateCropImage(const cv::Mat& src, std::vector<cv::Point> box);
OCRLITE_EXPORT cv::Mat adjustTargetImg(cv::Mat& src, int dstWidth, int dstHeight);
OCRLITE_EXPORT std::vector<cv::Point> getMinBoxes(const std::vector<cv::Point>& inVec, float& minSideLen, float& allEdgeSize);
OCRLITE_EXPORT float boxScoreFast(const cv::Mat& inMat, const std::vector<cv::Point>& inBox);
OCRLITE_EXPORT std::vector<cv::Point> unClip(const std::vector<cv::Point>& inBox, float perimeter, float unClipRatio);
OCRLITE_EXPORT std::vector<int> getAngleIndexes(std::vector<Angle>& angles);
OCRLITE_EXPORT void saveImg(cv::Mat& img, const char* imgPath);
OCRLITE_EXPORT std::string getSrcImgFilePath(const char* path, const char* imgName);
OCRLITE_EXPORT std::string getResultTxtFilePath(const char* path, const char* imgName);
OCRLITE_EXPORT std::string getResultImgFilePath(const char* path, const char* imgName);
OCRLITE_EXPORT std::string getDebugImgFilePath(const char* path, const char* imgName, int i, const char* tag);
OCRLITE_EXPORT void printGpuInfo();
}
#endif //__OCR_UTILS_H__

View File

@@ -0,0 +1,406 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 6.4.2 *
* Date : 27 February 2017 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2017 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: *
* "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
#ifndef clipper_hpp
#define clipper_hpp
#define CLIPPER_VERSION "6.4.2"
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz
//use_lines: Enables line clipping. Adds a very minor cost to performance.
#define use_lines
//use_deprecated: Enables temporary support for the obsolete functions
//#define use_deprecated
#include <vector>
#include <list>
#include <set>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
#include <functional>
#include <queue>
namespace ClipperLib {
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
enum PolyType { ptSubject, ptClip };
//By far the most widely used winding rules for polygon filling are
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
//see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
#ifdef use_int32
typedef int cInt;
static cInt const loRange = 0x7FFF;
static cInt const hiRange = 0x7FFF;
#else
typedef signed long long cInt;
static cInt const loRange = 0x3FFFFFFF;
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
typedef signed long long long64; //used by Int128 class
typedef unsigned long long ulong64;
#endif
struct IntPoint {
cInt X;
cInt Y;
#ifdef use_xyz
cInt Z;
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
#else
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
#endif
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
{
return a.X == b.X && a.Y == b.Y;
}
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
{
return a.X != b.X || a.Y != b.Y;
}
};
//------------------------------------------------------------------------------
typedef std::vector< IntPoint > Path;
typedef std::vector< Path > Paths;
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
std::ostream& operator <<(std::ostream &s, const IntPoint &p);
std::ostream& operator <<(std::ostream &s, const Path &p);
std::ostream& operator <<(std::ostream &s, const Paths &p);
struct DoublePoint
{
double X;
double Y;
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
};
//------------------------------------------------------------------------------
#ifdef use_xyz
typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
#endif
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
enum JoinType {jtSquare, jtRound, jtMiter};
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
class PolyNode
{
public:
PolyNode();
virtual ~PolyNode(){};
Path Contour;
PolyNodes Childs;
PolyNode* Parent;
PolyNode* GetNext() const;
bool IsHole() const;
bool IsOpen() const;
int ChildCount() const;
private:
//PolyNode& operator =(PolyNode& other);
unsigned Index; //node index in Parent.Childs
bool m_IsOpen;
JoinType m_jointype;
EndType m_endtype;
PolyNode* GetNextSiblingUp() const;
void AddChild(PolyNode& child);
friend class Clipper; //to access Index
friend class ClipperOffset;
};
class PolyTree: public PolyNode
{
public:
~PolyTree(){ Clear(); };
PolyNode* GetFirst() const;
void Clear();
int Total() const;
private:
//PolyTree& operator =(PolyTree& other);
PolyNodes AllNodes;
friend class Clipper; //to access AllNodes
};
bool Orientation(const Path &poly);
double Area(const Path &poly);
int PointInPolygon(const IntPoint &pt, const Path &path);
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
void CleanPolygon(Path& poly, double distance = 1.415);
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
void CleanPolygons(Paths& polys, double distance = 1.415);
void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
void ReversePath(Path& p);
void ReversePaths(Paths& p);
struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };
//enums that are used internally ...
enum EdgeSide { esLeft = 1, esRight = 2};
//forward declarations (for stuff used internally) ...
struct TEdge;
struct IntersectNode;
struct LocalMinimum;
struct OutPt;
struct OutRec;
struct Join;
typedef std::vector < OutRec* > PolyOutList;
typedef std::vector < TEdge* > EdgeList;
typedef std::vector < Join* > JoinList;
typedef std::vector < IntersectNode* > IntersectList;
//------------------------------------------------------------------------------
//ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of
//polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase
{
public:
ClipperBase();
virtual ~ClipperBase();
virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
virtual void Clear();
IntRect GetBounds();
bool PreserveCollinear() {return m_PreserveCollinear;};
void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
protected:
void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
virtual void Reset();
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
void InsertScanbeam(const cInt Y);
bool PopScanbeam(cInt &Y);
bool LocalMinimaPending();
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
OutRec* CreateOutRec();
void DisposeAllOutRecs();
void DisposeOutRec(PolyOutList::size_type index);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DeleteFromAEL(TEdge *e);
void UpdateEdgeIntoAEL(TEdge *&e);
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM;
MinimaList m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges;
bool m_PreserveCollinear;
bool m_HasOpenPaths;
PolyOutList m_PolyOuts;
TEdge *m_ActiveEdges;
typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam;
};
//------------------------------------------------------------------------------
class Clipper : public virtual ClipperBase
{
public:
Clipper(int initOptions = 0);
bool Execute(ClipType clipType,
Paths &solution,
PolyFillType fillType = pftEvenOdd);
bool Execute(ClipType clipType,
Paths &solution,
PolyFillType subjFillType,
PolyFillType clipFillType);
bool Execute(ClipType clipType,
PolyTree &polytree,
PolyFillType fillType = pftEvenOdd);
bool Execute(ClipType clipType,
PolyTree &polytree,
PolyFillType subjFillType,
PolyFillType clipFillType);
bool ReverseSolution() { return m_ReverseOutput; };
void ReverseSolution(bool value) {m_ReverseOutput = value;};
bool StrictlySimple() {return m_StrictSimple;};
void StrictlySimple(bool value) {m_StrictSimple = value;};
//set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz
void ZFillFunction(ZFillCallback zFillFunc);
#endif
protected:
virtual bool ExecuteInternal();
private:
JoinList m_Joins;
JoinList m_GhostJoins;
IntersectList m_IntersectList;
ClipType m_ClipType;
typedef std::list<cInt> MaximaList;
MaximaList m_Maxima;
TEdge *m_SortedEdges;
bool m_ExecuteLocked;
PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType;
bool m_ReverseOutput;
bool m_UsingPolyTree;
bool m_StrictSimple;
#ifdef use_xyz
ZFillCallback m_ZFill; //custom callback
#endif
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertLocalMinimaIntoAEL(const cInt botY);
void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
void AddEdgeToSEL(TEdge *edge);
bool PopEdgeFromSEL(TEdge *&edge);
void CopyAELToSEL();
void DeleteFromSEL(TEdge *e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const cInt XPos);
void DoMaxima(TEdge *e);
void ProcessHorizontals();
void ProcessHorizontal(TEdge *horzEdge);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2);
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
OutPt* GetLastOutPt(TEdge *e);
bool ProcessIntersections(const cInt topY);
void BuildIntersectList(const cInt topY);
void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths& polys);
void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *outrec);
void DisposeIntersectNodes();
bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outrec);
void FixupOutPolyline(OutRec &outrec);
bool IsHole(TEdge *e);
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
void FixHoleLinkage(OutRec &outrec);
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
void ClearJoins();
void ClearGhostJoins();
void AddGhostJoin(OutPt *op, const IntPoint offPt);
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
void JoinCommonEdges();
void DoSimplePolygons();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif
};
//------------------------------------------------------------------------------
class ClipperOffset
{
public:
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
~ClipperOffset();
void AddPath(const Path& path, JoinType joinType, EndType endType);
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
void Execute(Paths& solution, double delta);
void Execute(PolyTree& solution, double delta);
void Clear();
double MiterLimit;
double ArcTolerance;
private:
Paths m_destPolys;
Path m_srcPoly;
Path m_destPoly;
std::vector<DoublePoint> m_normals;
double m_delta, m_sinA, m_sin, m_cos;
double m_miterLim, m_StepsPerRad;
IntPoint m_lowest;
PolyNode m_polyNodes;
void FixOrientations();
void DoOffset(double delta);
void OffsetPoint(int j, int& k, JoinType jointype);
void DoSquare(int j, int k);
void DoMiter(int j, int k, double r);
void DoRound(int j, int k);
};
//------------------------------------------------------------------------------
class clipperException : public std::exception
{
public:
clipperException(const char* description): m_descr(description) {}
virtual ~clipperException() throw() {}
virtual const char* what() const throw() {return m_descr.c_str();}
private:
std::string m_descr;
};
//------------------------------------------------------------------------------
} //ClipperLib namespace
#endif //clipper_hpp

View File

@@ -0,0 +1,8 @@
#ifndef __OCR_VERSION_H__
#define __OCR_VERSION_H__
namespace ocr {
static const char* VERSION = "1.5.1.20210128";
}
#endif //__OCR_VERSION_H__

View File

@@ -0,0 +1,7 @@
#pragma once
#include "json_parser.h"
#include "json_value.h"
#include "json_object.h"
#include "json_array.h"
#include "json_exception.h"

View File

@@ -0,0 +1,84 @@
#pragma once
#include <string>
#include <vector>
#include <initializer_list>
namespace json
{
class value;
class array
{
public:
using raw_array = std::vector<value>;
using iterator = raw_array::iterator;
using const_iterator = raw_array::const_iterator;
using reverse_iterator = raw_array::reverse_iterator;
using const_reverse_iterator = raw_array::const_reverse_iterator;
array() = default;
array(const array &rhs) = default;
array(array &&rhs) noexcept = default;
array(const raw_array &arr);
array(raw_array &&arr) noexcept;
array(std::initializer_list<raw_array::value_type> init_list);
~array() noexcept = default;
bool empty() const noexcept { return _array_data.empty(); }
size_t size() const noexcept { return _array_data.size(); }
bool exist(size_t pos) const { return _array_data.size() < pos; }
const value &at(size_t pos) const;
const std::string to_string() const;
const std::string format(std::string shift_str = " ", size_t basic_shift_count = 0) const;
const bool get(size_t pos, bool default_value) const;
const int get(size_t pos, int default_value) const;
const long get(size_t pos, long default_value) const;
const unsigned long get(size_t pos, unsigned default_value) const;
const long long get(size_t pos, long long default_value) const;
const unsigned long long get(size_t pos, unsigned long long default_value) const;
const float get(size_t pos, float default_value) const;
const double get(size_t pos, double default_value) const;
const long double get(size_t pos, long double default_value) const;
const std::string get(size_t pos, std::string default_value) const;
const std::string get(size_t pos, const char * default_value) const;
template <typename... Args>
decltype(auto) emplace_back(Args &&... args)
{
static_assert(
std::is_constructible<raw_array::value_type, Args...>::value,
"Parameter can't be used to construct a raw_array::value_type");
return _array_data.emplace_back(std::forward<Args>(args)...);
}
void clear() noexcept;
// void earse(size_t pos);
iterator begin() noexcept;
iterator end() noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
reverse_iterator rbegin() noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
const value &operator[](size_t pos) const;
value &operator[](size_t pos);
array &operator=(const array &) = default;
array &operator=(array &&) noexcept = default;
// const raw_array &raw_data() const;
private:
raw_array _array_data;
};
std::ostream &operator<<(std::ostream &out, const array &arr);
} // namespace json

View File

@@ -0,0 +1,27 @@
#pragma once
#include <exception>
#include <string>
namespace json
{
class exception : public std::exception
{
public:
exception() = default;
exception(const std::string &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;
private:
std::string m_msg;
};
} // namespace json

View File

@@ -0,0 +1,77 @@
#pragma once
#include <string>
#include <unordered_map>
#include <initializer_list>
#include "json_value.h"
namespace json
{
class object
{
public:
using raw_object = std::unordered_map<std::string, value>;
using iterator = raw_object::iterator;
using const_iterator = raw_object::const_iterator;
object() = default;
object(const object& rhs) = default;
object(object&& rhs) = default;
object(const raw_object& raw_obj);
object(raw_object&& raw_obj);
object(std::initializer_list<raw_object::value_type> init_list);
~object() = default;
bool empty() const noexcept { return _object_data.empty(); }
size_t size() const noexcept { return _object_data.size(); }
bool exist(const std::string& key) const { return _object_data.find(key) != _object_data.cend(); }
const value& at(const std::string& key) const;
const std::string to_string() const;
const std::string format(std::string shift_str = " ", size_t basic_shift_count = 0) const;
const bool get(const std::string& key, bool default_value) const;
const int get(const std::string& key, int default_value) const;
const long get(const std::string& key, long default_value) const;
const unsigned long get(const std::string& key, unsigned default_value) const;
const long long get(const std::string& key, long long default_value) const;
const unsigned long long get(const std::string& key, unsigned long long default_value) const;
const float get(const std::string& key, float default_value) const;
const double get(const std::string& key, double default_value) const;
const long double get(const std::string& key, long double default_value) const;
const std::string get(const std::string& key, std::string default_value) const;
const std::string get(const std::string& key, const char* default_value) const;
template <typename... Args>
decltype(auto) emplace(Args &&... args)
{
static_assert(
std::is_constructible<raw_object::value_type, Args...>::value,
"Parameter can't be used to construct a raw_object::value_type");
return _object_data.emplace(std::forward<Args>(args)...);
}
void clear() noexcept;
bool earse(const std::string& key);
iterator begin() noexcept;
iterator end() noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
value& operator[](const std::string& key);
value& operator[](std::string&& key);
object& operator=(const object&) = default;
object& operator=(object&&) = default;
// const raw_object &raw_data() const;
private:
raw_object _object_data;
};
std::ostream& operator<<(std::ostream& out, const json::object& obj);
} // namespace json

View File

@@ -0,0 +1,47 @@
#pragma once
#include <string>
#include <optional>
namespace json
{
class value;
class object;
class array;
enum class value_type : char;
class parser
{
public:
~parser() noexcept = default;
static std::optional<value> parse(const std::string &content);
private:
parser(
const std::string::const_iterator &cbegin,
const std::string::const_iterator &cend) noexcept
: _cur(cbegin), _end(cend) {}
std::optional<value> parse();
value parse_value();
value parse_null();
value parse_boolean();
value parse_number();
// parse and return a json::value whose type is value_type::String
value parse_string();
value parse_array();
value parse_object();
// parse and return a std::string
std::optional<std::string> parse_stdstring();
bool skip_whitespace() noexcept;
bool skip_digit() noexcept;
private:
std::string::const_iterator _cur;
std::string::const_iterator _end;
};
} // namespace json

View File

@@ -0,0 +1,147 @@
#pragma once
#include <string>
#include <ostream>
// #include <iostream>
#include <memory>
namespace json
{
enum class value_type : char
{
Invalid,
Null,
Boolean,
String,
Number,
Array,
Object,
NUM_T
};
class array;
class object;
class value
{
using unique_array = std::unique_ptr<array>;
using unique_object = std::unique_ptr<object>;
public:
value();
value(const value &rhs);
value(value &&rhs) noexcept;
value(bool b);
value(int num);
value(unsigned num);
value(long num);
value(unsigned long num);
value(long long num);
value(unsigned long long num);
value(float num);
value(double num);
value(long double num);
value(const char *str);
value(const std::string &str);
value(std::string &&str);
value(const array &arr);
value(array &&arr);
// value(std::initializer_list<value> init_list); // for array
value(const object &obj);
value(object &&obj);
// error: conversion from <brace-enclosed initializer list> to json::value is ambiguous
// value(std::initializer_list<std::pair<std::string, value>> init_list); // for object
// Constructed from raw data
template <typename... Args>
value(value_type type, Args &&... args)
: _type(type),
_raw_data(std::forward<Args>(args)...)
{
static_assert(
std::is_constructible<std::string, Args...>::value,
"Parameter can't be used to construct a std::string");
}
// Prohibit conversion of other types to value
template <typename T>
value(T) = delete;
~value();
bool valid() const noexcept { return _type != value_type::Invalid ? true : false; }
bool empty() const noexcept { return (_type == value_type::Null && _raw_data.compare("null") == 0) ? true : false; }
bool is_null() const noexcept { return empty(); }
bool is_number() const noexcept { return _type == value_type::Number; }
bool is_boolean() const noexcept { return _type == value_type::Boolean; }
bool is_string() const noexcept { return _type == value_type::String; }
bool is_array() const noexcept { return _type == value_type::Array; }
bool is_object() const noexcept { return _type == value_type::Object; }
bool exist(const std::string& key) const;
bool exist(size_t pos) const;
value_type type() const noexcept { return _type; }
const value &at(size_t pos) const;
const value &at(const std::string &key) const;
template<typename Type>
decltype(auto) get(const std::string& key, Type default_value) {
return is_object() ? as_object().get(key, default_value) : default_value;
}
template<typename Type>
decltype(auto) get(size_t pos, Type default_value) {
return is_array() ? as_array().get(pos, default_value) : default_value;
}
const bool as_boolean() const;
const int as_integer() const;
// const unsigned as_unsigned() const;
const long as_long() const;
const unsigned long as_unsigned_long() const;
const long long as_long_long() const;
const unsigned long long as_unsigned_long_long() const;
const float as_float() const;
const double as_double() const;
const long double as_long_double() const;
const std::string as_string() const;
const array & as_array() const;
const object & as_object() const;
array& as_array();
object& as_object();
// return raw string
const std::string to_string() const;
const std::string format(std::string shift_str = " ", size_t basic_shift_count = 0) const;
value &operator=(const value &rhs);
value &operator=(value &&) noexcept;
const value &operator[](size_t pos) const;
value &operator[](size_t pos);
value &operator[](const std::string &key);
value &operator[](std::string &&key);
explicit operator bool() const noexcept { return valid(); }
private:
template <typename T>
static std::unique_ptr<T> copy_unique_ptr(const std::unique_ptr<T> &t)
{
return t == nullptr ? nullptr : std::make_unique<T>(*t);
}
value_type _type = value_type::Null;
std::string _raw_data = "null"; // If the value_type is Object or Array, the _raw_data will be a empty string.
unique_array _array_ptr;
unique_object _object_ptr;
};
const value invalid_value();
std::ostream &operator<<(std::ostream &out, const value &val);
// std::istream &operator>>(std::istream &in, value &val);
} // namespace json

View File

@@ -0,0 +1,73 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_CV_H
#define OPENCV_OLD_CV_H
#if defined(_MSC_VER)
#define CV_DO_PRAGMA(x) __pragma(x)
#define __CVSTR2__(x) #x
#define __CVSTR1__(x) __CVSTR2__(x)
#define __CVMSVCLOC__ __FILE__ "("__CVSTR1__(__LINE__)") : "
#define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (__CVMSVCLOC__ _msg))
#elif defined(__GNUC__)
#define CV_DO_PRAGMA(x) _Pragma (#x)
#define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (_msg))
#else
#define CV_DO_PRAGMA(x)
#define CV_MSG_PRAGMA(_msg)
#endif
#define CV_WARNING(x) CV_MSG_PRAGMA("Warning: " #x)
//CV_WARNING("This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module")
#include "opencv2/core/core_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/photo/photo_c.h"
#include "opencv2/video/tracking_c.h"
#include "opencv2/objdetect/objdetect_c.h"
#if !defined(CV_IMPL)
#define CV_IMPL extern "C"
#endif //CV_IMPL
#endif // __OPENCV_OLD_CV_H_

View File

@@ -0,0 +1,60 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_CV_HPP
#define OPENCV_OLD_CV_HPP
//#if defined(__GNUC__)
//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
//#endif
#include "cv.h"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/video.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/calib3d.hpp"
#include "opencv2/objdetect.hpp"
#endif

View File

@@ -0,0 +1,57 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_AUX_H
#define OPENCV_OLD_AUX_H
//#if defined(__GNUC__)
//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
//#endif
#include "opencv2/core/core_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/photo/photo_c.h"
#include "opencv2/video/tracking_c.h"
#include "opencv2/objdetect/objdetect_c.h"
#endif
/* End of file. */

View File

@@ -0,0 +1,52 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_AUX_HPP
#define OPENCV_OLD_AUX_HPP
//#if defined(__GNUC__)
//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
//#endif
#include "cvaux.h"
#include "opencv2/core/utility.hpp"
#endif

View File

@@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////////
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to
// this license. If you do not agree to this license, do not download,
// install, copy or use the software.
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2008, Google, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation or contributors may not be used to endorse
// or promote products derived from this software without specific
// prior written permission.
//
// This software is provided by the copyright holders and contributors "as is"
// and any express or implied warranties, including, but not limited to, the
// implied warranties of merchantability and fitness for a particular purpose
// are disclaimed. In no event shall the Intel Corporation or contributors be
// liable for any direct, indirect, incidental, special, exemplary, or
// consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
#ifndef OPENCV_OLD_WIMAGE_HPP
#define OPENCV_OLD_WIMAGE_HPP
#include "opencv2/core/wimage.hpp"
#endif

View File

@@ -0,0 +1,52 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_CXCORE_H
#define OPENCV_OLD_CXCORE_H
//#if defined(__GNUC__)
//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
//#endif
#include "opencv2/core/core_c.h"
#endif

View File

@@ -0,0 +1,53 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_CXCORE_HPP
#define OPENCV_OLD_CXCORE_HPP
//#if defined(__GNUC__)
//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
//#endif
#include "cxcore.h"
#include "opencv2/core.hpp"
#endif

View File

@@ -0,0 +1,48 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_EIGEN_HPP
#define OPENCV_OLD_EIGEN_HPP
#include "opencv2/core/eigen.hpp"
#endif

View File

@@ -0,0 +1,8 @@
#ifndef OPENCV_OLD_CXMISC_H
#define OPENCV_OLD_CXMISC_H
#ifdef __cplusplus
# include "opencv2/core/utility.hpp"
#endif
#endif

View File

@@ -0,0 +1,48 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_HIGHGUI_H
#define OPENCV_OLD_HIGHGUI_H
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#endif

View File

@@ -0,0 +1,47 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_OLD_ML_H
#define OPENCV_OLD_ML_H
#include "opencv2/core/core_c.h"
#include "opencv2/ml.hpp"
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifdef __OPENCV_BUILD
#error this is a compatibility header which should not be used inside the OpenCV library
#endif
#include "opencv2/calib3d.hpp"

View File

@@ -0,0 +1,427 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_CALIB3D_C_H
#define OPENCV_CALIB3D_C_H
#include "opencv2/core/core_c.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup calib3d_c
@{
*/
/****************************************************************************************\
* Camera Calibration, Pose Estimation and Stereo *
\****************************************************************************************/
typedef struct CvPOSITObject CvPOSITObject;
/* Allocates and initializes CvPOSITObject structure before doing cvPOSIT */
CVAPI(CvPOSITObject*) cvCreatePOSITObject( CvPoint3D32f* points, int point_count );
/* Runs POSIT (POSe from ITeration) algorithm for determining 3d position of
an object given its model and projection in a weak-perspective case */
CVAPI(void) cvPOSIT( CvPOSITObject* posit_object, CvPoint2D32f* image_points,
double focal_length, CvTermCriteria criteria,
float* rotation_matrix, float* translation_vector);
/* Releases CvPOSITObject structure */
CVAPI(void) cvReleasePOSITObject( CvPOSITObject** posit_object );
/* updates the number of RANSAC iterations */
CVAPI(int) cvRANSACUpdateNumIters( double p, double err_prob,
int model_points, int max_iters );
CVAPI(void) cvConvertPointsHomogeneous( const CvMat* src, CvMat* dst );
/* Calculates fundamental matrix given a set of corresponding points */
#define CV_FM_7POINT 1
#define CV_FM_8POINT 2
#define CV_LMEDS 4
#define CV_RANSAC 8
#define CV_FM_LMEDS_ONLY CV_LMEDS
#define CV_FM_RANSAC_ONLY CV_RANSAC
#define CV_FM_LMEDS CV_LMEDS
#define CV_FM_RANSAC CV_RANSAC
enum
{
CV_ITERATIVE = 0,
CV_EPNP = 1, // F.Moreno-Noguer, V.Lepetit and P.Fua "EPnP: Efficient Perspective-n-Point Camera Pose Estimation"
CV_P3P = 2, // X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang; "Complete Solution Classification for the Perspective-Three-Point Problem"
CV_DLS = 3 // Joel A. Hesch and Stergios I. Roumeliotis. "A Direct Least-Squares (DLS) Method for PnP"
};
CVAPI(int) cvFindFundamentalMat( const CvMat* points1, const CvMat* points2,
CvMat* fundamental_matrix,
int method CV_DEFAULT(CV_FM_RANSAC),
double param1 CV_DEFAULT(3.), double param2 CV_DEFAULT(0.99),
CvMat* status CV_DEFAULT(NULL) );
/* For each input point on one of images
computes parameters of the corresponding
epipolar line on the other image */
CVAPI(void) cvComputeCorrespondEpilines( const CvMat* points,
int which_image,
const CvMat* fundamental_matrix,
CvMat* correspondent_lines );
/* Triangulation functions */
CVAPI(void) cvTriangulatePoints(CvMat* projMatr1, CvMat* projMatr2,
CvMat* projPoints1, CvMat* projPoints2,
CvMat* points4D);
CVAPI(void) cvCorrectMatches(CvMat* F, CvMat* points1, CvMat* points2,
CvMat* new_points1, CvMat* new_points2);
/* Computes the optimal new camera matrix according to the free scaling parameter alpha:
alpha=0 - only valid pixels will be retained in the undistorted image
alpha=1 - all the source image pixels will be retained in the undistorted image
*/
CVAPI(void) cvGetOptimalNewCameraMatrix( const CvMat* camera_matrix,
const CvMat* dist_coeffs,
CvSize image_size, double alpha,
CvMat* new_camera_matrix,
CvSize new_imag_size CV_DEFAULT(cvSize(0,0)),
CvRect* valid_pixel_ROI CV_DEFAULT(0),
int center_principal_point CV_DEFAULT(0));
/* Converts rotation vector to rotation matrix or vice versa */
CVAPI(int) cvRodrigues2( const CvMat* src, CvMat* dst,
CvMat* jacobian CV_DEFAULT(0) );
/* Finds perspective transformation between the object plane and image (view) plane */
CVAPI(int) cvFindHomography( const CvMat* src_points,
const CvMat* dst_points,
CvMat* homography,
int method CV_DEFAULT(0),
double ransacReprojThreshold CV_DEFAULT(3),
CvMat* mask CV_DEFAULT(0),
int maxIters CV_DEFAULT(2000),
double confidence CV_DEFAULT(0.995));
/* Computes RQ decomposition for 3x3 matrices */
CVAPI(void) cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ,
CvMat *matrixQx CV_DEFAULT(NULL),
CvMat *matrixQy CV_DEFAULT(NULL),
CvMat *matrixQz CV_DEFAULT(NULL),
CvPoint3D64f *eulerAngles CV_DEFAULT(NULL));
/* Computes projection matrix decomposition */
CVAPI(void) cvDecomposeProjectionMatrix( const CvMat *projMatr, CvMat *calibMatr,
CvMat *rotMatr, CvMat *posVect,
CvMat *rotMatrX CV_DEFAULT(NULL),
CvMat *rotMatrY CV_DEFAULT(NULL),
CvMat *rotMatrZ CV_DEFAULT(NULL),
CvPoint3D64f *eulerAngles CV_DEFAULT(NULL));
/* Computes d(AB)/dA and d(AB)/dB */
CVAPI(void) cvCalcMatMulDeriv( const CvMat* A, const CvMat* B, CvMat* dABdA, CvMat* dABdB );
/* Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
t3 = rodrigues(r2)*t1 + t2 and the respective derivatives */
CVAPI(void) cvComposeRT( const CvMat* _rvec1, const CvMat* _tvec1,
const CvMat* _rvec2, const CvMat* _tvec2,
CvMat* _rvec3, CvMat* _tvec3,
CvMat* dr3dr1 CV_DEFAULT(0), CvMat* dr3dt1 CV_DEFAULT(0),
CvMat* dr3dr2 CV_DEFAULT(0), CvMat* dr3dt2 CV_DEFAULT(0),
CvMat* dt3dr1 CV_DEFAULT(0), CvMat* dt3dt1 CV_DEFAULT(0),
CvMat* dt3dr2 CV_DEFAULT(0), CvMat* dt3dt2 CV_DEFAULT(0) );
/* Projects object points to the view plane using
the specified extrinsic and intrinsic camera parameters */
CVAPI(void) cvProjectPoints2( const CvMat* object_points, const CvMat* rotation_vector,
const CvMat* translation_vector, const CvMat* camera_matrix,
const CvMat* distortion_coeffs, CvMat* image_points,
CvMat* dpdrot CV_DEFAULT(NULL), CvMat* dpdt CV_DEFAULT(NULL),
CvMat* dpdf CV_DEFAULT(NULL), CvMat* dpdc CV_DEFAULT(NULL),
CvMat* dpddist CV_DEFAULT(NULL),
double aspect_ratio CV_DEFAULT(0));
/* Finds extrinsic camera parameters from
a few known corresponding point pairs and intrinsic parameters */
CVAPI(void) cvFindExtrinsicCameraParams2( const CvMat* object_points,
const CvMat* image_points,
const CvMat* camera_matrix,
const CvMat* distortion_coeffs,
CvMat* rotation_vector,
CvMat* translation_vector,
int use_extrinsic_guess CV_DEFAULT(0) );
/* Computes initial estimate of the intrinsic camera parameters
in case of planar calibration target (e.g. chessboard) */
CVAPI(void) cvInitIntrinsicParams2D( const CvMat* object_points,
const CvMat* image_points,
const CvMat* npoints, CvSize image_size,
CvMat* camera_matrix,
double aspect_ratio CV_DEFAULT(1.) );
#define CV_CALIB_CB_ADAPTIVE_THRESH 1
#define CV_CALIB_CB_NORMALIZE_IMAGE 2
#define CV_CALIB_CB_FILTER_QUADS 4
#define CV_CALIB_CB_FAST_CHECK 8
// Performs a fast check if a chessboard is in the input image. This is a workaround to
// a problem of cvFindChessboardCorners being slow on images with no chessboard
// - src: input image
// - size: chessboard size
// Returns 1 if a chessboard can be in this image and findChessboardCorners should be called,
// 0 if there is no chessboard, -1 in case of error
CVAPI(int) cvCheckChessboard(IplImage* src, CvSize size);
/* Detects corners on a chessboard calibration pattern */
CVAPI(int) cvFindChessboardCorners( const void* image, CvSize pattern_size,
CvPoint2D32f* corners,
int* corner_count CV_DEFAULT(NULL),
int flags CV_DEFAULT(CV_CALIB_CB_ADAPTIVE_THRESH+CV_CALIB_CB_NORMALIZE_IMAGE) );
/* Draws individual chessboard corners or the whole chessboard detected */
CVAPI(void) cvDrawChessboardCorners( CvArr* image, CvSize pattern_size,
CvPoint2D32f* corners,
int count, int pattern_was_found );
#define CV_CALIB_USE_INTRINSIC_GUESS 1
#define CV_CALIB_FIX_ASPECT_RATIO 2
#define CV_CALIB_FIX_PRINCIPAL_POINT 4
#define CV_CALIB_ZERO_TANGENT_DIST 8
#define CV_CALIB_FIX_FOCAL_LENGTH 16
#define CV_CALIB_FIX_K1 32
#define CV_CALIB_FIX_K2 64
#define CV_CALIB_FIX_K3 128
#define CV_CALIB_FIX_K4 2048
#define CV_CALIB_FIX_K5 4096
#define CV_CALIB_FIX_K6 8192
#define CV_CALIB_RATIONAL_MODEL 16384
#define CV_CALIB_THIN_PRISM_MODEL 32768
#define CV_CALIB_FIX_S1_S2_S3_S4 65536
#define CV_CALIB_TILTED_MODEL 262144
#define CV_CALIB_FIX_TAUX_TAUY 524288
#define CV_CALIB_FIX_TANGENT_DIST 2097152
#define CV_CALIB_NINTRINSIC 18
/* Finds intrinsic and extrinsic camera parameters
from a few views of known calibration pattern */
CVAPI(double) cvCalibrateCamera2( const CvMat* object_points,
const CvMat* image_points,
const CvMat* point_counts,
CvSize image_size,
CvMat* camera_matrix,
CvMat* distortion_coeffs,
CvMat* rotation_vectors CV_DEFAULT(NULL),
CvMat* translation_vectors CV_DEFAULT(NULL),
int flags CV_DEFAULT(0),
CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria(
CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,DBL_EPSILON)) );
/* Computes various useful characteristics of the camera from the data computed by
cvCalibrateCamera2 */
CVAPI(void) cvCalibrationMatrixValues( const CvMat *camera_matrix,
CvSize image_size,
double aperture_width CV_DEFAULT(0),
double aperture_height CV_DEFAULT(0),
double *fovx CV_DEFAULT(NULL),
double *fovy CV_DEFAULT(NULL),
double *focal_length CV_DEFAULT(NULL),
CvPoint2D64f *principal_point CV_DEFAULT(NULL),
double *pixel_aspect_ratio CV_DEFAULT(NULL));
#define CV_CALIB_FIX_INTRINSIC 256
#define CV_CALIB_SAME_FOCAL_LENGTH 512
/* Computes the transformation from one camera coordinate system to another one
from a few correspondent views of the same calibration target. Optionally, calibrates
both cameras */
CVAPI(double) cvStereoCalibrate( const CvMat* object_points, const CvMat* image_points1,
const CvMat* image_points2, const CvMat* npoints,
CvMat* camera_matrix1, CvMat* dist_coeffs1,
CvMat* camera_matrix2, CvMat* dist_coeffs2,
CvSize image_size, CvMat* R, CvMat* T,
CvMat* E CV_DEFAULT(0), CvMat* F CV_DEFAULT(0),
int flags CV_DEFAULT(CV_CALIB_FIX_INTRINSIC),
CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria(
CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,1e-6)) );
#define CV_CALIB_ZERO_DISPARITY 1024
/* Computes 3D rotations (+ optional shift) for each camera coordinate system to make both
views parallel (=> to make all the epipolar lines horizontal or vertical) */
CVAPI(void) cvStereoRectify( const CvMat* camera_matrix1, const CvMat* camera_matrix2,
const CvMat* dist_coeffs1, const CvMat* dist_coeffs2,
CvSize image_size, const CvMat* R, const CvMat* T,
CvMat* R1, CvMat* R2, CvMat* P1, CvMat* P2,
CvMat* Q CV_DEFAULT(0),
int flags CV_DEFAULT(CV_CALIB_ZERO_DISPARITY),
double alpha CV_DEFAULT(-1),
CvSize new_image_size CV_DEFAULT(cvSize(0,0)),
CvRect* valid_pix_ROI1 CV_DEFAULT(0),
CvRect* valid_pix_ROI2 CV_DEFAULT(0));
/* Computes rectification transformations for uncalibrated pair of images using a set
of point correspondences */
CVAPI(int) cvStereoRectifyUncalibrated( const CvMat* points1, const CvMat* points2,
const CvMat* F, CvSize img_size,
CvMat* H1, CvMat* H2,
double threshold CV_DEFAULT(5));
/* stereo correspondence parameters and functions */
#define CV_STEREO_BM_NORMALIZED_RESPONSE 0
#define CV_STEREO_BM_XSOBEL 1
/* Block matching algorithm structure */
typedef struct CvStereoBMState
{
// pre-filtering (normalization of input images)
int preFilterType; // =CV_STEREO_BM_NORMALIZED_RESPONSE now
int preFilterSize; // averaging window size: ~5x5..21x21
int preFilterCap; // the output of pre-filtering is clipped by [-preFilterCap,preFilterCap]
// correspondence using Sum of Absolute Difference (SAD)
int SADWindowSize; // ~5x5..21x21
int minDisparity; // minimum disparity (can be negative)
int numberOfDisparities; // maximum disparity - minimum disparity (> 0)
// post-filtering
int textureThreshold; // the disparity is only computed for pixels
// with textured enough neighborhood
int uniquenessRatio; // accept the computed disparity d* only if
// SAD(d) >= SAD(d*)*(1 + uniquenessRatio/100.)
// for any d != d*+/-1 within the search range.
int speckleWindowSize; // disparity variation window
int speckleRange; // acceptable range of variation in window
int trySmallerWindows; // if 1, the results may be more accurate,
// at the expense of slower processing
CvRect roi1, roi2;
int disp12MaxDiff;
// temporary buffers
CvMat* preFilteredImg0;
CvMat* preFilteredImg1;
CvMat* slidingSumBuf;
CvMat* cost;
CvMat* disp;
} CvStereoBMState;
#define CV_STEREO_BM_BASIC 0
#define CV_STEREO_BM_FISH_EYE 1
#define CV_STEREO_BM_NARROW 2
CVAPI(CvStereoBMState*) cvCreateStereoBMState(int preset CV_DEFAULT(CV_STEREO_BM_BASIC),
int numberOfDisparities CV_DEFAULT(0));
CVAPI(void) cvReleaseStereoBMState( CvStereoBMState** state );
CVAPI(void) cvFindStereoCorrespondenceBM( const CvArr* left, const CvArr* right,
CvArr* disparity, CvStereoBMState* state );
CVAPI(CvRect) cvGetValidDisparityROI( CvRect roi1, CvRect roi2, int minDisparity,
int numberOfDisparities, int SADWindowSize );
CVAPI(void) cvValidateDisparity( CvArr* disparity, const CvArr* cost,
int minDisparity, int numberOfDisparities,
int disp12MaxDiff CV_DEFAULT(1) );
/* Reprojects the computed disparity image to the 3D space using the specified 4x4 matrix */
CVAPI(void) cvReprojectImageTo3D( const CvArr* disparityImage,
CvArr* _3dImage, const CvMat* Q,
int handleMissingValues CV_DEFAULT(0) );
/** @} calib3d_c */
#ifdef __cplusplus
} // extern "C"
//////////////////////////////////////////////////////////////////////////////////////////
class CV_EXPORTS CvLevMarq
{
public:
CvLevMarq();
CvLevMarq( int nparams, int nerrs, CvTermCriteria criteria=
cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
bool completeSymmFlag=false );
~CvLevMarq();
void init( int nparams, int nerrs, CvTermCriteria criteria=
cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
bool completeSymmFlag=false );
bool update( const CvMat*& param, CvMat*& J, CvMat*& err );
bool updateAlt( const CvMat*& param, CvMat*& JtJ, CvMat*& JtErr, double*& errNorm );
void clear();
void step();
enum { DONE=0, STARTED=1, CALC_J=2, CHECK_ERR=3 };
cv::Ptr<CvMat> mask;
cv::Ptr<CvMat> prevParam;
cv::Ptr<CvMat> param;
cv::Ptr<CvMat> J;
cv::Ptr<CvMat> err;
cv::Ptr<CvMat> JtJ;
cv::Ptr<CvMat> JtJN;
cv::Ptr<CvMat> JtErr;
cv::Ptr<CvMat> JtJV;
cv::Ptr<CvMat> JtJW;
double prevErrNorm, errNorm;
int lambdaLg10;
CvTermCriteria criteria;
int state;
int iters;
bool completeSymmFlag;
int solveMethod;
};
#endif
#endif /* OPENCV_CALIB3D_C_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,678 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_CORE_AFFINE3_HPP
#define OPENCV_CORE_AFFINE3_HPP
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv
{
//! @addtogroup core
//! @{
/** @brief Affine transform
*
* It represents a 4x4 homogeneous transformation matrix \f$T\f$
*
* \f[T =
* \begin{bmatrix}
* R & t\\
* 0 & 1\\
* \end{bmatrix}
* \f]
*
* where \f$R\f$ is a 3x3 rotation matrix and \f$t\f$ is a 3x1 translation vector.
*
* You can specify \f$R\f$ either by a 3x3 rotation matrix or by a 3x1 rotation vector,
* which is converted to a 3x3 rotation matrix by the Rodrigues formula.
*
* To construct a matrix \f$T\f$ representing first rotation around the axis \f$r\f$ with rotation
* angle \f$|r|\f$ in radian (right hand rule) and then translation by the vector \f$t\f$, you can use
*
* @code
* cv::Vec3f r, t;
* cv::Affine3f T(r, t);
* @endcode
*
* If you already have the rotation matrix \f$R\f$, then you can use
*
* @code
* cv::Matx33f R;
* cv::Affine3f T(R, t);
* @endcode
*
* To extract the rotation matrix \f$R\f$ from \f$T\f$, use
*
* @code
* cv::Matx33f R = T.rotation();
* @endcode
*
* To extract the translation vector \f$t\f$ from \f$T\f$, use
*
* @code
* cv::Vec3f t = T.translation();
* @endcode
*
* To extract the rotation vector \f$r\f$ from \f$T\f$, use
*
* @code
* cv::Vec3f r = T.rvec();
* @endcode
*
* Note that since the mapping from rotation vectors to rotation matrices
* is many to one. The returned rotation vector is not necessarily the one
* you used before to set the matrix.
*
* If you have two transformations \f$T = T_1 * T_2\f$, use
*
* @code
* cv::Affine3f T, T1, T2;
* T = T2.concatenate(T1);
* @endcode
*
* To get the inverse transform of \f$T\f$, use
*
* @code
* cv::Affine3f T, T_inv;
* T_inv = T.inv();
* @endcode
*
*/
template<typename T>
class Affine3
{
public:
typedef T float_type;
typedef Matx<float_type, 3, 3> Mat3;
typedef Matx<float_type, 4, 4> Mat4;
typedef Vec<float_type, 3> Vec3;
//! Default constructor. It represents a 4x4 identity matrix.
Affine3();
//! Augmented affine matrix
Affine3(const Mat4& affine);
/**
* The resulting 4x4 matrix is
*
* \f[
* \begin{bmatrix}
* R & t\\
* 0 & 1\\
* \end{bmatrix}
* \f]
*
* @param R 3x3 rotation matrix.
* @param t 3x1 translation vector.
*/
Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
/**
* Rodrigues vector.
*
* The last row of the current matrix is set to [0,0,0,1].
*
* @param rvec 3x1 rotation vector. Its direction indicates the rotation axis and its length
* indicates the rotation angle in radian (using right hand rule).
* @param t 3x1 translation vector.
*/
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
/**
* Combines all constructors above. Supports 4x4, 3x4, 3x3, 1x3, 3x1 sizes of data matrix.
*
* The last row of the current matrix is set to [0,0,0,1] when data is not 4x4.
*
* @param data 1-channel matrix.
* when it is 4x4, it is copied to the current matrix and t is not used.
* When it is 3x4, it is copied to the upper part 3x4 of the current matrix and t is not used.
* When it is 3x3, it is copied to the upper left 3x3 part of the current matrix.
* When it is 3x1 or 1x3, it is treated as a rotation vector and the Rodrigues formula is used
* to compute a 3x3 rotation matrix.
* @param t 3x1 translation vector. It is used only when data is neither 4x4 nor 3x4.
*/
explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
//! From 16-element array
explicit Affine3(const float_type* vals);
//! Create an 4x4 identity transform
static Affine3 Identity();
/**
* Rotation matrix.
*
* Copy the rotation matrix to the upper left 3x3 part of the current matrix.
* The remaining elements of the current matrix are not changed.
*
* @param R 3x3 rotation matrix.
*
*/
void rotation(const Mat3& R);
/**
* Rodrigues vector.
*
* It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
*
* @param rvec 3x1 rotation vector. The direction indicates the rotation axis and
* its length indicates the rotation angle in radian (using the right thumb convention).
*/
void rotation(const Vec3& rvec);
/**
* Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix.
*
* It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
*
* @param data 1-channel matrix.
* When it is a 3x3 matrix, it sets the upper left 3x3 part of the current matrix.
* When it is a 1x3 or 3x1 matrix, it is used as a rotation vector. The Rodrigues formula
* is used to compute the rotation matrix and sets the upper left 3x3 part of the current matrix.
*/
void rotation(const Mat& data);
/**
* Copy the 3x3 matrix L to the upper left part of the current matrix
*
* It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
*
* @param L 3x3 matrix.
*/
void linear(const Mat3& L);
/**
* Copy t to the first three elements of the last column of the current matrix
*
* It sets the upper right 3x1 part of the matrix. The remaining part is unaffected.
*
* @param t 3x1 translation vector.
*/
void translation(const Vec3& t);
//! @return the upper left 3x3 part
Mat3 rotation() const;
//! @return the upper left 3x3 part
Mat3 linear() const;
//! @return the upper right 3x1 part
Vec3 translation() const;
//! Rodrigues vector.
//! @return a vector representing the upper left 3x3 rotation matrix of the current matrix.
//! @warning Since the mapping between rotation vectors and rotation matrices is many to one,
//! this function returns only one rotation vector that represents the current rotation matrix,
//! which is not necessarily the same one set by `rotation(const Vec3& rvec)`.
Vec3 rvec() const;
//! @return the inverse of the current matrix.
Affine3 inv(int method = cv::DECOMP_SVD) const;
//! a.rotate(R) is equivalent to Affine(R, 0) * a;
Affine3 rotate(const Mat3& R) const;
//! a.rotate(rvec) is equivalent to Affine(rvec, 0) * a;
Affine3 rotate(const Vec3& rvec) const;
//! a.translate(t) is equivalent to Affine(E, t) * a, where E is an identity matrix
Affine3 translate(const Vec3& t) const;
//! a.concatenate(affine) is equivalent to affine * a;
Affine3 concatenate(const Affine3& affine) const;
template <typename Y> operator Affine3<Y>() const;
template <typename Y> Affine3<Y> cast() const;
Mat4 matrix;
#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine);
Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine);
operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const;
operator Eigen::Transform<T, 3, Eigen::Affine>() const;
#endif
};
template<typename T> static
Affine3<T> operator*(const Affine3<T>& affine1, const Affine3<T>& affine2);
//! V is a 3-element vector with member fields x, y and z
template<typename T, typename V> static
V operator*(const Affine3<T>& affine, const V& vector);
typedef Affine3<float> Affine3f;
typedef Affine3<double> Affine3d;
static Vec3f operator*(const Affine3f& affine, const Vec3f& vector);
static Vec3d operator*(const Affine3d& affine, const Vec3d& vector);
template<typename _Tp> class DataType< Affine3<_Tp> >
{
public:
typedef Affine3<_Tp> value_type;
typedef Affine3<typename DataType<_Tp>::work_type> work_type;
typedef _Tp channel_type;
enum { generic_type = 0,
channels = 16,
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
,depth = DataType<channel_type>::depth
,type = CV_MAKETYPE(depth, channels)
#endif
};
typedef Vec<channel_type, channels> vec_type;
};
namespace traits {
template<typename _Tp>
struct Depth< Affine3<_Tp> > { enum { value = Depth<_Tp>::value }; };
template<typename _Tp>
struct Type< Affine3<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 16) }; };
} // namespace
//! @} core
}
//! @cond IGNORED
///////////////////////////////////////////////////////////////////////////////////
// Implementation
template<typename T> inline
cv::Affine3<T>::Affine3()
: matrix(Mat4::eye())
{}
template<typename T> inline
cv::Affine3<T>::Affine3(const Mat4& affine)
: matrix(affine)
{}
template<typename T> inline
cv::Affine3<T>::Affine3(const Mat3& R, const Vec3& t)
{
rotation(R);
translation(t);
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
matrix.val[15] = 1;
}
template<typename T> inline
cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t)
{
rotation(_rvec);
translation(t);
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
matrix.val[15] = 1;
}
template<typename T> inline
cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
{
CV_Assert(data.type() == cv::traits::Type<T>::value);
CV_Assert(data.channels() == 1);
if (data.cols == 4 && data.rows == 4)
{
data.copyTo(matrix);
return;
}
else if (data.cols == 4 && data.rows == 3)
{
rotation(data(Rect(0, 0, 3, 3)));
translation(data(Rect(3, 0, 1, 3)));
}
else
{
rotation(data);
translation(t);
}
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
matrix.val[15] = 1;
}
template<typename T> inline
cv::Affine3<T>::Affine3(const float_type* vals) : matrix(vals)
{}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::Identity()
{
return Affine3<T>(cv::Affine3<T>::Mat4::eye());
}
template<typename T> inline
void cv::Affine3<T>::rotation(const Mat3& R)
{
linear(R);
}
template<typename T> inline
void cv::Affine3<T>::rotation(const Vec3& _rvec)
{
double theta = norm(_rvec);
if (theta < DBL_EPSILON)
rotation(Mat3::eye());
else
{
double c = std::cos(theta);
double s = std::sin(theta);
double c1 = 1. - c;
double itheta = (theta != 0) ? 1./theta : 0.;
Point3_<T> r = _rvec*itheta;
Mat3 rrt( r.x*r.x, r.x*r.y, r.x*r.z, r.x*r.y, r.y*r.y, r.y*r.z, r.x*r.z, r.y*r.z, r.z*r.z );
Mat3 r_x( 0, -r.z, r.y, r.z, 0, -r.x, -r.y, r.x, 0 );
// R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
// where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
Mat3 R = c*Mat3::eye() + c1*rrt + s*r_x;
rotation(R);
}
}
//Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix;
template<typename T> inline
void cv::Affine3<T>::rotation(const cv::Mat& data)
{
CV_Assert(data.type() == cv::traits::Type<T>::value);
CV_Assert(data.channels() == 1);
if (data.cols == 3 && data.rows == 3)
{
Mat3 R;
data.copyTo(R);
rotation(R);
}
else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3))
{
Vec3 _rvec;
data.reshape(1, 3).copyTo(_rvec);
rotation(_rvec);
}
else
CV_Error(Error::StsError, "Input matrix can only be 3x3, 1x3 or 3x1");
}
template<typename T> inline
void cv::Affine3<T>::linear(const Mat3& L)
{
matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2];
matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5];
matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8];
}
template<typename T> inline
void cv::Affine3<T>::translation(const Vec3& t)
{
matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2];
}
template<typename T> inline
typename cv::Affine3<T>::Mat3 cv::Affine3<T>::rotation() const
{
return linear();
}
template<typename T> inline
typename cv::Affine3<T>::Mat3 cv::Affine3<T>::linear() const
{
typename cv::Affine3<T>::Mat3 R;
R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2];
R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6];
R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10];
return R;
}
template<typename T> inline
typename cv::Affine3<T>::Vec3 cv::Affine3<T>::translation() const
{
return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]);
}
template<typename T> inline
typename cv::Affine3<T>::Vec3 cv::Affine3<T>::rvec() const
{
cv::Vec3d w;
cv::Matx33d u, vt, R = rotation();
cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
R = u * vt;
double rx = R.val[7] - R.val[5];
double ry = R.val[2] - R.val[6];
double rz = R.val[3] - R.val[1];
double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25);
double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5;
c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c;
double theta = acos(c);
if( s < 1e-5 )
{
if( c > 0 )
rx = ry = rz = 0;
else
{
double t;
t = (R.val[0] + 1) * 0.5;
rx = std::sqrt(std::max(t, 0.0));
t = (R.val[4] + 1) * 0.5;
ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0);
t = (R.val[8] + 1) * 0.5;
rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0);
if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) )
rz = -rz;
theta /= std::sqrt(rx*rx + ry*ry + rz*rz);
rx *= theta;
ry *= theta;
rz *= theta;
}
}
else
{
double vth = 1/(2*s);
vth *= theta;
rx *= vth; ry *= vth; rz *= vth;
}
return cv::Vec3d(rx, ry, rz);
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::inv(int method) const
{
return matrix.inv(method);
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::rotate(const Mat3& R) const
{
Mat3 Lc = linear();
Vec3 tc = translation();
Mat4 result;
result.val[12] = result.val[13] = result.val[14] = 0;
result.val[15] = 1;
for(int j = 0; j < 3; ++j)
{
for(int i = 0; i < 3; ++i)
{
float_type value = 0;
for(int k = 0; k < 3; ++k)
value += R(j, k) * Lc(k, i);
result(j, i) = value;
}
result(j, 3) = R.row(j).dot(tc.t());
}
return result;
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::rotate(const Vec3& _rvec) const
{
return rotate(Affine3f(_rvec).rotation());
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::translate(const Vec3& t) const
{
Mat4 m = matrix;
m.val[ 3] += t[0];
m.val[ 7] += t[1];
m.val[11] += t[2];
return m;
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::concatenate(const Affine3<T>& affine) const
{
return (*this).rotate(affine.rotation()).translate(affine.translation());
}
template<typename T> template <typename Y> inline
cv::Affine3<T>::operator Affine3<Y>() const
{
return Affine3<Y>(matrix);
}
template<typename T> template <typename Y> inline
cv::Affine3<Y> cv::Affine3<T>::cast() const
{
return Affine3<Y>(matrix);
}
template<typename T> inline
cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2)
{
return affine2.concatenate(affine1);
}
template<typename T, typename V> inline
V cv::operator*(const cv::Affine3<T>& affine, const V& v)
{
const typename Affine3<T>::Mat4& m = affine.matrix;
V r;
r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3];
r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7];
r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11];
return r;
}
static inline
cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v)
{
const cv::Matx44f& m = affine.matrix;
cv::Vec3f r;
r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
return r;
}
static inline
cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v)
{
const cv::Matx44d& m = affine.matrix;
cv::Vec3d r;
r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3];
r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7];
r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11];
return r;
}
#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
template<typename T> inline
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine)
{
cv::Mat(4, 4, cv::traits::Type<T>::value, affine.matrix().data()).copyTo(matrix);
}
template<typename T> inline
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine)
{
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> a = affine;
cv::Mat(4, 4, cv::traits::Type<T>::value, a.matrix().data()).copyTo(matrix);
}
template<typename T> inline
cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const
{
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r;
cv::Mat hdr(4, 4, cv::traits::Type<T>::value, r.matrix().data());
cv::Mat(matrix, false).copyTo(hdr);
return r;
}
template<typename T> inline
cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const
{
return this->operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>();
}
#endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */
//! @endcond
#endif /* __cplusplus */
#endif /* OPENCV_CORE_AFFINE3_HPP */

View File

@@ -0,0 +1,105 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_CORE_ASYNC_HPP
#define OPENCV_CORE_ASYNC_HPP
#include <opencv2/core/mat.hpp>
#ifdef CV_CXX11
//#include <future>
#include <chrono>
#endif
namespace cv {
/** @addtogroup core_async
@{
*/
/** @brief Returns result of asynchronous operations
Object has attached asynchronous state.
Assignment operator doesn't clone asynchronous state (it is shared between all instances).
Result can be fetched via get() method only once.
*/
class CV_EXPORTS_W AsyncArray
{
public:
~AsyncArray() CV_NOEXCEPT;
CV_WRAP AsyncArray() CV_NOEXCEPT;
AsyncArray(const AsyncArray& o) CV_NOEXCEPT;
AsyncArray& operator=(const AsyncArray& o) CV_NOEXCEPT;
CV_WRAP void release() CV_NOEXCEPT;
/** Fetch the result.
@param[out] dst destination array
Waits for result until container has valid result.
Throws exception if exception was stored as a result.
Throws exception on invalid container state.
@note Result or stored exception can be fetched only once.
*/
CV_WRAP void get(OutputArray dst) const;
/** Retrieving the result with timeout
@param[out] dst destination array
@param[in] timeoutNs timeout in nanoseconds, -1 for infinite wait
@returns true if result is ready, false if the timeout has expired
@note Result or stored exception can be fetched only once.
*/
bool get(OutputArray dst, int64 timeoutNs) const;
CV_WRAP inline
bool get(OutputArray dst, double timeoutNs) const { return get(dst, (int64)timeoutNs); }
bool wait_for(int64 timeoutNs) const;
CV_WRAP inline
bool wait_for(double timeoutNs) const { return wait_for((int64)timeoutNs); }
CV_WRAP bool valid() const CV_NOEXCEPT;
#ifdef CV_CXX11
inline AsyncArray(AsyncArray&& o) { p = o.p; o.p = NULL; }
inline AsyncArray& operator=(AsyncArray&& o) CV_NOEXCEPT { std::swap(p, o.p); return *this; }
template<typename _Rep, typename _Period>
inline bool get(OutputArray dst, const std::chrono::duration<_Rep, _Period>& timeout)
{
return get(dst, (int64)(std::chrono::nanoseconds(timeout).count()));
}
template<typename _Rep, typename _Period>
inline bool wait_for(const std::chrono::duration<_Rep, _Period>& timeout)
{
return wait_for((int64)(std::chrono::nanoseconds(timeout).count()));
}
#if 0
std::future<Mat> getFutureMat() const;
std::future<UMat> getFutureUMat() const;
#endif
#endif
// PImpl
struct Impl; friend struct Impl;
inline void* _getImpl() const CV_NOEXCEPT { return p; }
protected:
Impl* p;
};
//! @}
} // namespace
#endif // OPENCV_CORE_ASYNC_HPP

View File

@@ -0,0 +1,722 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Copyright (C) 2014, Itseez Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_CORE_BASE_HPP
#define OPENCV_CORE_BASE_HPP
#ifndef __cplusplus
# error base.hpp header must be compiled as C++
#endif
#include "opencv2/opencv_modules.hpp"
#include <climits>
#include <algorithm>
#include "opencv2/core/cvdef.h"
#include "opencv2/core/cvstd.hpp"
namespace cv
{
//! @addtogroup core_utils
//! @{
namespace Error {
//! error codes
enum Code {
StsOk= 0, //!< everything is ok
StsBackTrace= -1, //!< pseudo error for back trace
StsError= -2, //!< unknown /unspecified error
StsInternal= -3, //!< internal error (bad state)
StsNoMem= -4, //!< insufficient memory
StsBadArg= -5, //!< function arg/param is bad
StsBadFunc= -6, //!< unsupported function
StsNoConv= -7, //!< iteration didn't converge
StsAutoTrace= -8, //!< tracing
HeaderIsNull= -9, //!< image header is NULL
BadImageSize= -10, //!< image size is invalid
BadOffset= -11, //!< offset is invalid
BadDataPtr= -12, //!<
BadStep= -13, //!< image step is wrong, this may happen for a non-continuous matrix.
BadModelOrChSeq= -14, //!<
BadNumChannels= -15, //!< bad number of channels, for example, some functions accept only single channel matrices.
BadNumChannel1U= -16, //!<
BadDepth= -17, //!< input image depth is not supported by the function
BadAlphaChannel= -18, //!<
BadOrder= -19, //!< number of dimensions is out of range
BadOrigin= -20, //!< incorrect input origin
BadAlign= -21, //!< incorrect input align
BadCallBack= -22, //!<
BadTileSize= -23, //!<
BadCOI= -24, //!< input COI is not supported
BadROISize= -25, //!< incorrect input roi
MaskIsTiled= -26, //!<
StsNullPtr= -27, //!< null pointer
StsVecLengthErr= -28, //!< incorrect vector length
StsFilterStructContentErr= -29, //!< incorrect filter structure content
StsKernelStructContentErr= -30, //!< incorrect transform kernel content
StsFilterOffsetErr= -31, //!< incorrect filter offset value
StsBadSize= -201, //!< the input/output structure size is incorrect
StsDivByZero= -202, //!< division by zero
StsInplaceNotSupported= -203, //!< in-place operation is not supported
StsObjectNotFound= -204, //!< request can't be completed
StsUnmatchedFormats= -205, //!< formats of input/output arrays differ
StsBadFlag= -206, //!< flag is wrong or not supported
StsBadPoint= -207, //!< bad CvPoint
StsBadMask= -208, //!< bad format of mask (neither 8uC1 nor 8sC1)
StsUnmatchedSizes= -209, //!< sizes of input/output structures do not match
StsUnsupportedFormat= -210, //!< the data format/type is not supported by the function
StsOutOfRange= -211, //!< some of parameters are out of range
StsParseError= -212, //!< invalid syntax/structure of the parsed file
StsNotImplemented= -213, //!< the requested function/feature is not implemented
StsBadMemBlock= -214, //!< an allocated block has been corrupted
StsAssert= -215, //!< assertion failed
GpuNotSupported= -216, //!< no CUDA support
GpuApiCallError= -217, //!< GPU API call error
OpenGlNotSupported= -218, //!< no OpenGL support
OpenGlApiCallError= -219, //!< OpenGL API call error
OpenCLApiCallError= -220, //!< OpenCL API call error
OpenCLDoubleNotSupported= -221,
OpenCLInitError= -222, //!< OpenCL initialization error
OpenCLNoAMDBlasFft= -223
};
} //Error
//! @} core_utils
//! @addtogroup core_array
//! @{
//! matrix decomposition types
enum DecompTypes {
/** Gaussian elimination with the optimal pivot element chosen. */
DECOMP_LU = 0,
/** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix
src1 can be singular */
DECOMP_SVD = 1,
/** eigenvalue decomposition; the matrix src1 must be symmetrical */
DECOMP_EIG = 2,
/** Cholesky \f$LL^T\f$ factorization; the matrix src1 must be symmetrical and positively
defined */
DECOMP_CHOLESKY = 3,
/** QR factorization; the system can be over-defined and/or the matrix src1 can be singular */
DECOMP_QR = 4,
/** while all the previous flags are mutually exclusive, this flag can be used together with
any of the previous; it means that the normal equations
\f$\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}\f$ are
solved instead of the original system
\f$\texttt{src1}\cdot\texttt{dst}=\texttt{src2}\f$ */
DECOMP_NORMAL = 16
};
/** norm types
src1 and src2 denote input arrays.
*/
enum NormTypes {
/**
\f[
norm = \forkthree
{\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
{\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_INF}\) }
\f]
*/
NORM_INF = 1,
/**
\f[
norm = \forkthree
{\| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\)}
{ \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L1}\) }
\f]*/
NORM_L1 = 2,
/**
\f[
norm = \forkthree
{ \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }
{ \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }
{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2}\) }
\f]
*/
NORM_L2 = 4,
/**
\f[
norm = \forkthree
{ \| \texttt{src1} \| _{L_2} ^{2} = \sum_I \texttt{src1}(I)^2} {if \(\texttt{normType} = \texttt{NORM_L2SQR}\)}
{ \| \texttt{src1} - \texttt{src2} \| _{L_2} ^{2} = \sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2 }{if \(\texttt{normType} = \texttt{NORM_L2SQR}\) }
{ \left(\frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}}\right)^2 }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2SQR}\) }
\f]
*/
NORM_L2SQR = 5,
/**
In the case of one input array, calculates the Hamming distance of the array from zero,
In the case of two input arrays, calculates the Hamming distance between the arrays.
*/
NORM_HAMMING = 6,
/**
Similar to NORM_HAMMING, but in the calculation, each two bits of the input sequence will
be added and treated as a single bit to be used in the same calculation as NORM_HAMMING.
*/
NORM_HAMMING2 = 7,
NORM_TYPE_MASK = 7, //!< bit-mask which can be used to separate norm type from norm flags
NORM_RELATIVE = 8, //!< flag
NORM_MINMAX = 32 //!< flag
};
//! comparison types
enum CmpTypes { CMP_EQ = 0, //!< src1 is equal to src2.
CMP_GT = 1, //!< src1 is greater than src2.
CMP_GE = 2, //!< src1 is greater than or equal to src2.
CMP_LT = 3, //!< src1 is less than src2.
CMP_LE = 4, //!< src1 is less than or equal to src2.
CMP_NE = 5 //!< src1 is unequal to src2.
};
//! generalized matrix multiplication flags
enum GemmFlags { GEMM_1_T = 1, //!< transposes src1
GEMM_2_T = 2, //!< transposes src2
GEMM_3_T = 4 //!< transposes src3
};
enum DftFlags {
/** performs an inverse 1D or 2D transform instead of the default forward
transform. */
DFT_INVERSE = 1,
/** scales the result: divide it by the number of array elements. Normally, it is
combined with DFT_INVERSE. */
DFT_SCALE = 2,
/** performs a forward or inverse transform of every individual row of the input
matrix; this flag enables you to transform multiple vectors simultaneously and can be used to
decrease the overhead (which is sometimes several times larger than the processing itself) to
perform 3D and higher-dimensional transformations and so forth.*/
DFT_ROWS = 4,
/** performs a forward transformation of 1D or 2D real array; the result,
though being a complex array, has complex-conjugate symmetry (*CCS*, see the function
description below for details), and such an array can be packed into a real array of the same
size as input, which is the fastest option and which is what the function does by default;
however, you may wish to get a full complex array (for simpler spectrum analysis, and so on) -
pass the flag to enable the function to produce a full-size complex output array. */
DFT_COMPLEX_OUTPUT = 16,
/** performs an inverse transformation of a 1D or 2D complex array; the
result is normally a complex array of the same size, however, if the input array has
conjugate-complex symmetry (for example, it is a result of forward transformation with
DFT_COMPLEX_OUTPUT flag), the output is a real array; while the function itself does not
check whether the input is symmetrical or not, you can pass the flag and then the function
will assume the symmetry and produce the real output array (note that when the input is packed
into a real array and inverse transformation is executed, the function treats the input as a
packed complex-conjugate symmetrical array, and the output will also be a real array). */
DFT_REAL_OUTPUT = 32,
/** specifies that input is complex input. If this flag is set, the input must have 2 channels.
On the other hand, for backwards compatibility reason, if input has 2 channels, input is
already considered complex. */
DFT_COMPLEX_INPUT = 64,
/** performs an inverse 1D or 2D transform instead of the default forward transform. */
DCT_INVERSE = DFT_INVERSE,
/** performs a forward or inverse transform of every individual row of the input
matrix. This flag enables you to transform multiple vectors simultaneously and can be used to
decrease the overhead (which is sometimes several times larger than the processing itself) to
perform 3D and higher-dimensional transforms and so forth.*/
DCT_ROWS = DFT_ROWS
};
//! Various border types, image boundaries are denoted with `|`
//! @see borderInterpolate, copyMakeBorder
enum BorderTypes {
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`
BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_ISOLATED = 16 //!< do not look outside of ROI
};
//! @} core_array
//! @addtogroup core_utils
//! @{
/*! @brief Signals an error and raises the exception.
By default the function prints information about the error to stderr,
then it either stops if setBreakOnError() had been called before or raises the exception.
It is possible to alternate error processing by using redirectError().
@param _code - error code (Error::Code)
@param _err - error description
@param _func - function name. Available only when the compiler supports getting it
@param _file - source file name where the error has occurred
@param _line - line number in the source file where the error has occurred
@see CV_Error, CV_Error_, CV_Assert, CV_DbgAssert
*/
CV_EXPORTS void error(int _code, const String& _err, const char* _func, const char* _file, int _line);
#ifdef __GNUC__
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Winvalid-noreturn"
# endif
#endif
/** same as cv::error, but does not return */
CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const char* _func, const char* _file, int _line)
{
error(_code, _err, _func, _file, _line);
#ifdef __GNUC__
# if !defined __clang__ && !defined __APPLE__
// this suppresses this warning: "noreturn" function does return [enabled by default]
__builtin_trap();
// or use infinite loop: for (;;) {}
# endif
#endif
}
#ifdef __GNUC__
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic pop
# endif
#endif
#ifdef CV_STATIC_ANALYSIS
// In practice, some macro are not processed correctly (noreturn is not detected).
// We need to use simplified definition for them.
#define CV_Error(code, msg) do { (void)(code); (void)(msg); abort(); } while (0)
#define CV_Error_(code, args) do { (void)(code); (void)(cv::format args); abort(); } while (0)
#define CV_Assert( expr ) do { if (!(expr)) abort(); } while (0)
#define CV_ErrorNoReturn CV_Error
#define CV_ErrorNoReturn_ CV_Error_
#else // CV_STATIC_ANALYSIS
/** @brief Call the error handler.
Currently, the error handler prints the error code and the error message to the standard
error stream `stderr`. In the Debug configuration, it then provokes memory access violation, so that
the execution stack and all the parameters can be analyzed by the debugger. In the Release
configuration, the exception is thrown.
@param code one of Error::Code
@param msg error message
*/
#define CV_Error( code, msg ) cv::error( code, msg, CV_Func, __FILE__, __LINE__ )
/** @brief Call the error handler.
This macro can be used to construct an error message on-fly to include some dynamic information,
for example:
@code
// note the extra parentheses around the formatted text message
CV_Error_(Error::StsOutOfRange,
("the value at (%d, %d)=%g is out of range", badPt.x, badPt.y, badValue));
@endcode
@param code one of Error::Code
@param args printf-like formatted error message in parentheses
*/
#define CV_Error_( code, args ) cv::error( code, cv::format args, CV_Func, __FILE__, __LINE__ )
/** @brief Checks a condition at runtime and throws exception if it fails
The macros CV_Assert (and CV_DbgAssert(expr)) evaluate the specified expression. If it is 0, the macros
raise an error (see cv::error). The macro CV_Assert checks the condition in both Debug and Release
configurations while CV_DbgAssert is only retained in the Debug configuration.
*/
#define CV_Assert( expr ) do { if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ ); } while(0)
//! @cond IGNORED
#define CV__ErrorNoReturn( code, msg ) cv::errorNoReturn( code, msg, CV_Func, __FILE__, __LINE__ )
#define CV__ErrorNoReturn_( code, args ) cv::errorNoReturn( code, cv::format args, CV_Func, __FILE__, __LINE__ )
#ifdef __OPENCV_BUILD
#undef CV_Error
#define CV_Error CV__ErrorNoReturn
#undef CV_Error_
#define CV_Error_ CV__ErrorNoReturn_
#undef CV_Assert
#define CV_Assert( expr ) do { if(!!(expr)) ; else cv::errorNoReturn( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ ); } while(0)
#else
// backward compatibility
#define CV_ErrorNoReturn CV__ErrorNoReturn
#define CV_ErrorNoReturn_ CV__ErrorNoReturn_
#endif
//! @endcond
#endif // CV_STATIC_ANALYSIS
//! @cond IGNORED
#if defined OPENCV_FORCE_MULTIARG_ASSERT_CHECK && defined CV_STATIC_ANALYSIS
#warning "OPENCV_FORCE_MULTIARG_ASSERT_CHECK can't be used with CV_STATIC_ANALYSIS"
#undef OPENCV_FORCE_MULTIARG_ASSERT_CHECK
#endif
#ifdef OPENCV_FORCE_MULTIARG_ASSERT_CHECK
#define CV_Assert_1( expr ) do { if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ ); } while(0)
#else
#define CV_Assert_1 CV_Assert
#endif
#define CV_Assert_2( expr1, expr2 ) CV_Assert_1(expr1); CV_Assert_1(expr2)
#define CV_Assert_3( expr1, expr2, expr3 ) CV_Assert_2(expr1, expr2); CV_Assert_1(expr3)
#define CV_Assert_4( expr1, expr2, expr3, expr4 ) CV_Assert_3(expr1, expr2, expr3); CV_Assert_1(expr4)
#define CV_Assert_5( expr1, expr2, expr3, expr4, expr5 ) CV_Assert_4(expr1, expr2, expr3, expr4); CV_Assert_1(expr5)
#define CV_Assert_6( expr1, expr2, expr3, expr4, expr5, expr6 ) CV_Assert_5(expr1, expr2, expr3, expr4, expr5); CV_Assert_1(expr6)
#define CV_Assert_7( expr1, expr2, expr3, expr4, expr5, expr6, expr7 ) CV_Assert_6(expr1, expr2, expr3, expr4, expr5, expr6 ); CV_Assert_1(expr7)
#define CV_Assert_8( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8 ) CV_Assert_7(expr1, expr2, expr3, expr4, expr5, expr6, expr7 ); CV_Assert_1(expr8)
#define CV_Assert_9( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9 ) CV_Assert_8(expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8 ); CV_Assert_1(expr9)
#define CV_Assert_10( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9, expr10 ) CV_Assert_9(expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9 ); CV_Assert_1(expr10)
#define CV_Assert_N(...) do { __CV_CAT(CV_Assert_, __CV_VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__); } while(0)
#ifdef OPENCV_FORCE_MULTIARG_ASSERT_CHECK
#undef CV_Assert
#define CV_Assert CV_Assert_N
#endif
//! @endcond
#if defined _DEBUG || defined CV_STATIC_ANALYSIS
# define CV_DbgAssert(expr) CV_Assert(expr)
#else
/** replaced with CV_Assert(expr) in Debug configuration */
# define CV_DbgAssert(expr)
#endif
/*
* Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
* bit count of A exclusive XOR'ed with B
*/
struct CV_EXPORTS Hamming
{
enum { normType = NORM_HAMMING };
typedef unsigned char ValueType;
typedef int ResultType;
/** this will count the bits in a ^ b
*/
ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const;
};
typedef Hamming HammingLUT;
/////////////////////////////////// inline norms ////////////////////////////////////
template<typename _Tp> inline _Tp cv_abs(_Tp x) { return std::abs(x); }
inline int cv_abs(uchar x) { return x; }
inline int cv_abs(schar x) { return std::abs(x); }
inline int cv_abs(ushort x) { return x; }
inline int cv_abs(short x) { return std::abs(x); }
template<typename _Tp, typename _AccTp> static inline
_AccTp normL2Sqr(const _Tp* a, int n)
{
_AccTp s = 0;
int i=0;
#if CV_ENABLE_UNROLLED
for( ; i <= n - 4; i += 4 )
{
_AccTp v0 = a[i], v1 = a[i+1], v2 = a[i+2], v3 = a[i+3];
s += v0*v0 + v1*v1 + v2*v2 + v3*v3;
}
#endif
for( ; i < n; i++ )
{
_AccTp v = a[i];
s += v*v;
}
return s;
}
template<typename _Tp, typename _AccTp> static inline
_AccTp normL1(const _Tp* a, int n)
{
_AccTp s = 0;
int i = 0;
#if CV_ENABLE_UNROLLED
for(; i <= n - 4; i += 4 )
{
s += (_AccTp)cv_abs(a[i]) + (_AccTp)cv_abs(a[i+1]) +
(_AccTp)cv_abs(a[i+2]) + (_AccTp)cv_abs(a[i+3]);
}
#endif
for( ; i < n; i++ )
s += cv_abs(a[i]);
return s;
}
template<typename _Tp, typename _AccTp> static inline
_AccTp normInf(const _Tp* a, int n)
{
_AccTp s = 0;
for( int i = 0; i < n; i++ )
s = std::max(s, (_AccTp)cv_abs(a[i]));
return s;
}
template<typename _Tp, typename _AccTp> static inline
_AccTp normL2Sqr(const _Tp* a, const _Tp* b, int n)
{
_AccTp s = 0;
int i= 0;
#if CV_ENABLE_UNROLLED
for(; i <= n - 4; i += 4 )
{
_AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]);
s += v0*v0 + v1*v1 + v2*v2 + v3*v3;
}
#endif
for( ; i < n; i++ )
{
_AccTp v = _AccTp(a[i] - b[i]);
s += v*v;
}
return s;
}
static inline float normL2Sqr(const float* a, const float* b, int n)
{
float s = 0.f;
for( int i = 0; i < n; i++ )
{
float v = a[i] - b[i];
s += v*v;
}
return s;
}
template<typename _Tp, typename _AccTp> static inline
_AccTp normL1(const _Tp* a, const _Tp* b, int n)
{
_AccTp s = 0;
int i= 0;
#if CV_ENABLE_UNROLLED
for(; i <= n - 4; i += 4 )
{
_AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]);
s += std::abs(v0) + std::abs(v1) + std::abs(v2) + std::abs(v3);
}
#endif
for( ; i < n; i++ )
{
_AccTp v = _AccTp(a[i] - b[i]);
s += std::abs(v);
}
return s;
}
inline float normL1(const float* a, const float* b, int n)
{
float s = 0.f;
for( int i = 0; i < n; i++ )
{
s += std::abs(a[i] - b[i]);
}
return s;
}
inline int normL1(const uchar* a, const uchar* b, int n)
{
int s = 0;
for( int i = 0; i < n; i++ )
{
s += std::abs(a[i] - b[i]);
}
return s;
}
template<typename _Tp, typename _AccTp> static inline
_AccTp normInf(const _Tp* a, const _Tp* b, int n)
{
_AccTp s = 0;
for( int i = 0; i < n; i++ )
{
_AccTp v0 = a[i] - b[i];
s = std::max(s, std::abs(v0));
}
return s;
}
/** @brief Computes the cube root of an argument.
The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly.
NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for
single-precision data.
@param val A function argument.
*/
CV_EXPORTS_W float cubeRoot(float val);
/** @overload
cubeRoot with argument of `double` type calls `std::cbrt(double)` (C++11) or falls back on `pow()` for C++98 compilation mode.
*/
static inline
double cubeRoot(double val)
{
#ifdef CV_CXX11
return std::cbrt(val);
#else
double v = pow(abs(val), 1/3.); // pow doesn't support negative inputs with fractional exponents
return val >= 0 ? v : -v;
#endif
}
/** @brief Calculates the angle of a 2D vector in degrees.
The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured
in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees.
@param x x-coordinate of the vector.
@param y y-coordinate of the vector.
*/
CV_EXPORTS_W float fastAtan2(float y, float x);
/** proxy for hal::LU */
CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n);
/** proxy for hal::LU */
CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n);
/** proxy for hal::Cholesky */
CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n);
/** proxy for hal::Cholesky */
CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n);
////////////////// forward declarations for important OpenCV types //////////////////
//! @cond IGNORED
template<typename _Tp, int cn> class Vec;
template<typename _Tp, int m, int n> class Matx;
template<typename _Tp> class Complex;
template<typename _Tp> class Point_;
template<typename _Tp> class Point3_;
template<typename _Tp> class Size_;
template<typename _Tp> class Rect_;
template<typename _Tp> class Scalar_;
class CV_EXPORTS RotatedRect;
class CV_EXPORTS Range;
class CV_EXPORTS TermCriteria;
class CV_EXPORTS KeyPoint;
class CV_EXPORTS DMatch;
class CV_EXPORTS RNG;
class CV_EXPORTS Mat;
class CV_EXPORTS MatExpr;
class CV_EXPORTS UMat;
class CV_EXPORTS SparseMat;
typedef Mat MatND;
template<typename _Tp> class Mat_;
template<typename _Tp> class SparseMat_;
class CV_EXPORTS MatConstIterator;
class CV_EXPORTS SparseMatIterator;
class CV_EXPORTS SparseMatConstIterator;
template<typename _Tp> class MatIterator_;
template<typename _Tp> class MatConstIterator_;
template<typename _Tp> class SparseMatIterator_;
template<typename _Tp> class SparseMatConstIterator_;
namespace ogl
{
class CV_EXPORTS Buffer;
class CV_EXPORTS Texture2D;
class CV_EXPORTS Arrays;
}
namespace cuda
{
class CV_EXPORTS GpuMat;
class CV_EXPORTS HostMem;
class CV_EXPORTS Stream;
class CV_EXPORTS Event;
}
namespace cudev
{
template <typename _Tp> class GpuMat_;
}
namespace ipp
{
#if OPENCV_ABI_COMPATIBILITY > 300
CV_EXPORTS unsigned long long getIppFeatures();
#else
CV_EXPORTS int getIppFeatures();
#endif
CV_EXPORTS void setIppStatus(int status, const char * const funcname = NULL, const char * const filename = NULL,
int line = 0);
CV_EXPORTS int getIppStatus();
CV_EXPORTS String getIppErrorLocation();
CV_EXPORTS_W bool useIPP();
CV_EXPORTS_W void setUseIPP(bool flag);
CV_EXPORTS_W String getIppVersion();
// IPP Not-Exact mode. This function may force use of IPP then both IPP and OpenCV provide proper results
// but have internal accuracy differences which have too much direct or indirect impact on accuracy tests.
CV_EXPORTS_W bool useIPP_NotExact();
CV_EXPORTS_W void setUseIPP_NotExact(bool flag);
#if OPENCV_ABI_COMPATIBILITY < 400
CV_EXPORTS_W bool useIPP_NE();
CV_EXPORTS_W void setUseIPP_NE(bool flag);
#endif
} // ipp
//! @endcond
//! @} core_utils
} // cv
#include "opencv2/core/neon_utils.hpp"
#include "opencv2/core/vsx_utils.hpp"
#include "opencv2/core/check.hpp"
#endif //OPENCV_CORE_BASE_HPP

View File

@@ -0,0 +1,170 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_CORE_BINDINGS_UTILS_HPP
#define OPENCV_CORE_BINDINGS_UTILS_HPP
#include <opencv2/core/async.hpp>
#include <opencv2/core/detail/async_promise.hpp>
#include <opencv2/core/utils/logger.hpp>
#include <stdexcept>
namespace cv { namespace utils {
//! @addtogroup core_utils
//! @{
CV_EXPORTS_W String dumpInputArray(InputArray argument);
CV_EXPORTS_W String dumpInputArrayOfArrays(InputArrayOfArrays argument);
CV_EXPORTS_W String dumpInputOutputArray(InputOutputArray argument);
CV_EXPORTS_W String dumpInputOutputArrayOfArrays(InputOutputArrayOfArrays argument);
CV_WRAP static inline
String dumpBool(bool argument)
{
return (argument) ? String("Bool: True") : String("Bool: False");
}
CV_WRAP static inline
String dumpInt(int argument)
{
return cv::format("Int: %d", argument);
}
CV_WRAP static inline
String dumpSizeT(size_t argument)
{
std::ostringstream oss("size_t: ", std::ios::ate);
oss << argument;
return oss.str();
}
CV_WRAP static inline
String dumpFloat(float argument)
{
return cv::format("Float: %.2f", argument);
}
CV_WRAP static inline
String dumpDouble(double argument)
{
return cv::format("Double: %.2f", argument);
}
CV_WRAP static inline
String dumpCString(const char* argument)
{
return cv::format("String: %s", argument);
}
CV_WRAP static inline
String dumpString(const String& argument)
{
return cv::format("String: %s", argument.c_str());
}
CV_WRAP static inline
String testOverloadResolution(int value, const Point& point = Point(42, 24))
{
return format("overload (int=%d, point=(x=%d, y=%d))", value, point.x,
point.y);
}
CV_WRAP static inline
String testOverloadResolution(const Rect& rect)
{
return format("overload (rect=(x=%d, y=%d, w=%d, h=%d))", rect.x, rect.y,
rect.width, rect.height);
}
CV_WRAP static inline
String dumpRect(const Rect& argument)
{
return format("rect: (x=%d, y=%d, w=%d, h=%d)", argument.x, argument.y,
argument.width, argument.height);
}
CV_WRAP static inline
String dumpTermCriteria(const TermCriteria& argument)
{
return format("term_criteria: (type=%d, max_count=%d, epsilon=%lf",
argument.type, argument.maxCount, argument.epsilon);
}
CV_WRAP static inline
String dumpRotatedRect(const RotatedRect& argument)
{
return format("rotated_rect: (c_x=%f, c_y=%f, w=%f, h=%f, a=%f)",
argument.center.x, argument.center.y, argument.size.width,
argument.size.height, argument.angle);
}
CV_WRAP static inline
String dumpRange(const Range& argument)
{
if (argument == Range::all())
{
return "range: all";
}
else
{
return format("range: (s=%d, e=%d)", argument.start, argument.end);
}
}
CV_WRAP static inline
void testRaiseGeneralException()
{
throw std::runtime_error("exception text");
}
CV_WRAP static inline
AsyncArray testAsyncArray(InputArray argument)
{
AsyncPromise p;
p.setValue(argument);
return p.getArrayResult();
}
CV_WRAP static inline
AsyncArray testAsyncException()
{
AsyncPromise p;
try
{
CV_Error(Error::StsOk, "Test: Generated async error");
}
catch (const cv::Exception& e)
{
p.setException(e);
}
return p.getArrayResult();
}
//! @} // core_utils
} // namespace cv::utils
//! @cond IGNORED
CV_WRAP static inline
int setLogLevel(int level)
{
// NB: Binding generators doesn't work with enums properly yet, so we define separate overload here
return cv::utils::logging::setLogLevel((cv::utils::logging::LogLevel)level);
}
CV_WRAP static inline
int getLogLevel()
{
return cv::utils::logging::getLogLevel();
}
//! @endcond IGNORED
} // namespaces cv / utils
#endif // OPENCV_CORE_BINDINGS_UTILS_HPP

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