param ( [Parameter(Mandatory=$false)] [string]$instanceIP ) if(-not $instanceIP){$instanceIP = "10.0.211.121"} $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 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 $midX =[math]::Round($x1+$width/2) $midY =[math]::Round($y1+$height/2) [PSCustomObject]@{ Text = $_.text Coords = "$midX $midY" } } $Element = $Data | Where-Object {$_.Text -and $_.Text.ToLower() -eq $text} $coordsForText=$Element.Coords return $coordsForText } function Find-Element($xml, $keyword) { if (-not $xml -is [System.Xml.XmlDocument] -or -not $keyword) { return $null } $sanitizedKeyword = $keyword.Replace("'", "''").ToLower() $query = "//node[contains(translate(@text, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword') or contains(translate(@content-desc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '$sanitizedKeyword')]" return $xml.SelectSingleNode($query) } function Wait-For-ScreenChange($adbTarget, $initialHash, [ref]$newXmlData) { $xmlContent = Get-Content -Raw -Path "$global:LDPlayerPath\screen.xml" -Encoding UTF8 $Xml = [xml]$xmlContent $Hash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash $timeoutSeconds = 10 logger("Aguardando alteração 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("TIMEOUT: A tela não mudou após $timeoutSeconds segundos."); return $false } function Invoke-TapAction($adbTarget, $xml, $keyword) { $element = Find-Element -xml $xml -keyword $keyword if (-not $element) { logger("Elemento '$keyword' para tocar não foi encontrado."); return $false } $bounds = $element.bounds if ($bounds -notmatch '\[(\d+),(\d+)\]\[(\d+),(\d+)\]') { logger("Formato de 'bounds' inválido: $bounds"); return } $xMid = ([int]$Matches[1] + [int]$Matches[3]) / 2 $yMid = ([int]$Matches[2] + [int]$Matches[4]) / 2 logger("Ação: Tocando em '$($element.text)'...") adb -s $instanceIP shell input tap "$xMid $yMid" *>$null return } function Handle-SystemDialogs() { $xmlContent = Get-Content -Raw -Path "$global:LDPlayerPath\screen.xml" -Encoding UTF8 $Xml = [xml]$xmlContent $Hash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash # Verifica se o diálogo "não está a responder" (ANR) está na tela if ((Find-Element -xml $xml -keyword "não está a responder") -or (Find-Element -xml $xml -keyword "UI not responsive")) { logger("Detectado diálogo 'IU não está a responder'. Tentando tocar em 'Aguardar'.") $initialHash = $Hash if (Find-Element -xml $xml -keyword "Aguardar") { $tappedWait = Invoke-TapAction -adbTarget $adbTarget -xml $xml -keyword "Aguardar" } else { $tappedWait = Invoke-TapAction -adbTarget $adbTarget -xml $xml -keyword "wait" } if ($tappedWait) { # Espera o diálogo desaparecer $dialogDismissed = Wait-For-ScreenChange -initialHash $initialHash -newXmlData ([ref]$screenData) if (-not $dialogDismissed) { logger("Tocou em 'Aguardar', mas o diálogo não desapareceu.") } return $true # Indica que um diálogo foi tratado e o passo deve ser repetido } else { logger("Diálogo ANR detectado, mas o botão 'Aguardar' não foi encontrado.") return } } logger("Não houve irresponsividade") return } function Get-ScreenData() { for ($attempt = 1; $attempt -le 3; $attempt++) { try { logger("Capturando hierarquia da UI (Tentativa $attempt)...") Start-Sleep -Milliseconds 250 logger("$dumpOutput") $cnt=0 while($true){ logger("tentando fazer dump") logger("iteration: $cnt") #start-process "adb" -ArgumentList "-s $instanceIP shell uiautomator dump" -RedirectStandardOutput $global:LDPlayerPath\adbOut1.txt -RedirectStandardError $global:LDPlayerPath\adbOut2.txt $dumpOutput = adb -s $instanceIP shell uiautomator dump 2> $null #$dumpOutput = (cat $global:LDPlayerPath\adbOut1.txt) #$dumpError = (cat $global:LDPlayerPath\adbOut2.txt) logger("saida do commando dump: $dumpOutput") if(($dumpOutput -Like "*dumped*")) { logger("Comando 'uiautomator dump' deu successo. Saindo do loop") break} if(($cnt -gt 12) -and !($dumpOutput)){ logger("too many retries, going ahead anyway and breaking loop") break } $instanceIP | Out-File -FilePath "C:\Ldplayer\Ldplayer9\restartADB.txt" 2>$null logger("deu kill-server, pois deu erro o dump") adb start-server *> $null $cnt1=0 while($true){ if($cnt1 -gt 10){logger("breaking connect loop since retries exceeded");break} $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") $instanceIP | Out-File -FilePath "C:\Ldplayer\Ldplayer9\restartADB.txt" 2>$null Start-Sleep -Milliseconds 1000 } $cnt1+=1 } logger("deu connect") $cnt+=1 } if ($dumpOutput -match 'dumped to: (/[\w/.-]+\.xml)') { $dumpPath = $Matches[1].Trim() $fileName = $dumpPath.Split('/')[2] } else { logger("Não foi possível encontrar o caminho do dump XML. Tentando novamente...") Start-Sleep -Seconds 1; continue } if (Test-Path ".\$fileName") { Remove-Item ".\$fileName" } $fileNameLocal = "C:\LDPlayer\LDPlayer9\screen.xml" logger("começando baixar o arquivo $fileName") while($true){ $fetchXML=adb -s $instanceIP pull $dumpPath $fileNameLocal 2>$null logger($fetchXML) if($fetchXML -notLike "*1 file pulled*"){logger("error found");continue}else{logger("sucess");break} logger("done") } if ((Test-Path "$fileNameLocal") -and (Get-Item "$fileNameLocal").Length -gt 0) { $xmlContent = Get-Content -Raw -Path $fileNameLocal -Encoding UTF8 return <#return [PSCustomObject]@{ Xml = [xml]$xmlContent Hash = (Get-FileHash -Algorithm MD5 -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($xmlContent)))).Hash }#> } } catch { logger("Exceção na tentativa $attempt. $_"); Start-Sleep -Seconds 1 } } logger("Falha crítica ao capturar a UI após 3 tentativas.") return $null } adb connect $instanceIP *> $null Get-ScreenData Handle-SystemDialogs