微信跳一跳刷分java代码实现

朋友圈晒跳一跳成绩好久了,今天无意中看到以前一个同事小妞晒用代码刷分的视频,百度了一下果然看到了代码(代码在最后),几经波折,终于成功运行,刷了一点分数。

首先大概说一下步骤:

1.百度下载刷分代码

2.安装adb

3.找个手机使用USB调试模式连接电脑

4.启动跳一跳微信小程序

5.在eclipse中运行代码(此处要不断调试根据手机屏幕大小修改参数)

结果就是你的手机屏幕会自动按压然后让棋子跳。

再说下问题:

一、安装adb问题集:

下载adb工具地址

在此处的设备管理器中,如果没有安装在其他设备这里,adb就是一个感叹号,安装完毕后如图所示,会出现android device 这一行

安装的话在adb一栏里右击选择属性,弹出如下界面,点击更新驱动程序,选择浏览计算机选择程序(也就是第二个选项),此时会弹出一个浏览计算机上的驱动程序选项,选择安装包所在地,然后一切放行,就能安装。

问题来了:

安装完后,你在cmd命令窗口下能使用adb,但是在eclipse中运行代码完全没有效果(程序不报错,手机里也没有截图),然后eclipse控制台就显示图片不存在,

此时需要把你安装好的一个exe程序,两个动态链接库dll拷贝到如下两个目录下:(找不到就在c盘全局搜一下)

adb.exe

AdbWinApi.dll

AdbWinUsbApi.dll

C:\Windows\System32

C:\Windows\SysWOW64

此时一定要放在SysWOW64下,我是win7 64位,所以有这个目录(网上其他人说win32就不需要放这个了,我没试过),

如果没有放SysWOW64目录,此时eclipse运行依旧没有效果:但如果你在cmd中运行adb shell screencap -p /sdcard/tencent/customerpic/current.png这条命令,发现手机里面会有current.png图片,这说明eclipse没有找到对应的adb工具。

我找出这个问题是通过cd到System32和安装目录(C:\Program Files (x86)\Thunder Network\Thunder\Program)下,我在Program中运行上述命令成功,在System32中运行报错:

---------------------------adb.exe - 系统错误---------------------------

无法启动此程序,因为计算机中丢失 AdbWinApi.DLL。尝试重新安装该程序以解决此问题。

---------------------------

确定

---------------------------

OK,这说明System32中的adb找不到AdbWinApi.Dll动态链接文件,但明明就有,机缘巧合之下,老夫看到了SysWOW64这个目录,然后百度这个目录是什么意思,什么作用,OK,将拷贝到System32目录下的三个文件再次拷贝一份到此SysWOW64目录下,搞定。

问题二:device offline

在cmd命令窗口运行adb shell结果报错device offline,我以为是我adb安装有问题,百度了一大堆,试过adb kill server,adb remount等命令都没用,后来换了发现代码里面是/sdcard/,一看这应该是外置SD卡吧,是不是路径不对,(我用的是vivo x9,这手机没有外置SD卡选项),换了旧一点的手机(vivo y27)后运行adb shell可以了,不过/sdcard不是外置SD卡路径,而是手机U盘路径。

那么就说明不应该是代码路径问题,又是百度了一番,被告知是adb工具太老,adb version得到版本 1.0.26,好吧,我也懒得去找新版adb,用老的vivo y27调试了下能刷就行。

列举一下我学到的:

1.知道有adb这东西,也知道使用adb shell可以得到手机的bash会话,可以截图,使用adb pull可以从手机里面得到文件,更多命令的话官网有,我看多了也记不住。

2.知道原来代码里面java使用Runtime.getRuntime().exec()可以在windows中调用系统命令:

process = Runtime.getRuntime().exec(command);
 System.out.println("exec command start: " + command);
 process.waitFor();
 process.getInputStream();
 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
 String line = bufferedReader.readLine();

3.明白代码中通过计算截图的RGB颜色值等分析一张图片int pixel = bufferedImage.getRGB(x, y);

全部代码:

package com.lw.test; 

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.concurrent.TimeUnit; 

import javax.imageio.ImageIO; 

