干员识别,fix

This commit is contained in:
罗家欣
2023-04-18 15:32:19 +08:00
parent 358ed2ddf5
commit dbd0f4ffc1
37 changed files with 406 additions and 715 deletions

View File

@@ -1,283 +0,0 @@
{
"roles": [
"阿米娅",
"凯尔希",
"12F",
"陈",
"煌",
"炎狱炎熔",
"浊心斯卡蒂",
"假日威龙陈",
"耀骑士临光",
"空",
"焰影苇草",
"寒芒克洛丝",
"归溟幽灵鲨",
"濯尘芙蓉",
"百炼嘉维尔",
"承曦格雷伊",
"缄默德克萨斯",
"麒麟X夜刀",
"德克萨斯",
"火龙S黑角",
"能天使",
"芙兰卡",
"雷蛇",
"赫默",
"远山",
"深海色",
"推进之王",
"W",
"凛冬",
"末药",
"白雪",
"芙蓉",
"炎熔",
"米格鲁",
"芬",
"克洛丝",
"流星",
"艾丝黛尔",
"白面鸮",
"蓝毒",
"杜宾",
"炎客",
"梅",
"伊芙利特",
"星源",
"星熊",
"猎蜂",
"拉普兰德",
"夜烟",
"幽灵鲨",
"红",
"普罗旺斯",
"闪灵",
"临光",
"清道夫",
"蛇屠箱",
"桃金娘",
"摩根",
"因陀罗",
"达格达",
"守林人",
"断罪者",
"火神",
"夜魔",
"天火",
"华法琳",
"银灰",
"崖心",
"初雪",
"夜莺",
"艾雅法拉",
"调香师",
"地灵",
"慕斯",
"嘉维尔",
"赫拉格",
"红云",
"翎羽",
"霜叶",
"真理",
"古米",
"早露",
"讯使",
"角峰",
"刻俄柏",
"年",
"夕",
"可颂",
"令",
"重岳",
"塞雷娅",
"白金",
"灵知",
"玫兰莎",
"卡缇",
"史都华德",
"安德切尔",
"安赛尔",
"莫斯提马",
"卡夫卡",
"狮蝎",
"安哲拉",
"陨星",
"格拉尼",
"风笛",
"阿",
"吽",
"暴行",
"杰西卡",
"暗索",
"砾",
"香草",
"食铁兽",
"梅尔",
"槐琥",
"麦哲伦",
"傀影",
"柏喙",
"格雷伊",
"巫恋",
"波登可",
"坚雷",
"苇草",
"斯卡蒂",
"山",
"鞭刃",
"芳汀",
"孑",
"星极",
"微风",
"阿消",
"梓兰",
"送葬人",
"泡普卡",
"空爆",
"月见夜",
"斑点",
"Lancet-2",
"Castle-3",
"缠丸",
"红豆",
"安洁莉娜",
"棘刺",
"断崖",
"和弦",
"苏苏洛",
"菲亚梅塔",
"刻刀",
"安比尔",
"暴雨",
"惊蛰",
"诗怀雅",
"泥岩",
"老鲤",
"拜松",
"格劳克斯",
"卡达",
"空弦",
"铸铁",
"稀音",
"宴",
"爱丽丝",
"黑",
"月禾",
"蜜蜡",
"亚叶",
"奥斯塔",
"杰克",
"锡兰",
"贾维",
"史尔特尔",
"伊桑",
"布洛卡",
"铃兰",
"嵯峨",
"熔泉",
"四月",
"酸糖",
"灰喉",
"贝娜",
"莱恩哈特",
"THRM-EX",
"澄闪",
"石棉",
"慑砂",
"泡泡",
"雪雉",
"清流",
"薄绿",
"迷迭香",
"正义骑士号",
"布丁",
"艾丽妮",
"温蒂",
"耶拉",
"子月",
"风丸",
"谜图",
"九色鹿",
"极境",
"暮落",
"图耶",
"但书",
"见行者",
"号角",
"洛洛",
"褐果",
"流明",
"埃拉托",
"海蒂",
"黑键",
"车尔尼",
"多萝西",
"至简",
"鸿雪",
"苦艾",
"铅踝",
"石英",
"玛恩纳",
"斥罪",
"海沫",
"罗小黑",
"明椒",
"白铁",
"泰拉大陆调查团",
"截云",
"林",
"仇白",
"铎铃",
"伊内丝",
"U-Official",
"特米米",
"燧石",
"森蚺",
"焰尾",
"羽毛笔",
"极光",
"瑕光",
"卡涅利安",
"伺夜",
"远牙",
"灰毫",
"掠风",
"絮雨",
"水月",
"松果",
"蜜莓",
"罗宾",
"豆苗",
"乌有",
"灰烬",
"闪击",
"霜华",
"战车",
"洋灰",
"雪绒",
"深靛",
"异客",
"桑葚",
"歌蕾蒂娅",
"赤冬",
"夜半",
"绮良",
"琴柳",
"罗比菈塔",
"帕拉斯",
"龙舌兰",
"蚀清",
"休谟斯",
"夏栎",
"火哨",
"野鬃",
"晓歌",
"黑角",
"杜林",
"夜刀",
"巡林者",
"暮落"
],
"flag": "THRM-EX"
}

View File

