diff --git a/MeoAssistance.sln b/MeoAssistance.sln index b62df20fb0..591ef6a7e4 100644 --- a/MeoAssistance.sln +++ b/MeoAssistance.sln @@ -18,6 +18,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCaller", "tools\TestCal EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MeoAsstGui", "src\MeoAsstGui\MeoAsstGui.csproj", "{FFDC8F49-8EAF-45BE-B0A8-7EF0DB9875A2}" + ProjectSection(ProjectDependencies) = postProject + {362D1E30-F5AE-4279-9985-65C27B3BA300} = {362D1E30-F5AE-4279-9985-65C27B3BA300} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestPipe", "tools\TestPipe\TestPipe.vcxproj", "{0565E66B-28A0-435C-BDFC-6565CADE28D2}" EndProject diff --git a/resource/config.json b/resource/config.json index 30ff2fcba1..c84c7b29ce 100644 --- a/resource/config.json +++ b/resource/config.json @@ -1,25 +1,23 @@ { - "version": "0.4", + "version": "0.5", "options": { - "identifyCache": true, - "identifyCache_Doc": "图像识别缓存功能:开启后可以大幅降低CPU消耗,但需要保证要识别的按钮每次的位置不会改变。true-开启,false-关闭,默认true", "taskDelay": 1000, - "taskIdentifyDelay_Doc": "识别的延迟:越快识别频率越快,但会增加CPU消耗。单位毫秒,默认1000", + "taskDelay_Doc": "识别的延迟:越快识别频率越快,但会增加CPU消耗。单位毫秒,默认1000", "printWindow": true, "printWindow_Doc": "截图功能:开启后每次结算界面会截图到screenshot目录下。true-开启,false-关闭,默认true", "printWindowDelay": 3000, - "printWindowCropOffset_Doc": "截图额外裁剪:再额外把边框裁减掉一圈,不然企鹅物流有可能识别不出来。单位像素,默认5", + "printWindowDelay_Doc": "截图延时:每次到结算界面,掉落物品不是一次性出来的,有个动画,所以需要等一会再截图。单位毫秒,默认3000", "controlDelayRange": [ 0, 0 ], "controlDelayRange_Doc": "点击随机延时:每次点击操作会进行随机延时,降低封号风险(好像也没听说过谁被封号的)。格式为 [ 最小延时, 最大延时 ],单位为毫秒。例如想设置3~5秒延时,即修改为[ 3000, 5000 ],默认0~0", "ocrThreadNumber": 4, - "ocrThreadNumber_Doc": "OcrLite线程数量。默认4" + "ocrThreadNumber_Doc": "文字识别库OcrLite的线程数量,理论上开的高点识别会快点,但是会更卡。默认4" }, "infrastOptions": { "dormThreshold": 0.3, - "dormThreshold_Doc": "宿舍心情百分比阈值,心情百分比小于该值的干员会被放进宿舍。取值范围(0, 1.0),默认0.5" + "dormThreshold_Doc": "宿舍心情百分比阈值,心情百分比小于该值的干员会被放进宿舍。取值范围(0, 1.0),默认0.3" }, "emulator_Doc": "下面的和模拟器窗口捕获逻辑有关,不需要修改", "emulator": { @@ -54,611 +52,7 @@ } } }, - "tasks_Doc": "下面的和任务队列执行逻辑有关,不需要修改", - "tasks": { - "SanityBegin": { - "algorithm": "justreturn", - "action": "doNothing", - "next": [ - "UsePrts", - "StartButton1", - "StartButton2", - "PRTS", - "UseMedicine", - "UseStone", - "EndOfAction" - ] - }, - "UsePrts": { - "template": "UsePrts.png", - "templThreshold": 0.8, - "action": "clickSelf", - "next": [ - "StartButton1" - ] - }, - "StartButton1": { - "template": "StartButton1.png", - "templThreshold": 0.8, - "action": "clickSelf", - "next": [ - "StartButton2", - "UseMedicine", - "UseStone" - ] - }, - "StartButton2": { - "template": "StartButton2.png", - "action": "clickSelf", - "rearDelay": 20000, - "templThreshold": 0.95, - "next": [ - "StartButton2", - "PRTS" - ] - }, - "PRTS": { - "template": "PRTS.png", - "action": "doNothing", - "rearDelay": 5000, - "next": [ - "PRTS", - "PrtsErrorConfirm", - "EndOfAction", - "WaitAfterPRTS" - ] - }, - "WaitAfterPRTS": { - "rearDelay": 3000, - "algorithm": "justreturn", - "action": "doNothing", - "next": [ - "PRTS", - "EndOfAction", - "ClickCornerAfterPRTS" - ] - }, - "ClickCornerAfterPRTS": { - "ClickCorner_Doc": "点击右下角,既不会点到掉落物品,又能点到蓝色开始按钮(为了容错)的一块位置。", - "algorithm": "justreturn", - "action": "clickRect", - "specificArea": [ - 1100, - 700, - 150, - 30 - ], - "next": [ - "EndOfAction", - "Loading", - "StartButton1", - "StartButton2", - "UseMedicine", - "UseStone", - "ClickCornerAfterPRTS" - ] - }, - "EndOfAction": { - "algorithm": "OcrDetect", - "text": [ "行动结束" ], - "preDelay": 3000, - "action": "printWindow", - "next": [ - "ClickCorner" - ] - }, - "ClickCorner": { - "ClickCorner_Doc": "点击右下角,既不会点到掉落物品,又能点到蓝色开始按钮(为了容错)的一块位置。", - "algorithm": "justreturn", - "action": "clickRect", - "rearDelay": 2000, - "specificArea": [ - 1100, - 700, - 150, - 30 - ], - "next": [ - "Loading", - "StartButton1", - "StartButton2", - "UseMedicine", - "UseStone", - "EndOfAction" - ] - }, - "Loading": { - "template": "Loading.png", - "templThreshold": 0.8, - "action": "doNothing", - "next": [ - "StartButton1" - ] - }, - "UseMedicine": { - "template": "UseMedicine.png", - "action": "doNothing", - "next": [ - "MedicineConfirm" - ] - }, - "MedicineConfirm": { - "template": "MedicineConfirm.png", - "action": "clickSelf", - "reduceOtherTimes": [ - "StartButton1" - ], - "next": [ - "StartButton1" - ] - }, - "UseStone": { - "template": "UseStone.png", - "action": "doNothing", - "next": [ - "StoneConfirm" - ] - }, - "StoneConfirm": { - "template": "MedicineConfirm.png", - "action": "clickSelf", - "maxTimes": 0, - "reduceOtherTimes": [ - "StartButton1" - ], - "next": [ - "StartButton1" - ] - }, - "PrtsErrorConfirm": { - "template": "PrtsErrorConfirm.png", - "action": "doNothing", - "next": [ - "AbandonAction" - ] - }, - "AbandonAction": { - "template": "AbandonAction.png", - "action": "clickSelf", - "reduceOtherTimes": [ - "StartButton1", - "StartButton2", - "Loading" - ], - "next": [ - "EndOfAction" - ] - }, - "VisitBegin": { - "algorithm": "justreturn", - "action": "doNothing", - "next": [ - "Friends", - "FriendsList", - "StartToVisit", - "VisitNext", - "VisitNextBlack", - "ReturnToFriends" - ] - }, - "ReturnToFriends": { - "template": "Return.png", - "templThreshold": 0.85, - "histThreshold": 0.85, - "rearDelay": 1000, - "action": "clickSelf", - "next": [ - "Friends", - "ReturnToFriends" - ] - }, - "Friends": { - "template": "Friends.png", - "templThreshold": 0.85, - "preDelay": 1000, - "action": "clickSelf", - "next": [ - "FriendsList" - ] - }, - "FriendsList": { - "template": "FriendsList.png", - "action": "clickSelf", - "next": [ - "StartToVisit" - ] - }, - "StartToVisit": { - "template": "StartToVisit.png", - "templThreshold": 0.8, - "action": "clickSelf", - "rearDelay": 5000, - "next": [ - "VisitNext" - ] - }, - "VisitNext": { - "template": "VisitNext.png", - "action": "clickSelf", - "cache": false, - "rearDelay": 3000, - "identifyArea": [ - 1080, - 570, - 195, - 130 - ], - "exceededNext": [ - "ReturnToMall" - ], - "next": [ - "VisitLimited", - "VisitNext", - "VisitNextBlack", - "VisitNextOcr" - ] - }, - "VisitNextOcr": { - "algorithm": "OcrDetect", - "text": [ "访问下位" ], - "action": "clickSelf", - "rearDelay": 3000, - "identifyArea": [ - 1080, - 570, - 195, - 130 - ], - "exceededNext": [ - "ReturnToMall" - ], - "next": [ - "VisitLimited", - "VisitNext", - "VisitNextBlack", - "VisitNextOcr" - ] - }, - "ReturnToMall": { - "rearDelay": 1000, - "template": "Return.png", - "action": "clickSelf", - "next": [ - "Mall", - "ReturnToMall", - "ReturnToMallConfirm" - ] - }, - "ReturnToMallConfirm": { - "template": "PopupConfirm.png", - "action": "clickSelf", - "rearDelay": 5000, - "next": [ - "ReturnToMall" - ] - }, - "Mall": { - "template": "Mall.png", - "action": "clickSelf", - "next": [ - "CreditStore", - "CreditStoreOcr" - ] - }, - "CreditStore": { - "template": "CreditStore.png", - "templThreshold": 0.85, - "rearDelay": 1000, - "action": "clickSelf", - "next": [ - "CollectCredit", - "Stop" - ] - }, - "CreditStoreOcr": { - "algorithm": "OcrDetect", - "text": [ "信用交易所" ], - "rearDelay": 1000, - "action": "clickSelf", - "next": [ - "CollectCredit", - "Stop" - ] - }, - "CollectCredit": { - "template": "CollectCredit.png", - "action": "clickSelf", - "next": [ - "Stop" - ] - }, - "VisitLimited": { - "algorithm": "OcrDetect", - "text": [ "今日参与", "已达上限" ], - "action": "doNothing", - "identifyArea": [ - 900, - 50, - 375, - 140 - ], - "next": [ - "ReturnToMall" - ] - }, - "VisitNextBlack": { - "template": "VisitNextBlack.png", - "action": "doNothing", - "identifyArea": [ - 1080, - 570, - 195, - 130 - ], - "next": [ - "ReturnToMall" - ] - }, - "Stop": { - "algorithm": "justreturn", - "action": "stop", - "next": [] - }, - "RecruitTime": { - "template": "RecruitTimeReduce.png", - "templThreshold": 0.89, - "action": "clickRect", - "specificArea": [ 391, 279, 129, 44 ], - "next": [ - "Stop" - ] - }, - "Listless": { - "template": "Listless.png", - "action": "clickSelf", - "next": [ - "Stop" - ] - }, - "OperatorBegin": { - "algorithm": "justreturn", - "action": "doNothing", - "next": [ - "EnterOperator", - "ReturnToOperator" - ] - }, - "EnterOperator": { - "template": "EnterOperator.png", - "rareDelay": 1000, - "templThreshold": 0.8, - "action": "clickSelf", - "next": [ - "Stop" - ] - }, - "ReturnToOperator": { - "template": "Return.png", - "templThreshold": 0.85, - "histThreshold": 0.85, - "rearDelay": 1000, - "action": "clickSelf", - "next": [ - "EnterOperator", - "ReturnToOperator" - ] - }, - "InfrastBegin": { - "algorithm": "justreturn", - "action": "doNothing", - "next": [ - "EnterInfrast", - "InfrastEnteredFlag", - "InfrastNotification", - "ReturnToInfrast" - ] - }, - "ReturnToInfrast": { - "template": "Return.png", - "templThreshold": 0.85, - "histThreshold": 0.85, - "rearDelay": 1000, - "action": "clickSelf", - "next": [ - "EnterInfrast", - "InfrastNotification", - "InfrastEnteredFlag", - "ReturnToInfrast" - ] - }, - "EnterInfrast": { - "template": "EnterInfrast.png", - "templThreshold": 0.85, - "histThreshold": 0.85, - "rareDelay": 3000, - "action": "clickSelf", - "next": [ - "InfrastEnteredFlag" - ] - }, - "InfrastEnteredFlag": { - "template": "InfrastOverview.png", - "templThreshold": 0.8, - "action": "doNothing", - "next": [ - "InfrastNotification", - "InfrastSwipeToTheLeft" - ] - }, - "InfrastSwipeToTheLeft": { - "algorithm": "justReturn", - "action": "swipeToTheLeft", - "next": [ - "Stop" - ] - }, - "Trade": { - "template": "Trade.png", - "templThreshold": 0.8, - "cache": false, - "action": "clickSelf", - "rearDelay": 1000, - "next": [ - "ManufacturingLeftBottom" - ] - }, - "TradeMini": { - "template": "TradeMini.png", - "templThreshold": 0.8, - "cache": false, - "action": "clickSelf", - "rearDelay": 1000, - "next": [ - "ManufacturingLeftBottom" - ] - }, - "Manufacturing": { - "template": "Manufacturing.png", - "templThreshold": 0.8, - "cache": false, - "action": "clickSelf", - "rearDelay": 1000, - "next": [ - "ManufacturingLeftBottom" - ] - }, - "ManufacturingMini": { - "template": "ManufacturingMini.png", - "templThreshold": 0.8, - "cache": false, - "action": "clickSelf", - "rearDelay": 1000, - "next": [ - "ManufacturingLeftBottom" - ] - }, - "ManufacturingLeftBottom": { - "Doc": "制造站点进去之后,左下角那个“中级作战记录 制造中”", - "algorithm": "justreturn", - "action": "clickRect", - "specificArea": [ - 1, - 535, - 525, - 180 - ], - "next": [ - "Manufacturing1st" - ] - }, - "Manufacturing1st": { - "Doc": "设施列表里第一个(第一个制造站或者贸易站)", - "algorithm": "justreturn", - "action": "clickRect", - "specificArea": [ - 1, - 183, - 220, - 60 - ], - "next": [ - "Stop" - ] - }, - "InfrastNotification": { - "template": "InfrastNotification.png", - "templThreshold": 0.8, - "action": "clickSelf", - "next": [ - "InfrastReward", - "InfrastExitReward" - ] - }, - "InfrastReward": { - "algorithm": "OcrDetect", - "text": [ "可收获", "订单交付", "信赖" ], - "rearDelay": 1000, - "action": "clickSelf", - "identifyArea": [ - 0, - 600, - 800, - 118 - ], - "next": [ - "InfrastReward", - "InfrastExitReward" - ] - }, - "InfrastExitReward": { - "Doc": "干员疲劳、线索收集 是不能一键收获的,所以要先退出一键收获的界面,这里点击的是控制中枢左侧那一片空白的区域", - "algorithm": "justreturn", - "action": "clickRect", - "specificArea": [ - 250, - 100, - 380, - 140 - ], - "next": [ - "Stop" - ] - }, - "UavAssist-MFG": { - "template": "UavAssist-MFG.png", - "action": "clickSelf", - "cache": false, - "maxTimes": 1, - "Doc": "不同于贸易站,制造站的无人机是一次性全用掉的,所以只执行一次就够了", - "next": [ - "UavMax", - "UavConfirm" - ] - }, - "UavAssist-Trade": { - "template": "UavAssist-Trade.png", - "action": "clickSelf", - "cache": false, - "next": [ - "UavMax", - "UavConfirm" - ] - }, - "UavMax": { - "template": "UavMax.png", - "action": "clickSelf", - "next": [ - "UavConfirm" - ] - }, - "UavConfirm": { - "template": "UavConfirm.png", - "action": "clickSelf", - "rearDelay": 2000, - "next": [ - "DeliverableOrder", - "UavAssist-Trade-Stop", - "UavAssist-MFG" - ] - }, - "DeliverableOrder": { - "template": "DeliverableOrder.png", - "cache": false, - "action": "clickSelf", - "next": [ - "DeliverableOrder", - "UavAssist-Trade" - ] - }, - "UavAssist-Trade-Stop": { - "Doc": "如果找到了“无人机加速”按钮,却没有找到订单交付:说明上一次无人机没有把一个订单加速完成,也说明没有更多的无人机了,所以直接stop", - "template": "UavAssist-Trade.png", - "action": "stop", - "cache": false, - "next": [ - ] - } - }, + "ocrReplace_Doc": "下面为常见的文字识别错误纠正,不需要修改", "recruitOcrReplace": [ [ "沮击", "狙击" ], [ "泪击", "狙击" ], diff --git a/resource/tasks.json b/resource/tasks.json new file mode 100644 index 0000000000..f51518721d --- /dev/null +++ b/resource/tasks.json @@ -0,0 +1,604 @@ +{ + "SanityBegin": { + "algorithm": "justreturn", + "action": "doNothing", + "next": [ + "UsePrts", + "StartButton1", + "StartButton2", + "PRTS", + "UseMedicine", + "UseStone", + "EndOfAction" + ] + }, + "UsePrts": { + "template": "UsePrts.png", + "templThreshold": 0.8, + "action": "clickSelf", + "next": [ + "StartButton1" + ] + }, + "StartButton1": { + "template": "StartButton1.png", + "templThreshold": 0.8, + "action": "clickSelf", + "next": [ + "StartButton2", + "UseMedicine", + "UseStone" + ] + }, + "StartButton2": { + "template": "StartButton2.png", + "action": "clickSelf", + "rearDelay": 20000, + "templThreshold": 0.95, + "next": [ + "StartButton2", + "PRTS" + ] + }, + "PRTS": { + "template": "PRTS.png", + "action": "doNothing", + "rearDelay": 5000, + "next": [ + "PRTS", + "PrtsErrorConfirm", + "EndOfAction", + "WaitAfterPRTS" + ] + }, + "WaitAfterPRTS": { + "rearDelay": 3000, + "algorithm": "justreturn", + "action": "doNothing", + "next": [ + "PRTS", + "EndOfAction", + "ClickCornerAfterPRTS" + ] + }, + "ClickCornerAfterPRTS": { + "ClickCorner_Doc": "点击右下角,既不会点到掉落物品,又能点到蓝色开始按钮(为了容错)的一块位置。", + "algorithm": "justreturn", + "action": "clickRect", + "specificArea": [ + 1100, + 700, + 150, + 30 + ], + "next": [ + "EndOfAction", + "Loading", + "StartButton1", + "StartButton2", + "UseMedicine", + "UseStone", + "ClickCornerAfterPRTS" + ] + }, + "EndOfAction": { + "algorithm": "OcrDetect", + "text": [ "行动结束" ], + "preDelay": 3000, + "action": "printWindow", + "next": [ + "ClickCorner" + ] + }, + "ClickCorner": { + "ClickCorner_Doc": "点击右下角,既不会点到掉落物品,又能点到蓝色开始按钮(为了容错)的一块位置。", + "algorithm": "justreturn", + "action": "clickRect", + "rearDelay": 2000, + "specificArea": [ + 1100, + 700, + 150, + 30 + ], + "next": [ + "Loading", + "StartButton1", + "StartButton2", + "UseMedicine", + "UseStone", + "EndOfAction" + ] + }, + "Loading": { + "template": "Loading.png", + "templThreshold": 0.8, + "action": "doNothing", + "next": [ + "StartButton1" + ] + }, + "UseMedicine": { + "template": "UseMedicine.png", + "action": "doNothing", + "next": [ + "MedicineConfirm" + ] + }, + "MedicineConfirm": { + "template": "MedicineConfirm.png", + "action": "clickSelf", + "reduceOtherTimes": [ + "StartButton1" + ], + "next": [ + "StartButton1" + ] + }, + "UseStone": { + "template": "UseStone.png", + "action": "doNothing", + "next": [ + "StoneConfirm" + ] + }, + "StoneConfirm": { + "template": "MedicineConfirm.png", + "action": "clickSelf", + "maxTimes": 0, + "reduceOtherTimes": [ + "StartButton1" + ], + "next": [ + "StartButton1" + ] + }, + "PrtsErrorConfirm": { + "template": "PrtsErrorConfirm.png", + "action": "doNothing", + "next": [ + "AbandonAction" + ] + }, + "AbandonAction": { + "template": "AbandonAction.png", + "action": "clickSelf", + "reduceOtherTimes": [ + "StartButton1", + "StartButton2", + "Loading" + ], + "next": [ + "EndOfAction" + ] + }, + "VisitBegin": { + "algorithm": "justreturn", + "action": "doNothing", + "next": [ + "Friends", + "FriendsList", + "StartToVisit", + "VisitNext", + "VisitNextBlack", + "ReturnToFriends" + ] + }, + "ReturnToFriends": { + "template": "Return.png", + "templThreshold": 0.85, + "histThreshold": 0.85, + "rearDelay": 1000, + "action": "clickSelf", + "next": [ + "Friends", + "ReturnToFriends" + ] + }, + "Friends": { + "template": "Friends.png", + "templThreshold": 0.85, + "preDelay": 1000, + "action": "clickSelf", + "next": [ + "FriendsList" + ] + }, + "FriendsList": { + "template": "FriendsList.png", + "action": "clickSelf", + "next": [ + "StartToVisit" + ] + }, + "StartToVisit": { + "template": "StartToVisit.png", + "templThreshold": 0.8, + "action": "clickSelf", + "rearDelay": 5000, + "next": [ + "VisitNext" + ] + }, + "VisitNext": { + "template": "VisitNext.png", + "action": "clickSelf", + "cache": false, + "rearDelay": 3000, + "identifyArea": [ + 1080, + 570, + 195, + 130 + ], + "exceededNext": [ + "ReturnToMall" + ], + "next": [ + "VisitLimited", + "VisitNext", + "VisitNextBlack", + "VisitNextOcr" + ] + }, + "VisitNextOcr": { + "algorithm": "OcrDetect", + "text": [ "访问下位" ], + "action": "clickSelf", + "rearDelay": 3000, + "identifyArea": [ + 1080, + 570, + 195, + 130 + ], + "exceededNext": [ + "ReturnToMall" + ], + "next": [ + "VisitLimited", + "VisitNext", + "VisitNextBlack", + "VisitNextOcr" + ] + }, + "ReturnToMall": { + "rearDelay": 1000, + "template": "Return.png", + "action": "clickSelf", + "next": [ + "Mall", + "ReturnToMall", + "ReturnToMallConfirm" + ] + }, + "ReturnToMallConfirm": { + "template": "PopupConfirm.png", + "action": "clickSelf", + "rearDelay": 5000, + "next": [ + "ReturnToMall" + ] + }, + "Mall": { + "template": "Mall.png", + "action": "clickSelf", + "next": [ + "CreditStore", + "CreditStoreOcr" + ] + }, + "CreditStore": { + "template": "CreditStore.png", + "templThreshold": 0.85, + "rearDelay": 1000, + "action": "clickSelf", + "next": [ + "CollectCredit", + "Stop" + ] + }, + "CreditStoreOcr": { + "algorithm": "OcrDetect", + "text": [ "信用交易所" ], + "rearDelay": 1000, + "action": "clickSelf", + "next": [ + "CollectCredit", + "Stop" + ] + }, + "CollectCredit": { + "template": "CollectCredit.png", + "action": "clickSelf", + "next": [ + "Stop" + ] + }, + "VisitLimited": { + "algorithm": "OcrDetect", + "text": [ "今日参与", "已达上限" ], + "action": "doNothing", + "identifyArea": [ + 900, + 50, + 375, + 140 + ], + "next": [ + "ReturnToMall" + ] + }, + "VisitNextBlack": { + "template": "VisitNextBlack.png", + "action": "doNothing", + "identifyArea": [ + 1080, + 570, + 195, + 130 + ], + "next": [ + "ReturnToMall" + ] + }, + "Stop": { + "algorithm": "justreturn", + "action": "stop", + "next": [] + }, + "RecruitTime": { + "template": "RecruitTimeReduce.png", + "templThreshold": 0.89, + "action": "clickRect", + "specificArea": [ 391, 279, 129, 44 ], + "next": [ + "Stop" + ] + }, + "Listless": { + "template": "Listless.png", + "action": "clickSelf", + "next": [ + "Stop" + ] + }, + "OperatorBegin": { + "algorithm": "justreturn", + "action": "doNothing", + "next": [ + "EnterOperator", + "ReturnToOperator" + ] + }, + "EnterOperator": { + "template": "EnterOperator.png", + "rareDelay": 1000, + "templThreshold": 0.8, + "action": "clickSelf", + "next": [ + "Stop" + ] + }, + "ReturnToOperator": { + "template": "Return.png", + "templThreshold": 0.85, + "histThreshold": 0.85, + "rearDelay": 1000, + "action": "clickSelf", + "next": [ + "EnterOperator", + "ReturnToOperator" + ] + }, + "InfrastBegin": { + "algorithm": "justreturn", + "action": "doNothing", + "next": [ + "EnterInfrast", + "InfrastEnteredFlag", + "InfrastNotification", + "ReturnToInfrast" + ] + }, + "ReturnToInfrast": { + "template": "Return.png", + "templThreshold": 0.85, + "histThreshold": 0.85, + "rearDelay": 1000, + "action": "clickSelf", + "next": [ + "EnterInfrast", + "InfrastNotification", + "InfrastEnteredFlag", + "ReturnToInfrast" + ] + }, + "EnterInfrast": { + "template": "EnterInfrast.png", + "templThreshold": 0.85, + "histThreshold": 0.85, + "rareDelay": 3000, + "action": "clickSelf", + "next": [ + "InfrastEnteredFlag" + ] + }, + "InfrastEnteredFlag": { + "template": "InfrastOverview.png", + "templThreshold": 0.8, + "action": "doNothing", + "next": [ + "InfrastNotification", + "InfrastSwipeToTheLeft" + ] + }, + "InfrastSwipeToTheLeft": { + "algorithm": "justReturn", + "action": "swipeToTheLeft", + "next": [ + "Stop" + ] + }, + "Trade": { + "template": "Trade.png", + "templThreshold": 0.8, + "cache": false, + "action": "clickSelf", + "rearDelay": 1000, + "next": [ + "ManufacturingLeftBottom" + ] + }, + "TradeMini": { + "template": "TradeMini.png", + "templThreshold": 0.8, + "cache": false, + "action": "clickSelf", + "rearDelay": 1000, + "next": [ + "ManufacturingLeftBottom" + ] + }, + "Manufacturing": { + "template": "Manufacturing.png", + "templThreshold": 0.8, + "cache": false, + "action": "clickSelf", + "rearDelay": 1000, + "next": [ + "ManufacturingLeftBottom" + ] + }, + "ManufacturingMini": { + "template": "ManufacturingMini.png", + "templThreshold": 0.8, + "cache": false, + "action": "clickSelf", + "rearDelay": 1000, + "next": [ + "ManufacturingLeftBottom" + ] + }, + "ManufacturingLeftBottom": { + "Doc": "制造站点进去之后,左下角那个“中级作战记录 制造中”", + "algorithm": "justreturn", + "action": "clickRect", + "specificArea": [ + 1, + 535, + 525, + 180 + ], + "next": [ + "Manufacturing1st" + ] + }, + "Manufacturing1st": { + "Doc": "设施列表里第一个(第一个制造站或者贸易站)", + "algorithm": "justreturn", + "action": "clickRect", + "specificArea": [ + 1, + 183, + 220, + 60 + ], + "next": [ + "Stop" + ] + }, + "InfrastNotification": { + "template": "InfrastNotification.png", + "templThreshold": 0.8, + "action": "clickSelf", + "next": [ + "InfrastReward", + "InfrastExitReward" + ] + }, + "InfrastReward": { + "algorithm": "OcrDetect", + "text": [ "可收获", "订单交付", "信赖" ], + "rearDelay": 1000, + "action": "clickSelf", + "identifyArea": [ + 0, + 600, + 800, + 118 + ], + "next": [ + "InfrastReward", + "InfrastExitReward" + ] + }, + "InfrastExitReward": { + "Doc": "干员疲劳、线索收集 是不能一键收获的,所以要先退出一键收获的界面,这里点击的是控制中枢左侧那一片空白的区域", + "algorithm": "justreturn", + "action": "clickRect", + "specificArea": [ + 250, + 100, + 380, + 140 + ], + "next": [ + "Stop" + ] + }, + "UavAssist-MFG": { + "template": "UavAssist-MFG.png", + "action": "clickSelf", + "cache": false, + "maxTimes": 1, + "Doc": "不同于贸易站,制造站的无人机是一次性全用掉的,所以只执行一次就够了", + "next": [ + "UavMax", + "UavConfirm" + ] + }, + "UavAssist-Trade": { + "template": "UavAssist-Trade.png", + "action": "clickSelf", + "cache": false, + "next": [ + "UavMax", + "UavConfirm" + ] + }, + "UavMax": { + "template": "UavMax.png", + "action": "clickSelf", + "next": [ + "UavConfirm" + ] + }, + "UavConfirm": { + "template": "UavConfirm.png", + "action": "clickSelf", + "rearDelay": 2000, + "next": [ + "DeliverableOrder", + "UavAssist-Trade-Stop", + "UavAssist-MFG" + ] + }, + "DeliverableOrder": { + "template": "DeliverableOrder.png", + "cache": false, + "action": "clickSelf", + "next": [ + "DeliverableOrder", + "UavAssist-Trade" + ] + }, + "UavAssist-Trade-Stop": { + "Doc": "如果找到了“无人机加速”按钮,却没有找到订单交付:说明上一次无人机没有把一个订单加速完成,也说明没有更多的无人机了,所以直接stop", + "template": "UavAssist-Trade.png", + "action": "stop", + "cache": false, + "next": [ + ] + } +} \ No newline at end of file diff --git a/src/MeoAssistance/Assistance.cpp b/src/MeoAssistance/Assistance.cpp index c6a833e318..d37b1231f3 100644 --- a/src/MeoAssistance/Assistance.cpp +++ b/src/MeoAssistance/Assistance.cpp @@ -12,6 +12,7 @@ #include "Logger.hpp" #include "AsstAux.h" #include "Task.h" +#include "TaskConfiger.h" #include "RecruitConfiger.h" #include "InfrastConfiger.h" @@ -38,6 +39,11 @@ Assistance::Assistance(AsstCallback callback, void* callback_arg) callback_error(); return; } + ret = TaskConfiger::get_instance().load(GetResourceDir() + "tasks.json"); + if (!ret) { + callback_error(); + return; + } ret = RecruitConfiger::get_instance().load(GetResourceDir() + "recruit.json"); if (!ret) { callback_error(); @@ -50,7 +56,7 @@ Assistance::Assistance(AsstCallback callback, void* callback_arg) } m_identify_ptr = std::make_shared(); - for (const auto& [name, info] : Configer::get_instance().m_all_tasks_info) + for (const auto& [name, info] : TaskConfiger::get_instance().m_all_tasks_info) { if (info->algorithm != AlgorithmType::MatchTemplate) { @@ -71,8 +77,6 @@ Assistance::Assistance(AsstCallback callback, void* callback_arg) } } - m_identify_ptr->set_use_cache(Configer::get_instance().m_options.identify_cache); - m_identify_ptr->set_ocr_param(Configer::get_instance().m_options.ocr_gpu_index, Configer::get_instance().m_options.ocr_thread_number); ret = m_identify_ptr->ocr_init_models(GetResourceDir() + "OcrLiteOnnx\\models\\"); if (!ret) { @@ -402,7 +406,7 @@ bool Assistance::set_param(const std::string& type, const std::string& param, co DebugTraceFunction; DebugTrace("SetParam |", type, param, value); - return Configer::get_instance().set_param(type, param, value); + return TaskConfiger::get_instance().set_param(type, param, value); } void Assistance::working_proc() @@ -580,7 +584,7 @@ void asst::Assistance::append_callback(AsstMsg msg, json::value detail) void Assistance::clear_exec_times() { - for (auto&& pair : Configer::get_instance().m_all_tasks_info) + for (auto&& pair : TaskConfiger::get_instance().m_all_tasks_info) { pair.second->exec_times = 0; } diff --git a/src/MeoAssistance/AsstDef.h b/src/MeoAssistance/AsstDef.h index b3d2fd4e57..4f8cbdbc24 100644 --- a/src/MeoAssistance/AsstDef.h +++ b/src/MeoAssistance/AsstDef.h @@ -156,8 +156,7 @@ namespace asst { }; struct Options { - bool identify_cache = false; // 图像识别缓存功能:开启后可以大幅降低CPU消耗,但需要保证要识别的按钮每次的位置不会改变 - int task_delay = 0; // 任务间延时:越快操作越快,但会增加CPU消耗 + int task_delay = 0; // 任务间延时:越快操作越快,但会增加CPU消耗 int control_delay_lower = 0; // 点击随机延时下限:每次点击操作会进行随机延时 int control_delay_upper = 0; // 点击随机延时上限:每次点击操作会进行随机延时 bool print_window = false; // 截图功能:开启后每次结算界面会截图到screenshot目录下 diff --git a/src/MeoAssistance/Configer.cpp b/src/MeoAssistance/Configer.cpp index 22648da2e4..a6c444b170 100644 --- a/src/MeoAssistance/Configer.cpp +++ b/src/MeoAssistance/Configer.cpp @@ -10,45 +10,6 @@ using namespace asst; -bool Configer::set_param(const std::string& type, const std::string& param, const std::string& value) -{ - // 暂时只用到了这些,总的参数太多了,后面要用啥再加上 - if (type == "task.type") { - if (m_all_tasks_info.find(param) == m_all_tasks_info.cend()) { - return false; - } - auto task_info_ptr = m_all_tasks_info[param]; - std::string type = value; - std::transform(type.begin(), type.end(), type.begin(), std::tolower); - if (type == "clickself") { - task_info_ptr->action = ProcessTaskAction::ClickSelf; - } - else if (type == "clickrand") { - task_info_ptr->action = ProcessTaskAction::ClickRand; - } - else if (type == "donothing" || type.empty()) { - task_info_ptr->action = ProcessTaskAction::DoNothing; - } - else if (type == "stop") { - task_info_ptr->action = ProcessTaskAction::Stop; - } - else if (type == "clickrect") { - task_info_ptr->action = ProcessTaskAction::ClickRect; - } - else { - DebugTraceError("Task", param, "'s type error:", type); - return false; - } - } - else if (type == "task.maxTimes") { - if (m_all_tasks_info.find(param) == m_all_tasks_info.cend()) { - return false; - } - m_all_tasks_info[param]->max_times = std::stoi(value); - } - return true; -} - bool asst::Configer::parse(json::value&& json) { json::value root = std::move(json); @@ -58,7 +19,7 @@ bool asst::Configer::parse(json::value&& json) json::value& options_json = root["options"]; { m_options.task_delay = options_json["taskDelay"].as_integer(); - m_options.identify_cache = options_json["identifyCache"].as_boolean(); + //m_options.identify_cache = options_json["identifyCache"].as_boolean(); m_options.control_delay_lower = options_json["controlDelayRange"][0].as_integer(); m_options.control_delay_upper = options_json["controlDelayRange"][1].as_integer(); m_options.print_window = options_json["printWindow"].as_boolean(); @@ -73,132 +34,6 @@ bool asst::Configer::parse(json::value&& json) } DebugTrace("InfrastOptions", infrast_options_json.to_string()); - for (auto&& [name, task_json] : root["tasks"].as_object()) { - std::string algorithm_str = task_json.get("algorithm", "matchtemplate"); - std::transform(algorithm_str.begin(), algorithm_str.end(), algorithm_str.begin(), std::tolower); - AlgorithmType algorithm = AlgorithmType::Invaild; - if (algorithm_str == "matchtemplate") { - algorithm = AlgorithmType::MatchTemplate; - } - else if (algorithm_str == "justreturn") { - algorithm = AlgorithmType::JustReturn; - } - else if (algorithm_str == "ocrdetect") { - algorithm = AlgorithmType::OcrDetect; - } - //else if (algorithm_str == "comparehist") {} // CompareHist是MatchTemplate的衍生算法,不应作为单独的配置参数出现 - else { - DebugTraceError("Algorithm error:", algorithm_str); - return false; - } - - std::shared_ptr task_info_ptr = nullptr; - switch (algorithm) { - case AlgorithmType::JustReturn: - task_info_ptr = std::make_shared(); - break; - case AlgorithmType::MatchTemplate: - { - auto match_task_info_ptr = std::make_shared(); - match_task_info_ptr->template_filename = task_json["template"].as_string(); - match_task_info_ptr->templ_threshold = task_json.get("templThreshold", TemplThresholdDefault); - match_task_info_ptr->hist_threshold = task_json.get("histThreshold", HistThresholdDefault); - match_task_info_ptr->cache = task_json.get("cache", true); - task_info_ptr = match_task_info_ptr; - } - break; - case AlgorithmType::OcrDetect: - { - auto ocr_task_info_ptr = std::make_shared(); - for (const json::value& text : task_json["text"].as_array()) - { - ocr_task_info_ptr->text.emplace_back(text.as_string()); - } - ocr_task_info_ptr->need_match = task_json.get("need_match", false); - if (task_json.exist("ocrReplace")) - { - for (const auto& [key, value] : task_json["ocrReplace"].as_object()) { - ocr_task_info_ptr->replace_map.emplace(key, value.as_string()); - } - } - task_info_ptr = ocr_task_info_ptr; - } - break; - } - task_info_ptr->algorithm = algorithm; - task_info_ptr->name = name; - std::string action = task_json["action"].as_string(); - std::transform(action.begin(), action.end(), action.begin(), std::tolower); - if (action == "clickself") { - task_info_ptr->action = ProcessTaskAction::ClickSelf; - } - else if (action == "clickrand") { - task_info_ptr->action = ProcessTaskAction::ClickRand; - } - else if (action == "donothing" || action.empty()) { - task_info_ptr->action = ProcessTaskAction::DoNothing; - } - else if (action == "stop") { - task_info_ptr->action = ProcessTaskAction::Stop; - } - else if (action == "clickrect") { - task_info_ptr->action = ProcessTaskAction::ClickRect; - json::value& area_json = task_json["specificArea"]; - task_info_ptr->specific_area = Rect( - area_json[0].as_integer(), - area_json[1].as_integer(), - area_json[2].as_integer(), - area_json[3].as_integer()); - } - else if (action == "printwindow") { - task_info_ptr->action = ProcessTaskAction::PrintWindow; - } - else if (action == "swipetotheleft") { - task_info_ptr->action = ProcessTaskAction::SwipeToTheLeft; - } - else if (action == "swipetotheright") { - task_info_ptr->action = ProcessTaskAction::SwipeToTheRight; - } - else { - DebugTraceError("Task:", name, "error:", action); - return false; - } - - task_info_ptr->max_times = task_json.get("maxTimes", INT_MAX); - if (task_json.exist("exceededNext")) { - json::array& excceed_next_arr = task_json["exceededNext"].as_array(); - for (const json::value& excceed_next : excceed_next_arr) { - task_info_ptr->exceeded_next.emplace_back(excceed_next.as_string()); - } - } - else { - task_info_ptr->exceeded_next.emplace_back("Stop"); - } - task_info_ptr->pre_delay = task_json.get("preDelay", 0); - task_info_ptr->rear_delay = task_json.get("rearDelay", 0); - if (task_json.exist("reduceOtherTimes")) { - json::array& reduce_arr = task_json["reduceOtherTimes"].as_array(); - for (const json::value& reduce : reduce_arr) { - task_info_ptr->reduce_other_times.emplace_back(reduce.as_string()); - } - } - if (task_json.exist("identifyArea")) { - json::array& area_arr = task_json["identifyArea"].as_array(); - task_info_ptr->identify_area = Rect( - area_arr[0].as_integer(), - area_arr[1].as_integer(), - area_arr[2].as_integer(), - area_arr[3].as_integer()); - } - - json::array& next_arr = task_json["next"].as_array(); - for (const json::value& next : next_arr) { - task_info_ptr->next.emplace_back(next.as_string()); - } - - m_all_tasks_info.emplace(name, task_info_ptr); - } - for (auto&& [name, emulator_json] : root["emulator"].as_object()) { EmulatorInfo emulator_info; emulator_info.name = name; diff --git a/src/MeoAssistance/Configer.h b/src/MeoAssistance/Configer.h index 44b5634a25..881c7c03dc 100644 --- a/src/MeoAssistance/Configer.h +++ b/src/MeoAssistance/Configer.h @@ -21,8 +21,6 @@ namespace asst { //virtual bool load(const std::string& filename) override; - bool set_param(const std::string& type, const std::string& param, const std::string& value); - constexpr static int WindowWidthDefault = 1280; constexpr static int WindowHeightDefault = 720; constexpr static double TemplThresholdDefault = 0.9; @@ -30,7 +28,6 @@ namespace asst { std::string m_version; Options m_options; - std::unordered_map> m_all_tasks_info; std::unordered_map m_handles; std::unordered_map m_recruit_ocr_replace; std::unordered_map m_infrast_ocr_replace; diff --git a/src/MeoAssistance/Identify.cpp b/src/MeoAssistance/Identify.cpp index 961d0c7a39..1eabec0d08 100644 --- a/src/MeoAssistance/Identify.cpp +++ b/src/MeoAssistance/Identify.cpp @@ -37,17 +37,6 @@ bool asst::Identify::add_text_image(const std::string& text, const std::string& return true; } -void Identify::set_use_cache(bool b) noexcept -{ - if (b) { - m_use_cache = true; - } - else { - m_cache_map.clear(); - m_use_cache = false; - } -} - Mat Identify::image_2_hist(const cv::Mat& src) { Mat src_hsv; @@ -281,7 +270,7 @@ asst::Identify::FindImageResult asst::Identify::find_image( } // 有缓存,用直方图比较,CPU占用会低很多,但要保证每次按钮图片的位置不变 - if (m_use_cache && m_cache_map.find(templ_name) != m_cache_map.cend()) { + if (m_cache_map.find(templ_name) != m_cache_map.cend()) { const auto& [raw_rect, hist] = m_cache_map.at(templ_name); double value = image_hist_comp(image(raw_rect), hist); Rect dst_rect = make_rect(raw_rect); @@ -294,7 +283,7 @@ asst::Identify::FindImageResult asst::Identify::find_image( const cv::Mat& templ_mat = m_mat_map.at(templ_name); const auto& [value, point] = match_template(image, templ_mat); cv::Rect raw_rect(point.x, point.y, templ_mat.cols, templ_mat.rows); - if (m_use_cache && value >= add_cache_thres) { + if (value >= add_cache_thres) { m_cache_map.emplace(templ_name, std::make_pair(raw_rect, image_2_hist(image(raw_rect)))); } Rect dst_rect = make_rect(raw_rect); diff --git a/src/MeoAssistance/Identify.h b/src/MeoAssistance/Identify.h index 0431abc6a9..c66f87ecb0 100644 --- a/src/MeoAssistance/Identify.h +++ b/src/MeoAssistance/Identify.h @@ -32,7 +32,6 @@ namespace asst { ~Identify() = default; /*** OpenCV package ***/ - void set_use_cache(bool b) noexcept; bool add_image(const std::string& name, const std::string& path); bool add_text_image(const std::string& text, const std::string& path); diff --git a/src/MeoAssistance/MeoAssistance.vcxproj b/src/MeoAssistance/MeoAssistance.vcxproj index 3ff33921c1..6c568479e9 100644 --- a/src/MeoAssistance/MeoAssistance.vcxproj +++ b/src/MeoAssistance/MeoAssistance.vcxproj @@ -34,6 +34,7 @@ + @@ -56,6 +57,7 @@ + diff --git a/src/MeoAssistance/MeoAssistance.vcxproj.filters b/src/MeoAssistance/MeoAssistance.vcxproj.filters index c4e7c4ad23..fb2df0ebe7 100644 --- a/src/MeoAssistance/MeoAssistance.vcxproj.filters +++ b/src/MeoAssistance/MeoAssistance.vcxproj.filters @@ -120,6 +120,9 @@ 头文件\Task + + 头文件\Configer + @@ -179,5 +182,8 @@ 源文件\Task + + 源文件\Configer + \ No newline at end of file diff --git a/src/MeoAssistance/OpenRecruitTask.cpp b/src/MeoAssistance/OpenRecruitTask.cpp index 10f3fb9ba8..b7fd06140d 100644 --- a/src/MeoAssistance/OpenRecruitTask.cpp +++ b/src/MeoAssistance/OpenRecruitTask.cpp @@ -8,6 +8,7 @@ #include "WinMacro.h" #include "Configer.h" #include "Identify.h" +#include "TaskConfiger.h" #include "RecruitConfiger.h" #include "AsstAux.h" @@ -40,7 +41,7 @@ bool OpenRecruitTask::run() m_identify_ptr->find_image(image(identify_area), "RecruitTime"); const static auto time_reduce_task_ptr = std::dynamic_pointer_cast( - Configer::get_instance().m_all_tasks_info["RecruitTime"]); + TaskConfiger::get_instance().m_all_tasks_info["RecruitTime"]); if (score >= time_reduce_task_ptr->templ_threshold) { m_controller_ptr->click(time_reduce_task_ptr->specific_area, false); diff --git a/src/MeoAssistance/ProcessTask.cpp b/src/MeoAssistance/ProcessTask.cpp index cc98d552a8..20e999c738 100644 --- a/src/MeoAssistance/ProcessTask.cpp +++ b/src/MeoAssistance/ProcessTask.cpp @@ -7,6 +7,7 @@ #include "AsstAux.h" #include "Configer.h" +#include "TaskConfiger.h" #include "WinMacro.h" #include "Identify.h" @@ -83,15 +84,12 @@ bool ProcessTask::run() need_stop = true; break; case ProcessTaskAction::PrintWindow: - { - if (!sleep(Configer::get_instance().m_options.print_window_delay)) - { - return false; + if (Configer::get_instance().m_options.print_window) { + sleep(Configer::get_instance().m_options.print_window_delay); + static const std::string dirname = GetCurrentDir() + "screenshot\\"; + print_window(dirname); } - static const std::string dirname = GetCurrentDir() + "screenshot\\"; - print_window(dirname); - } - break; + break; default: break; } @@ -102,7 +100,7 @@ bool ProcessTask::run() // 例如,进入吃理智药的界面了,相当于上一次点蓝色开始行动没生效 // 所以要给蓝色开始行动的次数减一 for (const std::string& reduce : task_info_ptr->reduce_other_times) { - --Configer::get_instance().m_all_tasks_info[reduce]->exec_times; + --TaskConfiger::get_instance().m_all_tasks_info[reduce]->exec_times; } if (need_stop) { @@ -135,7 +133,7 @@ std::shared_ptr ProcessTask::match_image(Rect* matched_rect) // 逐个匹配当前可能的任务 for (const std::string& task_name : m_cur_tasks_name) { - std::shared_ptr task_info_ptr = Configer::get_instance().m_all_tasks_info[task_name]; + std::shared_ptr task_info_ptr = TaskConfiger::get_instance().m_all_tasks_info[task_name]; if (task_info_ptr == nullptr) { // 说明配置文件里没这个任务 m_callback(AsstMsg::PtrIsNull, json::value(), m_callback_arg); continue; diff --git a/src/MeoAssistance/TaskConfiger.cpp b/src/MeoAssistance/TaskConfiger.cpp new file mode 100644 index 0000000000..cd6d526d8e --- /dev/null +++ b/src/MeoAssistance/TaskConfiger.cpp @@ -0,0 +1,182 @@ +#include "TaskConfiger.h" + +#include + +#include + +#include "AsstDef.h" +#include "Logger.hpp" +#include "Configer.h" + +using namespace asst; + +bool TaskConfiger::set_param(const std::string& type, const std::string& param, const std::string& value) +{ + // 暂时只用到了这些,总的参数太多了,后面要用啥再加上 + if (type == "task.type") { + if (m_all_tasks_info.find(param) == m_all_tasks_info.cend()) { + return false; + } + auto task_info_ptr = m_all_tasks_info[param]; + std::string type = value; + std::transform(type.begin(), type.end(), type.begin(), std::tolower); + if (type == "clickself") { + task_info_ptr->action = ProcessTaskAction::ClickSelf; + } + else if (type == "clickrand") { + task_info_ptr->action = ProcessTaskAction::ClickRand; + } + else if (type == "donothing" || type.empty()) { + task_info_ptr->action = ProcessTaskAction::DoNothing; + } + else if (type == "stop") { + task_info_ptr->action = ProcessTaskAction::Stop; + } + else if (type == "clickrect") { + task_info_ptr->action = ProcessTaskAction::ClickRect; + } + else { + DebugTraceError("Task", param, "'s type error:", type); + return false; + } + } + else if (type == "task.maxTimes") { + if (m_all_tasks_info.find(param) == m_all_tasks_info.cend()) { + return false; + } + m_all_tasks_info[param]->max_times = std::stoi(value); + } + return true; +} + +bool asst::TaskConfiger::parse(json::value&& json) +{ + json::value root = std::move(json); + + for (auto&& [name, task_json] : root.as_object()) { + std::string algorithm_str = task_json.get("algorithm", "matchtemplate"); + std::transform(algorithm_str.begin(), algorithm_str.end(), algorithm_str.begin(), std::tolower); + AlgorithmType algorithm = AlgorithmType::Invaild; + if (algorithm_str == "matchtemplate") { + algorithm = AlgorithmType::MatchTemplate; + } + else if (algorithm_str == "justreturn") { + algorithm = AlgorithmType::JustReturn; + } + else if (algorithm_str == "ocrdetect") { + algorithm = AlgorithmType::OcrDetect; + } + //else if (algorithm_str == "comparehist") {} // CompareHist是MatchTemplate的衍生算法,不应作为单独的配置参数出现 + else { + DebugTraceError("Algorithm error:", algorithm_str); + return false; + } + + std::shared_ptr task_info_ptr = nullptr; + switch (algorithm) { + case AlgorithmType::JustReturn: + task_info_ptr = std::make_shared(); + break; + case AlgorithmType::MatchTemplate: + { + auto match_task_info_ptr = std::make_shared(); + match_task_info_ptr->template_filename = task_json["template"].as_string(); + match_task_info_ptr->templ_threshold = task_json.get("templThreshold", Configer::TemplThresholdDefault); + match_task_info_ptr->hist_threshold = task_json.get("histThreshold", Configer::HistThresholdDefault); + match_task_info_ptr->cache = task_json.get("cache", true); + task_info_ptr = match_task_info_ptr; + } + break; + case AlgorithmType::OcrDetect: + { + auto ocr_task_info_ptr = std::make_shared(); + for (const json::value& text : task_json["text"].as_array()) + { + ocr_task_info_ptr->text.emplace_back(text.as_string()); + } + ocr_task_info_ptr->need_match = task_json.get("need_match", false); + if (task_json.exist("ocrReplace")) + { + for (const auto& [key, value] : task_json["ocrReplace"].as_object()) { + ocr_task_info_ptr->replace_map.emplace(key, value.as_string()); + } + } + task_info_ptr = ocr_task_info_ptr; + } + break; + } + task_info_ptr->algorithm = algorithm; + task_info_ptr->name = name; + std::string action = task_json["action"].as_string(); + std::transform(action.begin(), action.end(), action.begin(), std::tolower); + if (action == "clickself") { + task_info_ptr->action = ProcessTaskAction::ClickSelf; + } + else if (action == "clickrand") { + task_info_ptr->action = ProcessTaskAction::ClickRand; + } + else if (action == "donothing" || action.empty()) { + task_info_ptr->action = ProcessTaskAction::DoNothing; + } + else if (action == "stop") { + task_info_ptr->action = ProcessTaskAction::Stop; + } + else if (action == "clickrect") { + task_info_ptr->action = ProcessTaskAction::ClickRect; + json::value& area_json = task_json["specificArea"]; + task_info_ptr->specific_area = Rect( + area_json[0].as_integer(), + area_json[1].as_integer(), + area_json[2].as_integer(), + area_json[3].as_integer()); + } + else if (action == "printwindow") { + task_info_ptr->action = ProcessTaskAction::PrintWindow; + } + else if (action == "swipetotheleft") { + task_info_ptr->action = ProcessTaskAction::SwipeToTheLeft; + } + else if (action == "swipetotheright") { + task_info_ptr->action = ProcessTaskAction::SwipeToTheRight; + } + else { + DebugTraceError("Task:", name, "error:", action); + return false; + } + + task_info_ptr->max_times = task_json.get("maxTimes", INT_MAX); + if (task_json.exist("exceededNext")) { + json::array& excceed_next_arr = task_json["exceededNext"].as_array(); + for (const json::value& excceed_next : excceed_next_arr) { + task_info_ptr->exceeded_next.emplace_back(excceed_next.as_string()); + } + } + else { + task_info_ptr->exceeded_next.emplace_back("Stop"); + } + task_info_ptr->pre_delay = task_json.get("preDelay", 0); + task_info_ptr->rear_delay = task_json.get("rearDelay", 0); + if (task_json.exist("reduceOtherTimes")) { + json::array& reduce_arr = task_json["reduceOtherTimes"].as_array(); + for (const json::value& reduce : reduce_arr) { + task_info_ptr->reduce_other_times.emplace_back(reduce.as_string()); + } + } + if (task_json.exist("identifyArea")) { + json::array& area_arr = task_json["identifyArea"].as_array(); + task_info_ptr->identify_area = Rect( + area_arr[0].as_integer(), + area_arr[1].as_integer(), + area_arr[2].as_integer(), + area_arr[3].as_integer()); + } + + json::array& next_arr = task_json["next"].as_array(); + for (const json::value& next : next_arr) { + task_info_ptr->next.emplace_back(next.as_string()); + } + + m_all_tasks_info.emplace(name, task_info_ptr); + } + +} diff --git a/src/MeoAssistance/TaskConfiger.h b/src/MeoAssistance/TaskConfiger.h new file mode 100644 index 0000000000..f83a8c6c43 --- /dev/null +++ b/src/MeoAssistance/TaskConfiger.h @@ -0,0 +1,27 @@ +#pragma once + +#include "AbstractConfiger.h" + +#include + +namespace asst { + class TaskInfo; + + class TaskConfiger : public AbstractConfiger + { + public: + virtual ~TaskConfiger() = default; + + static TaskConfiger& get_instance() { + static TaskConfiger unique_instance; + return unique_instance; + } + + bool set_param(const std::string& type, const std::string& param, const std::string& value); + + std::unordered_map> m_all_tasks_info; + protected: + virtual bool parse(json::value&& json); + }; + +} \ No newline at end of file