/**
 * 参考知乎
 *
 * @link <a href="https://zhuanlan.zhihu.com/p/32452473" rel="external nofollow" target="_blank">https://zhuanlan.zhihu.com/p/32452473</a>
 *
 * 跳一跳辅助
 *
 * @author LeeHo
 */
public class JumpJumpHelper
{ 

 private static final String IMAGE_NAME = "current.png"; 

 private static final String STORE_DIR = "d:/jump_screencapture"; 

 //数量
 private static final int imageLengthLength = 5; 

 //存放图片的大小
 private static final long[] imageLength = new long[imageLengthLength]; 

 private final RGBInfo rgbInfo = new RGBInfo(); 

 private final String path = "/sdcard/tencent/customerpic/";
 private final String[] ADB_SCREEN_CAPTURE_CMDS =
  {"adb shell screencap -p "+path + IMAGE_NAME,
 "adb pull "+path+"current.png " + STORE_DIR }; 

 //截屏中游戏分数显示区域最下方的Y坐标,300是 1920x1080的值,根据实际情况修改
 private final int gameScoreBottomY = 300; 

 //按压的时间系数,可根据具体情况适当调节
 private final double pressTimeCoefficient = 2.05; 

 //按压的起始点坐标,也是再来一局的起始点坐标
 private final int swipeX = 280; 

 private final int swipeY = 600; 

 //二分之一的棋子底座高度
 private final int halfBaseBoardHeight = 20; 

 //棋子的宽度,从截屏中量取,自行调节
 private final int halmaBodyWidth = 74; 

 //游戏截屏里的两个跳板的中点坐标,主要用来计算角度,可依据实际的截屏计算,计算XY的比例
 private final int boardX1 = 813; 

 private final int boardY1 = 1122; 

 private final int boardX2 = 310; 

 private final int boardY2 = 813; 

 /**
 * 获取跳棋以及下一块跳板的中心坐标
 *
 * @return
 * @author LeeHo
 * @throws IOException
 * @update 2017年12月31日 下午12:18:22
 */
 private int[] getHalmaAndBoardXYValue(File currentImage) throws IOException
 {
 BufferedImage bufferedImage = ImageIO.read(currentImage);
 int width = bufferedImage.getWidth();
 int height = bufferedImage.getHeight();
 System.out.println("宽度:" + width + ",高度:" + height);
 int halmaXSum = 0;
 int halmaXCount = 0;
 int halmaYMax = 0;
 int boardX = 0;
 int boardY = 0;
 //从截屏从上往下逐行遍历像素点,以棋子颜色作为位置识别的依据,最终取出棋子颜色最低行所有像素点的平均值,即计算出棋子所在的坐标
 for (int y = gameScoreBottomY; y < height; y++)
 {
 for (int x = 0; x < width; x++)
 {
 processRGBInfo(bufferedImage, x, y);
 int rValue = this.rgbInfo.getRValue();
 int gValue = this.rgbInfo.getGValue();
 int bValue = this.rgbInfo.getBValue();
 //根据RGB的颜色来识别棋子的位置,
 if (rValue > 50 && rValue < 60 && gValue > 53 && gValue < 63 && bValue > 95 && bValue < 110)
 {
 halmaXSum += x;
 halmaXCount++;
 //棋子底行的Y坐标值
 halmaYMax = y > halmaYMax ? y : halmaYMax;
 }
 }
 } 

 if (halmaXSum != 0 && halmaXCount != 0)
 {
 //棋子底行的X坐标值
 int halmaX = halmaXSum / halmaXCount;
 //上移棋子底盘高度的一半
 int halmaY = halmaYMax - halfBaseBoardHeight;
 //从gameScoreBottomY开始
 for (int y = gameScoreBottomY; y < height; y++)
 {
 processRGBInfo(bufferedImage, 0, y);
 int lastPixelR = this.rgbInfo.getRValue();
 int lastPixelG = this.rgbInfo.getGValue();
 int lastPixelB = this.rgbInfo.getBValue();
 //只要计算出来的boardX的值大于0,就表示下个跳板的中心坐标X值取到了。
 if (boardX > 0)
 {
 break;
 }
 int boardXSum = 0;
 int boardXCount = 0;
 for (int x = 0; x < width; x++)
 {
 processRGBInfo(bufferedImage, x, y);
 int pixelR = this.rgbInfo.getRValue();
 int pixelG = this.rgbInfo.getGValue();
 int pixelB = this.rgbInfo.getBValue();
 //处理棋子头部比下一个跳板还高的情况
 if (Math.abs(x - halmaX) < halmaBodyWidth)
 {
 continue;
 } 

 //从上往下逐行扫描至下一个跳板的顶点位置,下个跳板可能为圆形,也可能为方框,取多个点,求平均值
 if ((Math.abs(pixelR - lastPixelR) + Math.abs(pixelG - lastPixelG) + Math.abs(pixelB - lastPixelB)) > 10)
 {
 boardXSum += x;
 boardXCount++;
 }
 } 

 if (boardXSum > 0)
 {
 boardX = boardXSum / boardXCount;
 }
 } 

 //按实际的角度来算,找到接近下一个 board 中心的坐标
 boardY = (int) (halmaY - Math.abs(boardX - halmaX) * Math.abs(boardY1 - boardY2)
 / Math.abs(boardX1 - boardX2));
 if (boardX > 0 && boardY > 0)
 {
 int[] result = new int[4];
 //棋子的X坐标
 result[0] = halmaX;
 //棋子的Y坐标
 result[1] = halmaY;
 //下一块跳板的X坐标
 result[2] = boardX;
 //下一块跳板的Y坐标
 result[3] = boardY;
 return result;
 }
 } 

 return null;
 } 