@@ -9592,18 +9592,18 @@
20
]
},
"RoleBegin": {
"OperatorBegin": {
"algorithm": "JustReturn",
"action": "DoNothing",
"next": [
"RoleEnter",
"RoleRareTab",
"RoleRareTabU",
"RoleRareTabD",
"RoleEnter@ReturnTo"
"OperatorEnter",
"OperatorRarityTab",
"OperatorRarityTabU",
"OperatorRarityTabD",
"OperatorEnter@ReturnTo"
]
},
"RoleEnter": {
"OperatorEnter": {
"action": "ClickSelf",
"roi": [
935,
@@ -9612,10 +9612,10 @@
110
],
"next": [
"RoleRareTab"
"OperatorRarityTab"
]
},
"RoleRareTab": {
"OperatorRarityTab": {
"action": "ClickSelf",
"roi": [
922,
@@ -9624,10 +9624,10 @@
50
],
"next": [
"RoleRareTabD"
"OperatorRarityTabD"
]
},
"RoleRareTabU": {
"OperatorRarityTabU": {
"action": "ClickSelf",
"roi": [
922,
@@ -9636,10 +9636,10 @@
50
],
"next": [
"RoleRareTabD"
"OperatorRarityTabD"
]
},
"RoleRareTabD": {
"OperatorRarityTabD": {
"action": "DoNothing",
"roi": [
922,
@@ -9648,7 +9648,7 @@
50
]
},
"RoleSlowlySwipeToTheRight": {
"OperatorSlowlySwipeToTheRight": {
"doc": "6个横向干员防止识别不全990px",
"baseTask": "SlowlySwipeToTheRight",
"specificRect": [
@@ -9664,7 +9664,7 @@
20
]
},
"RoleOperNameFlag": {
"OperatorNameFlag": {
"templThreshold": 0.8,
"roi": [
5,
@@ -9673,7 +9673,7 @@
21
]
},
"RoleOperNameFlag1": {
"OperatorNameFlag1": {
"templThreshold": 0.8,
"roi": [
5,
@@ -9682,7 +9682,16 @@
21
]
},
"RoleOCR": {
"OperatorNameFlagLV": {
"templThreshold": 0.7,
"roi": [
40,
310,
1128,
327
]
},
"OperatorOCR": {
"algorithm": "OcrDetect",
"fullMatch": true,
"text": [],
@@ -9694,6 +9703,18 @@
],
"postDelay": 100
},
"OperatorOCRLV": {
"algorithm": "OcrDetect",
"fullMatch": true,
"text": [],
"roi": [
-10,
42,
120,
20
],
"postDelay": 100
},
"RoguelikeRecruitSwipeMaxTime": {
"algorithm": "JustReturn",
"maxTimes_Doc": "这个参数是肉鸽招募时,向右划动的最大次数",

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -13,7 +13,7 @@
#include "Task/Interface/CopilotTask.h"
#include "Task/Interface/CustomTask.h"
#include "Task/Interface/DepotTask.h"
#include "Task/Interface/RoleTask.h"
#include "Task/Interface/OperTask.h"
#include "Task/Interface/FightTask.h"
#include "Task/Interface/InfrastTask.h"
#include "Task/Interface/MallTask.h"
@@ -202,7 +202,7 @@ asst::Assistant::TaskId asst::Assistant::append_task(const std::string& type, co
ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(SingleStepTask)
ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(VideoRecognitionTask)
ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(DepotTask)
ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(RoleTask)
ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(OperTask)
ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(ReclamationTask)
ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(CustomTask)
#ifdef ASST_DEBUG

View File

@@ -2,11 +2,15 @@
#include "Utils/Ranges.hpp"
#include <meojson/json.hpp>
#include <regex>
#include "Utils/Logger.hpp"
bool asst::BattleDataConfig::parse(const json::value& json)
{
m_opers.clear();
//使用正则筛选干员
std::regex regexStr("^char.*");
std::smatch match;
for (const auto& [id, char_data_json] : json.at("chars").as_object()) {
battle::OperProps data;
data.id = id;
@@ -19,6 +23,8 @@ bool asst::BattleDataConfig::parse(const json::value& json)
{ "TANK", battle::Role::Tank }, { "WARRIOR", battle::Role::Warrior },
};
if (std::regex_match(id, match, regexStr)) m_opers.insert(name);
if (auto iter = RoleMap.find(char_data_json.at("profession").as_string()); iter == RoleMap.cend()) {
data.role = battle::Role::Drone;
}

View File

@@ -2,7 +2,7 @@
#include "Config/AbstractConfig.h"
#include <unordered_map>
#include <unordered_set>
#include "Common/AsstBattleDef.h"
#include "Common/AsstTypes.h"
@@ -90,12 +90,15 @@ namespace asst
return name.empty() || m_chars.find(name) == m_chars.cend();
}
const std::unordered_set<std::string>& get_all_oper_names() const noexcept { return m_opers; }
protected:
virtual bool parse(const json::value& json) override;
private:
std::unordered_map<std::string, battle::OperProps> m_chars;
std::unordered_map<std::string, battle::AttackRange> m_ranges;
std::unordered_set<std::string> m_opers;
};
inline static auto& BattleData = BattleDataConfig::get_instance();
} // namespace asst

View File

@@ -1,26 +0,0 @@
#include "RoleConfig.h"
#include "Utils/Ranges.hpp"
#include <meojson/json.hpp>
#include "Utils/Logger.hpp"
bool asst::RoleConfig::parse(const json::value& json)
{
LogTraceFunction;
clear();
const auto& roleFile = json.as_object();
tagname = roleFile.at("flag").as_string();
for (const auto& name : roleFile.at("roles").as_array()) {
std::string rolename = name.as_string();
role_all_name.insert(rolename);
}
return true;
}
void asst::RoleConfig::clear()
{
role_all_name.clear();
tagname = "";
}

View File

@@ -1,35 +0,0 @@
#pragma once
#pragma once
#pragma once
#include "Config/AbstractConfigWithTempl.h"
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace asst
{
class RoleConfig final : public SingletonHolder<RoleConfig>, public AbstractConfigWithTempl
{
public:
virtual ~RoleConfig() override = default;
const auto& get_all_role_name() const noexcept { return role_all_name; }
virtual const std::unordered_set<std::string>& get_templ_required() const noexcept override
{
return get_all_role_name();
}
const auto& get_role_tag() const noexcept { return tagname; }
protected:
virtual bool parse(const json::value& json) override;
void clear();
// 干员名zhutf8
std::unordered_set<std::string> role_all_name;
std::string tagname;
};
inline static auto& RoleData = RoleConfig::get_instance();
}

View File

@@ -9,7 +9,6 @@
#include "Miscellaneous/CopilotConfig.h"
#include "Miscellaneous/InfrastConfig.h"
#include "Miscellaneous/ItemConfig.h"
#include "Miscellaneous/RoleConfig.h"
#include "Miscellaneous/OcrConfig.h"
#include "Miscellaneous/OcrPack.h"
#include "Miscellaneous/RecruitConfig.h"
@@ -84,7 +83,6 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path)
LoadResourceWithTemplAndCheckRet(TaskData, "tasks.json"_p, "template"_p);
LoadResourceWithTemplAndCheckRet(InfrastConfig, "infrast.json"_p, "template"_p / "infrast"_p);
LoadResourceWithTemplAndCheckRet(ItemConfig, "item_index.json"_p, "template"_p / "items"_p);
LoadResourceWithTemplAndCheckRet(RoleConfig, "role_index.json"_p, "template"_p);
/* load cache */
LoadCacheWithoutRet(AvatarCacheManager, "avatars"_p);

View File

@@ -39,7 +39,6 @@
<ClInclude Include="Config\Miscellaneous\AvatarCacheManager.h" />
<ClInclude Include="Config\Miscellaneous\OcrConfig.h" />
<ClInclude Include="Config\Miscellaneous\SSSCopilotConfig.h" />
<ClInclude Include="Config\Miscellaneous\RoleConfig.h" />
<ClInclude Include="Config\OnnxSessions.h" />
<ClInclude Include="Controller\adb-lite\client.hpp" />
<ClInclude Include="Controller\adb-lite\protocol.hpp" />
@@ -61,8 +60,8 @@
<ClInclude Include="Task\Experiment\SingleStepBattleProcessTask.h" />
<ClInclude Include="Task\Interface\CustomTask.h" />
<ClInclude Include="Task\Interface\VideoRecognitionTask.h" />
<ClInclude Include="Task\Interface\RoleTask.h" />
<ClInclude Include="Task\Miscellaneous\RoleRecognitionTask.h" />
<ClInclude Include="Task\Interface\OperTask.h" />
<ClInclude Include="Task\Miscellaneous\OperRecognitionTask.h" />
<ClInclude Include="Task\Reclamation\ReclamationControlTask.h" />
<ClInclude Include="Task\Reclamation\ReclamationConclusionReportPlugin.h" />
<ClInclude Include="Task\Reclamation\ReclamationBattlePlugin.h" />
@@ -200,7 +199,6 @@
<ClCompile Include="Config\Miscellaneous\AvatarCacheManager.cpp" />
<ClCompile Include="Config\Miscellaneous\OcrConfig.cpp" />
<ClCompile Include="Config\Miscellaneous\SSSCopilotConfig.cpp" />
<ClCompile Include="Config\Miscellaneous\RoleConfig.cpp" />
<ClCompile Include="Config\OnnxSessions.cpp" />
<ClCompile Include="Controller\adb-lite\client.cpp" />
<ClCompile Include="Controller\adb-lite\protocol.cpp" />
@@ -216,8 +214,8 @@
<ClCompile Include="Task\Experiment\CombatRecordRecognitionTask.cpp" />
<ClCompile Include="Task\Experiment\SingleStepBattleProcessTask.cpp" />
<ClCompile Include="Task\Interface\VideoRecognitionTask.cpp" />
<ClCompile Include="Task\Interface\RoleTask.cpp" />
<ClCompile Include="Task\Miscellaneous\RoleRecognitionTask.cpp" />
<ClCompile Include="Task\Interface\OperTask.cpp" />
<ClCompile Include="Task\Miscellaneous\OperRecognitionTask.cpp" />
<ClCompile Include="Task\Reclamation\ReclamationControlTask.cpp" />
<ClCompile Include="Task\Reclamation\ReclamationConclusionReportPlugin.cpp" />
<ClCompile Include="Task\Reclamation\ReclamationBattlePlugin.cpp" />

View File

@@ -603,13 +603,10 @@
<ClInclude Include="Controller\PlayToolsController.h">
<Filter>源文件\Controller</Filter>
</ClInclude>
<ClInclude Include="Config\Miscellaneous\RoleConfig.h">
<Filter>源文件\Resource\Miscellaneous</Filter>
</ClInclude>
<ClInclude Include="Task\Interface\RoleTask.h">
<ClInclude Include="Task\Interface\OperTask.h">
<Filter>源文件\Task\Interface</Filter>
</ClInclude>
<ClInclude Include="Task\Miscellaneous\RoleRecognitionTask.h">
<ClInclude Include="Task\Miscellaneous\OperRecognitionTask.h">
<Filter>源文件\Task\Miscellaneous</Filter>
</ClInclude>
</ItemGroup>
@@ -1001,13 +998,10 @@
<ClCompile Include="Controller\PlayToolsController.cpp">
<Filter>源文件\Controller</Filter>
</ClCompile>
<ClCompile Include="Config\Miscellaneous\RoleConfig.cpp">
<Filter>源文件\Resource\Miscellaneous</Filter>
</ClCompile>
<ClCompile Include="Task\Interface\RoleTask.cpp">
<ClCompile Include="Task\Interface\OperTask.cpp">
<Filter>源文件\Task\Interface</Filter>
</ClCompile>
<ClCompile Include="Task\Miscellaneous\RoleRecognitionTask.cpp">
<ClCompile Include="Task\Miscellaneous\OperRecognitionTask.cpp">
<Filter>源文件\Task\Miscellaneous</Filter>
</ClCompile>
</ItemGroup>

View File

@@ -1,15 +1,15 @@
#include "RoleTask.h"
#include "OperTask.h"
#include "Task/Miscellaneous/RoleRecognitionTask.h"
#include "Task/Miscellaneous/OperRecognitionTask.h"
#include "Task/ProcessTask.h"
asst::RoleTask::RoleTask(const AsstCallback& callback, Assistant* inst) : InterfaceTask(callback, inst, TaskType)
asst::OperTask::OperTask(const AsstCallback& callback, Assistant* inst) : InterfaceTask(callback, inst, TaskType)
{
auto enter_task = std::make_shared<ProcessTask>(m_callback, m_inst, TaskType);
enter_task->set_tasks({ "RoleBegin" }).set_ignore_error(true);
enter_task->set_tasks({ "OperatorBegin" }).set_ignore_error(true);
m_subtasks.emplace_back(enter_task);
auto recognition_task = std::make_shared<RoleRecognitionTask>(m_callback, m_inst, TaskType);
auto recognition_task = std::make_shared<OperRecognitionTask>(m_callback, m_inst, TaskType);
recognition_task->set_retry_times(0);
m_subtasks.emplace_back(recognition_task);
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "Task/InterfaceTask.h"
namespace asst
{
class OperTask final : public InterfaceTask
{
public:
inline static constexpr std::string_view TaskType = "Oper";
OperTask(const AsstCallback& callback, Assistant* inst);
virtual ~OperTask() override = default;
};
}

View File

@@ -1,15 +0,0 @@
#pragma once
#pragma once
#include "Task/InterfaceTask.h"
namespace asst
{
class RoleTask final : public InterfaceTask
{
public:
inline static constexpr std::string_view TaskType = "Role";
RoleTask(const AsstCallback& callback, Assistant* inst);
virtual ~RoleTask() override = default;
};
}

View File

@@ -0,0 +1,109 @@
#include "OperRecognitionTask.h"
#include "Utils/Ranges.hpp"
#include "Config/Miscellaneous/BattleDataConfig.h"
#include "Config/TaskData.h"
#include "Controller/Controller.h"
#include "Task/ProcessTask.h"
#include "Utils/Logger.hpp"
#include "Vision/OcrWithFlagTemplImageAnalyzer.h"
bool asst::OperRecognitionTask::_run()
{
LogTraceFunction;
std::string current_page_last_oper_name = "";
own_opers.clear();
while (!need_exit()) {
auto resOpers = analyzer_opers();
if (resOpers.back().name == current_page_last_oper_name) {
break;
}
else {
current_page_last_oper_name = resOpers.back().name;
own_opers.insert(own_opers.end(),resOpers.begin(),resOpers.end());
}
swipe_page();
// callback_analyze_result(true);
}
callback_analyze_result(true);
return true;
}
std::vector<asst::OperRecognitionTask::OperBoxInfo> asst::OperRecognitionTask::analyzer_opers()
{
std::vector<OperBoxInfo> current_page_opers;
current_page_opers.clear();
auto image = ctrler()->get_image();
const auto& ocr_replace = Task.get<OcrTaskInfo>("CharsNameOcrReplace");
OcrWithFlagTemplImageAnalyzer oper_name_analyzer(image);
// 识别第一行
//name_analyzer.set_task_info("OperatorNameFlag", "OperatorOCR");
oper_name_analyzer.set_task_info("OperatorNameFlagLV", "OperatorOCRLV");
oper_name_analyzer.set_replace(ocr_replace->replace_map, ocr_replace->replace_full);
oper_name_analyzer.analyze();
auto oper_names_result = oper_name_analyzer.get_result();
//if (opers_result.empty() || opers_res.empty()) {
if (oper_names_result.empty()) {
return {};
}
for (auto& opername : oper_names_result) {
OperBoxInfo oper_info;
oper_info.name = std::move(opername.text);
current_page_opers.push_back(oper_info);
}
return current_page_opers;
}
void asst::OperRecognitionTask::swipe_page()
{
ProcessTask(*this, { "OperatorSlowlySwipeToTheRight" }).run();
}
void asst::OperRecognitionTask::callback_analyze_result(bool done)
{
LogTraceFunction;
// 获取所有干员名
const auto& all_oper_names = BattleData.get_all_oper_names();
//size_t total = all_oper_names.size();
// 获取识别干员名
const auto own_oper_names = get_own_oper_names();
// 识别干员个数
//size_t own_count = own_oper_names.size();
// 未拥有干员名
std::unordered_set<std::string> n_own_oper_names;
n_own_oper_names.clear();
for (const auto& oper : all_oper_names) {
if (own_oper_names.find(oper) == own_oper_names.end()) n_own_oper_names.insert(oper);
}
json::value info = basic_info_with_what("OperInfo");
auto& details = info["details"];
details["done"] = done;
//details["total"] = total;
//details["owncount"] = own_count;
details["have"] = json::array(own_oper_names);
details["nhave"] = json::array(n_own_oper_names);
details["all"] = json::array(all_oper_names);
// details["hroles"] = json::array(roles);
callback(AsstMsg::SubTaskExtraInfo, info);
}
std::unordered_set<std::string> asst::OperRecognitionTask::get_own_oper_names()
{
LogTraceFunction;
std::unordered_set<std::string> own_oper_names;
for (auto& oper_info : own_opers) {
own_oper_names.insert(std::move(oper_info.name));
}
return own_oper_names;
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include "Common/AsstBattleDef.h"
#include "Task/AbstractTask.h"
#include <unordered_set>
namespace asst
{
class OperRecognitionTask : public AbstractTask
{
public:
using AbstractTask::AbstractTask;
virtual ~OperRecognitionTask() override = default;
protected:
struct OperBoxInfo
{
std::string name;
};
virtual bool _run() override;
void swipe_page();
std::vector<OperBoxInfo> analyzer_opers();
std::vector<OperBoxInfo> own_opers;
void callback_analyze_result(bool done);
std::unordered_set<std::string> get_own_oper_names();
};
}

View File

@@ -1,127 +0,0 @@
#include "RoleRecognitionTask.h"
#include "Utils/Ranges.hpp"
#include "Config/Miscellaneous/RoleConfig.h"
#include "Config/TaskData.h"
#include "Controller/Controller.h"
#include "Task/ProcessTask.h"
#include "Utils/Logger.hpp"
#include "Vision/OcrWithFlagTemplImageAnalyzer.h"
bool asst::RoleRecognitionTask::_run()
{
LogTraceFunction;
lastRole = "";
roles.clear();
// lastRole = RoleData.get_role_tag();
while (!need_exit()) {
auto resRole = analyzer_opers();
if (resRole.back().text == lastRole) {
break;
}
else {
lastRole = resRole.back().text;
for (const auto& res : resRole) {
const std::string& name = res.text;
roles.insert(name);
}
}
swipe_page();
// callback_analyze_result(true);
}
callback_analyze_result(true);
return true;
}
std::vector<asst::TextRect> asst::RoleRecognitionTask::analyzer_opers()
{
std::vector<std::string> cRole;
cRole.clear();
auto image = ctrler()->get_image();
const auto& ocr_replace = Task.get<OcrTaskInfo>("CharsNameOcrReplace");
OcrWithFlagTemplImageAnalyzer name_analyzer(image);
// 识别第一行
name_analyzer.set_task_info("RoleOperNameFlag", "RoleOCR");
name_analyzer.set_replace(ocr_replace->replace_map, ocr_replace->replace_full);
name_analyzer.analyze();
////识别第二行
OcrWithFlagTemplImageAnalyzer name_analyzer2(image);
name_analyzer2.set_task_info("RoleOperNameFlag1", "RoleOCR");
name_analyzer2.set_replace(ocr_replace->replace_map, ocr_replace->replace_full);
name_analyzer2.analyze();
auto opers_result = name_analyzer.get_result();
auto opers_res = name_analyzer2.get_result();
if (opers_result.empty() || opers_res.empty()) {
return {};
}
opers_result.insert(opers_result.end(), opers_res.begin(), opers_res.end());
// 按位置排个序
// ranges::sort(opers_result, [](const TextRect& lhs, const TextRect& rhs) -> bool {
// if (std::abs(lhs.rect.x - rhs.rect.x) < 5) { // x差距较小则理解为是同一列的按y排序
// return lhs.rect.y < rhs.rect.y;
// }
// else {
// return lhs.rect.x < rhs.rect.x; // 否则按x排序
// }
//});
// save_img(utils::path("debug") / utils::path("role"));
/*for (const auto& res : opers_result) {
const std::string& name = res.text;
json::value info = basic_info_with_what("RoleInfo");
auto& details = info["details"];
details["name"] = name;
callback(AsstMsg::SubTaskExtraInfo, info);
}*/
return opers_result;
}
void asst::RoleRecognitionTask::swipe_page()
{
ProcessTask(*this, { "RoleSlowlySwipeToTheRight" }).run();
}
bool asst::RoleRecognitionTask::isLastRole(std::string name)
{
return name == lastRole;
}
void asst::RoleRecognitionTask::callback_analyze_result(bool done)
{
LogTraceFunction;
// 获取所有role
const auto& all_roles = RoleData.get_all_role_name();
size_t total = all_roles.size();
// 如果有U-Official,识别出来为U-official,需要替换
if (roles.find("U-official") != roles.end()) {
roles.erase("U-official");
roles.insert("U-Official");
}
// 去掉不存在的干员名
for (const auto& r : roles) {
if (all_roles.find(r) == all_roles.end()) roles.erase(r);
}
// 识别干员个数
size_t roleHave = roles.size();
// 未拥有干员名
std::list<std::string> noRoles;
noRoles.clear();
for (const auto& r : all_roles) {
if (roles.find(r) == roles.end()) noRoles.push_back(r);
}
json::value info = basic_info_with_what("RoleInfo");
auto& details = info["details"];
details["done"] = done;
details["total"] = total;
details["have"] = roleHave;
details["nroles"] = json::array(noRoles);
// details["allroles"] = json::array(all_roles);
// details["hroles"] = json::array(roles);
callback(AsstMsg::SubTaskExtraInfo, info);
}

View File

@@ -1,25 +0,0 @@
#pragma once
#pragma once
#include "Common/AsstBattleDef.h"
#include "Task/AbstractTask.h"
#include <unordered_set>
namespace asst
{
class RoleRecognitionTask : public AbstractTask
{
public:
using AbstractTask::AbstractTask;
virtual ~RoleRecognitionTask() override = default;
protected:
virtual bool _run() override;
void swipe_page();
std::vector<TextRect> analyzer_opers();
std::string lastRole;
std::string m_support_unit_name;
std::unordered_set<std::string> roles;
bool isLastRole(std::string name);
void callback_analyze_result(bool done);
};
}

View File

@@ -37,7 +37,7 @@ bool asst::OcrWithFlagTemplImageAnalyzer::analyze()
std::make_move_iterator(m_ocr_result.end()));
}
}
save_img(utils::path("debug") / utils::path("oper"));
return !m_all_result.empty();
}

View File

@@ -32,7 +32,6 @@ bool asst::OcrWithPreprocessImageAnalyzer::analyze()
#ifdef ASST_DEBUG
cv::rectangle(m_image_draw, make_rect<cv::Rect>(new_roi), cv::Scalar(0, 0, 255), 1);
#endif // ASST_DEBUG
return OcrImageAnalyzer::analyze();
}

View File

@@ -165,7 +165,7 @@ namespace MaaWpfGui.Main
private readonly RecruitViewModel _recruitViewModel;
private readonly CopilotViewModel _copilotViewModel;
private readonly DepotViewModel _depotViewModel;
private readonly RoleViewModel _roleViewModel;
private readonly OperViewModel _operViewModel;
/// <summary>
/// Initializes a new instance of the <see cref="AsstProxy"/> class.
@@ -179,7 +179,7 @@ namespace MaaWpfGui.Main
_recruitViewModel = container.Get<RecruitViewModel>();
_copilotViewModel = container.Get<CopilotViewModel>();
_depotViewModel = container.Get<DepotViewModel>();
_roleViewModel = container.Get<RoleViewModel>();
_operViewModel = container.Get<OperViewModel>();
_windowManager = windowManager;
_callback = CallbackFunction;
@@ -571,7 +571,7 @@ namespace MaaWpfGui.Main
|| unique_finished_task == (_latestTaskId.TryGetValue(TaskType.RecruitCalc, out var recruitCalcTaskId) ? recruitCalcTaskId : 0)
|| unique_finished_task == (_latestTaskId.TryGetValue(TaskType.CloseDown, out var closeDownTaskId) ? closeDownTaskId : 0)
|| unique_finished_task == (_latestTaskId.TryGetValue(TaskType.Depot, out var depotTaskId) ? depotTaskId : 0)
|| unique_finished_task == (_latestTaskId.TryGetValue(TaskType.Role, out var roleTaskId) ? roleTaskId : 0))
|| unique_finished_task == (_latestTaskId.TryGetValue(TaskType.Oper, out var operTaskId) ? operTaskId : 0))
{
isMainTaskQueueAllCompleted = false;
}
@@ -826,9 +826,9 @@ namespace MaaWpfGui.Main
_depotViewModel.Parse((JObject)subTaskDetails);
}
if (taskChain == "Role")
if (taskChain == "Oper")
{
_roleViewModel.Parse((JObject)subTaskDetails);
_operViewModel.Parse((JObject)subTaskDetails);
}
string what = details["what"].ToString();
@@ -1251,7 +1251,7 @@ namespace MaaWpfGui.Main
Copilot,
VideoRec,
Depot,
Role,
Oper,
}
private readonly Dictionary<TaskType, AsstTaskId> _latestTaskId = new Dictionary<TaskType, AsstTaskId>();
@@ -1653,11 +1653,11 @@ namespace MaaWpfGui.Main
/// 干员识别。
/// </summary>
/// <returns>是否成功。</returns>
public bool AsstStartRole()
public bool AsstStartOper()
{
var task_params = new JObject();
AsstTaskId id = AsstAppendTaskWithEncoding("Role", task_params);
_latestTaskId[TaskType.Role] = id;
AsstTaskId id = AsstAppendTaskWithEncoding("Oper", task_params);
_latestTaskId[TaskType.Oper] = id;
return id != 0 && AsstStart();
}

