首页
社区
课程
招聘
[原创]QQ斗地主简易自动化刷分工具源码
发表于: 2013-6-30 22:06 7820

[原创]QQ斗地主简易自动化刷分工具源码

2013-6-30 22:06
7820

本人最近编写了一款QQ斗地主的刷分工具,现将关键代码附上来(代码中有注释),以供参考。本人新手,请大侠切勿耻笑。成品软件可以点击此处下载:http://yunpan.cn/QtVWNVy2iIwqt

// 获取指定位置的屏幕颜色
COLORREF CQQGameAddInDlg::GetColorAtPos(int nX, int nY)
{
        HDC hdcSrc = ::GetDC(s_hwndQQGame);
        if (NULL == hdcSrc)
        {
                AfxMessageBox(_T("获取设备上下文失败"));
                GetDlgItem(IDC_BUTTON2)->SendMessage(BM_CLICK, 0, 0);
                return -1;
        }
        int nBPP = GetDeviceCaps(hdcSrc, BITSPIXEL) * GetDeviceCaps(hdcSrc, PLANES);
        CRect rect;
        ::GetClientRect(s_hwndQQGame, &rect);
        CImage image;
        if (!image.Create(rect.Width(), rect.Height(), nBPP))
        {
                AfxMessageBox(_T("创建图像对象失败"));
                ::ReleaseDC(s_hwndQQGame, hdcSrc);
                GetDlgItem(IDC_BUTTON2)->SendMessage(BM_CLICK, 0, 0);
                return -1;
        }
        BitBlt(image.GetDC(), 0, 0, rect.Width(), rect.Height(), hdcSrc, rect.left, rect.top, SRCCOPY);
        COLORREF color = image.GetPixel(nX, nY);
        if (-1 == color)
        {
                ReportLog(_T("获取颜色值失败:%u\n"), GetLastError());
                image.ReleaseDC();
                image.Destroy();
                ::ReleaseDC(s_hwndQQGame, hdcSrc);
                return -1;
        }
        ::ReleaseDC(s_hwndQQGame, hdcSrc);
        image.ReleaseDC();
        image.Destroy();
        return color;
}

