天天看点

通过jna简单实现java后台监听键盘触发修改系统时间

      由于玩某网游需要在出副本时等一分钟,而修改系统时间+1分钟可以提前出副本,避免麻烦写了个java后台监听键盘触发修改系统时间的脚本,当按下设置好的键盘组合即调用修改函数。

修改时间的函数代码如下(调用CMD命令):

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class changeTime
{
	static void plus_min(int min) throws IOException {
		Long millis = Long.valueOf(System.currentTimeMillis() + 60000*min);
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(millis.longValue());
		Date newDate = c.getTime();
		SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd");
		System.out.println(date.format(newDate));
		SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
		System.out.println(time.format(newDate));
		String cmd = " cmd /c date " + date.format(newDate);
		Runtime.getRuntime().exec(cmd);
		cmd = " cmd /c time " + time.format(newDate);
		System.out.println(cmd);
		Runtime.getRuntime().exec(cmd);
	}
	
}
           

后台通过jna实现的键盘监听代码如下(当按下的键盘组合符合设置好的条件,调用上述函数):

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.KBDLLHOOKSTRUCT;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.WinUser.MSG;

import java.io.IOException;
import java.util.ArrayList;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

/** Sample implementation of a low-level keyboard hook on W32. */
public class KeyHook {
	private static volatile boolean quit;
	private static HHOOK hhk;
	private static LowLevelKeyboardProc keyboardHook;
	
	//设置按键组合的vkCode,具体vkCode与键盘的对照表可百度
	private static ArrayList<Integer> keyList=new ArrayList<Integer>(){{add(65); add(83);add(68);add(38);}};
	private static ArrayList<Integer> inputList=new ArrayList<Integer>();
	private static Long listSetTime;
	private static int min=1;    //每次增加一分钟
	
	static void setJframe(){   //窗口界面
		JFrame jframe=new JFrame("修改系统时间");
	    jframe.setSize(300,200);
        jframe.setLocation(550, 250);
	    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
	    JLabel field=new JLabel();
	    field.setBounds(30, 20, 400, 100);
	    field.setText("同时按下A,S,D,↑ 系统时间+1分钟");
        jframe.setLayout(null);
		JButton button=new JButton("关闭");
	    jframe.add(field);
        jframe.add(button);
		button.setBounds(60,120,150,30);
		button.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
               System.exit(0);
			}
			});     
		jframe.setLayout(null);
        jframe.setResizable(true);
        jframe.setVisible(true);
	}
	
	public static void setList(int code,ArrayList<Integer> list){
		
		if(!list.contains(code)){
		 	if(list.size()<=keyList.size()){
		 		list.add(code);
			}
			else{
		 		list.remove(0);
		 		list.add(code);
			}
		 }
    }
	
    public static boolean isGetAllKey(){
		boolean b=true;
		for(int i=0;i<keyList.size();i++){
			if(!inputList.contains(keyList.get(i))){
				b=false;
				break;
			}
		}
		return b;
	}
	public static void main(String[] args) {
		setJframe();
		final User32 lib = User32.INSTANCE;
		HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
		keyboardHook = new LowLevelKeyboardProc() {
			@Override
			public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
				if (nCode >= 0) {
					switch(wParam.intValue()) {
						case WinUser.WM_KEYUP:
						case WinUser.WM_KEYDOWN:
						case WinUser.WM_SYSKEYUP:
						case WinUser.WM_SYSKEYDOWN:
							if (!keyList.contains(info.vkCode)) {
								inputList.clear();
							//	System.out.println("key="+info.vkCode);
							} else {
								if(inputList.size()==0){
									listSetTime=System.currentTimeMillis();
								}
								setList(info.vkCode, inputList);
								//System.err.println("in callback, key=" + info.vkCode);
								if (isGetAllKey()) {
									if(System.currentTimeMillis()-listSetTime<50) {
										quit = true;
									}
									else{
										inputList.clear();
									}
								}
							
							}
					}
				}
                Pointer ptr = info.getPointer();
				long peer = Pointer.nativeValue(ptr);
				return lib.CallNextHookEx(hhk, nCode, wParam, new LPARAM(peer));
			}
		};
		hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
		
		new Thread() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(200);
					} catch (Exception e) {
					}

					//System.err.println("unhook and exit");
					//lib.UnhookWindowsHookEx(hhk);
					if(quit) {
						try {
							changeTime.plus_min(min);
						} catch (IOException e) {
							e.printStackTrace();
						}
						quit = false;
						inputList.clear();
						//System.exit(0);
					}
				}
			}
		}.start();

		// This bit never returns from GetMessage
		int result;
		MSG msg = new MSG();
		while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
			if (result == -1) {
			//	System.err.println("error in get message");
				break;
			}
			else {
			//	System.err.println("got message");
				lib.TranslateMessage(msg);
				lib.DispatchMessage(msg);
			}
		}
		lib.UnhookWindowsHookEx(hhk);
	}
}
           

运行可弹出界面(保持界面不关闭,则后台持续监听键盘事件):

通过jna简单实现java后台监听键盘触发修改系统时间
通过jna简单实现java后台监听键盘触发修改系统时间

打包好的项目下载地址如下,已包含对应的jna包,可直接运行:

http://download.csdn.net/download/capricio/10130898