View File

@@ -147,7 +147,7 @@ namespace MaaWpfGui.Main
builder.Bind<SettingsViewModel>().ToSelf().InSingletonScope();
builder.Bind<CopilotViewModel>().ToSelf().InSingletonScope();
builder.Bind<DepotViewModel>().ToSelf().InSingletonScope();
builder.Bind<RoleViewModel>().ToSelf().InSingletonScope();
builder.Bind<OperViewModel>().ToSelf().InSingletonScope();
builder.Bind<AsstProxy>().ToSelf().InSingletonScope();
builder.Bind<TrayIcon>().ToSelf().InSingletonScope();

View File

@@ -377,9 +377,9 @@
<!-- Depot Recognition -->
<!-- 干员识别 -->
<system:String x:Key="RoleRecognition">干员识别 beta</system:String>
<system:String x:Key="RoleRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToRoleRecognition">开始识别</system:String>
<system:String x:Key="OperRecognition">干员识别 beta</system:String>
<system:String x:Key="OperRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToOperRecognition">开始识别</system:String>
<!-- 干员识别 -->
<!-- Logs -->

View File

@@ -378,9 +378,9 @@
<!-- 倉庫アイテム認識 -->
<!-- 干员识别 -->
<system:String x:Key="RoleRecognition">干员识别 beta</system:String>
<system:String x:Key="RoleRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToRoleRecognition">开始识别</system:String>
<system:String x:Key="OperRecognition">干员识别 beta</system:String>
<system:String x:Key="OperRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToOperRecognition">开始识别</system:String>
<!-- 干员识别 -->
<!-- ログ -->