void CQQGameAddInDlg::OnTimer(UINT_PTR nIDEvent)
{
        // TODO: Add your message handler code here and/or call default
        switch (nIDEvent)
        {
        case FAST_START_GAME_TIMER_ID:
                {
                        if (s_colorFastStart == GetColorAtPos(s_nFastStartX, s_nFastStartY))
                        {
                                KillTimer(FAST_START_GAME_TIMER_ID);
                                ClickAtPos(s_nFastStartX, s_nFastStartY);
                                TCHAR szTime[9] = {0};
                                _strtime(szTime);
                                ReportLog(_T("快速开始游戏 %s\n"), szTime);
                                Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                SetTimer(FAST_START_GAME_TIMER_ID, TIMER_INTERVAL, NULL);
                        }
                }
                break;
        case START_GAME_TIMER_ID:
                {
                        COLORREF colorStart = GetColorAtPos(s_nStartX, s_nStartY);
                        BOOL bStart = s_colorStart == colorStart;
                        // 主账户多增加了两个判断
                        if (!bStart && s_nBrowserType == 0)
                        {
                                bStart = s_colorMajorStart1 == colorStart;
                                if (!bStart)
                                {
                                        bStart = s_colorMajorStart2 == colorStart;
                                }
                        }

                        if (bStart)
                        {
                                KillTimer(START_GAME_TIMER_ID);
                                if (BST_CHECKED == ((CButton *)GetDlgItem(IDC_CHECK1))->GetCheck())
                                {
                                        // 主账户计时
                                        if (0 == s_timeStartGame)
                                        {
                                                time(&s_timeStartGame);
                                        }
                                        else
                                        {
                                                time_t timeStartGame = 0;
                                                time(&timeStartGame);
                                                CTime time(timeStartGame - s_timeStartGame);
                                                s_timeStartGame = timeStartGame;
                                                CString strTimeDuration = time.FormatGmt(_T("上一局牌持续时间:%H:%M:%S\n"));
                                                ReportLog(strTimeDuration);
                                        }

                                }
                                ClickAtPos(s_nStartX, s_nStartY);
                                TCHAR szTime[9] = {0};
                                _strtime(szTime);
                                ReportLog(_T("开始第%d局游戏 %s\n"), ++s_nPKTimes, szTime);
                                Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                SetTimer(START_GAME_TIMER_ID, TIMER_INTERVAL, NULL);
                                KillTimer(TUOGUAN_TIMER_ID);                // 叫分前禁用托管
                        }
                        else
                        {
                                TRACE(_T("开始游戏的颜色为:%ul\n"), colorStart);
                        }
                }
                break;
        case SANFEI_TIMER_ID:
                {
                        if (s_colorSanfei == GetColorAtPos(s_nSanFeiX, s_nSanFeiY))
                        {
                                KillTimer(SANFEI_TIMER_ID);
                                ClickAtPos(s_nSanFeiX, s_nSanFeiY);
                                TCHAR szTime[9] = {0};
                                _strtime(szTime);
                                ReportLog(_T("三分: %s\n"), szTime);
                                Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                SetTimer(SANFEI_TIMER_ID, TIMER_INTERVAL, NULL);
                                if (BST_CHECKED == ((CButton *)GetDlgItem(IDC_CHECK1))->GetCheck())
                                {
                                        // 主账号开始托管
                                        SetTimer(TUOGUAN_TIMER_ID, TIMER_INTERVAL, NULL);
                                }
                                SetTimer(SANFEI_TIMER_ID, TIMER_INTERVAL, NULL);
                        }
                }
                break;
                case BUCHU_TIMER_ID:
                {
                        if (s_colorBuChu1 == GetColorAtPos(s_nBuChuX, s_nBuChuY) || s_colorBuChu2 == GetColorAtPos(s_nBuChuX, s_nBuChuY))
                        {
                                KillTimer(BUCHU_TIMER_ID);
                                ClickAtPos(s_nBuChuX, s_nBuChuY);
                                TCHAR szTime[9] = {0};
                                _strtime(szTime);
                                ReportLog(_T("不出: %s\n"), szTime);
                                Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                SetTimer(BUCHU_TIMER_ID, TIMER_INTERVAL, NULL);
                        }
                }
                break;
                case BUJIAO_TIMER_ID:
                {
                        if (s_colorBuJiao == GetColorAtPos(s_nBuJiaoX, s_nBuJiaoY))
                        {
                                KillTimer(BUJIAO_TIMER_ID);
                                ClickAtPos(s_nBuJiaoX, s_nBuJiaoY);
                                TCHAR szTime[9] = {0};
                                _strtime(szTime);
                                ReportLog(_T("不叫: %s\n"), szTime);
                                Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                SetTimer(BUJIAO_TIMER_ID, TIMER_INTERVAL, NULL);
                        }
                }
                break;
                case TUOGUAN_TIMER_ID:
                {
                        if (s_colorTuoGuan == GetColorAtPos(s_nTuoGuanX, s_nTuoGuanY))
                        {
                                KillTimer(TUOGUAN_TIMER_ID);
                                ClickAtPos(s_nTuoGuanX, s_nTuoGuanY);
                                TCHAR szTime[9] = {0};
                                _strtime(szTime);
                                ReportLog(_T("托管: %s\n"), szTime);
                                Sleep(REST_TIME_AFTER_SEND_COMMAND);
                        }
                }
                break;
                case LIANSHENG_TIMER_ID:
                        {
                                if (s_colorLianSheng == GetColorAtPos(s_nLianShengX, s_nLianShengY))
                                {
                                        KillTimer(LIANSHENG_TIMER_ID);
                                        ClickAtPos(s_nLianShengX, s_nLianShengY);
                                        TCHAR szTime[9] = {0};
                                        _strtime(szTime);
                                        ReportLog(_T("连剩五局: %s\n"), szTime);
                                        Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                        SetTimer(LIANSHENG_TIMER_ID, TIMER_INTERVAL, NULL);
                                }
                        }
                        break;
                case TUO_GUAN_BUG_TIMER_ID:
                        {
                                // 托管时不出牌时的BUG
                                if (s_colorTuoGuanBug == GetColorAtPos(s_nTuoGuanBugX, s_nTuoGuanBugY))
                                {
                                        KillTimer(TUO_GUAN_BUG_TIMER_ID);
                                        KillTimer(TUOGUAN_TIMER_ID);                //  取消托管
                                        Beep(32767, 1000);
                                        TCHAR szTime[9] = {0};
                                        _strtime(szTime);
                                        ReportLog(_T("托管不出牌BUG: %s\n"), szTime);
                                        Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                        ClickAtPos(s_nTuoGuanBugQuXiaoTuoGuanX, s_nTuoGuanBugQuXiaoTuoGuanY);        // 取消托管
                                        ReportLog(_T("取消托管\n"));
                                        Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                        ClickAtPos(s_nTuoGuanBugClickX, s_nTuoGuanBugClickX);        // 选牌
                                        ReportLog(_T("选牌\n"));
                                        Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                        ClickAtPos(s_nTuoGuanBugChuPaiX, s_nTuoGuanBugChuPaiY);                // 出牌
                                        ReportLog(_T("出牌\n"));
                                        Sleep(REST_TIME_AFTER_SEND_COMMAND);
                                        SetTimer(TUO_GUAN_BUG_TIMER_ID, TIMER_INTERVAL, NULL);
                                        SetTimer(TUOGUAN_TIMER_ID, TIMER_INTERVAL, NULL);                        // 恢复托管
                                }
                        }
                        break;
                case PREVIEW_GAEM_TIME_ID:
                        {
                                KillTimer(PREVIEW_GAEM_TIME_ID);
                                CRect rectClient;
                                GetClientRect(&rectClient);
                                CRect rectRedt;
                                m_redtLog.GetWindowRect(&rectRedt);
                                ScreenToClient(&rectRedt);
                                rectClient.top = rectRedt.bottom;
                                InvalidateRect(&rectClient);
                                SetTimer(PREVIEW_GAEM_TIME_ID, TIMER_INTERVAL, NULL);
                        }
                        break;
        }
        CDialogEx::OnTimer(nIDEvent);
}

