Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Struggling with _PixelSearch
#1
I am attempting to re purpose some of the code in the bot, but I am running into issues with _PixelSearch. Specifically, I can not seem to get it to find the pixel I am looking for. I can not get it to find the pixel in the 'Train Troops' button. I am using an older version of BlueStacks and I don't have BS's resolution set to what you recommend however, that should not be the issue.
Let me apologize in advance to the wall of code but below is the code I am using. If the code worked, nothing should happen. But, I keep getting the 'Barracks is not available' messagebox instead.
If a super smart coder would like to take a look at this mess and let me know what I am doing wrong, I would appreciate it.
Code:
#include <GDIPlus.au3>
#include <WinAPIProc.au3>
#include <ScreenCapture.au3>
#include <ColorConstants.au3>
#include <Misc.au3>

Opt("MouseClickDelay", 10)
Opt("MouseClickDownDelay", 10)

Global $hBitmap; Image for pixel functions
Global $hHBitmap; Handle Image for Pixel Functions

Global $BSpos[2] ; Inside BlueStacks positions relative to the screen

Global $ichkBackground = 0

$Title = "BlueStacks App Player for Windows (beta-1)" ; Window name
$Full = WinGetTitle ($Title) ; Get The Full Title..
$HWnD = WinGetHandle ($Full) ; Get The Handle
WinActivate ($HWnD)
WinMove ($HWnD, "", 0, 0)

Global $RunState = True

;Barrak 01 - 131, 309
;Barrak 02 - 296, 46
;Barrak 03 - 838, 50
;Barrak 04 - 994, 314

HotKeySet ("{F7}", "Train")

While 1
   Sleep (100)
WEnd

Func Train()
       While 1
            If _Sleep(500) Then ExitLoop

            Click(1, 1) ;Click Away

            If _Sleep(500) Then ExitLoop

            Click(131, 309) ;Click Barrack 01

            If _Sleep(500) Then ExitLoop

            Local $TrainPos = _PixelSearch(625, 457, 686, 520, Hex(0x885733, 6), 5) ;Finds Train Troops button
            If IsArray($TrainPos) = False Then
                ;SetLog("Barrack " & $i + 1 & " is not available")
                MsgBox ($MB_SYSTEMMODAL, "Barracks is not available", "")
                If _Sleep(500) Then ExitLoop
            Else
                Click($TrainPos[0], $TrainPos[1]) ;Click Train Troops button
            EndIf
    WEnd
EndFunc   ;==>Train

Func Click($x, $y, $times = 1, $speed = 0)
   If $times <> 1 Then
      For $i = 0 To ($times - 1)
         ControlClick($HWnD, "", "", "left", "1", $x, $y)
         If _Sleep($speed, False) Then ExitLoop
      Next
   Else
      ControlClick($HWnD, "", "", "left", "1", $x, $y)
   EndIf
EndFunc   ;==>Click

Func _Sleep($iDelay, $iSleep = True)
   Local $iBegin = TimerInit()
   While TimerDiff($iBegin) < $iDelay
      If $RunState = False Then Return True
      If $iSleep = True Then Sleep(100)
   WEnd
   Return False
EndFunc   ;==>_Sleep

Func _PixelSearch($iLeft, $iTop, $iRight, $iBottom, $iColor, $iColorVariation)
    _CaptureRegion($iLeft, $iTop, $iRight, $iBottom)
    For $x = $iRight - $iLeft To 0 Step -1
        For $y = $iBottom - $iTop To 0 Step -1
            Local $nColor1 = $iColor
            Local $nColor2 = _PixelGetColor_GetPixel($x, $y)
            If _ColorCheckVariation($nColor1, $nColor2, $iColorVariation) Then
                Local $Pos[2] = [$iLeft + $x, $iTop + $y]
                Return $Pos
            EndIf
        Next
    Next
    Return 0
EndFunc   ;==>_PixelSearch

