넷게임
블루스택2 비활성클릭 공유 본문
;매크로상수,전역변수, 스크립트의 속성을 정의한다. 라이브러리를 로드한다.#Include Gdip.ahk ; 비활성 윈도우의 이미지를 가져오는데 필요한 라이브러리, 현재 dx11이상 opengl로 출력되는 화면은 제대로 검출못함#Include Gdip_ImageSearch.ahk ; 2개 이미지를 비교하는데 필요한 라이브러리bmp폴더:=A_WorkingDir "\img\"WinTitle:="Bluestacks App Player" ; 작업할 윈도우 타이틀작업프로그램:="C:\Program Files\BlueStacks\HD-StartLauncher.exe" ; 작업프로그램실행파일. 경로포함SetBatchLines, -1 ; 스크립트라인 실행후 10ms(기본값)의 지연을 없에므로써 최상의속도를 구현한다.#NoEnv ; 변수명을 해석할 때, 환경 변수를 무시한다. 변수명중복오류 방지. 빈값의 환경변수는 패싱해 특정명령문에서 속도를 높인다#WinActivateForce ; 오토핫키에 특정윈도우활성화권한을 줌, 블루스택창 활성화에 사용; 전역변수설정 ; 여기서 선언한 변수는 global을 사용안해도 전역변수가 됩니다.global 자식창_핸들, 자식창_이름, 자식창x, 자식창y, 자식창w, 자식창h ; 여기선 복수개의 변수를 선언할거기 때문에 global 씀; 매크로 구동전 초기화 자동실행블루스택자식창핸들찾기() ; 블루스택2의 좌표정보, PostMessage입력에 사용될 (블루스택)핸들을 찾아냅니다.;Gui 꾸미기Gui, Font, S20 CDefault Bold, VerdanaGui, Add, Text, x12 y10 h50 +Center , 스크립트중지/진행:F1키Gui, Add, Button, x12 y50 h50 +Center gMainMacro, 스크립트시작:Insert키Gui, Add, Button, x12 y100 h60 gGuiClose, 프로그램종료:Delete키Gui, Font, S12 CDefault Bold, VerdanaGui, Add, Text, x12 y170 h50 +Center , 블루스택비활성스샷 PrintScreen키로 `n 작동여부를 테스트해볼 수 있습니다.`n capture폴더에 저장Gui, Show, Center AutoSize, 블루스택2 비활성매크로return ; 위까지 자동실행 영역. 끝 /*핫키를 만나면 스크립트가 멈추기 때문에 핫키는 아래에 등록*/; MainMacro: 서브루틴 안에 매크로 스크립트를 작성합니다. 메크로시작 insert키MainMacro:{;Loop ; 무한루프;{/* 테스트 입니다.무한루프안에 매크로를 만들면 매크로가 멈추지 않고 진행됩니다. 매크로를 일시정지/재진행하려면 F1키를 토글합니다.무한루프안의 매크로 진행중에 다른 핫키 사용됩니다. ex) 매크로진행중 핫키PrintScreen::블루스택비활성스샷() 실행*/비활성드래그(300,300,500,500,2) ; x300,y300 -> x500,y500 좌표로 2의 속도로 드래그합니다. 속도크기를 높이면 슬라이딩을 줄입니다.sleep,500비활성드래그(500,500,300,300,2) ; x500,y500 -> x300,y300 좌표로 2의 속도로 드래그합니다.sleep,500if 비활성찾기("test",x,y,400,200,500,300) ; 비활성이미지를 찾으면 해당 좌표 비활성클릭을 합니다. \img폴더에 test.bmp 파일넣고 테스트{MsgBox,% "찾은좌표는 x" x " y" y " 입니다";비활성클릭(x,y) ; 위에서 찾은 x,y좌표를 클릭합니다. 비활성클릭(500,600)처럼 값을 지정하면, 500,600을 클릭합니다.}/* 비활성찾고클릭() 함수는 사용편의를 위해 찾기,클릭을 합쳐 놓았습니다.전체화면검색시 비활성찾고클릭("이미지이름") 으로 간편하게 사용할 수 있고,필요에 따라 세부옵션을 함수인자에 넣어 조정할 수 있습니다.찾는범위를 줄이면 실행속도가 빨라집니다. 또한, 비슷한 이미지 다른좌표 찾는것을 방지할 수 있습니다.비활성찾고클릭("이미지이름", 시작x,시작y,마지막x,마지막y,색상범위,제외할색상(0~0xFFFFFF) (이미지이름외 생략가능)*/if 비활성찾고클릭("test",400,200,500,300,7,0xFFFFFF) ; 검정색을 무시하고, 색상범위7이내의 400,200,500,300범위 안의 이미지를 찾음.MsgBox, 비활성 찾고클릭 성공elseMsgBox, 비활성 찾고클릭 실패;sleep,100 ; 적당한 지연시간은 cpu과부하를 막아줍니다.;}}return; 핫키설정, 이벤트반응, 서브루틴 등등..f1::pause ; 오토핫키 일시정지f2::ReloadPrintScreen::블루스택비활성스샷()insert::Gosub, MainMacro ; 메인매크로 스크립트 시작delete:: ; delete 키를 눌렀을때 아래를 실행. 아래서브루틴들도 각각 아래 스크립트내용을 실행함.GuiClose: ; Gui창이 닫히는 이벤트에 오토핫키를 종료.{BlockInput, MouseMoveoff ; 마우스 이동방지 끔ifWinExist, %WinTitle%{CenterWindow(WinTitle) ; 종료시 블루스택을 화면 가운데로 가져와 활성화 시킵니다WinActivate,%WinTitle% ;}else{Gui,DestroyMsgBox, %wintitle% 프로그램은 실행중이 아닙니다}ExitApp ; 오토핫키 종료}; 함수를 정의합니다.CenterWindow(WinTitle) ; 해당 윈도우를 모니터화면 가운데로 이동합니다.{WinGetPos,,, Width, Height, %WinTitle%WinMove, %WinTitle%,, (A_ScreenWidth/2)-(Width/2), (A_ScreenHeight/2)-(Height/2)}블루스택자식창핸들찾기() ; 블루스택2의 좌표정보, PostMessage입력에 사용될 (블루스택)핸들을 찾아냅니다.{global 자식창_핸들, 자식창_이름, 자식창x, 자식창y, 자식창w, 자식창h, 블루스택핸들, WinTitle ; 이미 선언된 전역변수 값을 함수내에서 공유합니다.IfWinNotExist,%WinTitle% ; 블루스택2가 실행되지 않으면 함수를 종료합니다.{MsgBox, 오류, 블루스택2가 실행되지 않았습니다.Run C:\Program Files\BlueStacks\HD-StartLauncher.exesleep,5000return 블루스택자식창핸들찾기()}WinActivate,%WinTitle%while !WinActive(WinTitle) ; 블루스택2창 활성화될때까지sleep,100WinGetPos,x,y,,,%WinTitle% ; 블루스택2창의 좌상단 x,y좌표를 구합니다.MouseMove, x+10, y+40, 0 ; 마우스커서를 블루스택창에서 자식윈도우위로 옮깁니다.MouseGetPos, , , 자식창_핸들, 자식창_이름 ; 마우스커서 위치의 자식창이름, 자식창핸들을 얻음MouseGetPos, , , ,블루스택핸들,3 ; 마우스커서 위치의 자식윈도우의핸들을 찾아서 hclwnd변수에 넣음WinMove,%WinTitle%,,0,0 ; 해당 윈도우의 좌표를 이동하고 [사이즈를 조절], 비활성작업시 모니터해상도를 벗어나게 만들면 숨길 수 있습니다. ex)WinMove,%WinTitle%,,2000,0ControlGetPos, 자식창x, 자식창y, 자식창w, 자식창h, %자식창_이름%, ahk_id %자식창_핸들% ; 자식창의 x,y와 폭w 높이h를 받음return};비활성찾고클릭("이미지이름", 시작x,시작y,마지막x,마지막y,색상범위,제외할색상(0~0xFFFFFF) (이미지이름외 생략가능)비활성찾고클릭(image, sx=0, sy=0, ex="", ey="", n=0, trans=0) ; 비활성이미지서치 찾고클릭 간소화함수, 이미지 찾아서 클릭하고 참값을 돌려주어 조건문에 활용가능{if 비활성찾기(image,x,y,sx,sy,ex,ey,n,trans){비활성클릭(x,y)return true}return false};비활성찾기("이미지이름", 찾은x,찾은y,시작x,시작y,마지막x,마지막y,색상범위,제외할색상(0~0xFFFFFF) (이미지이름외 생략가능)비활성찾기(image, byref vx="", byref vy="", sx=0, sy=0, ex="", ey="", n=0, trans=0 ) ; 이미지파일 비교검색에 \img폴더의 bmp파일을 사용합니다.{global 자식창_핸들, 자식창x, 자식창y, 자식창w, 자식창h,bmp폴더 ; 이미 선언된 전역변수 값을 함수내에서 공유합니다.if ex=ex:=자식창w ; ex인자 생략하면 블루스택화면 w값elseex:=자식창x+ex ; 자식창시작위치에 사용자가 원하는 검색끝x값을 더해 완성if ey=ey:=자식창h ; ey인자 생략하면 블루스택화면 h값elseey:=자식창y+ey ; 자식창시작위치에 사용자가 원하는 검색끝y값을 더해 완성image=%image%.bmp같은이미지찾음:=0if !fileExist(bmp폴더 image) ; 비교할 이미지파일이 없으면 함수종료{MsgBox, 오류, 비교할 이미지파일 "%image%"이 `n%bmp폴더% 폴더에 존재하지 않습니다.return false}pToken:=Gdip_Startup() ; Gdip 활성화pBitmapHayStack := Gdip_BitmapFromHWND(자식창_핸들) ; 자식창에서 비활성화면을 가져온 후 pBitmap에 저장loop,100 ; 블루스택2 비활성, 제대로 나온화면 찾기 100회 시도{Gdip_FromARGB(Gdip_GetPixel(pBitmapHayStack, 10, 30),A,R,G,B) ; 10,30 좌표의if !R and !G and !B ; 검정픽셀이면(rgb각각 0값){if a_index=100{MsgBox, 오류, BlackScreen! 블루스택2 비활성 화면을 찾지 못했습니다.break}pBitmapHayStack := Gdip_BitmapFromHWND(자식창_핸들) ; 자식창에서 비활성화면을 가져온 후 pBitmap에 저장}else ; 블랙스크린이 아니면, 이미지비교시작{pBitmapHayStack := Gdip_CloneBitmapArea(pBitmapHayStack, 자식창x, 자식창y, ex, ey)pBitmapNeedle:=Gdip_CreateBitmapFromFile(bmp폴더 image);if Gdip_ImageSearch(pBitmapHayStack,pBitmapNeedle,list,0,0,0,0,10,0x000000,1,1)if Gdip_ImageSearch(pBitmapHayStack,pBitmapNeedle,list,sx,sy,ex,ey,n,trans){StringSplit, LISTArray, LIST, `,vx:=LISTArray1vy:=LISTArray2같은이미지찾음:=1}else같은이미지찾음:=0break}}Gdip_DisposeImage(pBitmapHayStack), Gdip_DisposeImage(pBitmapNeedle)Gdip_Shutdown(pToken)return 같은이미지찾음}블루스택비활성스샷(){global 자식창_핸들, 자식창x, 자식창y, 자식창w, 자식창hif !자식창_핸들return false캡쳐폴더명=capture ; 캡쳐폴더명 설정if not fileExist(A_WorkingDir "\" 캡쳐폴더명) ; 캡쳐폴더가 존재하지 않으면FileCreateDir, %캡쳐폴더명% ; 캡쳐폴더 생성월일시간:=% a_mm "월" a_dd "일 " A_Hour "시" A_MM "분" A_Sec "초"캡쳐파일명:=A_WorkingDir "\" 캡쳐폴더명 "\" 월일시간 ".png" ; 확장명에 따라 저장방식이 달라짐. 원본화질의 용량적은 png로 저장pToken := Gdip_Startup() ; Gdip 활성화pBitmap := Gdip_BitmapFromHWND(자식창_핸들) ; 자식창에서 비활성화면을 가져온 후 pBitmap에 저장IfWinExist,Bluestacks App Player ; 블루스택용{loop,100{Gdip_FromARGB(Gdip_GetPixel(pBitmap, 10, 30),A,R,G,B) ; 비활성 블루스택이미지의 10,30좌표 1개의 픽셀색상정보if !R and !G and !B ; 검정픽셀이면(블랙스크린이면){if A_Index=100{MsgBox, 오류, BlackScreen! 블루스택2 비활성 화면을 찾지 못했습니다.break}pBitmap := Gdip_BitmapFromHWND(자식창_핸들) ; 자식창에서 비활성화면을 가져온 후 pBitmap에 저장}else ; 블랙스크린이 아니면{pBitmap := Gdip_CloneBitmapArea(pBitmap, 자식창x, 자식창y, 자식창w, 자식창h) ; 자식창 좌표에 맞게 이미지 잘라낸 후 pBitmap에 다시 저장, 이줄을 생략해주면 부모창 그대로 캡쳐한다.If (pBitmap = -1) ; pBitmap에 오류가 없는지.. 이상없으면 chord소리내고 이미지파일 저장함MsgBox, 오류, 이미지가 없습니다.else{SoundPlay, %A_WinDir%\Media\chord.wavGdip_SaveBitmapToFile(pBitmap, 캡쳐파일명) ; 비트맵hex코드가 담긴 pBitmap을 파일로 저장}break}}}Gdip_DisposeImage(pBitmap) ; pBitmap 이미지데이터 메모리에서 지움Gdip_Shutdown(pToken) ; Gdip 종료return}/* 비활성 클릭,드래그*/비활성클릭(x,y){global 블루스택핸들 ; 이미 선언된 전역변수 값을 함수내에서 공유합니다.lparam:=x|y<<16 ; x,y 좌표값PostMessage,0x201,0x0000,%lparam%,,ahk_Id %블루스택핸들% ; PostMessage 왼쪽 마우스버튼 downPostMessage,0x202,0x0000,%lparam%,,ahk_Id %블루스택핸들% ; PostMessage 왼쪽 마우스버튼 upreturn}비활성드래그(sx,sy,ex,ey,speed="") ; sx,sy는 드래그시작지점, ex,et는 드래그 도착지점입니다. (speed로 감도를 조절합니다. 생략가능){global 블루스택핸들 ; 이미 선언된 전역변수 값을 함수내에서 공유합니다.if speed= ; 마우스스피드 생략하면 오토핫키 기본값 2 가져옴speed:=A_DefaultMouseSpeedelse if ( speed<0 or speed>100 ){MsgBox, speed값에 음수는 넣을 수 없습니다. (0~100범위 입력가능)return false}lparam:=sx|sy<<16 ; 시작좌표PostMessage,0x201,0x0000,%lparam%,,ahk_Id %블루스택핸들% ; PostMessage 왼쪽 마우스버튼 downloop,% speed-1 ; 목표지점까지 drag를 위해 반복합니다. speed 값을 결국 드래그 감도에 영향을 줍니다.{sleep, 20 ; 너무 낮은값을 주면 제대로 클릭이 안되고 반대로 너무 높은값은 시간이 오래걸립니다.x:=Round(sx+(ex-sx)/speed*a_index) ; 목표지점까지 조금씩 이동할 x좌표를 구합니다.y:=Round(sy+(ey-sy)/speed*a_index) ; 목표지점까지 조금씩 이동할 y좌표를 구합니다.lparam:=x|y<<16 ; 조금씩이동되는 좌표PostMessage,0x200,0x0001,%lparam%,,ahk_Id %블루스택핸들% ; PostMessage 왼쪽버튼 down유지(wparam값 0x0001)하면서 마우스이동}lparam:=ex|ey<<16 ; 마지막좌표sleep, 100 ; 값이 낮을수록 드래그후 슬라이딩하는 길이가 길어짐.PostMessage,0x200,0x0001,%lparam%,,ahk_Id %블루스택핸들% ; PostMessage 왼쪽버튼 down유지(wparam값 0x0001)하면서 마우스이동sleep, 100 ; 여기서 슬립생략하면 슬라이딩 안함.PostMessage,0x202,0x0000,%lparam%,,ahk_Id %블루스택핸들% ; PostMessage 왼쪽 마우스버튼 upreturn}
Comments