작업 프로토콜
약 915 단어약 3 분
resource/tasks의 사용법 및 각 필드 설명
팁
Visual Studio Code를 사용하고 Maa Pipeline Support 확장을 설치하여 효율적으로 편집하는 것을 권장합니다. 자세한 내용은 확장 홈페이지와 문서를 참조하세요.
경고
JSON 파일은 주석을 지원하지 않으므로, 텍스트 내의 주석은 예시용입니다. 직접 복사하여 사용하지 마세요.
전체 필드 목록
{
"TaskName": { // 작업 이름, @가 포함된 경우 특수 작업일 수 있으며 기본값이 다를 수 있음. 아래 특수 작업 유형 참조
"baseTask": "xxx", // xxx 작업을 템플릿(기반)으로 하여 작업 생성. 아래 특수 작업 유형의 '파생 작업' 참조
"algorithm": "MatchTemplate", // 선택 사항, 인식 알고리즘 유형
// 비워둘 시 기본값: MatchTemplate
// - JustReturn: 인식 없이 바로 action 실행
// - MatchTemplate: 이미지 매칭
// - OcrDetect: 텍스트 인식
// - FeatureMatch: 특징 매칭
"action": "ClickSelf", // 선택 사항, 인식 성공 후 동작
// 비워둘 시 기본값: DoNothing
// - ClickSelf: 인식된 위치 클릭 (인식된 목표 범위 내 무작위 지점)
// - ClickRect: 지정된 영역 클릭, specificRect 필드에 대응 (비권장)
// - DoNothing: 아무것도 하지 않음
// - Stop: 현재 작업 정지
// - Swipe: 스와이프, specificRect 및 rectMove 필드에 대응
// - Input: 텍스트 입력, algorithm이 JustReturn이어야 함, inputText 필드에 대응
"sub": ["SubTaskName1", "SubTaskName2"],
// 선택 사항, 서브 작업 (비권장). 현재 작업 실행 후 서브 작업들을 순차적으로 실행
// 중첩 가능(서브 작업의 서브 작업). 단, 무한 루프에 주의
"subErrorIgnored": true, // 선택 사항, 서브 작업 오류 무시 여부
// 비워둘 시 기본값: false
// false: 서브 작업 중 하나라도 오류 발생 시 후속 작업 실행 안 함 (본 작업 오류로 간주)
// true: 서브 작업 오류 여부가 영향을 주지 않음
"next": ["OtherTaskName1", "OtherTaskName2"],
// 선택 사항, 현재 작업 및 sub 작업 완료 후 실행할 다음 작업
// 앞에서부터 순차적으로 인식하여 첫 번째로 매칭된 작업 실행
// 비워둘 시 현재 작업 완료 후 바로 정지
// 동일 작업에 대해 첫 번째 인식 후 두 번째는 인식하지 않음:
// "next": [ "A", "B", "A", "A" ] -> "next": [ "A", "B" ]
// JustReturn 유형 작업은 마지막 항목이 아닌 곳에 위치할 수 없음
"maxTimes": 10, // 선택 사항, 최대 실행 횟수
// 비워둘 시 기본값: 무한
// 최대 횟수 도달 후, exceededNext 필드가 있으면 실행, 없으면 작업 정지
"exceededNext": ["OtherTaskName1", "OtherTaskName2"],
// 선택 사항, 최대 실행 횟수 도달 시 실행할 작업
// 비워둘 시 정지; 작성 시 next 대신 이곳의 작업 실행
"onErrorNext": ["OtherTaskName1", "OtherTaskName2"],
// 선택 사항, 실행 오류 발생 시 후속 실행할 작업
"preDelay": 1000, // 선택 사항, 인식 성공 후 action 실행 전 지연 시간 (ms); 기본값 0
"postDelay": 1000, // 선택 사항, action 실행 후 다음 next 인식 전 지연 시간 (ms); 기본값 0
"roi": [0, 0, 1280, 720], // 선택 사항, 인식 범위 [x, y, width, height]
// 1280 * 720 기준 자동 스케일링; 기본값 [0, 0, 1280, 720]
// 범위를 줄이면 성능 소모를 줄이고 인식 속도를 높일 수 있음
"cache": true, // 선택 사항, 캐시 사용 여부, 기본값 true;
// 첫 인식 성공 시 이후에는 해당 위치에서만 인식. 성능 대폭 절약 가능
// 단, 인식 대상 위치가 절대 변하지 않는 경우에만 사용. 변할 수 있다면 false로 설정
"rectMove": [0, 0, 0, 0], // 선택 사항, 인식 후 목표 이동 (비권장). 1280 * 720 기준 자동 스케일링
// 예: A를 인식했지만 실제 클릭은 A 아래 10픽셀 5*2 영역일 때
// [0, 10, 5, 2]로 설정. 가능하면 클릭 위치를 직접 인식하는 것을 권장
// 추가로, action이 Swipe일 때 유효하며 필수 (스와이프 종점)
"reduceOtherTimes": ["OtherTaskName1", "OtherTaskName2"],
// 선택 사항, 실행 후 다른 작업의 실행 카운트 감소
// 예: 이성 회복제 사용 시, 이전에 누른 파란색 작전 시작 버튼이 무효화되었으므로 해당 작업 카운트 -1
"specificRect": [100, 100, 50, 50],
// action이 ClickRect일 때 유효하며 필수, 지정 클릭 위치 (범위 내 무작위 점)
// action이 Swipe일 때 유효하며 필수, 스와이프 시점
// 1280 * 720 기준 자동 스케일링
// algorithm이 "OcrDetect"일 때, specificRect[0]과 [1]은 그레이스케일 상/하한 임계값
"specialParams": [int, ...], // 특정 인식기에 필요한 추가 파라미터
// action이 Swipe일 때 선택 사항: [0] duration, [1] 추가 슬라이드 활성화 여부
"highResolutionSwipeFix": false, // 선택 사항, 고해상도 스와이프 보정 활성화 여부
// 현재 스테이지 내비게이션만 Unity 스와이프를 사용하지 않으므로 켜야 함
// 기본값 false
/* 이하 필드는 algorithm이 MatchTemplate일 때만 유효 */
"template": "xxx.png", // 선택 사항, 매칭할 이미지 파일명 (문자열 또는 리스트)
// 기본값 "TaskName.png"
// 템플릿 파일은 template 폴더 및 하위 폴더에서 재귀적으로 검색됨
"templThreshold": 0.8, // 선택 사항, 템플릿 매칭 점수 임계값. 이 값 이상이어야 인식 성공 (숫자 또는 리스트)
// 기본값 0.8, 실제 점수는 로그 확인
"maskRange": [1, 255], // 선택 사항, 매칭 시 그레이스케일 마스크 범위. array<int, 2>
// 예: 인식 불필요 부분을 검은색(0)으로 칠하고
// [1, 255]로 설정하면 검은색 부분 무시
"colorScales": [ // method가 HSVCount 또는 RGBCount일 때 유효하며 필수, 색상 카운트 마스크 범위
[ // list<array<array<int, 3>, 2>> / list<array<int, 2>>
[23, 150, 40], // 구조: [[lower1, upper1], [lower2, upper2], ...]
[25, 230, 150] // 내부가 int면 그레이스케일,
], // array<int, 3>이면 3채널 색상 (method에 따라 RGB/HSV)
... // 중간층 array<*, 2>는 색상(또는 그레이스케일) 하한/상한
], // 최외각은 서로 다른 색상 범위를 나타내며, 인식 대상 영역은 이들의 마스크 합집합임
"colorWithClose": true, // 선택 사항, method가 HSVCount/RGBCount일 때 유효, 기본값 true
// 색상 카운트 시 마스크 범위에 대해 닫힘 연산(Closing) 수행 여부
// 작은 구멍을 메워 매칭 효과를 높이나, 글자가 포함된 경우 false 권장
"pureColor": false, // 선택 사항, method가 HSVCount/RGBCount일 때 유효, 기본값 false
// true일 경우 템플릿 매칭 점수 무시, 색상 매칭 결과만 신뢰
// 색상 특징은 뚜렷하나 템플릿 매칭이 잘 안 될 때 사용
// 사용 시 templThreshold를 높이는 것을 권장
"method": "Ccoeff", // 선택 사항, 템플릿 매칭 알고리즘 (리스트 가능)
// 비워둘 시 기본값 Ccoeff
// - Ccoeff: 색상에 둔감한 템플릿 매칭 (cv::TM_CCOEFF_NORMED)
// - RGBCount: 색상에 민감. colorScales로 이진화 후
// RGB 공간 내 유사도(F1-score) 계산,
// 그 결과를 Ccoeff 결과와 곱함
// - HSVCount: RGBCount와 유사하나 HSV 공간 사용
/* 이하 필드는 algorithm이 OcrDetect일 때만 유효 */
"text": [ "작전 수행", "대리 지휘" ], // 필수, 인식할 텍스트 내용. 하나라도 매칭되면 성공
"ocrReplace": [ // 선택 사항, 자주 오인식되는 텍스트 교정 (정규식 지원)
[ "머틀", "머틀" ],
[ ".+격대원", "저격대원" ]
],
"fullMatch": false, // 선택 사항, 전체 일치 여부, 기본값 false
// false: 부분 문자열 매칭 허용 (예: text ["시작"] -> "작전 시작" 인식 성공)
// true: 정확히 일치해야 함 ("시작" -> "작전 시작" 실패)
"isAscii": false, // 선택 사항, 인식 대상이 ASCII 문자인지 여부
// 기본값 false
"withoutDet": false, // 선택 사항, 디텍션 모델 미사용 여부
// 기본값 false
/* 이하 필드는 algorithm이 OcrDetect이고 withoutDet가 true일 때만 유효 */
"useRaw": true, // 선택 사항, 원본 이미지 사용 여부
// 기본값 true, false면 그레이스케일 매칭
"binThreshold": [140, 255], // 선택 사항, 이진화 임계값 (기본값 [140, 255])
// 범위 밖 픽셀은 배경으로 간주되어 제외됨
// [lower, upper] 구간 픽셀만 전경(글자)으로 남음
/* 이하 필드는 algorithm이 JustReturn, action이 Input일 때만 유효 */
"inputText": "A string text.", // 필수, 입력할 문자열
/* 이하 필드는 algorithm이 FeatureMatch일 때만 유효 */
"template": "xxx.png", // 선택 사항, 매칭할 이미지 파일명 (문자열/리스트)
// 기본값 "TaskName.png"
"count": 4, // 매칭 특징점 수 (임계값), 기본값 4
"ratio": 0.6, // KNN 매칭 거리 비율 [0 - 1.0]. 클수록 느슨하여 매칭 쉬움. 기본값 0.6
"detector": "SIFT", // 특징점 검출기. SIFT, ORB, BRISK, KAZE, AKAZE, SURF. 기본값 SIFT
// SIFT: 느리지만 스케일/회전 불변성 우수. 성능 최고.
// ORB: 매우 빠름, 회전 불변. 스케일 불변성 없음.
// BRISK: 매우 빠름, 스케일/회전 불변.
// KAZE: 2D/3D 적용 가능, 스케일/회전 불변.
// AKAZE: 빠름, 스케일/회전 불변.
}
}표현식 계산
작업 목록 유형 필드 (sub, next, onErrorNext, exceededNext, reduceOtherTimes)는 표현식 계산을 지원합니다.
| 기호 | 의미 | 예시 |
|---|---|---|
@ | @ 형 작업 | Fight@ReturnTo |
# (단항) | 가상 작업 | #self |
# (이항) | 가상 작업 | StartUpThemes#next |
* | 다중 작업 반복 | (ClickCornerAfterPRTS+ClickCorner)*10 |
+ | 작업 목록 병합 (next 계열 필드에서 동명 작업은 앞쪽 우선) | A+B |
^ | 작업 목록 차집합 (전자에만 존재, 순서 유지) | (A+A+B+C)^(A+B+D) (결과는 C) |
연산자 @, #, *, +, ^의 우선순위: #(단항) > @ = #(이항) > * > + = ^.
특수 작업 유형
템플릿 작업
템플릿 작업은 파생 작업과 @ 형 작업을 포함합니다. 템플릿 작업의 핵심은 기반 작업을 바탕으로 필드의 기본값을 수정하는 것입니다.
파생 작업 (Derived Task)
baseTask 필드가 존재하는 작업이 파생 작업이며, baseTask에 지정된 작업을 해당 파생 작업의 **기반 작업(Base Task)**이라고 합니다. 파생 작업에서:
- 템플릿 매칭 작업이라도
template필드의 기본값은 여전히"TaskName.png"입니다. algorithm필드가 기반 작업과 다르면, 파생 클래스 파라미터는 상속되지 않습니다 (TaskInfo 정의 파라미터만 상속).- 나머지 필드의 기본값은 모두 기반 작업의 해당 필드를 따릅니다.
암시적 @ 형 작업
작업 "A"가 존재할 때, 작업 파일에 직접 정의되지 않았지만 "B@A" 형태의 작업이 사용되면 이를 암시적 @ 형 작업이라 합니다. 작업 "A"는 작업 "B@A"의 기반 작업이 됩니다. 암시적 @ 형 작업에서:
- 작업 목록 유형 필드(
sub,next,onErrorNext,exceededNext,reduceOtherTimes)의 기본값은 기반 작업의 해당 필드에 직접B@접두사를 붙인 값이 됩니다 (작업명이#로 시작하면B접두사). - 나머지 필드의 기본값은 모두 기반 작업의 해당 필드를 따릅니다 (필드
template포함).
명시적 @ 형 작업
작업 "A"가 존재하고, 작업 파일에 "B@A" 형태의 작업이 직접 정의되어 있으면 이를 명시적 @ 형 작업이라 합니다. 작업 "A"는 작업 "B@A"의 기반 작업이 됩니다. 명시적 @ 형 작업에서:
- 작업 목록 유형 필드(
sub,next,onErrorNext,exceededNext,reduceOtherTimes)의 기본값은 기반 작업의 해당 필드에 직접B@접두사를 붙인 값이 됩니다 (작업명이#로 시작하면B접두사). - 템플릿 매칭 작업이라도
template필드의 기본값은 여전히"TaskName.png"입니다. algorithm필드가 기반 작업과 다르면, 파생 클래스 파라미터는 상속되지 않습니다 (TaskInfo 정의 파라미터만 상속).- 나머지 필드의 기본값은 모두 기반 작업의 해당 필드를 따릅니다.
가상 작업 (# 형 작업)
가상 작업은 "#{sharp_type}" 또는 "B#{sharp_type}" 형태의 작업입니다. 여기서 {sharp_type}은 none, self, back, next, sub, on_error_next, exceeded_next, reduce_other_times 중 하나입니다.
가상 작업은 명령 가상 작업(none / self / back)과 필드 가상 작업(next 등)으로 나뉩니다.
| 가상 작업 유형 | 의미 | 간단 예시 |
|---|---|---|
| none | 빈 작업 | 직접 건너뜀1"A": {"next": ["#none", "T1"]} -> "A": {"next": ["T1"]}"A#none + T1" -> "T1" |
| self | 현재 작업명 | "A": {"next": ["#self"]}의 "#self" -> "A""B": {"next": ["A@B@C#self"]}의 "A@B@C#self" -> "B"2 |
| back | # 앞의 작업명 | "A@B#back" -> "A@B""#back"이 직접 등장하면 건너뜀3 |
| next, sub 등 | # 앞 작업의 해당 필드 | next 예시:"A#next" -> Task.get("A")->next"#next"가 직접 등장하면 건너뜀 |
Note1: "#none"은 주로 템플릿 작업의 접두사 추가 특성과 함께 사용하거나, baseTask 사용 시 불필요한 필드 상속을 피하기 위해 사용합니다.
Note2: "XXX#self"와 "#self"는 동일한 의미입니다.
Note3: 여러 작업이 "next": [ "#back" ]을 가질 때, "T1@T2@T3"는 T3, T2, T1 순으로 실행됨을 의미합니다.
다중 파일 작업
나중에 로드된 작업 파일(예: 외섭 tasks.json, 이하 파일2)에 정의된 작업이 먼저 로드된 작업 파일(예: 중섭 tasks.json, 이하 파일1)에도 정의되어 있다면:
- 파일2 작업에
baseTask필드가 없으면, 파일1의 동명 작업 필드를 직접 상속합니다. - 파일2 작업에
baseTask필드가 있으면, 파일1의 동명 작업 필드를 상속하지 않고 덮어씁니다. 특히, 템플릿이 없을 때"baseTask": "#none"을 사용하여 불필요한 필드 상속을 막을 수 있습니다.
사용 예시
파생 작업 예시 (
baseTask필드)다음 두 작업이 정의되어 있다고 가정합니다:
"Return": { "action": "ClickSelf", "next": [ "Stop" ] }, "Return2": { "baseTask": "Return" },"Return2"작업은"Return"작업을 상속받아 실제로 다음 파라미터를 가집니다:"Return2": { "algorithm": "MatchTemplate", // 직접 상속 "template": "Return2.png", // "TaskName.png" 규칙 (템플릿 매칭이므로) "action": "ClickSelf", // 직접 상속 "next": [ "Stop" ] // 직접 상속 (Template Task와 달리 접두사 없음) }@형 작업 예시다음 파라미터를 가진 작업
"A"가 있다고 가정합니다:"A": { "template": "A.png", ..., "next": [ "N1", "#back" ] },작업
"B@A"가 직접 정의되지 않았다면(암시적),"B@A"는 실제로 다음 파라미터를 가집니다:"B@A": { "template": "A.png", ..., "next": [ "B@N1", "B#back" ] }작업
"B@A"가"B@A": {}로 정의되어 있다면(명시적),"B@A"는 실제로 다음 파라미터를 가집니다:"B@A": { "template": "B@A.png", ..., "next": [ "B@N1", "B#back" ] }가상 작업 예시
{ "A": { "next": ["N1", "N2"] }, "C": { "next": ["B@A#next"] }, "Loading": { "next": ["#self", "#next", "#back"] }, "B": { "next": ["Other", "B@Loading"] } }결과는 다음과 같습니다:
Task.get("C")->next = { "B@N1", "B@N2" }; Task.get("B@Loading")->next = { "B@Loading", "Other", "B" }; Task.get("Loading")->next = { "Loading" }; Task.get_raw("B@Loading")->next = { "B#self", "B#next", "B#back" };
주의 사항
작업 목록 유형 필드(next 등)에 정의된 작업이 낮은 우선순위 연산을 포함할 경우, 실제 결과가 예상과 다를 수 있습니다.
@와 이항#연산 순서에 따른 특례{ "A": { "next": ["N0"] }, "B": { "next": ["A#next"] }, "C@A": { "next": ["N1"] } }이 경우,
"C@B" -> next(즉C@A#next)는[ "N1" ]이 되며,[ "C@N0" ]가 아닙니다.@와+연산 순서에 따른 특례{ "A": { "next": ["#back + N0"] }, "B@A": {} }이 경우,
Task.get("A")->next = { "N0" }; Task.get_raw("B@A")->next = { "B#back + N0" }; Task.get("B@A")->next = { "B", "N0" }; // [ "B", "B@N0" ]가 아님에 주의사실 이 특성을 이용해 불필요한 접두사 추가를 피할 수 있습니다:
{ "A": { "next": ["#none + N0"] } }
런타임 작업 수정
Task.lazy_parse()는 런타임에 JSON 작업 설정을 로드할 수 있습니다. lazy_parse 규칙은 다중 파일 작업과 동일합니다.Task.set_task_base()는 작업의baseTask필드를 수정할 수 있습니다.
사용 예시
다음과 같은 작업 설정 파일이 있다고 가정합니다:
{
"A": {
"baseTask": "A_default"
},
"A_default": {
"next": ["xxx"]
},
"A_mode1": {
"next": ["yyy"]
},
"A_mode2": {
"next": ["zzz"]
}
}다음 코드는 mode 값에 따라 작업 "A"를 변경하며, 동시에 "B@A"와 같이 "A"에 의존하는 다른 작업들도 변경합니다:
switch (mode) {
case 1:
Task.set_task_base("A", "A_mode1"); // 기본적으로 A를 A_mode1 내용으로 덮어쓰는 것과 같음. 아래도 동일
break;
case 2:
Task.set_task_base("A", "A_mode2");
break;
default:
Task.set_task_base("A", "A_default");
break;
}Schema 검증
본 프로젝트는 tasks.json에 대한 JSON schema 검증을 구성했습니다. 프로토콜 파일은 docs/maa_tasks_schema.json입니다.
Visual Studio
MaaCore.vcxproj에 구성되어 있어 바로 사용 가능합니다. 힌트 효과는 다소 불명확하며 일부 정보가 누락될 수 있습니다.
Visual Studio Code
.vscode/settings.json에 구성되어 있으며, VS Code로 해당 프로젝트 폴더를 열면 사용할 수 있습니다. 힌트 효과가 좋습니다.
