前言
炉石更新新版收益系统,心血来潮,写一个简陋的脚本在战棋挂机。不选择在天体烧绳是mmr没到互投区,会被举报。
Java模拟鼠标比较简单,引入Java的awt包,使用其中的robot类即可实现模拟。
注: 这种模拟鼠标点击并不是后台模拟,而是占用你的鼠标进程。水平有限,脚本是定死坐标点击,假如我移动了炉石窗口,则会导致脚本失效。
PS:该脚本毫无技术含量
一、获取坐标
- 大家可以使用QQ,TIM的截图工具,一拖就可以显示坐标。
- 使用代码手动完成获取坐标的工作
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做的挺好的。