首页
社区
课程
招聘
[求助]鼠标键盘模拟、多线程、定时器的问题
发表于: 2006-7-11 13:49 7667

[求助]鼠标键盘模拟、多线程、定时器的问题

2006-7-11 13:49
7667

    最近我在玩冒险岛(国际服的,mapleglobal),人太多,要想做组队任务(Party Quest),就得飞似的双击鼠标左键和回车。游戏里很多人都有Auto-Clicker(AC),能模拟鼠标双击和按回车,速度很快。现在没有AC几乎做不上组队任务。   
     于是,我自己写了一个模拟双击的程序。因为有nProtect(GameGuard),几乎把能用于hack的API、native API全hook上了 我花了2周时间,费了九牛二虎之力,终于把我自己写的代码插到了游戏进程(maplestory.exe)。因为不能用SendMessage/PostMessage,我只好通过FindWindow获取游戏窗口句柄,然后找到窗口过程地址,自己调用游戏的窗口过程。下面是我插到游戏进程的地址空间的代码:

.data
szM        db        'Maplestory',0
dwWProc        dd        0
               
.data?
bKey        db        ?

.code
FindM        proc hwnd,uMsg,idEvent,dwTime
               
                invoke FindWindow ,0,addr szM
                .if eax
                        mov hWndM,eax
                        .if        bKey==0
                                ret
                        .endif
                       
                        invoke GetClassLong,hWndM,GCL_WNDPROC
                        mov dwWProc,eax         

.while TRUE
                        .if bKey==0
                                ret
                        .endif
;>>>>>>>>>>>>>>>>>>>>>>>>>
                        push        015201fbh  ;点的坐标507,338
                        push        0
                        push WM_LBUTTONDOWN
                        push        hWndM
                        call        dwWProc
;>>>>>>>>>>>>>>>>>>>>>>>>>
                        push        015201fbh
                        push        0
                        push WM_LBUTTONUP
                        push        hWndM
                        call        dwWProc
;>>>>>>>>>>>>>>>>>>>>>>>>>
                        push        015201fbh
                        push        0
                        push WM_LBUTTONDBLCLK
                        push        hWndM
                        call        dwWProc
;>>>>>>>>>>>>>>>>>>>>>>>>>
                        push        015201fbh
                        push        0
                        push WM_LBUTTONUP
                        push        hWndM
                        call        dwWProc
;>>>>>>>>>>>>>>>{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
                        push        001c0001h
                        push        0000000dh ;回车键
                        push WM_KEYDOWN
                        push        hWndM
                        call        dwWProc
;>>>>>>>>>>>>>>>>>>>>>>>>>
                        push        001c0001h
                        push        0000000dh ;回车键
                        push WM_KEYUP
                        push        hWndM
                        call        dwWProc
.endw
                .endif
                ret
FindM        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EntClick        proc       
                .if hWndM==0
                        invoke SetTimer ,0,0,4,addr FindM
                .endif
                mov        eax,TRUE
                ret

EntClick        Endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    进入游戏后,EntClick函数先被调用,设置定时器。然后我另一个线程控制bKey来决定是否开始模拟双击和按回车。刚开始我用游戏中的交易功能作试验,双击一次向别人发一次交易申请,再回车就取消交易。bKey=1后,整个屏幕冻住了,没反应,我的网卡灯狂闪。5秒后,bKey=0,对方告诉我他接到的交易申请已经不可计数了。但是,我用它却进不了组队任务!!!!.......
    我不知道SetTimer是怎么工作的,虽然我写了4ms,但听说触发间隔最小是55ms。当FindM这个回调函数被调用时,系统是另开一个线程吗?如果函数没执行完,就到了下一次调用的时间,系统会再开新线程还是等着?(谁能教教我啊)。。。不过我感觉系统好像没创建新线程,因为屏幕冻住了,主线程似乎不处理消息队列中的消息...我想问题可能出在这里,游戏只是向服务器发送“我想做组队任务”消息,而不处理服务器发回来的“你可以做组队任务” 我还试过开一个新线程来调用窗口过程,但开始双击不出10秒,游戏就退出了,什么也没剩下,可能是nProtect的原因。
   呜呜呜呜呜呜。。2周时间什么也没干成,谁能给我点思路啊?我先谢谢各位了。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
没怎么看懂.
我所知道的:
触发间隔最小 1/18.3秒,由主板上的震荡晶片决定
SetTimer设置以后,每过指定长的时间会投递一个消息到主线程中,主线程发现这个消息(当然要把先前的处理完)才开始执行对应的FindM
看了你的FindM函数应该是一直在死循环等待什么,主线程当然一直停止响应
2006-7-11 17:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zby
3
还是不明白,函数本来是SetTimer(hWnd,nIDEvent,uElapse,lpTimerFunc)
而我的程序中没有给出窗口句柄,像这种只用定时器过程的用法,SetTimer还会发WM_TIMER到主线程的消息队列,再由窗口过程调用定时器过程吗?找了几本Win32编程的书,都没说明。
invoke SetTimer ,0,0,4,addr FindM
2006-7-12 00:35
0
雪    币: 222
活跃值: (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
NT5.0之后的触发间隔基本上接近线程时间片长度(每15ms触发一次),Win95才是55ms(依赖于系统时钟每秒18.2次的中断)
2006-7-13 16:01
0
雪    币: 249
活跃值: (10)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
5
模拟鼠标、键盘消息可以用 mouse_event() 和 keybd_event()
2006-7-13 16:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zby
6
555~~~~刚试完mouse_event(),没作用啊。由于有nProtect GameGuard,好像只能在游戏进程里 “Call 窗口过程地址”。但像我1楼里用循环不停的“Call 窗口过程地址”,主线程好像停了。要是在定时器过程里只Call一次,运行时发现鼠标点的又太慢,无论SetTimer里我写多少毫秒。我的程序是一个DLL,随游戏一起加载的,到底是不是主线程在执行我的定时器过程代码啊?
2006-7-17 10:16
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
请问楼主是在玩MAPLESTORY还是其他的?盛大的吗?
2006-7-17 10:28
0
雪    币: 249
活跃值: (10)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
8
我没玩过这个游戏。

写个dll、exe用message hook 或者干脆WM_HOTKEY挂上。

在自己写的那个程序里createwindowex,在自己的窗口上settimer

可以通过诸如判断某点的颜色之类实现需要的功能。这是在“按键精灵”上得到的启发。
3年前玩传世的时候就写过这样的程序,十分好用。
2006-7-17 11:41
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
9
bKey是你手动控制的变量,
用SetTimer设置间隔4ms,一旦启动就每隔4ms就发送一个消息
这样就形成很庞大的消息队列,所以屏幕会停止响应

你手动控制变量的时间少说也得好几秒,

你的每个消息里都有一个while循环,这在你手动控制变量的时间内估计少说也执行个几千次,也就是说对方的无数多个信息

而你一旦手动停止把bKey=0,
消息队列中你的第一个Timer消息就会停止,此时对于队列中剩余的所有Timer消息来说,当调用FindM时一旦进入while循环就会立即退出(bKey=0),

这也就是说,除了第一个消息外,其他的Timer消息都是无效的,
你的SetTimer用的是失败的
从效果上来说,撤消SetTimer,替换为直接调用FindM,效果一样

至于如何实现你说的功能,我没有类似的经验
2006-7-17 20:34
0
游客
登录 | 注册 方可回帖
返回
//