Java模拟鼠标

  • Post author:
  • Post category:java




前言

炉石更新新版收益系统,心血来潮,写一个简陋的脚本在战棋挂机。不选择在天体烧绳是mmr没到互投区,会被举报。

Java模拟鼠标比较简单,引入Java的awt包,使用其中的robot类即可实现模拟。

注:

这种模拟鼠标点击并不是后台模拟,而是占用你的鼠标进程。水平有限,脚本是定死坐标点击,假如我移动了炉石窗口,则会导致脚本失效。


PS:

该脚本毫无技术含量




一、获取坐标

  1. 大家可以使用QQ,TIM的截图工具,一拖就可以显示坐标。
  2. 使用代码手动完成获取坐标的工作

    new一个robot对象,用里面的函数

    robot.delay() 里面填的是延迟秒数,与线程休眠是一样的,1000为一秒

    PointerInfo 获取鼠标点信息

    getLocation()获取坐标

    getPixelColor(mx,my)获取mx,my坐标上的rgb信息

    每次获取坐标是就跑一下该函数,鼠标移过去即可。
import java.awt.*;

public class GetPoint {
    public int[] getPoint() throws Exception{
        Robot robot = new Robot();
        robot.delay(2500);
        PointerInfo pinfo = MouseInfo.getPointerInfo();
        Point p = pinfo.getLocation();
        int mx = (int) p.getX();
        int my = (int) p.getY();
        Color mouseRGB = robot.getPixelColor(mx,my);
        int R = mouseRGB.getRed();
        int G = mouseRGB.getGreen();
        int B = mouseRGB.getBlue();
        int[] array = new int[] {mx,my,R,G,B};
        return array;
    }

    public static void main(String[] args) {
        GetPoint getPoint = new GetPoint();
        int[] xyrgb = null;
        try {
            xyrgb = getPoint.getPoint();
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (int i = 0;i< xyrgb.length;i++)
            System.out.print(xyrgb[i] +" ");
    }



二、鼠标点击模拟



1.模拟移动

mouseMove方法,输入xy坐标,但需要嵌入循环,因为这个方法不够稳定,他的逐渐向给定坐标靠近,大概6次以上就移动到指定位置。

	for (int i =0;i<10;i++)
		robot.mouseMove(x,y);

随机移动,在坐标周围小范围移动

public void Random_Moveto(int x,int y,int z){
        //int temp=m+(int)(Math.random()*(n+1-m)); //生成从m到n的随机整数[m,n]
        int a=-z+(int)(Math.random()*(z+1+z));
        int b=-z+(int)(Math.random()*(z+1+z));
        for (int i =0;i<10;i++)
            robot.mouseMove(x+a,y+b);
    }



2.模拟点击

mousePress与mouseRelease是模拟鼠标按下和抬起,做一个点击函数记得要在其中穿插

延迟

或是

随机延迟

,延迟填感觉差不多的即可

public void press(){
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
    }

    public void up(){
        Random_Delay(100);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    }

    public void click(){
        press();
        Random_Delay(100);
        up();
        Random_Delay(1500);
    }
    
    public void Random_Delay(int s){//随机延迟
        int a=(int)(Math.random()*10);//生成[0,9]之间的随机整数
        robot.delay(s+a*100);
    }

小结:接下来的函数大致都是这两类的结合,即 移动-判断-点击 ,剩下点击函数不一一列述。



3.比色判断

炉石的判断可以做得很复杂,比如截图判断;但也有很简单的判断,呼出esc,有个菜单栏,假如你匹配到,进入对战,则会有一个认输按键,这个认输是红色的且坐标固定,但注意,当鼠标悬浮在上面时,亮度会加一层金色;假如下棋输掉,则认输按键消失,则红色没有。利用这一点来判断是否进入和输掉。其实选完英雄也可以判断其他玩家是否也选好英雄,对比随便一处的颜色即可(选英雄时整个界面灰度很高)。

输入点的信息,里面带有rgb数据对比即可,但要记得给出误差,大概是10到15,按照情况改变。

public boolean is_have_esc(int[] Point){
        int x = Point[0];
        int y = Point[1];
        int r = Point[2];
        int g = Point[3];
        int b = Point[4];
        if (Math.abs(250 - r)<15 && Math.abs(127 - g)<15 && Math.abs(79 - b)<15)
            return true;
        else
            return false;
    }



4.酒馆操作

这里只列出两个主要例子,只买最左边的,拖到头像:移动,按下,移动,抬起,其中穿插延迟。

让棋子上场也是如此。更何况目的是挂机,这些可有可无。

    public void buy_one_in_three(){
        for (int i =0;i<10;i++)
            robot.mouseMove(858 ,459);
        press();
        robot.delay(500);
        for (int i =0;i<10;i++)
            robot.mouseMove(955 ,758);
        robot.delay(500);
        up();
    }

    public void let_chess_up(){
        for (int i =0;i<10;i++)
            robot.mouseMove(938 ,872);
        press();
        robot.delay(500);
        for (int i =0;i<10;i++)
            robot.mouseMove(948 ,591);
        robot.delay(500);
        up();
    }



三、主要流程

大概就是开始匹配,然后不停地判断是否进入,记得做出延迟,别搞太快。再判断别人是否选好英雄,开始挂机,也可以买怪升级,纯挂机不上怪的话大概在7分钟之后开始判断自己是否阵亡,同样是开esc来判断有没有认输键。确认死亡后,必须点右下角的键,然后随便点个地方。重复这些操作即可。

import UtilsPackage.MouseDo;
/*
* 炉石窗口的句柄类名:UnityWndClass
* 句柄:000F05E6*/
public class ScriptRun {
    public static void main(String[] args) {

        MouseDo mouseDo = new MouseDo();
        mouseDo.enter_step();
        try {
            while (true){
                Thread.sleep(500);
                mouseDo.start_to_play();

                while (!mouseDo.is_have_lose()){
                    System.out.println("还没有进入对战阶段,一秒后继续判断");
                    mouseDo.Delay(500);
                    mouseDo.click_other_place();
                }
                System.out.println("已经进入对战阶段");
                
                mouseDo.Delay(2000);
                mouseDo.click_other_place();
                mouseDo.choose_hero();
                while (!mouseDo.is_could_play()){
                    System.out.println("别人还没选好英雄,一秒后继续判断");
                    mouseDo.Delay(1000);
                    mouseDo.click_other_place();
                }
                System.out.println("开始对战");

                for (int i =0;i<420;i++){
                    mouseDo.Delay(1000);
                    if (i%60==0)
                        System.out.println("已过"+i/60+"分钟");
                }
                
				/*这里填自己想要的酒馆操作*/

                while (mouseDo.is_have_lose()){
                    System.out.println("还没死");
                    mouseDo.Delay(1000);
                    mouseDo.click_other_place();
                }
                System.out.println("已经死了");

                mouseDo.esc();
                mouseDo.click();
                mouseDo.click_other_place();
                mouseDo.Delay(5000);
            }
        } catch (Exception e){
            System.out.println(e);
        }

    }

}




总结

并没有用到什么十分厉害的技术,没什么技术含量。仅仅是对Java的模拟鼠标操作进行了浅显地学习,个人感觉这与python的autogui差不多,需要用到后台操作窗口句柄的话,需要win32的包才行,这方面python做的挺好的。



版权声明:本文为graveyard233原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。