Files
adbAutomation/actions.ps1

251 lines
9.5 KiB
PowerShell

param (
[Parameter(Mandatory=$true)]
[string[]]$action,
[Parameter(Mandatory=$false)]
[switch]$waitForChange,
[Parameter(Mandatory=$false)]
[int]$numberOfPresses,
[Parameter(Mandatory=$false)]
[string]$instanceIP,
[Parameter(Mandatory=$false)]
[switch]$fakeTap
)
if(-not $instanceIP){$instanceIP = "10.0.211.121"}
$DEBUG = 0
$global:LDPlayerPath ="C:\Ldplayer\LDplayer9"
function logger($logMessage) {
[int]$number = (get-content -path "$global:LDPlayerPath\index_count.txt")
if($number -gt 21){ $number=0}
$instanceList = Get-Content -Path "$global:LDPlayerPath\instanceList.txt"
$instanceNumber = $instanceList[$number]
$instanceData = (cat C:\Ldplayer\LDplayer9\vms\config\leidian${instanceNumber}.config)
$convertedData = $instanceData | ConvertFrom-Json
$name = $convertedData."statusSettings.playerName"
$count = $number+1
$scriptName = Split-Path -Leaf $PSCommandPath
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss.fff"
$timestampedLogMessage = $timestamp + "-$name, ($count/22)-$scriptName-PID: ${PID}-:" + $logMessage
$logFilePath = "$global:LDPlayerPath\LDAutoLog.txt"
$fs = New-Object System.IO.FileStream($logFilePath, [System.IO.FileMode]::Append, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Read)
$sw = New-Object System.IO.StreamWriter($fs)
try {
$sw.WriteLine($timestampedLogMessage)
} finally {
$sw.Close()
$fs.Close()
}
}
function Get-ScreenshotData($text) {
adb connect $instanceIP *>$null
$status = & adb devices
if ($status -eq "${instanceIP}:5555 offline") {
$instanceIP | Out-File -FilePath "C:\Ldplayer\Ldplayer9\restartADB.txt"
adb connect $instanceIP *>null
}
adb -s $instanceIP exec-out screencap -p > $global:LDPlayerPath\screenshot.png *>$null
& "C:\Program Files\Tesseract-OCR\tesseract.exe" "$global:LDPlayerPath\screenshot.png" "$global:LDPlayerPath\tesseract" -l eng tsv *>$null
$tsvFile = "$global:LDPlayerPath\tesseract.tsv"
$wordCoords = Get-Content $tsvFile | ConvertFrom-Csv -Delimiter "`t"
$wordCoords | Where-Object ($_.level -eq 5) | Select-Object text, left, top, width, height
$Data = $wordCoords | ForEach-Object {
$x1 =[int]$_._left
$y1 =[int]$_.top
$width = [int]$_.width
$height = [int]$_.height
$z1 = $width/2
$z2 = $height/2
$midX =[math]::Round($x1+$z1)
$midY =[math]::Round($y1+$z2)
[PSCustomObject]@{
Text = $_.text
Coords = "$midX $midY"
}
}
$Element = $Data | Where-Object {$_.Text -and $_.Text.ToLower() -eq $text}
$coordsForText=$Element.Coords
if($coordsForText[1]){ return $coordsForTest[0]}
return $coordsForText
}
function Find-Element($xml, $keyword) {
if (-not $xml -is [System.Xml.XmlDocument] -or -not $keyword) { return $null }
$sanitizedKeyword = $keyword.Replace("'", "''").ToLower()
if($fakeTap){
Write-Host "faketap"
$query = "//node[contains(translate(@text, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword') or contains(translate(@content-desc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword')]"
} else {
$query = "//node[@class='android.widget.Button' and (contains(translate(@text, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword') or contains(translate(@content-desc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword'))]"
}
$element = $xml.SelectSingleNode($query)
return $xml.SelectSingleNode($query)
}
function Wait-For-ScreenChange($initialHash, [ref]$newXmlData) {
$timeoutSeconds = 10
logger("Aguardando alteracao na tela (timeout de $timeoutSeconds segundos)...")
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
while ($stopwatch.Elapsed.TotalSeconds -lt $timeoutSeconds) {
$currentScreenData = Get-ScreenData -adbTarget $adbTarget
if ($currentScreenData -and $currentScreenData.Hash -ne $initialHash) {
$stopwatch.Stop(); logger("Tela alterada! Prosseguindo..."); $newXmlData.Value = $currentScreenData; return $true
}
Start-Sleep -Seconds 1
}
$stopwatch.Stop(); logger("!!!ERROR: TIMEOUT: A tela nao mudou apos $timeoutSeconds segundos."); return $false
}
function Invoke-TapAction($adbTarget, $xml, $keyword) {
$element = Find-Element -xml $xml -keyword $keyword
if (-not $element) { logger("!!WARNING: Elemento '$keyword' para tocar nao foi encontrado."); return $false }
$bounds = $element.bounds
if ($bounds -notmatch '\[(\d+),(\d+)\]\[(\d+),(\d+)\]') { logger("!!WARNING: Formato de 'bounds' invalido: $bounds"); return $false }
$xMid = ([int]$Matches[1] + [int]$Matches[3]) / 2
$yMid = ([int]$Matches[2] + [int]$Matches[4]) / 2
logger("Acao: Tocando em '$element'...")
adb -s $instanceIP shell input tap "$xMid $yMid"
return $true
}
function Invoke-TypeAction($adbTarget, $textToType) {
$formattedText = $textToType.Replace(' ', '%s')
logger("Acao: Digitando o texto '$textToType'...")
adb -s $instanceIP shell input text "'$formattedText'" 2>&1
return $true
}
if($waitForChange) {
$xmlContent = (Get-Content -Path $global:LDPlayerPath\screen.xml)
$initialHash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash
}
$actionType = $action.split('\s')[0]
$cnt=0
while($true){
if($cnt -gt 50){return $false}
$connected = adb connect $instanceIP 2>$null
logger("$connected")
$isOnline = adb devices 2> $null
$pattern = [regex]::Escape($instanceIP) + ':\d+\s+device'
if($isOnline -match $pattern){
break
}else{
logger("falhou, tenando connectar de novo")
& tskill adb
Start-Sleep -Milliseconds 1000
$cnt+=1
}
}
switch ($actionType) {
"tap" {
& $global:LDPlayerPath\test.ps1 -instanceIP $instanceIP
$actionType = $action.split('\s')[0]
$keyword = $action.split('\s')[1]
$xmlFile = get-content -path "$global:LDPlayerPath\screen.xml"
$xml = [xml]$xmlFile
logger("$actionType")
$element = Find-Element -xml $xml -keyword $keyword
if (-not $element) { logger("!!WARNING: Elemento '$keyword' para tocar nao foi encontrado."); return $false}
$bounds = $element.bounds
if ($bounds -notmatch '\[(\d+),(\d+)\]\[(\d+),(\d+)\]') { logger("!!WARNING: Formato de 'bounds' invalido: $bounds"); return }
$xMid = ([int]$Matches[1] + [int]$Matches[3]) / 2
$yMid = ([int]$Matches[2] + [int]$Matches[4]) / 2
logger("Acao: Tocando em '$keyword'...")
adb -s $instanceIP shell input tap "$xMid $yMid" 2>&1
}
"tap_image" {
$actionType = $action.split('\s')[0]
$keyword = $action.split('\s')[1]
$keyword
$coords = Get-ScreenshotData($keyword)
if (-not $coords) { logger("!!WARNING: Elemento '$keyword' para tocar nao foi encontrado."); return}
if($coords[1]){$newCoords=$coords[1]}else{$newCoords=$coords}
logger("Acao: Tocando em '$keyword' $newCoords...")
$tapCommand = adb -s $instanceIP shell input tap $newCoords 2>&1
$tapCommand
$coords
} else {logger("not clickable and since not mentioned, not forcing")}
"type" {
$textToType = $action[1]
logger("$actionType")
$formattedText = $textToType
logger("Acao: Digitando o texto '$textToType'...")
$letters = $formattedText.ToCharArray()
foreach($char in $letters) {
$charInterval = get-random -minimum .1 -maximum 50
logger("$char")
adb -s $instanceIP shell input text "'$char'" *>$null
start-sleep -Milliseconds $charInterval
}
}
"key" {
$keyEventName = $action[1]
if (-not $numberOfPresses) {$numberOfPresses = 1}
logger("$actionType")
logger("$keyEventName")
$KeyEventMapJson = get-content -path "$global:LDPlayerPath\adb_key_events.json" -Raw
$keyEventMap = $KeyEventMapJson | ConvertFrom-Json
if ($keyEventMap.key_events.($keyEventName)) {
$keyCode = $keyEventMap.key_events.$keyEventName
for ($i = $numberOfPresses; $i -gt 0; $i--){
logger("Acao: Enviando evento de tecla '$keyEventName' $i/$numberOfPresses (codigo $keyCode)...")
adb -s $instanceIP shell input keyevent $keyCode *>$null
}
} else { logger("!!WARNING: Evento de tecla '$keyEventName' desconhecido."); }
}
"open" {
$appName = $action[1]
logger("$actionType")
logger("$appName")
$csvData = Import-Csv -Path "$global:LDPlayerPath\appReference.csv"
$appReference = @{}
$csvData | ForEach-Object {
$appReference[$_.Key] = $_.Value
}
if ($appReference[$appName]) {
$appCode = $appReference[$appName]
logger("Acao: Abrindo app '$appName' (codigo $appCode)...")
$adbOUT = & adb -s $instanceIP shell monkey -p $appCode 1 2>&1
logger("$adbOUT")
if($adbOUT -like "*No activities found to run*") {return $false}
} else { logger("!!WARNING: App '$appCode' desconhecido.")}
}
}