MaplePlacard开发随笔

来源:互联网 发布:什么是2g3g4g网络 编辑:程序博客网 时间:2024/06/02 17:55

继完成TimeSwitch的两个版本之后,我一直在忙学习,写程序的爱好暂时放到了一边。不过这两天有琢磨写个小程序,用来在冒险岛里面打“竖字”,闲话少叙切入正题吧!(因为时间宝贵,一会儿还有网络实验课)

 

功能设计:

玩家首先运行MaplePlacard然后进入游戏,在游戏中正常使用“喊话”功能,将频道切换为“对所有人”,然后输入要说的话,之后不是直接按Enter键而是按Ctrl+Enter键(像是用QQ发消息那样),就可以打出竖着显示的汉字了。

 

实现方案:

初步设想是采用全局Hook拦截键盘消息Ctrl+Enter,然后判断发送消息的窗口为冒险岛客户端后,向其发送一系列按键消息,从而将文本框中的内容全选并复制到系统剪贴板。完成上述操作后软件将系统剪贴板的内容复制到字符串对象中,做一定修改后存回系统剪贴板。最后向冒险岛客户端发送按键消息,将文本粘贴并发送出去。如果不想改变系统剪贴板的内容,可以提前进行系统剪贴板的备份。

 

实现方案的小结:

这种方案的缺点在于使用全局Hook技术将略微降低系统的运行效率,不过用户不必担心,除非系统中有很多进程同时挂载了全局Hook,但这种情况一般并不多见,例如用户同时使用了数十款外挂进行游戏。

优点在于实现的思路比较巧妙,通过发送键盘消息模拟用户按键,使用系统剪贴板完成了两个进程间的通信,从而避免了针对网游的编程中可能遇到的诸多问题(因为网游通常会附带保护程序,它们在“有效”防止盗号软件和外挂程序的同时,也会对一些敏感操作进行检测和封杀,有时甚至会导致客户端的强制关闭,例如冒险岛采用的就是韩国网游中广为流传的nProtect)

 

 

【一期开发】

 

刚上来就遇到个问题,为了让Hook与所有进程关联,我把它的实现代码放到了DLL中,这个DLL是这么写的:

我的目的是测试用户按下了F2键,然后用响铃(Beep)给出提示,结果意外听到了两次响铃。这说明程序进入了钩子过程两遍,为什么会这样呢?后来我上网搜了一下答案,结果在MSDN社区里的一篇帖子给了我启示(是tracing大哥的回复),我翻回来再去查MSDN,果然印证了这个答案:

The KeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.

原来是用户按一个按键会产生“按键按下”和“按键抬起”两个消息,因此Hook会钩到这两个消息,因为它们都符合判断条件,因而Beep被执行了两遍!

作为解决方法,我们可以将lParam第31位的值作为判断依据,它在MSDN中是这样被叙述的:Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up. 因此,只需对判断条件做如下修改即可:

 

 

 

我参考过的资料:

http://topic.csdn.net/t/20061103/08/5129759.html