|
@@ -8,6 +8,37 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
::ShowWindow(m_hGameWnd, SW_SHOWNORMAL);\
|
|
::ShowWindow(m_hGameWnd, SW_SHOWNORMAL);\
|
|
::SetForegroundWindow(m_hGameWnd);
|
|
::SetForegroundWindow(m_hGameWnd);
|
|
|
|
|
|
|
|
+ std::map<std::string, POINT> g_mapZYNPC;
|
|
|
|
+ std::map<std::string, PNPC> g_mapZYNPC2;
|
|
|
|
+
|
|
|
|
+ // 使用快捷键来处理:读取配置文件
|
|
|
|
+ auto FindJNShortCut = [](LPCTSTR lpSkillName, int& nKeyValue, int& nSkilltime)->BOOL {
|
|
|
|
+ // 读取文件:jnmap.bin
|
|
|
|
+ // 格式:技能=快捷键的键值;
|
|
|
|
+ std::string line;
|
|
|
|
+ std::ifstream ifJN("img\\jnmap.bin");
|
|
|
|
+ if (ifJN)
|
|
|
|
+ {
|
|
|
|
+ TCHAR szKeyValue[MAX_PATH] = { 0 };
|
|
|
|
+ TCHAR szSkillName[MAX_PATH] = { 0 };
|
|
|
|
+ TCHAR szSkillTime[MAX_PATH] = { 0 };
|
|
|
|
+ while (std::getline(ifJN, line))
|
|
|
|
+ {
|
|
|
|
+ int nRet = _stscanf_s(line.c_str(), _T("%[^;];%[^;];%s"), szSkillName, MAX_PATH, szKeyValue, MAX_PATH, szSkillTime, MAX_PATH);
|
|
|
|
+ if (nRet == 3 && _tcsicmp(lpSkillName, szSkillName) == 0) {
|
|
|
|
+ // 将快捷键值
|
|
|
|
+ nKeyValue = atol(szKeyValue);
|
|
|
|
+ nSkilltime = atol(szSkillTime);
|
|
|
|
+ return TRUE;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 没有找到jnmap.bin文件;
|
|
|
|
+ return FALSE;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+
|
|
ThreadSection CAction::m_ts;
|
|
ThreadSection CAction::m_ts;
|
|
VOID DebugLog(CHAR* pszStr, ...)
|
|
VOID DebugLog(CHAR* pszStr, ...)
|
|
{
|
|
{
|
|
@@ -22,8 +53,9 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
OutputDebugStringA(szData);
|
|
OutputDebugStringA(szData);
|
|
}
|
|
}
|
|
|
|
|
|
- CAction::CAction(HWND hWnd) :m_hGameWnd(hWnd)
|
|
|
|
|
|
+ CAction::CAction(HWND hWnd) :m_hGameWnd(hWnd), m_ptCur({0,0})
|
|
{
|
|
{
|
|
|
|
+ InitNPCInfo();
|
|
}
|
|
}
|
|
|
|
|
|
CAction::~CAction()
|
|
CAction::~CAction()
|
|
@@ -34,7 +66,34 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
{
|
|
{
|
|
SETGAMEFOREGROUND;
|
|
SETGAMEFOREGROUND;
|
|
GameAssist::GamePos2Screen(m_hGameWnd, pt);
|
|
GameAssist::GamePos2Screen(m_hGameWnd, pt);
|
|
- GameAssist::MouseMove(pt);
|
|
|
|
|
|
+ GameAssist::MouseMove(pt, bSetCurPos);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void CAction::MouseMove(POINT ptStart, POINT ptEnd, bool bSetCurPos)
|
|
|
|
+ {
|
|
|
|
+ SETGAMEFOREGROUND;
|
|
|
|
+ GameAssist::GamePos2Screen(m_hGameWnd, ptStart);
|
|
|
|
+ GameAssist::MouseMove(ptStart, bSetCurPos);
|
|
|
|
+
|
|
|
|
+ GameAssist::GamePos2Screen(m_hGameWnd, ptEnd);
|
|
|
|
+ GameAssist::MouseMove(ptEnd, bSetCurPos);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void CAction::MouseMoveEx(POINT pt, bool bSetCurPos)
|
|
|
|
+ {
|
|
|
|
+ SETGAMEFOREGROUND;
|
|
|
|
+ GameAssist::GamePos2Screen(m_hGameWnd, pt);
|
|
|
|
+ GameAssist::MouseClick(pt);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void CAction::MouseMoveEx(POINT ptStart, POINT ptEnd, bool bSetCurPos)
|
|
|
|
+ {
|
|
|
|
+ SETGAMEFOREGROUND;
|
|
|
|
+ GameAssist::GamePos2Screen(m_hGameWnd, ptStart);
|
|
|
|
+ GameAssist::MouseMove(ptStart, bSetCurPos);
|
|
|
|
+
|
|
|
|
+ GameAssist::GamePos2Screen(m_hGameWnd, ptEnd);
|
|
|
|
+ GameAssist::MouseClick(ptEnd);
|
|
}
|
|
}
|
|
|
|
|
|
void CAction::MouseClick()
|
|
void CAction::MouseClick()
|
|
@@ -89,6 +148,41 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
GameAssist::SendKey(key, bCtrl, bAtl, bShift);
|
|
GameAssist::SendKey(key, bCtrl, bAtl, bShift);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ void CAction::InitNPCInfo()
|
|
|
|
+ {
|
|
|
|
+ static bool bInit = false;
|
|
|
|
+ if (!bInit) {
|
|
|
|
+ // "医师独侠","术士独侠","道士独侠","武师独侠","浪子独侠","剑客独侠", "弓手独侠", "禁卫独侠", "墨者独侠", "巫煞独侠", "魂武独侠"
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("医师独侠"), { 305, 325 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("术士独侠"), { 305, 325 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("道士独侠"), { 305, 325 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("武师独侠"), { 305, 325 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("浪子独侠"), { 160, 435 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("剑客独侠"), { 420, 215 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("弓手独侠"), { 265, 230 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("禁卫独侠"), { 155, 205 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("墨者独侠"), { 155, 205 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("巫煞独侠"), { 155, 205 }));
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("魂武独侠"), { 165, 335 }));
|
|
|
|
+ // 应天府NPC
|
|
|
|
+ g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("职业训导大师"), { 315, 415 }));
|
|
|
|
+
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("医师独侠"), { { 305, 325 }, { 590, 380 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("术士独侠"), { { 305, 325 }, { 610, 160 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("道士独侠"), { { 305, 325 }, { 140, 160 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("武师独侠"), { { 305, 325 }, { 140, 380 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("浪子独侠"), { { 160, 435 }, { 190, 370 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("剑客独侠"), { { 420, 215 }, { 540, 170 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("弓手独侠"), { { 265, 230 }, { 460, 150 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("禁卫独侠"), { { 155, 205 }, { 605, 235 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("墨者独侠"), { { 155, 205 }, { 315, 380 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("巫煞独侠"), { { 155, 205 }, { 270, 175 } }));
|
|
|
|
+ g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("魂武独侠"), { { 165, 335 }, { 270, 305 } }));
|
|
|
|
+
|
|
|
|
+ bInit = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
void CAction::SetGameForeground()
|
|
void CAction::SetGameForeground()
|
|
{
|
|
{
|
|
AutoThreadSection ats(&m_ts);
|
|
AutoThreadSection ats(&m_ts);
|
|
@@ -149,7 +243,7 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
DebugLog(_T("FindMatchIcon=%s"), lpszTemplateImage);
|
|
DebugLog(_T("FindMatchIcon=%s"), lpszTemplateImage);
|
|
ImgAssist::CaptureGameWnd(m_hGameWnd); SRAND(200, 500);
|
|
ImgAssist::CaptureGameWnd(m_hGameWnd); SRAND(200, 500);
|
|
_stprintf_s(szTemplateImage, _T("%s%s"), GameGlobal::g_strAppdir.c_str(), lpszTemplateImage);
|
|
_stprintf_s(szTemplateImage, _T("%s%s"), GameGlobal::g_strAppdir.c_str(), lpszTemplateImage);
|
|
- if (ImgAssist::GetImgMatchtemplate(GameGlobal::BuildImgPath(m_hGameWnd, _T("Game")), szTemplateImage, rc)) {
|
|
|
|
|
|
+ if (ImgAssist::GetImgMatchtemplate(GameGlobal::BuildImgPath(m_hGameWnd), szTemplateImage, rc)) {
|
|
// 找到匹配的模块;
|
|
// 找到匹配的模块;
|
|
DebugLog(_T("====> 找到匹配目标:%s"), lpszTemplateImage);
|
|
DebugLog(_T("====> 找到匹配目标:%s"), lpszTemplateImage);
|
|
return rc;
|
|
return rc;
|
|
@@ -267,7 +361,7 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
bool bFind = false;
|
|
bool bFind = false;
|
|
for (int i = 0; i < 3; i++)
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
{
|
|
- Sleep(600 - i * 150);
|
|
|
|
|
|
+ Sleep(800 - i * 150);
|
|
rc = FindMatchIcon(_T("img\\对话框关闭按钮.bmp"));
|
|
rc = FindMatchIcon(_T("img\\对话框关闭按钮.bmp"));
|
|
if (!rc.IsRectEmpty() && !rc.IsRectNull())
|
|
if (!rc.IsRectEmpty() && !rc.IsRectNull())
|
|
{
|
|
{
|
|
@@ -358,6 +452,20 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
return bFind;
|
|
return bFind;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ bool CAction::FindNPCByMap(LPCTSTR lpszNPCName)
|
|
|
|
+ {
|
|
|
|
+ auto it = g_mapZYNPC2.find(lpszNPCName);
|
|
|
|
+ if (it != g_mapZYNPC2.end())
|
|
|
|
+ {
|
|
|
|
+ if (FindNPCByIconAndPos(it->first.c_str(), it->second.ptMap, it->second.ptNpc))
|
|
|
|
+ {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
void CAction::BattleJY(BOOL bHasSummoner, int nZJType, BOOL bAggressiveSkill)
|
|
void CAction::BattleJY(BOOL bHasSummoner, int nZJType, BOOL bAggressiveSkill)
|
|
{
|
|
{
|
|
BOOL bFirstAttack = TRUE;
|
|
BOOL bFirstAttack = TRUE;
|
|
@@ -504,4 +612,166 @@ if (!::IsWindow(m_hGameWnd)) return;\
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ void CAction::BattleYS(LPCTSTR lpszSkillName)
|
|
|
|
+ {
|
|
|
|
+ CRect rc;
|
|
|
|
+ BOOL bBattle = FALSE;
|
|
|
|
+ if (!FindNPCByMap("医师独侠"))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ // 废话少说:表示这个没打过;
|
|
|
|
+ rc = FindMatchIcon(_T("img\\gdd\\废话少说.bmp"));
|
|
|
|
+ if (!rc.IsRectEmpty() && !rc.IsRectNull())
|
|
|
|
+ {
|
|
|
|
+ // 确定
|
|
|
|
+ bBattle = TRUE;
|
|
|
|
+ MouseMove({ rc.left - RAND(30, 50), rc.top - RAND(30, 50) });
|
|
|
|
+ SRAND(20, 50);
|
|
|
|
+ MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
|
|
|
|
+ SRAND(500, 800); // 切图时间长;
|
|
|
|
+ MouseMoveEx({ rc.left, rc.top }, { rc.right + rand() % 10, rc.bottom + rand() % 10 });
|
|
|
|
+ SRAND(20, 60);
|
|
|
|
+ ClickDlgSetup(_T("img\\确定.bmp"));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ rc = FindMatchIcon(_T("img\\gdd\\离开这里.bmp"));
|
|
|
|
+ if (!rc.IsRectEmpty() && !rc.IsRectNull())
|
|
|
|
+ {
|
|
|
|
+ SRAND(150, 250);
|
|
|
|
+ // 只有离开这里:已经打过,右键并退出 ;
|
|
|
|
+ DebugLog("只有离开这里:已经打过,右键并退出");
|
|
|
|
+ MouseRClick();
|
|
|
|
+ SRAND(200, 500);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // 找下一页的技能:没有下一页返回-1,找到返回0,没找到返回1;
|
|
|
|
+ auto FindNextPageJZ = [&](TCHAR* pJN)->int {
|
|
|
|
+ // 没有在当前页找到目标,看看是否在下一页;
|
|
|
|
+ rc = FindMatchIcon(_T("img\\jn-jk\\gdd\\xyy.bmp"));
|
|
|
|
+ if (rc.IsRectEmpty() || rc.IsRectNull())
|
|
|
|
+ {
|
|
|
|
+ // 没有下一页,右键退出;
|
|
|
|
+ MouseRClick();
|
|
|
|
+ SRAND(200, 300);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
|
|
|
|
+ SRAND(500, 750);
|
|
|
|
+ // 下一页中查看;
|
|
|
|
+ rc = FindMatchIcon(pJN);
|
|
|
|
+ if (!rc.IsRectEmpty() && !rc.IsRectNull())
|
|
|
|
+ {
|
|
|
|
+ // 找到目标,单击;
|
|
|
|
+ MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
|
|
|
|
+ SRAND(500, 800);
|
|
|
|
+ // 移动下,防止高亮识别失败;
|
|
|
|
+ MouseMoveEx({ rc.left, rc.top }, { rc.right - rand() % 10, rc.bottom - rand() % 10 });
|
|
|
|
+ SRAND(250, 300);
|
|
|
|
+ ClickDlgSetup(_T("img\\确定.bmp"));
|
|
|
|
+ SRAND(350, 500);
|
|
|
|
+
|
|
|
|
+ rc = FindMatchIcon(_T("img\\gdd\\接受挑战.bmp"));
|
|
|
|
+ if (!rc.IsRectEmpty() && !rc.IsRectNull())
|
|
|
|
+ {// 第二次开始都会多这个;
|
|
|
|
+ // 找到目标,单击;
|
|
|
|
+ MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
|
|
|
|
+ SRAND(500, 800);
|
|
|
|
+ // 移动下,防止高亮识别失败;
|
|
|
|
+ MouseMoveEx({ rc.left, rc.top }, { rc.left - rand() % 20, rc.top - rand() % 20 });
|
|
|
|
+ SRAND(250, 350);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ClickDlgSetup(_T("img\\确定.bmp"));
|
|
|
|
+ SRAND(250, 300);
|
|
|
|
+
|
|
|
|
+ // 战斗;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ TCHAR szJN[MAX_PATH] = { 0 };
|
|
|
|
+ _stprintf_s(szJN, _T("img\\jn-jk\\gdd\\%s.bmp"), lpszSkillName);
|
|
|
|
+ rc = FindMatchIcon(szJN);
|
|
|
|
+ if (rc.IsRectEmpty() || rc.IsRectNull())
|
|
|
|
+ {
|
|
|
|
+ // 最多只有三页;
|
|
|
|
+ for (int i = 0; i < 3; i++)
|
|
|
|
+ {
|
|
|
|
+ // 没有在当前页找到目标,看看是否在下一页;
|
|
|
|
+ int nRet = FindNextPageJZ(szJN);
|
|
|
|
+ if (nRet == 1)
|
|
|
|
+ {
|
|
|
|
+ // 没有找到技能;
|
|
|
|
+ SRAND(500, 800);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (nRet == 0)
|
|
|
|
+ {
|
|
|
|
+ // 找到了;
|
|
|
|
+ bBattle = TRUE;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ break; // 没有下一页也直接break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ bBattle = TRUE;
|
|
|
|
+ // 找到目标,单击;
|
|
|
|
+ MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
|
|
|
|
+ // 切图时间比较长;
|
|
|
|
+ SRAND(500, 800);
|
|
|
|
+ // 战斗;
|
|
|
|
+ ClickDlgSetup(_T("img\\确定.bmp"));
|
|
|
|
+ SRAND(200, 300);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int KeyValue, SkillTime;
|
|
|
|
+ // 进入战斗;
|
|
|
|
+ if (bBattle)
|
|
|
|
+ {
|
|
|
|
+ // 人物:Alt+S显示技能,双击选择技能,单击怪物发动技能;
|
|
|
|
+ // 注:有的人物技能太多,导致会有滚动条:这是有难点;
|
|
|
|
+ BOOL bRet = FindJNShortCut(lpszSkillName, KeyValue, SkillTime);
|
|
|
|
+ DebugLog("快捷键值=%ld", KeyValue);
|
|
|
|
+
|
|
|
|
+ // 快捷键;
|
|
|
|
+ SendKey(KeyValue);
|
|
|
|
+ SRAND(350, 650);
|
|
|
|
+ // 单击指定位置;
|
|
|
|
+ MouseClick({ 230, 170 });
|
|
|
|
+ SRAND(260, 380);
|
|
|
|
+ // 将鼠标移动到指定位置;
|
|
|
|
+ POINT ptDest = { 625, 28 }; // 左上角;
|
|
|
|
+ MouseMove(ptDest);
|
|
|
|
+ while (IsBattle())
|
|
|
|
+ {
|
|
|
|
+ // 判断是否我方攻击;
|
|
|
|
+ if (IsWattingAttack(1))
|
|
|
|
+ {
|
|
|
|
+ SendKey(VK_A, FALSE, TRUE);
|
|
|
|
+ }
|
|
|
|
+ SRAND(500, 900);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 右键退出;
|
|
|
|
+ SRAND(300, 500); //必要的等待时间;
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ rc = FindMatchIcon("img\\对话框关闭按钮.bmp");
|
|
|
|
+ Sleep(900);
|
|
|
|
+ } while (rc.IsRectEmpty() || rc.IsRectNull());
|
|
|
|
+
|
|
|
|
+ MouseRClick();
|
|
|
|
+ }
|
|
};
|
|
};
|