I have been posting my jump results in my circle of friends for a long time. Today I accidentally saw a video of a colleague who used code to make scores. I went to Baidu and saw the code (the code was at the end). After several twists and turns, I finally ran successfully and scored a little.
First, let’s briefly talk about the steps:
1. Baidu download score code
2. Install adb
3. Find a phone to connect to the computer using USB debugging mode
4. Start the WeChat mini program
5. Run the code in eclipse (here we need to constantly debug and modify parameters according to the size of the mobile phone screen)
The result is that your phone screen will automatically press and let the chess piece jump.
Let’s talk about the question:
1. Install adb problem set:
Download adb tool address
In the device manager here, if it is not installed on other devices, adb is an exclamation point. After installation, as shown in the figure, the line android device will appear.
If you install it, right-click in the adb column to select properties, and the following interface pops up, click Update Driver, select Browse Computer and select Programs (that is, the second option). At this time, a browse driver option on the computer will pop up, select the location of the installation package, and then everything will be released to install.
The question is:
After installation, you can use adb under the cmd command window, but running the code in eclipse has no effect at all (the program does not report an error, and there are no screenshots on the phone), and then the eclipse console shows that the picture does not exist.
At this time, you need to copy the two dynamic link libraries dlls you installed into the following two directories: (If you can't find them, search globally on the C drive)
adb.exe
AdbWinApi.dll
AdbWinUsbApi.dll
C:/Windows/System32
C:/Windows/SysWOW64
At this time, it must be placed under SysWOW64. I am win7 64 bit, so there is this directory (other people on the Internet say that win32 doesn't need to put this, I haven't tried it).
If the SysWOW64 directory is not placed, the eclipse operation still has no effect at this time: but if you run the adb shell screencap -p /sdcard/tencent/customerpic/current.png command in cmd, you will find that there will be a current.png picture in the phone, which means that eclipse has not found the corresponding adb tool.
I found out that I was using cd to System32 and under installation directory (C:/Program Files (x86)/Thunder Network/Thunder/Program), I successfully ran the above command in Program, and reported an error in System32:
--------------------------------------------------------------------------------------------------------------------------------
This program cannot be started because AdbWinApi.DLL is missing from the computer. Try reinstalling the program to resolve this issue.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sure
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OK, this means that the Adb in System32 cannot find the AdbWinApi.Dll dynamic link file, but it is obvious that, by chance, I saw the directory SysWOW64, and then what does this directory mean and what does it mean? OK, copy the three files copied to the System32 directory and then copy them to this directory SysWOW64, and get it done.
Question 2: device offline
Running adb shell in the cmd command window resulted in an error device offline. I thought there was something wrong with my adb installation. I had a lot of Baidu. I tried adb kill server, adb remount and other commands, but I found that the code was /sdcard/. I saw that this should be an external SD card. Is the path wrong? (I used vivo x9, and this phone has no external SD card option). After changing to an older phone (vivo y27), I can run adb shell, but /sdcard is not an external SD card path, but the U disk path of the phone.
That means it shouldn't be a code path problem. I was told that the adb tool is too old and the adb version has version 1.0.26. Well, I'm too lazy to find the new version of adb. I debugged it with the old vivo y27 and it can be flashed.
Let me list what I have learned:
1. I know that there is adb, and I also know that using the adb shell can get the bash session of the phone. You can take screenshots, and using adb pull can get files from the phone. If there are more commands on the official website, I can't remember it even if I read it too much.
2. Know that Java uses Runtime.getRuntime().exec() in the original code to call system commands in 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. Understand that in the code, analyze an image by calculating the RGB color value of the screenshot, etc., int pixel = bufferedImage.getRGB(x, y);
All codes:
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; /** * Reference Zhihu* * @link <a href="https://zhuanlan.zhihu.com/p/32452473" rel="external nofollow" target="_blank">https://zhuanlan.zhihu.com/p/32452473</a> * * Jump assist* * @author LeeHo */ public class JumpJumpHelper { private static final String IMAGE_NAME = "current.png"; private static final String STORE_DIR = "d:/jump_screencapture"; //quantity private static final int imageLengthLength = 5; //size of the image 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 }; //The Y coordinate at the bottom of the game score display area in the screenshot, 300 is the value of 1920x1080. Modify private final int gameScoreBottomY = 300 according to the actual situation; //The press time coefficient can be appropriately adjusted according to the specific situation; private final double pressTimeCoefficient = 2.05; //The starting point coordinate of the press is also the starting point coordinate of the next game private final int swipeX = 280; private final int swipeY = 600; //The height of the base of the chess piece is private final int halfBaseBoardHeight = 20; //The width of the chess piece is taken from the screenshot and adjust the private final int by yourself halmaBodyWidth = 74; //The midpoint coordinates of the two springboards in the game screenshot are mainly used to calculate the angle. The proportion of XY can be calculated based on the actual screenshot. Private final int boardX1 = 813; private final int boardY1 = 1122; private final int boardX2 = 310; private final int boardY2 = 813; /** * Get the checkers and the center coordinates of the next springboard* * @return * @author LeeHo * @throws IOException * @update December 31, 2017 at 12:18:22 pm */ private int[] getHalmaAndBoardXYValue(File currentImage) throws IOException { BufferedImage bufferedImage = ImageIO.read(currentImage); int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); System.out.println("Width: " + width + ", height: " + height); int halmaXSum = 0; int halmaXCount = 0; int halmaYMax = 0; int boardX = 0; int boardY = 0; //Transfer the pixel points from the screenshot from top to bottom, and use the color of the chess piece as the basis for position recognition. Finally, the average value of all pixels on the lowest row of the chess piece color is taken out, that is, calculate the coordinates of the chess piece 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(); //Identify the position of the chess piece according to the color of RGB, if (rValue > 50 && rValue < 60 && gValue > 53 && gValue < 63 && bValue > 95 && bValue < 110) { halmaXSum += x; halmaXCount++; //Y coordinate value of the bottom row of the chess piece halmaYMax = y > halmaYMax ? y : halmaYMax; } } } if (halmaXSum != 0 && halmaXCount != 0) { //X coordinate value of the bottom row of the chess piece int halmaX = halmaXSum / halmaXCount; //Move half of the chess piece chassis height up int halmaY = halmaYMax - halfBaseBoardHeight; //Start from 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(); //As long as the calculated boardX value is greater than 0, it means that the center coordinate X value of the next springboard has been obtained. 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(); //Train the case where the head of the chess piece is higher than the next springboard if (Math.abs(x - halmaX) < halmaBodyWidth) { continue; } //Scan from top to bottom to the vertex position of the next springboard. The next springboard may be a circle or a box. Take multiple points and find the average if ((Math.abs(pixelR - lastPixelR) + Math.abs(pixelG - lastPixelG) + Math.abs(pixelB - lastPixelB)) > 10) { boardXSum += x; boardXCount++; } } if (boardXSum > 0) { boardX = boardXSum / boardXCount; } } //From the actual angle, find the coordinates close to the center of the next 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]; //The X coordinate result[0] = halmaX; //The Y coordinate result[1] = halmaY; //The X coordinate result[2] = boardX; //The Y coordinate result[3] = boardY; return result; } } return null; } /** * Execute the command* * @param command * @author LeeHo * @update December 31, 2017 at 12:13:39 pm */ 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 gets Android screenshots* * @author LeeHo * @update December 31, 2017 12:11:42 pm */ private void executeADBCaptureCommands() { for (String command : ADB_SCREEN_CAPTURE_CMDS) { executeCommand(command); } } /** * Jump* * @param distance * @author LeeHo * @update December 31, 2017 at 12:23:19 pm */ private void doJump(double distance) { System.out.println("distance: " + distance); // Calculate the press time, minimum 200ms int pressTime = (int) Math.max(distance * pressTimeCoefficient, 200); System.out.println("pressTime: " + pressTime); //Execute the press operation String command = String.format("adb shell input swipe %s %s %s %s %s", swipeX, swipeY, swipeX, swipeY, pressTime); System.out.println(command); executeCommand(command); } /** * Another game* * @author LeeHo * @update December 31, 2017 at 12:47:06 pm */ private void replayGame() { String command = String.format("adb shell input tap %s %s", swipeX, swipeY); executeCommand(command); } /** * Calculate the distance of the jump, that is, the distance between two points* * @param halmaX * @param halmaY * @param boardX * @param boardY * @return * @author LeeHo * @update December 31, 2017 at 12:27:30 pm */ 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("Create image storage directory failed"); return; } } //Number of executions int executeCount = 0; for (;;) { //Execute ADB command to get Android screenshot jumpjumpHelper.executeADBCaptureCommands(); File currentImage = new File(STORE_DIR, IMAGE_NAME); if (!currentImage.exists()) { System.out.println("The image does not exist"); continue; } long length = currentImage.length(); imageLength[executeCount % imageLengthLength] = length; //Check whether you need to re-start jumpjumpHelper.checkDoReplay(); executeCount++; System.out.println("currentth" + executeCount + "Execution!"); //Get the center coordinates of checkers and base plate 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); //calculate the distance of the jump double jumpDistance = jumpjumpHelper.computeJumpDistance(halmaX, halmaY, boardX, boardY); jumpjumpHelper.doJump(jumpDistance); //Stay for 2.5 seconds each time TimeUnit.MILLISECONDS.sleep(2500); } } catch (Exception e) { e.printStackTrace(); } } /** * Check whether you need to restart* * @author LeeHo * @update December 31, 2017 1:39:18 pm */ private void checkDoReplay() { if (imageLength[0] > 0 && imageLength[0] == imageLength[1] && imageLength[1] == imageLength[2] && imageLength[2] == imageLength[3] && imageLength[3] == imageLength[4]) { //This means that the image size has been the same for 5 consecutive times. You can know that the current screen is in another round of Arrays.fill(imageLength, 0); //Simulate and click the button to start the game again replayGame(); } } /** * Get the RGB value of the specified coordinates* * @param bufferedImage * @param x * @param y * @author LeeHo * @update 2017-02-31 12:12:43 pm */ private void processRGBInfo(BufferedImage bufferedImage, int x, int y) { this.rgbInfo.reset(); int pixel = bufferedImage.getRGB(x, y); //Convert to RGB digit this.rgbInfo.setRValue((pixel & 0xff0000) >> 16); this.rgbInfo.setGValue((pixel & 0xff000) >> 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; } } }Of course, the results will be cleared after a while, but as a programmer, it is still good. From the initial post submission vulnerability, the computer was asked to grab packets and modify data as an agent. Now the code simulates clicks (although it will not take effect.)
For more content, you can refer to the special topic "Jump on WeChat" to learn.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.