Func _CaptureRegion($iLeft = 0, $iTop = 0, $iRight = 860, $iBottom = 720, $ReturnBMP = False)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hHBitmap)

    If $ichkBackground = 1 Then
        Local $iW = Number($iRight) - Number($iLeft), $iH = Number($iBottom) - Number($iTop)

        Local $hDC_Capture = _WinAPI_GetWindowDC(ControlGetHandle("BlueStacks App Player", "", "[CLASS:BlueStacksApp; INSTANCE:1]"))
        Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
        $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $iW, $iH)
        Local $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)

        DllCall("user32.dll", "int", "PrintWindow", "hwnd", $HWnD, "handle", $hMemDC, "int", 0)
        _WinAPI_SelectObject($hMemDC, $hHBitmap)
        _WinAPI_BitBlt($hMemDC, 0, 0, $iW, $iH, $hDC_Capture, $iLeft, $iTop, 0x00CC0020)

        Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)

        _WinAPI_DeleteDC($hMemDC)
        _WinAPI_SelectObject($hMemDC, $hObjectOld)
        _WinAPI_ReleaseDC($HWnD, $hDC_Capture)
    Else
        getBSPos()
        $hHBitmap = _ScreenCapture_Capture("", $iLeft + $BSpos[0], $iTop + $BSpos[1], $iRight + $BSpos[0], $iBottom + $BSpos[1])
        Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    EndIf

    If $ReturnBMP Then Return $hBitmap
EndFunc   ;==>_CaptureRegion

Func getBSPos()
    $aPos = ControlGetPos($Title, "", "[CLASS:BlueStacksApp; INSTANCE:1]")
    $tPoint = DllStructCreate("int X;int Y")
    DllStructSetData($tPoint, "X", $aPos[0])
    DllStructSetData($tPoint, "Y", $aPos[1])
    _WinAPI_ClientToScreen(WinGetHandle(WinGetTitle($Title)), $tPoint)

    $BSpos[0] = DllStructGetData($tPoint, "X")
    $BSpos[1] = DllStructGetData($tPoint, "Y")
EndFunc   ;==>getBSPos

Func _PixelGetColor_GetPixel($iX, $iY)
    Local $aPixelColor = _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Return Hex($aPixelColor, 6)
EndFunc   ;==>_PixelGetColor_GetPixel

Func _ColorCheckVariation($nColor1, $nColor2, $sVari = 5)
    Local $Red1, $Red2, $Blue1, $Blue2, $Green1, $Green2

    $Red1 = Dec(StringMid(String($nColor1), 1, 2))
    $Blue1 = Dec(StringMid(String($nColor1), 3, 2))
    $Green1 = Dec(StringMid(String($nColor1), 5, 2))

    $Red2 = Dec(StringMid(String($nColor2), 1, 2))
    $Blue2 = Dec(StringMid(String($nColor2), 3, 2))
    $Green2 = Dec(StringMid(String($nColor2), 5, 2))

    If Abs($Blue1 - $Blue2) > $sVari Then Return False
    If Abs($Green1 - $Green2) > $sVari Then Return False
    If Abs($Red1 - $Red2) > $sVari Then Return False
    Return True
EndFunc   ;==>_ColorCheckVariation
Reply
#2
Most likely you are not using the correct coords in your pixelsearch...
How did you get those coords?
Reply
#3
(02-10-2015, 04:47 PM)Henk500 Wrote:  Most likely you are not using the correct coords in your pixelsearch...
How did you get those coords?

I am using Control Viewer.
Reply
#4
(02-10-2015, 11:32 PM)Snarg Wrote:  
(02-10-2015, 04:47 PM)Henk500 Wrote:  Most likely you are not using the correct coords in your pixelsearch...
How did you get those coords?

I am using Control Viewer.

I had some issues to... the x coordinate was not the coordinate i expected.
in my screenshot, $x=1 was the 3rd pixel.. I expected $x=1 to be the 2nd pixel ( and $x=0) the first pixel
Reply
#5
(02-11-2015, 12:10 AM)Henk500 Wrote:  I had some issues to... the x coordinate was not the coordinate i expected.
in my screenshot, $x=1 was the 3rd pixel.. I expected $x=1 to be the 2nd pixel ( and $x=0) the first pixel