 /**
 * 执行命令
 *
 * @param command
 * @author LeeHo
 * @update 2017年12月31日 下午12:13:39
 */
 private void executeCommand(String command)
 {
 Process process = null;
 try
 {
 process = Runtime.getRuntime().exec(command);
 System.out.println("exec command start: " + command);
 process.waitFor();
 process.getInputStream();
 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
 String line = bufferedReader.readLine();
 if (line != null)
 {
 System.out.println(line);
 }
 bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
 String line02 = bufferedReader.readLine();
 if (line02 != null)
 {
 System.out.println(line02);
 } 

 System.out.println("exec command end: " + command);
 }
 catch (Exception e)
 {
 e.printStackTrace();
 }
 finally
 {
 if (process != null)
 {
 process.destroy();
 }
 }
 } 

 /**
 * ADB获取安卓截屏
 *
 * @author LeeHo
 * @update 2017年12月31日 下午12:11:42
 */
 private void executeADBCaptureCommands()
 {
 for (String command : ADB_SCREEN_CAPTURE_CMDS)
 {
 executeCommand(command);
 }
 } 

 /**
 * 跳一下
 *
 * @param distance
 * @author LeeHo
 * @update 2017年12月31日 下午12:23:19
 */
 private void doJump(double distance)
 {
 System.out.println("distance: " + distance);
 //计算按压时间,最小200毫秒
 int pressTime = (int) Math.max(distance * pressTimeCoefficient, 200);
 System.out.println("pressTime: " + pressTime);
 //执行按压操作
 String command = String.format("adb shell input swipe %s %s %s %s %s", swipeX, swipeY, swipeX, swipeY,
 pressTime);
 System.out.println(command);
 executeCommand(command);
 } 

 /**
 * 再来一局
 *
 * @author LeeHo
 * @update 2017年12月31日 下午12:47:06
 */
 private void replayGame()
 {
 String command = String.format("adb shell input tap %s %s", swipeX, swipeY);
 executeCommand(command);
 } 

 /**
 * 计算跳跃的距离,也即两个点之间的距离
 *
 * @param halmaX
 * @param halmaY
 * @param boardX
 * @param boardY
 * @return
 * @author LeeHo
 * @update 2017年12月31日 下午12:27:30
 */
 private double computeJumpDistance(int halmaX, int halmaY, int boardX, int boardY)
 {
 return Math.sqrt(Math.pow(Math.abs(boardX - halmaX), 2) + Math.pow(Math.abs(boardY - halmaY), 2));
 } 