View File

@@ -358,9 +358,9 @@
<!-- 창고 정리 -->
<!-- 干员识别 -->
<system:String x:Key="RoleRecognition">干员识别 beta</system:String>
<system:String x:Key="RoleRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToRoleRecognition">开始识别</system:String>
<system:String x:Key="OperRecognition">干员识别 beta</system:String>
<system:String x:Key="OperRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToOperRecognition">开始识别</system:String>
<!-- 干员识别 -->
<!-- 로그 -->

View File

@@ -380,9 +380,9 @@
<!-- 仓库识别 -->
<!-- 干员识别 -->
<system:String x:Key="RoleRecognition">干员识别 beta</system:String>
<system:String x:Key="RoleRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToRoleRecognition">开始识别</system:String>
<system:String x:Key="OperRecognition">干员识别 beta</system:String>
<system:String x:Key="OperRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToOperRecognition">开始识别</system:String>
<!-- 干员识别 -->
<!-- 日志 -->

View File

@@ -312,9 +312,9 @@
<!-- 倉庫識別 -->
<!-- 干员识别 -->
<system:String x:Key="RoleRecognition">干员识别 beta</system:String>
<system:String x:Key="RoleRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToRoleRecognition">开始识别</system:String>
<system:String x:Key="OperRecognition">干员识别 beta</system:String>
<system:String x:Key="OperRecognitionTip">该功能尚处于测试阶段,请清空特别关注干员再使用,若统计有误,欢迎打包 asst.log 文件后向我们提交issue ~</system:String>
<system:String x:Key="BeganToOperRecognition">开始识别</system:String>
<!-- 干员识别 -->
<!-- 日誌 -->

