上一次的小程序只是演示了一下如何用robot类控制鼠标键盘操作
这种方法有很大的弊端:1、不能后台运行。2、坐标代码写死,窗口甚至都不可移动。3、某些游戏会屏蔽该类 下面讲述下如何用JNI技术实现游戏内脚本后台执行
什么是JNI
简单讲就是实现了java和其他语言的通信,下面要用到是c或c++
JNI自行阅读,不赘述
另:不到万不得已不要使用JNI,一方面它需要你掌握更多的知识才可以驾驭,一方面使用了JNI你的程序就会丧失可移植性
为什么要用JNI
java本身无法获得windows的接口,如窗口句柄等,需要借助c或c++
java代码
public class TowerUtil {
public static native void keyPress(int hwnd, int key);
public static native void mouseClick(int hwnd,int x,int y);
static{
System.loadLibrary("towerutil");
}
public static void main(String[] args) {
int hwnd=1050990;
TowerUtil.keyPress(hwnd, 0x42);
}
}
注意keyPress和mouseClick函数的声明,它有一个关键字native,表明这个方法使用java以外的语言实现。方法不包括实现,因为我们要用c/c++语言实现它
System.loadLibrary(“towerutil”)这句代码,在静态初始化块中定义的,用来装载towerutil.dll动态链接库
编译生成头文件
使用命令javah:
javah TowerUtil.java
文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class TowerUtil */
#ifndef _Included_TowerUtil
#define _Included_TowerUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TowerUtil
* Method: keyPress
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_TowerUtil_keyPress
(JNIEnv *, jclass, jint, jint);
/*
* Class: TowerUtil
* Method: mouseClick
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_TowerUtil_mouseClick
(JNIEnv *, jclass, jint, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
用c/c++实现函数体
第三部里定义了keyPress和mouseClick两个函数,接下来要用c语言实现它,注意观察上一步生成的头文件里的函数名和参数,按照其来写 如:
#include "stdafx.h"
#include "jni.h"
#include "TowerUtil.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
JNIEXPORT void JNICALL Java_TowerUtil_mouseClick
(JNIEnv *env, jobject obj, jint hwnd, jint x, jint y){
LPARAM lparam = MAKELPARAM(x,y);
SendMessage((HWND)hwnd, WM_LBUTTONDOWN, MK_LBUTTON, lparam);
sleep(10);
SendMessage((HWND)hwnd, WM_LBUTTONUP, MK_LBUTTON, lparam);
return;
}
JNIEXPORT void JNICALL Java_TowerUtil_keyPress
(JNIEnv *env, jobject obj, jint hwnd, jint key){
SendMessage((HWND)hwnd,WM_KEYDOWN,key,0);
sleep(100);
SendMessage((HWND)hwnd,WM_KEYUP,key,0);
return;
}
关于代码里出现的SendMessage函数:SendMessage 函数参数大全 的 注意在开头引入jni.h和前面生成的TowerUtil.h
生成dll文件
下面生成前面提到的 towerutil.dll,windows可以下载MinGW进行编译:
gcc -shared TowerUtil.cpp -o towerutil.dll -I (.h头文件目录)
运行java程序
把上面生成的dll文件加入到java.library.path内
main函数里写上一行:
TowerUtil.keyPress(hwnd, 0x42);
解释下, hwnd是我玩的完美国际当前的句柄值,0x42是键盘“b”的asiic值,游戏内b键打开背包 执行后可以看到游戏里的背包界面打开 大功告成! 再结合上一篇文章写到的脚本解析函数的思路,就可以写出一个略微简陋的游戏脚本执行器了 使用JNI的好处上面已提到,脚本编写好后,你可以把游戏最小化,也不影响执行 如果能够再获得游戏内属性基址,就能写出一个功能更丰富的??了