如果这也算外挂。。。
上学期接触 QQ 对对碰,无奈水平太菜,屡次被虐,于是发挥专业特长,(*^__^*) 嘻嘻……
贴两张截图:
我是一号,刚开局时
不久之后
原理很简单:
1,找到对对碰窗口
2,获取窗口中各点像素,依像素分析局面
3,确定对策
4,向对对碰窗口发送鼠标消息,实施对策
一局结束后,会自动点开始,开始下一局,因而可以长时间挂着。
我用这个挂了接近一个上午和一个下午的时间,积分从负几百升到了正一千多,中间手工连接服务器两三次。
不会使用道具,而且长时间挂着的话,有时候会和服务器断开。
使用道具,重新连接服务器,都是可以实现的,懒得写了,毕竟胜率已经很高了。
在我机器上可以使用,一切正常,在一个学长的机器上却完全没有效果,不知移植性如何。
使用时注意,对对碰窗口不能最小化,一定要保持正常大小,当然,可以被其它窗口遮挡。。。
代码如下
qqddp.cpp
1#include <iostream>
2#include <cstdio>
3#include <map>
4#include <windows.h>
5
6using namespace std;
7
8CONST TCHAR ddpWndName[ 30 ] = TEXT( "对对碰角色版" );
9CONST INT BOARD_UNIT_LEN = 48;
10CONST INT BOARD_LEFT = 270;
11CONST INT BOARD_TOP = 95;
12CONST INT BOARD_UNIT_NUM_X = 8;
13CONST INT BOARD_UNIT_NUM_Y = 8;
14CONST INT BOARD_UNIT_COLOR_DELTA = 17;
15CONST INT BOARD_MAX_COLOR = 20;
16CONST INT BOARD_MIN_COLOR = 2;
17CONST INT BOARD_NUM_TO_TRY_GET = 30;
18CONST INT WND_NUM_TO_TRY_GET = 100;
19CONST INT SOLVE_NUM_TO_TRY_GET = 20;
20CONST INT START_BUTTON_X = 384;
21CONST INT START_BUTTON_Y = 390;
22CONST INT TOOL_X = 1; //
23CONST INT TOOL_Y = 1; //
24CONST INT CLICK_CYCLE = 400;
25
26HWND ddpWndHandle = 0;
27::COLORREF board[ BOARD_UNIT_NUM_X ][ BOARD_UNIT_NUM_Y ];
28POINT clickUnitPoint[ 2 ];
29int totCantGetBoard = 0, totCantGetSolve = 0, totCantGetWnd = 0;
30
31/**//*
32BOOL CALLBACK OnEnumWnd( HWND hWnd, LPARAM lparam ) {
33 CONST INT MAXLEN = 1000;
34 ::TCHAR name[ MAXLEN ];
35 ::GetWindowText( hWnd, name, MAXLEN );
36 BOOL same = TRUE;
37 for ( int i = 0; i < 6; ++i ) {
38 if ( ddpWndName[ i ] != name[ i ] ) {
39 same = FALSE;
40 }
41 }
42 if ( same ) {
43 ddpWndHandle = hWnd;
44 return FALSE;
45 }
46 return TRUE;
47}
48*/
49
50BOOL GetDdpWindowHandle() {
51 /**//*
52 ddpWndHandle = 0;
53 ::EnumWindows( OnEnumWnd, 0 );
54 */
55 ddpWndHandle = ::FindWindow( 0, ddpWndName );
56 return ddpWndHandle != 0;
57}
58
59BOOL GetBoard() {
60 int x, y, totColor = 0;
61 map<::COLORREF,INT> dict;
62 ::HDC hdc = ::GetDC( ddpWndHandle );
63 for ( x = 0; x < BOARD_UNIT_NUM_X; ++x ) {
64 for ( y = 0; y < BOARD_UNIT_NUM_Y; ++y ) {
65 board[ x ][ y ] = ::GetPixel( hdc,
66 BOARD_LEFT + x * BOARD_UNIT_LEN + BOARD_UNIT_COLOR_DELTA,
67 BOARD_TOP + y * BOARD_UNIT_LEN + BOARD_UNIT_COLOR_DELTA );
68 dict[ board[ x ][ y ] ] = 1;
69 }
70 }
71 ::ReleaseDC( ddpWndHandle, hdc );
72 totColor = dict.size();
73 //
74 /**//*
75 cout << "totColor = " << totColor << endl;
76 for ( y = 0; y < ::BOARD_UNIT_NUM_Y; ++y ) {
77 for ( x = 0; x < ::BOARD_UNIT_NUM_X; ++x ) {
78 cout << board[ x ][ y ] << " ";
79 }
80 cout << endl;
81 }
82 cout << endl;
83 */
84 //
85 return ( totColor > ::BOARD_MIN_COLOR ) && ( totColor < ::BOARD_MAX_COLOR );
86}
87
88BOOL GetClickUnitPoint() {
89 int x, y;
90 for ( x = 0; x < BOARD_UNIT_NUM_X; ++x ) {
91 for ( y = 0; y < BOARD_UNIT_NUM_Y; ++y ) {
92 clickUnitPoint[ 0 ].x = x;
93 clickUnitPoint[ 0 ].y = y;
94 clickUnitPoint[ 1 ].x = x;
95 clickUnitPoint[ 1 ].y = y;
96 // *_**
97 if ( ( x + 3 < ::BOARD_UNIT_NUM_X ) &&
98 ( board[ x ][ y ] == board[ x + 2 ][ y ] ) &&
99 ( board[ x ][ y ] == board[ x + 3 ][ y ] )
100 ) {
101 clickUnitPoint[ 1 ].x = x + 1;
102 return TRUE;
103 }
104 // **_*
105 if ( ( x > 2 ) &&
106 ( board[ x ][ y ] == board[ x - 2 ][ y ] ) &&
107 ( board[ x ][ y ] == board[ x - 3 ][ y ] )
108 ) {
109 clickUnitPoint[ 1 ].x = x - 1;
110 return TRUE;
111 }
112 // *
113 // _
114 // *
115 // *
116 if ( ( y + 3 < ::BOARD_UNIT_NUM_Y ) &&
117 ( board[ x ][ y ] == board[ x ][ y + 2 ] ) &&
118 ( board[ x ][ y ] == board[ x ][ y + 3 ] )
119 ) {
120 clickUnitPoint[ 1 ].y = y + 1;
121 return TRUE;
122 }
123 // *
124 // *
125 // _
126 // *
127 if ( ( y > 2 ) &&
128 ( board[ x ][ y ] == board[ x ][ y - 2 ] ) &&
129 ( board[ x ][ y ] == board[ x ][ y - 3 ] )
130 ) {
131 clickUnitPoint[ 1 ].y = y - 1;
132 return TRUE;
133 }
134 // *
135 // *_
136 // *
137 if ( ( x + 1 < ::BOARD_UNIT_NUM_X ) && ( y > 0 ) && ( y + 1 < ::BOARD_UNIT_NUM_Y ) &&
138 ( board[ x ][ y ] == board[ x + 1 ][ y - 1 ] ) &&
139 ( board[ x ][ y ] == board[ x + 1 ][ y + 1 ] )
140 ) {
141 clickUnitPoint[ 1 ].x = x + 1;
142 return TRUE;
143 }
144 // *
145 // _*
146 // *
147 if ( ( x > 0 ) && ( y > 0 ) && ( y + 1 < ::BOARD_UNIT_NUM_Y ) &&
148 ( board[ x ][ y ] == board[ x - 1 ][ y - 1 ] ) &&
149 ( board[ x ][ y ] == board[ x - 1 ][ y + 1 ] )
150 ) {
151 clickUnitPoint[ 1 ].x = x - 1;
152 return TRUE;
153 }
154 // *
155 // *_*
156 if ( ( x > 0 ) && ( x + 1 < ::BOARD_UNIT_NUM_X ) && ( y + 1 < ::BOARD_UNIT_NUM_Y ) &&
157 ( board[ x ][ y ] == board[ x - 1 ][ y + 1 ] ) &&
158 ( board[ x ][ y ] == board[ x + 1 ][ y + 1 ] )
159 ) {
160 clickUnitPoint[ 1 ].y = y + 1;
161 return TRUE;
162 }
163 // *_*
164 // *
165 if ( ( x > 0 ) && ( x + 1 < ::BOARD_UNIT_NUM_X ) && ( y > 0 ) &&
166 ( board[ x ][ y ] == board[ x - 1 ][ y - 1 ] ) &&
167 ( board[ x ][ y ] == board[ x + 1 ][ y - 1 ] )
168 ) {
169 clickUnitPoint[ 1 ].y = y - 1;
170 return TRUE;
171 }
172 // *
173 // **_
174 if ( ( y + 1 < ::BOARD_UNIT_NUM_Y ) && ( x > 1 ) &&
175 ( board[ x ][ y ] == board[ x - 1 ][ y + 1 ] ) &&
176 ( board[ x ][ y ] == board[ x - 2 ][ y + 1 ] )
177 ) {
178 clickUnitPoint[ 1 ].y = y + 1;
179 return TRUE;
180 }
181 // **_
182 // *
183 if ( ( x > 1 ) && ( y > 0 ) &&
184 ( board[ x ][ y ] == board[ x - 1 ][ y - 1 ] ) &&
185 ( board[ x ][ y ] == board[ x - 2 ][ y - 1 ] )
186 ) {
187 clickUnitPoint[ 1 ].y = y - 1;
188 return TRUE;
189 }
190 // *
191 // _**
192 if ( ( x + 2 < ::BOARD_UNIT_NUM_X ) && ( y + 1 < ::BOARD_UNIT_NUM_Y ) &&
193 ( board[ x ][ y ] == board[ x + 1 ][ y + 1 ] ) &&
194 ( board[ x ][ y ] == board[ x + 2 ][ y + 1 ] )
195 ) {
196 clickUnitPoint[ 1 ].y = y + 1;
197 return TRUE;
198 }
199 // _**
200 // *
201 if ( ( x + 2 < ::BOARD_UNIT_NUM_X ) && ( y > 0 ) &&
202 ( board[ x ][ y ] == board[ x + 1 ][ y - 1 ] ) &&
203 ( board[ x ][ y ] == board[ x + 2 ][ y - 1 ] )
204 ) {
205 clickUnitPoint[ 1 ].y = y - 1;
206 return TRUE;
207 }
208 // *_
209 // *
210 // *
211 if ( ( x + 1 < ::BOARD_UNIT_NUM_X ) && ( y + 2 < ::BOARD_UNIT_NUM_Y ) &&
212 ( board[ x ][ y ] == board[ x + 1 ][ y + 1 ] ) &&
213 ( board[ x ][ y ] == board[ x + 1 ][ y + 2 ] )
214 ) {
215 clickUnitPoint[ 1 ].x = x + 1;
216 return TRUE;
217 }
218 // _*
219 // *
220 // *
221 if ( ( x > 0 ) && ( y + 2 < ::BOARD_UNIT_NUM_Y ) &&
222 ( board[ x ][ y ] == board[ x - 1 ][ y + 1 ] ) &&
223 ( board[ x ][ y ] == board[ x - 1 ][ y + 2 ] )
224 ) {
225 clickUnitPoint[ 1 ].x = x - 1;
226 return TRUE;
227 }
228 // *
229 // *
230 // *_
231 if ( ( x + 1 < ::BOARD_UNIT_NUM_X ) && ( y > 1 ) &&
232 ( board[ x ][ y ] == board[ x + 1 ][ y - 1 ] ) &&
233 ( board[ x ][ y ] == board[ x + 1 ][ y - 2 ] )
234 ) {
235 clickUnitPoint[ 1 ].x = x + 1;
236 return TRUE;
237 }
238 // *
239 // *
240 // _*
241 if ( ( x > 0 ) && ( y > 1 ) &&
242 ( board[ x ][ y ] == board[ x - 1 ][ y - 1 ] ) &&
243 ( board[ x ][ y ] == board[ x - 1 ][ y - 2 ] )
244 ) {
245 clickUnitPoint[ 1 ].x = x - 1;
246 return TRUE;
247 }
248 }
249 }
250 return FALSE;
251}
252
253VOID DoClick() {
254 for ( int i = 0; i < 2; ++i ) {
255 INT x = BOARD_LEFT + clickUnitPoint[ i ].x * BOARD_UNIT_LEN + BOARD_UNIT_COLOR_DELTA;
256 INT y = BOARD_TOP + clickUnitPoint[ i ].y * BOARD_UNIT_LEN + BOARD_UNIT_COLOR_DELTA;
257 ::PostMessage( ddpWndHandle, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM( x, y ) );
258 ::PostMessage( ddpWndHandle, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM( x, y ) );
259 }
260}
261
262VOID TryToStart() {
263 ::PostMessage( ddpWndHandle, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM( ::START_BUTTON_X, ::START_BUTTON_Y ) );
264 ::PostMessage( ddpWndHandle, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM( ::START_BUTTON_X, ::START_BUTTON_Y ) );
265}
266
267VOID HackMain() {
268 totCantGetBoard = 0;
269 totCantGetSolve = 0;
270 while ( ( totCantGetBoard < ::BOARD_NUM_TO_TRY_GET ) &&
271 ( totCantGetWnd < ::WND_NUM_TO_TRY_GET ) &&
272 ( totCantGetSolve < ::SOLVE_NUM_TO_TRY_GET )
273 ) {
274 if ( ! ::GetDdpWindowHandle() ) {
275 ++totCantGetWnd;
276 cout << "未发现对对碰窗口 " << totCantGetWnd << " 次" << endl << endl;
277 ::Sleep( 1000 );
278 continue;
279 }
280 totCantGetWnd = 0;
281 if ( ::GetBoard() ) {
282 totCantGetBoard = 0;
283 //
284 // cout << "get board" << endl;
285 //
286 if ( ::GetClickUnitPoint() ) {
287 totCantGetSolve = 0;
288 DoClick();
289 }
290 else {
291 ++totCantGetSolve;
292 cout << "没有找到解法 " << totCantGetSolve << " 次" << endl << endl;
293 }
294 }
295 else {
296 ++totCantGetBoard;
297 cout << "无法获取局面 " << totCantGetBoard << " 次" << endl << endl;
298 ::Sleep( 1000 );
299 ::TryToStart();
300 }
301 ::Sleep( ::CLICK_CYCLE );
302 }
303 //
304 // cout << "not get board" << endl;
305 //
306}
307
308int main() {
309 while ( totCantGetWnd < ::WND_NUM_TO_TRY_GET ) {
310 ::Sleep( 1000 );
311 if ( ::GetDdpWindowHandle() ) {
312 totCantGetWnd = 0;
313 ::HackMain();
314 }
315 else {
316 ++totCantGetWnd;
317 cout << "未发现对对碰窗口 " << totCantGetWnd << " 次" << endl << endl;
318 }
319 }
320 cout << "未发现对对碰窗口次数过多,程序将在 5 秒后退出" << endl << endl;
321 ::Sleep( 5000 );
322 return 0;
323}
324