나는 오랫동안 친구들의 원에 점프 결과를 게시 해 왔습니다. 오늘 나는 실수로 코드를 사용하여 점수를 올린 동료의 비디오를 보았습니다. 나는 바이두로 가서 코드를 보았습니다 (코드가 끝났습니다). 몇 번의 비틀림과 회전 후, 나는 마침내 성공적으로 달렸고 조금 득점했습니다.
먼저 단계에 대해 간단히 이야기 해 봅시다.
1. Baidu 다운로드 점수 코드
2. ADB를 설치하십시오
3. USB 디버깅 모드를 사용하여 컴퓨터에 연결할 전화기 찾기
4. Wechat Mini 프로그램을 시작하십시오
5. Eclipse에서 코드를 실행합니다 (여기서는 휴대 전화 화면의 크기에 따라 매개 변수를 지속적으로 디버그하고 수정해야합니다).
결과적으로 전화 화면이 자동으로 누르고 체스 조각이 점프하게됩니다.
질문에 대해 이야기합시다.
1. ADB 문제 세트 설치 :
ADB 도구 주소를 다운로드하십시오
여기의 장치 관리자에서 다른 장치에 설치되지 않은 경우 ADB는 느낌표입니다. 설치 후 그림과 같이 라인 안드로이드 장치가 나타납니다.
설치하면 ADB 열에서 마우스 오른쪽 버튼을 클릭하면 속성을 선택하면 다음 인터페이스가 팝업됩니다. 드라이버 업데이트를 클릭하고 컴퓨터 탐색을 선택하고 프로그램을 선택하십시오 (즉, 두 번째 옵션). 현재 컴퓨터에서 드라이버 옵션을 찾아 보면 설치 패키지의 위치를 선택하면 모든 것이 릴리스되도록 설치됩니다.
문제는 다음과 같습니다.
설치 후 CMD 명령 창에서 ADB를 사용할 수 있지만 Eclipse에서 코드를 실행하면 전혀 영향을 미치지 않습니다 (프로그램은 오류를보고하지 않으며 전화에 스크린 샷이 없음).
현재 설치 한 두 개의 동적 링크 라이브러리 DLL을 다음 두 디렉토리에 복사해야합니다. (찾을 수없는 경우 C 드라이브에서 전 세계적으로 검색).
adb.exe
adbwinapi.dll
adbwinusbapi.dll
C :/Windows/System32
C :/Windows/Syswow64
현재 SYSWOW64에 배치해야합니다. 나는 Win7 64 비트 이므로이 디렉토리가 있습니다 (인터넷의 다른 사람들은 Win32를 넣을 필요가 없다고 말합니다. 시도하지 않았습니다).
SYSWOW64 디렉토리가 배치되지 않은 경우, Eclipse 작업은 여전히 영향을 미치지 않습니다. 그러나 CMD의 ADB Shell Screencap -tencent/customerpic/current.png 명령을 실행하는 경우 전화에 PRORENT.PNG 그림이 있음을 알게 될 것입니다.
CD를 System32에 사용하고 설치 디렉토리 (C :/Program Files (x86)/Thunder Network/Thunder/Program)에서 위의 명령을 성공적으로 실행했으며 System32에서 오류를보고했습니다.
--------------------------------------------------------------------------------------------------------------------------------
Adbwinapi.dll이 컴퓨터에서 누락 되었으므로이 프로그램을 시작할 수 없습니다. 이 문제를 해결하기 위해 프로그램을 다시 설치하십시오.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
확신하는
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
자, 이것은 System32의 ADB가 ADBWINAPI.DLL Dynamic Link 파일을 찾을 수 없다는 것을 의미하지만 우연히 디렉토리 SYSWOW64를 보았을 때이 디렉토리는 무엇을 의미하고 무엇을 의미합니까? 자, System32 디렉토리에 복사 된 세 가지 파일을 복사 한 다음이 디렉토리 Syswow64에 복사 한 후 완료하십시오.
질문 2 : 장치 오프라인
CMD 명령 창에서 ADB 쉘을 실행하면 오류 장치가 오프라인 상태가되었습니다. ADB 설치에 문제가 있다고 생각했습니다. 나는 바이두가 많았다. ADB Kill Server, ADB Remount 및 기타 명령을 시도했지만 코드가 /sdcard /임을 알았습니다. 나는 이것이 외부 SD 카드 여야한다는 것을 보았다. 길이 잘못 되었습니까? (Vivo X9를 사용 했는데이 전화에는 외부 SD 카드 옵션이 없습니다). 이전 전화 (Vivo Y27)로 변경 한 후 ADB 쉘을 실행할 수 있지만 /SDCard는 외부 SD 카드 경로가 아니라 전화의 U 디스크 경로입니다.
그것은 코드 경로 문제가되어서는 안된다는 것을 의미합니다. ADB 도구가 너무 오래되었고 ADB 버전에는 버전 1.0.26이 있다고 들었습니다. 글쎄, 나는 새 버전의 ADB를 찾기에는 너무 게으르다. 오래된 Vivo Y27로 디버깅을했는데 플래시 될 수 있습니다.
내가 배운 것을 나열하겠습니다.
1. ADB가 있다는 것을 알고 있으며 ADB 쉘을 사용하면 전화기의 배쉬 세션을 얻을 수 있습니다. 스크린 샷을 찍을 수 있으며 ADB PULL을 사용하면 휴대 전화에서 파일을 얻을 수 있습니다. 공식 웹 사이트에 더 많은 명령이 있다면 너무 많이 읽더라도 기억할 수 없습니다.
2. Java는 원래 코드에서 runtime.getRuntime ()를 사용하여 Windows에서 시스템 명령을 호출합니다.
process = runtime.getRuntime (). exec (명령); System.out.println ( "Exec 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);
모든 코드 :
패키지 com.lw.test; java.awt.image.bufferedimage import; import java.io.bufferedReader; import java.io.file; import java.io.ioexception; import java.io.inputStreamReader; import java.util.arrays; java.util.concurrent.timeUnit import; import javax.imageio.imageio; /** * 참조 ZHIHU * * @link <a href = "https://zhuanlan.zhihu.com/p/32452473"rel = "external nofollow"target = "_blank"> https://zhuanlan.zhihu.com/p/32452473 </aite * * * * * * * * * * * * * * * * * * * * * * * * */ public class j 개인 정적 최종 문자열 store_dir = "d :/jump_screencapture"; // 수량 비공개 정적 최종 최종 intimelengrength = 5; // 이미지의 크기 개인 정적 최종 long [] imageLength = new Long [imageLengthlength]; 개인 최종 RGBINFO RGBINFO = NEW RGBINFO (); 개인 최종 문자열 경로 = "/sdcard/tencent/customerpic/"; 개인 최종 문자열 [] adb_screen_capture_cmds = { "adb shell screencap -p"+path+image_name, "adb pull"+path+"current.png"+store_dir}; // 스크린 샷의 게임 점수 표시 영역의 하단에있는 Y 좌표, 300은 1920x1080입니다. 실제 상황에 따라 개인 최종 INT GamesCoreBottomy = 300을 수정하십시오. // 프레스 타임 계수는 특정 상황에 따라 적절하게 조정할 수 있습니다. 개인 최종 Double PresstimeCoefficial = 2.05; // 프레스의 시작점 좌표는 다음 게임의 시작점 좌표이기도합니다. 개인 최종 int swipex = 280; 개인 최종 INT Swipey = 600; // 체스 조각의 기저 높이는 개인 최종 최종 int HalfBaseboardHeight = 20입니다. // 체스 조각의 너비는 스크린 샷에서 가져와 개인 최종 int를 직접 조정합니다. HalmabodyWidth = 74; // 게임 스크린 샷에서 두 스프링 보드의 중간 점 좌표는 주로 각도를 계산하는 데 사용됩니다. XY의 비율은 실제 스크린 샷에 따라 계산할 수 있습니다. 개인 최종 int Boardx1 = 813; 개인 최종 int Boardy1 = 1122; 개인 최종 int Boardx2 = 310; 개인 최종 int Boardy2 = 813; / ** * 내년 스프링 보드의 체커와 중앙 좌표를 얻습니다 * @return * @Author Leeho * @Throws IOException * @Update 2017 년 12 월 31 일 오후 12 월 31 일 오후 10시 */ private int [] gethalmaandboardxyValue (파일 전류)는 ioexection {bufferedimage vbilleceation {indimeio.rede); int width = bufferedImage.getWidth (); int height = bufferedImage.getheight (); System.out.println ( "너비 :" + 너비 + ", 높이 :" + 높이); int halmaxsum = 0; int halmaxcount = 0; int halmaymax = 0; int boardx = 0; int boardy = 0; // 스크린 샷에서 픽셀 포인트를 위에서 아래로 전송하고 위치 인식의 기초로 체스 조각의 색상을 사용하십시오. 마지막으로, 체스 조각 색상의 가장 낮은 줄에있는 모든 픽셀의 평균값, 즉 (int y = gamescorebottomy; y <높이; 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) {// 체스 조각의 하단 행의 좌표 값 halmax = halmaxsum /halmaxcount; // 체스 조각의 절반을 섀시 높이로 이동 int halmay = halmaymax -HalfbaseboardHeight; // 게임에서 시작하여 (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 (); // 체스 조각의 헤드가 다음 스프링 보드보다 높은 경우 (math.abs (x -halmax) <halmabodywidth) {계속; } // 다음 스프링 보드의 위에서 아래로 스캔합니다. 다음 스프링 보드는 원이나 상자 일 수 있습니다. 여러 포인트를 가져 와서 평균 if ((Math.abs (Pixelr -LastPixelr) + math.abs (pixelg -lastpixelg) + math.abs (pixelb -lastpixelb))> 10) {boardxsum + = x; BoardxCount ++; }} if (boardxsum> 0) {boardx = boardxsum / boardxcount; }} // 실제 각도에서 다음 보드 중앙에 가까운 좌표를 찾으십시오. 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 좌표 결과 [0] = halmax; // y 좌표 결과 [1] = Halmay; // x 좌표 결과 [2] = boardx; // y 좌표 결과 [3] = Boardy; 반환 결과; }} return null; } / ** * 명령 실행 * * @param command * @author leeho * @update 2017 년 12 월 31 일 오후 12:13:39 * / private void executeCommand (String Command) {process process = null; {process = runtime.getRuntime (). exec (명령); System.out.println ( "Exec 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 (예외 e) {e.printstacktrace (); } 마지막으로 {if (process! = null) {process.destroy (); }}} / ** * adb가 안드로이드 스크린 샷을 가져옵니다. }} / ** * jump * * @param 거리 * @author leeho * @update 2017 년 12 월 31 일 오후 12:23:19 pm * / private void dojump (double distone) {System.out.println ( "거리 :" + 거리); // 프레스 타임을 계산, 최소 200ms int presstime = (int) math.max (거리 * presstimeCoefficial, 200); System.out.println ( "프레스 타임 :" + 프레스 타임); // 프레스 작동 문자열 명령 = String.format ( "ADB 쉘 입력 스 와이프 %s %s %s %s %s", swipex, swipey, swipex, swipey, presstime); System.out.println (명령); 집행 명령 (명령); } / ** * 또 다른 게임 * * @author leeho * @update 2017 년 12 월 31 일 오후 12시 47 분 66 분 * / 개인 void ReplayGame () {String Command = String.Format ( "adb 쉘 입력 탭 %s %s", swipex, swipey); 집행 명령 (명령); } / ** * 점프의 거리, 즉 두 지점 사이의 거리를 계산합니다. 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; //// 명령 = "ADB 장치"; // jumpjumphelper.executecommand (명령); // // if (true) {return;} try {file storedir = new File (store_dir); if (! storedir.exists ()) {boolean flag = storedir.mkdir (); if (! flag) {System.err.println ( "이미지 스토리지 디렉토리 만들기 실패"); 반품; }} // 실행 수 Int ExecuteCount = 0; for (;;) {// adb 명령을 실행하여 Android Screenshot jumpjumphelper.executeadbcapturecommands ()를 얻습니다. 파일 currentImage = 새 파일 (store_dir, image_name); if (! currentImage.exists ()) {system.out.println ( "이미지가 존재하지 않는다"); 계속하다; } 긴 길이 = currentImage.length (); imageLength [ExecuteCount % imageLengthlength] = 길이; // JumpJumpHelper.CheckDorePlay ()를 다시 시작 해야하는지 확인하십시오. ExecuteCount ++; System.out.println ( "currentth" + executeCount + "execution!"); // 체커 및베이스 플레이트의 중앙 좌표를 가져옵니다 int [] result = jumpjumphelper.gethalmaandboardxyvalue (currentImage); if (result == null) {system.out.println ( "메소드의 결과 GethalmaandboardxyValue의 결과는 null!"); 계속하다; } int halmax = 결과 [0]; int halmay = 결과 [1]; int boardx = 결과 [2]; int boardy = 결과 [3]; System.out.println ( "Halmax :" + Halmax + ", Halmay :" + Halmay + ", Boardx :" + Boardx + ", Boardy :" + Boardy); // 점프의 거리를 계산합니다. Double Dougn JumpDistance = JumpJumphelper.computeJumpdistance (Halmax, Halmay, Boardx, Boardy); jumpjumphelper.dojump (점프 디스턴스); // TimeUnit.milliseconds.sleep (2500)마다 2.5 초 동안 머무 릅니다. }} catch (예외 e) {e.printstacktrace (); }} / ** * 다시 시작 해야하는지 확인하십시오 * * @author leeho * @update 2017 년 12 월 31 일 1:39:18 pm * / private void checkdoreplay () {if (imageLength [0]> 0 && imageLength [0] == imagelength [1] && imageLength [2] & imageLength [2] = imageLength [2]. ImageLength [3] == imagelength [4]) {// 이미지 크기가 5 번 연속 동일하다는 것을 의미합니다. 현재 화면이 다른 배열 라운드에 있음을 알 수 있습니다 .fill (imageLength, 0); // 게임을 다시 시작하려면 버튼을 시뮬레이션하고 클릭하십시오. 다시 ReplayGame (); }} / ** * 지정된 좌표의 RGB 값을 가져옵니다 * * @param bufferedImage * @param x * @param y * @author leeho * @update 2017-02-31 12:12:43 pm * / private void processRgbinfo (버퍼링 완충식, Int x, int y) {the. int pixel = bufferedImage.getRGB (x, y); // rgb 숫자로 변환 this.rgbinfo.setrvalue ((pixel & 0xff0000) >> 16); this.rgbinfo.setgvalue ((pixel & 0xff000) >> 8); this.rgbinfo.setbvalue ((pixel & 0xff)); } class rgbinfo {private int rvalue; 프라이빗 int gvalue; 개인 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; }}}물론, 결과는 잠시 후에 청소 될 것이지만 프로그래머로서 여전히 좋습니다. 초기 포스트 제출 취약성에서 컴퓨터는 패킷을 잡고 에이전트로서 데이터를 수정하도록 요청 받았다. 이제 코드는 클릭을 시뮬레이션합니다 (적용되지는 않지만).
더 많은 내용을 보려면 학습 할 특별한 주제 "Jump On Wechat"을 참조하십시오.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.