I can understand that. There is a bit of an offset with the coordinates. But I gave it a decent sized search area with the pixel I am looking for just about in the middle of the box.

Code:
Local $TrainPos = _PixelSearch(625, 457, 686, 520, Hex(0x885733, 6), 5)

Here is my top left coordinates:
[Image: rZmnySe.png]

And here is my bottom right:
[Image: s0klVtR.png]

Do I have the coordinates wrong in the function call?
Reply
#6
in captureregion, change this value with your BS resolution

.....$iRight = 860, $iBottom = 720....
Reply
#7
(02-11-2015, 02:31 AM)safar46 Wrote:  in captureregion, change this value with your BS resolution

.....$iRight = 860, $iBottom = 720....

It's always the blatantly obvious, isn't it? Thank you.
Reply
#8
(sigh) Still failing Sad

Sorry for the wall of code, but here is the whole thing. All it should do is click a barracks and find the 'train troops' button.

Code:
#include <GDIPlus.au3>
#include <WinAPIProc.au3>
#include <ScreenCapture.au3>
#include <ColorConstants.au3>
#include <Misc.au3>

Opt("MouseClickDelay", 10)
Opt("MouseClickDownDelay", 10)

Global $hBitmap; Image for pixel functions
Global $hHBitmap; Handle Image for Pixel Functions

Global $BSpos[2] ; Inside BlueStacks positions relative to the screen

Global $ichkBackground = 0

$Title = "BlueStacks App Player for Windows (beta-1)" ; Window name
$Full = WinGetTitle ($Title) ; Get The Full Title..
$HWnD = WinGetHandle ($Full) ; Get The Handle
WinActivate ($HWnD)
WinMove ($HWnD, "", 0, 0)

Global $RunState = True

;Barrak 01 - 131, 309
;Barrak 02 - 296, 46
;Barrak 03 - 838, 50
;Barrak 04 - 994, 314

HotKeySet ("{F7}", "Train")

While 1
   Sleep (100)
WEnd

Func Train()
       While 1
            If _Sleep(500) Then ExitLoop

            Click(1, 1) ;Click Away

            If _Sleep(500) Then ExitLoop

            Click(131, 309) ;Click Barrack 01

            If _Sleep(500) Then ExitLoop

            Local $TrainPos = _PixelSearch(625, 457, 686, 520, Hex(0x885733, 6), 5) ;Finds Train Troops button
            If IsArray($TrainPos) = False Then
                ;SetLog("Barrack " & $i + 1 & " is not available")
                MsgBox ($MB_SYSTEMMODAL, "Barracks is not available", "")
                If _Sleep(500) Then ExitLoop
            Else
                MsgBox ($MB_SYSTEMMODAL, "Found it!!", "")
                ;Click($TrainPos[0], $TrainPos[1]) ;Click Train Troops button
            EndIf
    WEnd
EndFunc   ;==>Train

Func Click($x, $y, $times = 1, $speed = 0)
   If $times <> 1 Then
      For $i = 0 To ($times - 1)
         ControlClick($HWnD, "", "", "left", "1", $x, $y)
         If _Sleep($speed, False) Then ExitLoop
      Next
   Else
      ControlClick($HWnD, "", "", "left", "1", $x, $y)
   EndIf
EndFunc   ;==>Click

Func _Sleep($iDelay, $iSleep = True)
   Local $iBegin = TimerInit()
   While TimerDiff($iBegin) < $iDelay
      If $RunState = False Then Return True
      If $iSleep = True Then Sleep(100)
   WEnd
   Return False
EndFunc   ;==>_Sleep