 public static void main(String[] args)
 { 

 JumpJumpHelper jumpjumpHelper = new JumpJumpHelper();
// String command = "adb shell screencap -p "+jumpjumpHelper.path + IMAGE_NAME;
//// command = "adb devices";
// jumpjumpHelper.executeCommand(command);
//
// if(true){return ;} 

 try
 {
 File storeDir = new File(STORE_DIR);
 if (!storeDir.exists()) {
 boolean flag = storeDir.mkdir();
 if (!flag) {
 System.err.println("创建图片存储目录失败");
 return;
 }
 } 

 //执行次数
 int executeCount = 0;
 for (;;)
 {
 //执行ADB命令,获取安卓截屏
 jumpjumpHelper.executeADBCaptureCommands();
 File currentImage = new File(STORE_DIR, IMAGE_NAME);
 if (!currentImage.exists())
 {
 System.out.println("图片不存在");
 continue;
 } 

 long length = currentImage.length();
 imageLength[executeCount % imageLengthLength] = length;
 //查看是否需要重新开局
 jumpjumpHelper.checkDoReplay();
 executeCount++;
 System.out.println("当前第" + executeCount + "次执行!");
 //获取跳棋和底板的中心坐标
 int[] result = jumpjumpHelper.getHalmaAndBoardXYValue(currentImage);
 if (result == null)
 {
 System.out.println("The result of method getHalmaAndBoardXYValue is null!");
 continue;
 }
 int halmaX = result[0];
 int halmaY = result[1];
 int boardX = result[2];
 int boardY = result[3];
 System.out.println("halmaX: " + halmaX + ", halmaY: " + halmaY + ", boardX: " + boardX + ", boardY: "
 + boardY);
 //计算跳跃的距离
 double jumpDistance = jumpjumpHelper.computeJumpDistance(halmaX, halmaY, boardX, boardY);
 jumpjumpHelper.doJump(jumpDistance);
 //每次停留2.5秒
 TimeUnit.MILLISECONDS.sleep(2500);
 }
 }
 catch (Exception e)
 {
 e.printStackTrace();
 }
 } 

 /**
 * 检查是否需要重新开局
 *
 * @author LeeHo
 * @update 2017年12月31日 下午1:39:18
 */
 private void checkDoReplay()
 {
 if (imageLength[0] > 0 && imageLength[0] == imageLength[1] && imageLength[1] == imageLength[2]
 && imageLength[2] == imageLength[3] && imageLength[3] == imageLength[4])
 {
 //此时表示已经连续5次图片大小一样了,可知当前屏幕处于再来一局
 Arrays.fill(imageLength, 0);
 //模拟点击再来一局按钮重新开局
 replayGame();
 }
 } 

 /**
 * 获取指定坐标的RGB值
 *
 * @param bufferedImage
 * @param x
 * @param y
 * @author LeeHo
 * @update 2017年12月31日 下午12:12:43
 */
 private void processRGBInfo(BufferedImage bufferedImage, int x, int y)
 {
 this.rgbInfo.reset();
 int pixel = bufferedImage.getRGB(x, y);
 //转换为RGB数字
 this.rgbInfo.setRValue((pixel & 0xff0000) >> 16);
 this.rgbInfo.setGValue((pixel & 0xff00) >> 8);
 this.rgbInfo.setBValue((pixel & 0xff));
 } 

 class RGBInfo
 {
 private int RValue; 

 private int GValue; 

 private int BValue; 

 public int getRValue()
 {
 return RValue;
 } 

 public void setRValue(int rValue)
 {
 RValue = rValue;
 } 

 public int getGValue()
 {
 return GValue;
 } 

 public void setGValue(int gValue)
 {
 GValue = gValue;
 } 

 public int getBValue()
 {
 return BValue;
 } 

 public void setBValue(int bValue)
 {
 BValue = bValue;
 } 

 public void reset()
 {
 this.RValue = 0;
 this.GValue = 0;
 this.BValue = 0;
 }
 }
} 

当然,现在刷了一会就被清空成绩,但作为一个程序员知道还是好的。从一开始的post提交漏洞,让电脑作为代理抓包修改数据,现在代码模拟点击(虽然不会生效。)