// 指定位置单击
int CQQGameAddInDlg::ClickAtPos(int nX, int nY)
{
        ::SendMessage(s_hwndQQGame, WM_LBUTTONDOWN, MK_LBUTTON, (nY << 16) + nX);
        ::SendMessage(s_hwndQQGame, WM_LBUTTONUP, 0, (nY << 16) + nX);
        return 0;

        int nX1 = 0, nY1 = 0;                // 转化后的坐标
        int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
        int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
        nX1 = nX * (65535. / nScreenWidth );
        nY1 = nY * (65535. / nScreenHeight);
        mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, nX1, nY1, 0, NULL);
        mouse_event(MOUSEEVENTF_LEFTDOWN, nX1, nY1, 0, NULL);
        mouse_event(MOUSEEVENTF_LEFTUP, nX1, nY1, 0, NULL);
        return 0;
}


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 5
支持
分享
最新回复 (8)
雪    币: 19
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
现附软件截图:
2013-6-30 22:23
0
雪    币: 190
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
想问下楼主打牌算法怎么实现的,还是直接托管的?
感谢分享,顶源码
2013-6-30 23:06
0
雪    币: 19
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
其中两个玩家为自己的临时账号,第三个玩家是自己主号。主号托管、叫分,另两个号不出牌、不叫分。
2013-7-1 10:03
0
雪    币: 190
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
哈哈,好YD啊,看雪什么时候也河蟹yindang了啊
2013-7-1 14:42
0
雪    币: 80
活跃值: (109)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
想知道CQQGameAddInDlg::ClickAtPos(int nX, int nY)函数(见1楼最下面)函数怎么执行。
执行到一半就return 0了啊?
2013-7-1 17:13
0
雪    币: 19
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
return后面的那段代码就不要了,原来是用的模拟鼠标单击,后来改成了发送消息,也就是return前面的代码.
2013-7-1 19:10
0
雪    币: 92
活跃值: (209)
能力值: ( LV6,RANK:95 )
在线值:
发帖
回帖
粉丝
8
其实斗地主的出牌算法不难的,斗地主那些牌识别一下也不是很难吧??
2013-7-4 07:30
0
雪    币: 24
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
很好,学习了
2013-7-4 19:27
0
游客
登录 | 注册 方可回帖
返回
//