Func _PixelSearch($iLeft, $iTop, $iRight, $iBottom, $iColor, $iColorVariation)
    _CaptureRegion($iLeft, $iTop, $iRight, $iBottom)
    For $x = $iRight - $iLeft To 0 Step -1
        For $y = $iBottom - $iTop To 0 Step -1
            Local $nColor1 = $iColor
            Local $nColor2 = _PixelGetColor_GetPixel($x, $y)
            If _ColorCheckVariation($nColor1, $nColor2, $iColorVariation) Then
                Local $Pos[2] = [$iLeft + $x, $iTop + $y]
                Return $Pos
            EndIf
        Next
    Next
    Return 0
EndFunc   ;==>_PixelSearch

Func _CaptureRegion($iLeft = 0, $iTop = 0, $iRight = 599, $iBottom = 1065, $ReturnBMP = False)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hHBitmap)

    If $ichkBackground = 1 Then
        Local $iW = Number($iRight) - Number($iLeft), $iH = Number($iBottom) - Number($iTop)

        Local $hDC_Capture = _WinAPI_GetWindowDC(ControlGetHandle("BlueStacks App Player", "", "[CLASS:BlueStacksApp; INSTANCE:1]"))
        Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
        $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $iW, $iH)
        Local $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)

        DllCall("user32.dll", "int", "PrintWindow", "hwnd", $HWnD, "handle", $hMemDC, "int", 0)
        _WinAPI_SelectObject($hMemDC, $hHBitmap)
        _WinAPI_BitBlt($hMemDC, 0, 0, $iW, $iH, $hDC_Capture, $iLeft, $iTop, 0x00CC0020)

        Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)

        _WinAPI_DeleteDC($hMemDC)
        _WinAPI_SelectObject($hMemDC, $hObjectOld)
        _WinAPI_ReleaseDC($HWnD, $hDC_Capture)
    Else
        getBSPos()
        $hHBitmap = _ScreenCapture_Capture("", $iLeft + $BSpos[0], $iTop + $BSpos[1], $iRight + $BSpos[0], $iBottom + $BSpos[1])
        Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    EndIf

    If $ReturnBMP Then Return $hBitmap
EndFunc   ;==>_CaptureRegion

Func getBSPos()
    $aPos = ControlGetPos($Title, "", "[CLASS:BlueStacksApp; INSTANCE:1]")
    $tPoint = DllStructCreate("int X;int Y")
    DllStructSetData($tPoint, "X", $aPos[0])
    DllStructSetData($tPoint, "Y", $aPos[1])
    _WinAPI_ClientToScreen(WinGetHandle(WinGetTitle($Title)), $tPoint)

    $BSpos[0] = DllStructGetData($tPoint, "X")
    $BSpos[1] = DllStructGetData($tPoint, "Y")
EndFunc   ;==>getBSPos

Func _PixelGetColor_GetPixel($iX, $iY)
    Local $aPixelColor = _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Return Hex($aPixelColor, 6)
EndFunc   ;==>_PixelGetColor_GetPixel

Func _ColorCheckVariation($nColor1, $nColor2, $sVari = 5)
    Local $Red1, $Red2, $Blue1, $Blue2, $Green1, $Green2

    $Red1 = Dec(StringMid(String($nColor1), 1, 2))
    $Blue1 = Dec(StringMid(String($nColor1), 3, 2))
    $Green1 = Dec(StringMid(String($nColor1), 5, 2))

    $Red2 = Dec(StringMid(String($nColor2), 1, 2))
    $Blue2 = Dec(StringMid(String($nColor2), 3, 2))
    $Green2 = Dec(StringMid(String($nColor2), 5, 2))

    If Abs($Blue1 - $Blue2) > $sVari Then Return False
    If Abs($Green1 - $Green2) > $sVari Then Return False
    If Abs($Red1 - $Red2) > $sVari Then Return False
    Return True
EndFunc   ;==>_ColorCheckVariation
Reply
 


Forum Jump:


Users browsing this thread: 1 Guest(s)

About The Bytecode Club

We're a community focused on Reverse Engineering, we try to target Java/Android but we also include other langauges/platforms. We pride ourselves in supporting and free and open sourced applications.

Website