View File

@@ -0,0 +1,159 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using MaaWpfGui.Helper;
using MaaWpfGui.Main;
using Newtonsoft.Json.Linq;
using Stylet;
using StyletIoC;
namespace MaaWpfGui.ViewModels.UI
{
public class OperViewModel : Screen
{
private readonly IWindowManager _windowManager;
private readonly IContainer _container;
private AsstProxy _asstProxy;
/// <summary>
/// 未实装干员但在battle_data中
/// </summary>
private static readonly string[] VirtuallyOpers =
{
"预备干员-近战",
"预备干员-术师",
"预备干员-后勤",
"预备干员-狙击",
"预备干员-重装",
"郁金香",
"Stormeye",
"Touch",
"Pith",
"Sharp",
"阿米娅-WARRIOR",
};
public OperViewModel(IContainer container, IWindowManager windowManager)
{
_windowManager = windowManager;
_container = container;
DisplayName = LocalizationHelper.GetString("OperRecognition");
}
protected override void OnInitialActivate()
{
base.OnInitialActivate();
_asstProxy = _container.Get<AsstProxy>();
}
private string _operInfo = LocalizationHelper.GetString("OperRecognitionTip");
public string OperInfo
{
get => _operInfo;
set => SetAndNotify(ref _operInfo, value);
}
private string _operResult;
public string OperResult
{
get => _operResult;
set => SetAndNotify(ref _operResult, value);
}
public bool Parse(JObject details)
{
string result = string.Empty;
/*已拥有干员*/
JArray operOwn = (JArray)details["have"];
/*未拥有干员,包含预备干员等*/
JArray operNotOwn = (JArray)details["nhave"];
/*JArray operAll = (JArray)details["all"];*/
/*groups.Where(i => i.Type == JTokenType.String && (string)i == groupName).ToList().ForEach(i => i.Remove());*/
/*移除未实装干员*/
foreach (var name in VirtuallyOpers)
{
operNotOwn.Where(i => i.Type == JTokenType.String && (string)i == name).ToList().ForEach(i => i.Remove());
}
result = "已拥有:" + operOwn.Count.ToString() + "名,未拥有:" + operNotOwn.Count.ToString() + "名;" + "\n\n";
result += "以下干员未拥有:\n\t";
int count = 0;
foreach (var name in operNotOwn)
{
if (count++ < 3)
{
result += name + ", ";
}
else
{
result += name + "\n\t";
count = 0;
}
}
result += "\n\n以下干员已拥有\n\n\t";
count = 0;
foreach (var name in operOwn)
{
if (count++ < 3)
{
result += name + ", ";
}
else
{
result += name + "\n\t";
count = 0;
}
}
OperResult = result;
bool done = (bool)details["done"];
if (done)
{
OperInfo = LocalizationHelper.GetString("IdentificationCompleted") + "\n" + LocalizationHelper.GetString("OperRecognitionTip");
Done = true;
}
return true;
}
private bool _done = false;
/// <summary>
/// Gets or sets a value indicating whether depot info is parsed.
/// </summary>
public bool Done
{
get => _done;
set => SetAndNotify(ref _done, value);
}
private void Clear()
{
OperResult = string.Empty;
Done = false;
}
public async void Start()
{
string errMsg = string.Empty;
OperInfo = LocalizationHelper.GetString("ConnectingToEmulator");
bool caught = await Task.Run(() => _asstProxy.AsstConnect(ref errMsg));
if (!caught)
{
OperInfo = errMsg;
return;
}
OperInfo = LocalizationHelper.GetString("Identifying");
Clear();
_asstProxy.AsstStartOper();
}
}
}