更多内容大家可以参考专题《微信跳一跳》进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 微信跳一跳辅助Java代码实现

    微信跳一跳辅助的Java具体实现代码,供大家参考,具体内容如下 1.参考知乎教你用Python来玩微信跳一跳,鉴于本人Python一直都是半吊子水平,之前打算用python刷分,可无奈安装python环境各种模块缺失,报错不停,于是乎,使用Java重新实现了一下. 2.环境配置及相关说明: 1).Windows系统,本人win10 2).AVA环境安装,JDK7以上即可 3).安卓手机一部.数据线一条 4).电脑安装ADB驱动,连接安卓手机,同时打开USB调试模式 5).打开微信小程序的跳一跳游

  • 微信跳一跳游戏Android刷分代码

    本文实例为大家分享了微信跳一跳游戏Android实现刷分,供大家参考,具体内容如下 # coding:utf-8 ''' # === 思路 === # 核心:每次落稳之后截图,根据截图算出棋子的坐标和下一个块顶面的中点坐标, # 根据两个点的距离乘以一个时间系数获得长按的时间 # 识别棋子:靠棋子的颜色来识别位置,通过截图发现最下面一行大概是一条直线,就从上往下一行一行遍历, # 比较颜色(颜色用了一个区间来比较)找到最下面的那一行的所有点,然后求个中点, # 求好之后再让 Y 轴坐标减小棋子底

  • python版微信跳一跳游戏辅助

    本文实例为大家分享了微信跳一跳游戏辅助python代码,供大家参考,具体内容如下 import os import PIL import numpy import matplotlib matplotlib.use('TKAgg') import matplotlib.pyplot as plt import time from matplotlib.animation import FuncAnimation # 是否需要进行图片更新 need_update = True def get_sc

  • 基于VS+Opencv2.4.10微信跳一跳辅助工具

    最近微信的跳一跳小程序可谓火了一把,不是因为它本身多好玩,而是有大部分的程序员们加入其中,利用各种领域方法,实现了微信跳一跳的外挂,分数轻松上千或上万.之前也看了基于Python开源的代码,GitHub上现在的star已经快超过1W了,简直不敢想.趁着今天礼拜天,在实验室中也简单的实现了一下微信跳一跳的辅助工具,精度还不够高,我跑了一下才到90,纯属娱乐好玩的,后期再继续改进,主要是依赖C++来实现了一下. 环境: Win10+VS2012+Opencv2.4.10+ADB工具 环境的搭建请查阅

  • Java微信跳一跳操作指南

    Java微信跳一跳操作指南,指哪挑哪. 本文的思路是通过adb来控制手机进行操作,通过java写一个jframe覆盖在手机屏幕上,用鼠标获取跳的起点和终点,经过试验获取跳的jframe距离和按压时长的关系(线性关系),然后通过adb来根据计算出的结果操作按下时长,(此处还需要一个第三方工具来实时把画面传送给电脑,将jframe覆盖在电脑上的画面上). 代码很短,如下: package jump; import java.awt.FlowLayout; import java.awt.event.

  • 安卓版微信跳一跳辅助 跳一跳辅助Java代码

    安卓版微信跳一跳辅助,java实现,具体内容如下 已经看到网上有大神用各种方式实现了,我这是属于简易版ADB命令式实现. 操作方法 1.光标移动到起始点,点击FORM 2.光标移动到目标点,点击TO 3.小人已经跳过去了 原理说明 安装APP,通过设置起点和目标点位置,获得弹跳的毫秒数,发送请求到连接手机的电脑中,电脑执行adb命令起跳. 具体实现 本人的测试设备是Mate9,android版本为7.0,由于在非Root环境下,普通安卓应用并不能通过Runtime.getRuntime().ex

  • 100行java写的微信跳一跳辅助程序

    前几天没事干看别人一直在玩微信上线的那一个跳一跳小游戏,玩着玩着老是掉下去,闲着没事呗就想了想做一个辅助程序的呗.不过先做的手动版的.自动版的有点麻烦.就不发了.用的Java写的,也就一个蒙版. 下面就开始介绍我的小程序,没好多东西,真正的代码应该就是100行左右,没啥难的. 下面这是我的微信朋友们的跳一跳 也就这样吧,因为wechat还是有那个仿作弊系统的,所以还是低调的吧... 话不多说,还是下面奉上我的code吧,说多了墨迹呢.... package com.rain.jump.util;

  • 微信跳一跳python辅助脚本(总结)

    这段时间微信跳一跳这个游戏非常火爆,但是上分又非常的难,对于程序员来说第一个念头就是通过写一个辅助脚本外挂让上分变的容易,python现在比较火,我们一起来以python语言为基础总结以下各路神仙写的关于跳一跳的辅助脚本,大家在学习的时候主要理解他们的写法思路,对你学习python非常的有帮助. 1.微信跳一跳自动运行python脚本 注解:思路 核心:每次落稳之后截图,根据截图算出棋子的坐标和下一个块顶面的中点坐标, 根据两个点的距离乘以一个时间系数获得长按的时间 识别棋子:靠棋子的颜色来识别

  • 微信跳一跳刷分java代码实现

    朋友圈晒跳一跳成绩好久了,今天无意中看到以前一个同事小妞晒用代码刷分的视频,百度了一下果然看到了代码(代码在最后),几经波折,终于成功运行,刷了一点分数. 首先大概说一下步骤: 1.百度下载刷分代码 2.安装adb 3.找个手机使用USB调试模式连接电脑 4.启动跳一跳微信小程序 5.在eclipse中运行代码(此处要不断调试根据手机屏幕大小修改参数) 结果就是你的手机屏幕会自动按压然后让棋子跳. 再说下问题: 一.安装adb问题集: 下载adb工具地址 在此处的设备管理器中,如果没有安装在其他

  • 微信跳一跳辅助python代码实现

    微信跳一跳辅助的python具体实现代码,供大家参考,具体内容如下 这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短来控制这个「小人」跳跃的距离.可能刚开始上手的时候,因为时间距离之间的关系把握不恰当,只能跳出几个就掉到了台子下面. 玩法类似于<flappy bird> 下载github的一个程序,但是在windows10下不能运行,原因是windows10下没有copy命令了,修改为Python自带的复制方法,即可完成.今天运行好像一开始不能正确跳第一次,人工辅助后,后

  • python微信跳一跳游戏辅助代码解析

    这个代码实现的是   手动点击起点 和 终点  ,程序自动判断距离.触屏时间  完成跳跃 原理(摘自项目说明页面): 1. 将手机点击到"跳一跳"小程序界面: 2. 用Adb 工具获取当前手机截图,并用adb将截图pull上来: adb shell screencap -p /sdcard/1.png adb pull /sdcard/1.png . 3. 用matplot显示截图: 4. 用鼠标点击起始点和目标位置,计算像素距离: 5. 根据像素距离,计算按压时间: 6. 用Adb工

  • 微信跳一跳python自动代码解读1.0

    微信跳一跳自动代码,具体内容如下 那个跳一跳python"外挂",有几个python文件,其中有一个是得到截图,然后鼠标在图片上点击两次,python窗口上会打印两次鼠标的位置,并且会跟上一行这两个点之间的距离. 这个功能我先给除去获取截屏,就说怎么在某张图片上算出两次点击的距离. 首先,需要用到图形模块,PIL: from PIL import Image img = Image.open('0.jpg') 然后用图形绘制模块matplotlib来给出一个plot对象: import

  • 安卓版本微信跳一跳自动执行代码剖析

    手动版的这里不多说,图像识别,坐标计算跳跃,要想得高分会点的手疼.这里主要剖析下自动版的,这里仅介绍安卓版本. 整体的结构 脚本的整体结构还是比较简洁的,如下图所示. 手机连接PC,PC通过adb命令对手机游戏界面进行截图: PC通过adb命令将该截图拷贝回PC: PC端通过python对图像进行处理(第一版中使用的opencv,目前使用的是直接读取像素的rgb值),获取棋子的位置,获取下一个棋盘的位置,然后计算出下一跳的距离,从而根据经验值计算出按压时间t: 通过adb命令模拟按压时间t即可实

随机推荐