View File

@@ -1,125 +0,0 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using MaaWpfGui.Helper;
using MaaWpfGui.Main;
using Newtonsoft.Json.Linq;
using Stylet;
using StyletIoC;
namespace MaaWpfGui.ViewModels.UI
{
public class RoleViewModel : Screen
{
private readonly IWindowManager _windowManager;
private readonly IContainer _container;
private AsstProxy _asstProxy;
public RoleViewModel(IContainer container, IWindowManager windowManager)
{
_windowManager = windowManager;
_container = container;
DisplayName = LocalizationHelper.GetString("RoleRecognition");
}
protected override void OnInitialActivate()
{
base.OnInitialActivate();
_asstProxy = _container.Get<AsstProxy>();
}
private string _roleInfo = LocalizationHelper.GetString("RoleRecognitionTip");
public string RoleInfo
{
get => _roleInfo;
set => SetAndNotify(ref _roleInfo, value);
}
private string _roleResult;
public string RoleResult
{
get => _roleResult;
set => SetAndNotify(ref _roleResult, value);
}
public bool Parse(JObject details)
{
string result = string.Empty;
/*foreach (var item in details.Cast<JProperty>())
{
result += (string)item["name"] + "\n";
}*/
/*result += details.Cast<JObject>();*/
JArray allRoles = (JArray)details["allroles"];
JArray nRoles = (JArray)details["nroles"];
JArray hRoles = (JArray)details["hroles"];
/*string[] allroles = details["allroles"].Value<List<string>>().ToArray();
string[] noroles = details["nroles"].Value<List<string>>().ToArray();*/
result = "干员总计:" + (int)details["total"] + "名,已拥有:" + (int)details["have"] + "名,未拥有:" + nRoles.Count.ToString() + "名;" + "\n\n\t";
int count = 0;
foreach (var name in nRoles)
{
if (count++ < 3)
{
result += name + ", ";
}
else
{
result += name + "\n\t";
count = 0;
}
}
RoleResult = result;
bool done = (bool)details["done"];
if (done)
{
RoleInfo = LocalizationHelper.GetString("IdentificationCompleted") + "\n" + LocalizationHelper.GetString("RoleRecognitionTip");
Done = true;
}
return true;
}
private bool _done = false;
/// <summary>
/// Gets or sets a value indicating whether depot info is parsed.
/// </summary>
public bool Done
{
get => _done;
set => SetAndNotify(ref _done, value);
}
private void Clear()
{
RoleResult = string.Empty;
Done = false;
}
public async void Start()
{
string errMsg = string.Empty;
RoleInfo = LocalizationHelper.GetString("ConnectingToEmulator");
bool caught = await Task.Run(() => _asstProxy.AsstConnect(ref errMsg));
if (!caught)
{
RoleInfo = errMsg;
return;
}
RoleInfo = LocalizationHelper.GetString("Identifying");
Clear();
_asstProxy.AsstStartRole();
}
}
}

View File

@@ -32,7 +32,7 @@ namespace MaaWpfGui.ViewModels.UI
private readonly SettingsViewModel _settingsViewModel;
private readonly CopilotViewModel _copilotViewModel;
private readonly DepotViewModel _depotViewModel;
private readonly RoleViewModel _roleViewModel;
private readonly OperViewModel _operViewModel;
private readonly VersionUpdateViewModel _versionUpdateViewModel;
/// <summary>
@@ -49,7 +49,7 @@ namespace MaaWpfGui.ViewModels.UI
_settingsViewModel = container.Get<SettingsViewModel>();
_copilotViewModel = container.Get<CopilotViewModel>();
_depotViewModel = container.Get<DepotViewModel>();
_roleViewModel = container.Get<RoleViewModel>();
_operViewModel = container.Get<OperViewModel>();
_versionUpdateViewModel = container.Get<VersionUpdateViewModel>();
}
@@ -73,7 +73,7 @@ namespace MaaWpfGui.ViewModels.UI
Items.Add(_copilotViewModel);
Items.Add(_recruitViewModel);
Items.Add(_depotViewModel);
Items.Add(_roleViewModel);
Items.Add(_operViewModel);
Items.Add(_settingsViewModel);
_settingsViewModel.UpdateWindowTitle(); // 在标题栏上显示模拟器和IP端口 必须在 Items.Add(settings)之后执行。

View File

@@ -1,4 +1,4 @@
<UserControl x:Class="MaaWpfGui.Views.UI.RoleView"
<UserControl x:Class="MaaWpfGui.Views.UI.OperView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -9,7 +9,7 @@
xmlns:ui="clr-namespace:MaaWpfGui.ViewModels.UI"
xmlns:styles="clr-namespace:MaaWpfGui.Styles"
xmlns:controls="clr-namespace:MaaWpfGui.Styles.Controls"
d:DataContext="{d:DesignInstance {x:Type ui:RoleViewModel}}"
d:DataContext="{d:DesignInstance {x:Type ui:OperViewModel}}"
mc:Ignorable="d"
d:DesignHeight="495" d:DesignWidth="800">
@@ -30,13 +30,13 @@
VerticalAlignment="Top"
FontSize="14"
Style="{StaticResource TextBlockDefaultBold}"
Text="{Binding RoleInfo}"
Text="{Binding OperInfo}"
TextWrapping="Wrap"/>
<controls:TextBlock
Margin="10"
HorizontalAlignment="Left"
FontSize="14"
Text="{Binding RoleResult}"
Text="{Binding OperResult}"
TextWrapping="Wrap"/>
</StackPanel>
@@ -54,7 +54,7 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Command="{s:Action Start}"
Content="{DynamicResource BeganToRoleRecognition}"
Content="{DynamicResource BeganToOperRecognition}"
/>
</StackPanel>
</Grid>