# ============================================================
#  BadRO - Atualizador v3 (roda no PC do jogador)
#  Baixa as atualizacoes pendentes (em ordem), confere cada uma,
#  aplica na pasta do BadRO e abre o jogo.
#
#  DOIS MODOS DE USO:
#   1) Modo janela (como sempre foi): abrindo o Atualizar-BadRO.bat.
#      Mostra tudo numa janela preta e abre o jogo no final.
#   2) Modo silencioso (-Silencioso): usado pelo BadRO Patcher, a
#      interface bonita. Sem janela e sem teclado, entao:
#        - NUNCA pergunta nada (nada de "Pressione ENTER")
#        - NUNCA abre o jogo (quem abre e o botao JOGAR do patcher)
#        - Escreve o andamento em linhas "##STATUS" e "##PROGRESSO"
#          que o patcher le para mexer na barra e no texto de status.
#
#  Novidades da v3:
#   - modo silencioso para o BadRO Patcher
#   - baixa de https://badro.online (com o endereco antigo de reserva)
#   - forca TLS 1.2 (Windows antigo nao abre HTTPS sem isso)
#
#  Novidades da v2:
#   - mostra o andamento do download e tenta de novo sozinho (3x)
#   - se a extracao normal falhar, extrai arquivo por arquivo
#   - se algo ficar de fora, baixa a atualizacao inteira de novo
#     na proxima vez (nada fica quebrado para sempre)
#   - confere se a traducao esta no lugar e se auto-conserta
#   - grava um diario em atualizador.log (mande pro Pedro se
#     algo der errado)
#   - avisa se o Windows esta com a opcao "Beta: UTF-8" ligada
#     (ela faz o jogo aparecer em coreano) e ensina a desligar
#
#  (Este arquivo fica DENTRO da pasta BadRO, junto do BadRO.exe.
#   Um patch pode conter um atualizar.ps1 novo: o PowerShell le o
#   script inteiro antes de rodar, entao sobrescrever e seguro.)
# ============================================================
param(
  [switch]$Silencioso,   # chamado pelo BadRO Patcher: sem perguntas, sem abrir o jogo
  [switch]$SemJogo       # so nao abre o jogo no final (continua mostrando a janela)
)

$ErrorActionPreference = "Stop"
$ProgressPreference    = "SilentlyContinue"  # a barra de progresso do PowerShell deixa o download lento

# HTTPS em Windows mais antigo: sem isto o TLS 1.2 nao e usado e o
# download de https://badro.online falha com "conexao encerrada".
try {
  [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12)
} catch { }

# ---- Configuracao (so muda se o endereco do servidor mudar) ----
# O primeiro que responder e o usado. O segundo e reserva para o caso
# de o dominio estar fora do ar ou o DNS do jogador estar com problema.
$Bases = @(
  "https://badro.online/patches",
  "http://179.198.118.161:8080/patches"
)

# ---- Caminhos (a pasta do BadRO e onde este script esta) ----
$Root    = Split-Path -Parent $MyInvocation.MyCommand.Path
$Exe     = Join-Path $Root "BadRO.exe"
$VerFile = Join-Path $Root "patch-version.txt"
$LogFile = Join-Path $Root "atualizador.log"
if (-not $env:TEMP) { $env:TEMP = [System.IO.Path]::GetTempPath() }

# Pasta da traducao em ingles. O nome parece estranho de proposito:
# e assim que o jogo procura a pasta num Windows normal.
$NomePastaTraducao = -join ([char]0xC0,[char]0xAF,[char]0xC0,[char]0xFA,[char]0xC0,[char]0xCE,
                            [char]0xC5,[char]0xCD,[char]0xC6,[char]0xE4,[char]0xC0,[char]0xCC,
                            [char]0xBD,[char]0xBA)
$PastaTraducao = Join-Path (Join-Path (Join-Path $Root "data") "texture") $NomePastaTraducao

$script:Problemas       = @()
$script:VersaoTravada   = $false   # vira $true se algum patch nao entrar completo
$script:UltimoPct       = -1
$script:BytesFeitos     = 0
$script:BytesTotalGeral = 0

function Log($msg) {
  try {
    Add-Content -LiteralPath $LogFile -Value ("[{0}] {1}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $msg)
  } catch { }
}

# ---- Conversa com o BadRO Patcher -------------------------------
# No modo silencioso o patcher le a nossa saida linha a linha.
# Ele so olha as linhas que comecam com "##". O resto vai pro log dele.
function Status($txt) {
  if ($Silencioso) { Write-Host ("##STATUS " + $txt) }
}

function Progresso($pct) {
  if (-not $Silencioso) { return }
  $p = [int]$pct
  if ($p -lt 0)   { $p = 0 }
  if ($p -gt 100) { $p = 100 }
  if ($p -ne $script:UltimoPct) {
    $script:UltimoPct = $p
    Write-Host ("##PROGRESSO " + $p)
  }
}

# Substitui o antigo Read-Host: no modo silencioso nao ha teclado,
# entao esperar por ENTER travaria o patcher para sempre.
function Pausa($msg) {
  if ($Silencioso) {
    if ($msg) { Log ("(modo silencioso, nao pergunto) " + $msg) }
    return
  }
  Read-Host $msg | Out-Null
}

function Problema($msg) {
  $script:Problemas += $msg
  Log ("PROBLEMA: " + $msg)
  if (-not $Silencioso) { Write-Host ("     ATENCAO: " + $msg) }
}

function Versao-Local {
  if (Test-Path -LiteralPath $VerFile) {
    try { return [int](Get-Content -LiteralPath $VerFile -Raw) } catch { return 0 }
  }
  return 0
}

function Gravar-Versao($n) {
  try { Set-Content -LiteralPath $VerFile -Value $n } catch {
    Problema ("nao consegui anotar a versao " + $n + " (disco cheio?). Detalhe: " + $_.Exception.Message)
  }
}

function Abrir-Jogo {
  # No modo silencioso quem abre o jogo e o botao JOGAR do patcher.
  if ($Silencioso -or $SemJogo) {
    Log "nao abro o jogo (modo silencioso / SemJogo)"
    return
  }
  if (Test-Path -LiteralPath $Exe) {
    try { Start-Process -FilePath $Exe -WorkingDirectory $Root }
    catch {
      Log ("nao consegui abrir o jogo: " + $_.Exception.Message)
      Write-Host "Nao consegui abrir o jogo sozinho - abra o BadRO.exe na pasta do jogo."
    }
  } else {
    Write-Host "AVISO: nao achei o BadRO.exe nesta pasta. Rode o atualizador de novo ou fale com o Pedro."
  }
}

# Quem abre pelo Atualizar-BadRO.bat antigo nunca ficaria sabendo que agora
# existe o BadRO Patcher. Entao, na primeira vez que ele aparecer na pasta,
# criamos um atalho na Area de Trabalho e avisamos o jogador.
function Avisar-Do-Patcher {
  if ($Silencioso) { return }
  $patcher = Join-Path $Root "BadROPatcher.exe"
  if (-not (Test-Path -LiteralPath $patcher)) { return }
  $marca = Join-Path $Root "badro-atalho.txt"
  if (Test-Path -LiteralPath $marca) { return }
  $criou = $false
  try {
    $mesa = [Environment]::GetFolderPath("Desktop")
    if ($mesa) {
      $lnk = Join-Path $mesa "BadRO.lnk"
      $ws  = New-Object -ComObject WScript.Shell
      $at  = $ws.CreateShortcut($lnk)
      $at.TargetPath       = $patcher
      $at.WorkingDirectory = $Root
      $at.IconLocation     = $patcher
      $at.Description      = "BadRO Patcher - atualiza e abre o jogo"
      $at.Save()
      $criou = $true
    }
  } catch { Log ("nao consegui criar o atalho na area de trabalho: " + $_.Exception.Message) }
  try { Set-Content -LiteralPath $marca -Value "Arquivo de controle do atualizador. Pode apagar." } catch { }
  Write-Host ""
  Write-Host "  +---------------------------------------------------------------+"
  Write-Host "  |  NOVIDADE: o BadRO agora tem um atualizador bonito!            |"
  if ($criou) {
    Write-Host "  |  Criei um atalho chamado 'BadRO' na sua Area de Trabalho.      |"
    Write-Host "  |  A partir de agora abra o jogo por ele.                        |"
  } else {
    Write-Host "  |  Na pasta do jogo procure o 'BadROPatcher' e abra por ele      |"
    Write-Host "  |  a partir de agora.                                            |"
  }
  Write-Host "  +---------------------------------------------------------------+"
  Log ("avisei do BadRO Patcher (atalho criado: " + $criou + ")")
}

function Espaco-Livre($caminho) {
  try {
    $raiz = [System.IO.Path]::GetPathRoot([System.IO.Path]::GetFullPath($caminho))
    if (-not $raiz) { return $null }
    return (New-Object System.IO.DriveInfo($raiz)).AvailableFreeSpace
  } catch { return $null }
}

# Baixa mostrando o andamento; tenta 3x; desiste se ficar 2 min sem andar.
function Baixar($url, $destino, $mbTotal) {
  for ($tent = 1; $tent -le 3; $tent++) {
    $wc = $null
    try {
      Remove-Item -LiteralPath $destino -Force -ErrorAction SilentlyContinue
      $wc = New-Object System.Net.WebClient
      $wc.Headers.Add("User-Agent", "BadRO-Atualizador")
      $tarefa = $wc.DownloadFileTaskAsync($url, $destino)
      $ultimoMb = -1.0
      $parado   = 0
      while (-not $tarefa.IsCompleted) {
        Start-Sleep -Milliseconds 500
        $bytes = 0
        try { $bytes = (Get-Item -LiteralPath $destino -ErrorAction Stop).Length } catch { }
        $mb = [math]::Round($bytes / 1MB, 1)
        if ($mb -gt $ultimoMb) {
          if (-not $Silencioso) {
            Write-Host ("`r     baixando... " + $mb + " / " + $mbTotal + " MB (nao feche esta janela)   ") -NoNewline
          }
          $ultimoMb = $mb
          $parado   = 0
        } else {
          $parado++
          if ($parado -ge 240) { $wc.CancelAsync(); throw "o download ficou 2 minutos sem andar" }
        }
        # Barra do patcher: quanto ja andou de TUDO que falta baixar.
        # Vai so ate 97% - os ultimos 3% sao a instalacao e as conferencias,
        # senao a barra enche antes da hora e o jogador acha que travou.
        if ($script:BytesTotalGeral -gt 0) {
          Progresso ((($script:BytesFeitos + $bytes) * 97.0) / $script:BytesTotalGeral)
        }
      }
      if ((-not $Silencioso) -and ($ultimoMb -ge 0)) { Write-Host "" }
      if ($tarefa.IsFaulted -or $tarefa.IsCanceled) {
        $motivo = "o download falhou"
        if ($tarefa.Exception -and $tarefa.Exception.InnerException) { $motivo = $tarefa.Exception.InnerException.Message }
        throw $motivo
      }
      return $true
    } catch {
      if (-not $Silencioso) { Write-Host "" }
      Log ("download falhou (tentativa " + $tent + "/3) " + $url + " : " + $_.Exception.Message)
      if ($tent -lt 3) {
        Status "o download falhou, tentando de novo"
        if (-not $Silencioso) { Write-Host "     (o download falhou, tentando de novo...)" }
        Start-Sleep -Seconds (3 * $tent)
      }
    } finally {
      if ($wc) { $wc.Dispose() }
    }
  }
  return $false
}

function Conferir-Sha($arquivo, $shaEsperado) {
  if (-not (Test-Path -LiteralPath $arquivo)) {
    Log "o arquivo baixado sumiu antes da conferencia (antivirus apagou?)"
    return $false
  }
  try {
    $h = (Get-FileHash -LiteralPath $arquivo -Algorithm SHA256).Hash.ToLower()
    return ($h -eq ([string]$shaEsperado).ToLower())
  } catch { return $false }
}

# A pasta da traducao existe e tem arquivos dentro?
function Traducao-Ok {
  if (-not (Test-Path -LiteralPath $PastaTraducao)) { return $false }
  try {
    $um = Get-ChildItem -LiteralPath $PastaTraducao -Recurse -File -ErrorAction Stop | Select-Object -First 1
    return ($null -ne $um)
  } catch { return $false }
}

# Plano B de extracao: arquivo por arquivo, pulando so o que falhar.
# Devolve quantos arquivos ficaram de fora.
function Extrair-UmPorUm($zipPath, $destino) {
  Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Stop
  $sep    = [string][System.IO.Path]::DirectorySeparatorChar
  $falhas = 0
  $zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
  try {
    foreach ($entry in $zip.Entries) {
      $nome = $entry.FullName
      if (-not $nome -or $nome.EndsWith("/") -or $nome.EndsWith("\")) { continue }   # pasta
      if (($nome -split '[/\\]') -contains "..") { Log ("pulando entrada suspeita: " + $nome); continue }
      try {
        $alvo  = Join-Path $destino ($nome -replace "/", $sep)
        $pasta = Split-Path -Parent $alvo
        if ($pasta) { [void][System.IO.Directory]::CreateDirectory($pasta) }
        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $alvo, $true)
      } catch {
        $falhas++
        Log ("nao consegui extrair '" + $nome + "': " + $_.Exception.Message)
      }
    }
  } finally {
    $zip.Dispose()
  }
  return $falhas
}

# O BadROPatcher.exe e quem chama este script. Enquanto ele esta aberto o
# Windows NAO deixa sobrescrever o arquivo dele - mas DEIXA renomear. Entao,
# antes de aplicar o patch, tiramos da frente todo .exe/.dll que estiver em uso.
# Sem isto, um patch que traga um patcher novo nunca entraria e seria baixado
# de novo para sempre.
function Liberar-Arquivos-Em-Uso($zipPath, $destino) {
  try {
    Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Stop
    $sep = [string][System.IO.Path]::DirectorySeparatorChar
    $zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
    try {
      foreach ($entry in $zip.Entries) {
        $nome = $entry.FullName
        if (-not $nome -or $nome.EndsWith("/") -or $nome.EndsWith("\")) { continue }
        if (($nome -split '[/\\]') -contains "..") { continue }
        $alvo = Join-Path $destino ($nome -replace "/", $sep)
        if (-not (Test-Path -LiteralPath $alvo)) { continue }
        $ext = [System.IO.Path]::GetExtension($alvo).ToLower()
        if ($ext -ne ".exe" -and $ext -ne ".dll") { continue }
        # Consigo escrever nele? Se nao, esta em uso.
        $emUso = $false
        try {
          $fs = [System.IO.File]::Open($alvo, "Open", "Write", "None")
          $fs.Close()
        } catch { $emUso = $true }
        if (-not $emUso) { continue }
        try {
          $velho = $alvo + ".velho"
          Remove-Item -LiteralPath $velho -Force -ErrorAction SilentlyContinue
          Rename-Item -LiteralPath $alvo -NewName ([System.IO.Path]::GetFileName($velho)) -Force
          Log ("'" + $nome + "' estava em uso; renomeei para .velho para o novo entrar")
        } catch {
          Log ("nao consegui liberar '" + $nome + "' (em uso): " + $_.Exception.Message)
        }
      }
    } finally { $zip.Dispose() }
  } catch {
    Log ("Liberar-Arquivos-Em-Uso falhou: " + $_.Exception.Message)
  }
}

# Devolve: 0 = tudo certo | N > 0 = N arquivos ficaram de fora | -1 = nao deu de jeito nenhum
function Aplicar-Patch($zipPath) {
  Liberar-Arquivos-Em-Uso $zipPath $Root
  try {
    Expand-Archive -LiteralPath $zipPath -DestinationPath $Root -Force -ErrorAction Stop
    return 0
  } catch {
    Log ("extracao normal falhou: " + $_.Exception.Message + " -- tentando arquivo por arquivo")
    if (-not $Silencioso) { Write-Host "     (a extracao normal falhou; tentando arquivo por arquivo...)" }
    try {
      return (Extrair-UmPorUm $zipPath $Root)
    } catch {
      Log ("extracao arquivo por arquivo tambem falhou: " + $_.Exception.Message)
      return -1
    }
  }
}

# ============================================================
if (-not $Silencioso) {
  Write-Host "==============================="
  Write-Host "   BadRO - Atualizador"
  Write-Host "==============================="
}
Status "iniciando"
Progresso 0

# So uma janela do atualizador por vez
$script:Trava = $null
try {
  $script:Trava = New-Object System.Threading.Mutex($false, "BadRO-Atualizador-trava")
  $sozinho = $false
  try { $sozinho = $script:Trava.WaitOne(0) } catch { $sozinho = $true }  # a outra janela morreu no meio: pode seguir
  if (-not $sozinho) {
    Status "o atualizador ja esta aberto em outra janela"
    Log "ja havia outro atualizador rodando; sai sem fazer nada"
    if (-not $Silencioso) {
      Write-Host "O atualizador ja esta aberto em outra janela. Use a que ja estava aberta."
      Pausa "Pressione ENTER para fechar esta"
      exit 0
    }
    # No patcher: sai com erro para ele nao dizer "atualizacao concluida".
    exit 1
  }
} catch { }

# Log muito grande? Guarda o antigo e comeca um novo (nunca no meio de uma execucao)
try {
  if ((Test-Path -LiteralPath $LogFile) -and ((Get-Item -LiteralPath $LogFile).Length -gt 500KB)) {
    Move-Item -LiteralPath $LogFile -Destination ($LogFile + ".antigo") -Force
  }
} catch { }
Log ("----- atualizador iniciado" + $(if ($Silencioso) { " (modo patcher)" } else { "" }) + " -----")

# Limpa sobras de atualizacoes anteriores (arquivos que estavam em uso na hora).
try {
  Get-ChildItem -LiteralPath $Root -Filter "*.velho" -File -ErrorAction SilentlyContinue |
    ForEach-Object { Remove-Item -LiteralPath $_.FullName -Force -ErrorAction SilentlyContinue }
} catch { }

# Estamos mesmo na pasta do jogo?
$pareceJogo = (Test-Path -LiteralPath $Exe) -or
              (Test-Path -LiteralPath (Join-Path $Root "data.grf")) -or
              (Test-Path -LiteralPath (Join-Path $Root "data"))
if (-not $pareceJogo) {
  Log ("pasta errada: " + $Root)
  Status "o atualizador nao esta na pasta do jogo"
  if (-not $Silencioso) {
    Write-Host ""
    Write-Host "Opa! Este atualizador precisa ficar DENTRO da pasta do jogo BadRO,"
    Write-Host "na mesma pasta onde esta o BadRO.exe."
    Write-Host ""
    Write-Host "Como resolver:"
    Write-Host "  1. Abra a pasta onde o BadRO esta instalado (a que tem o BadRO.exe)"
    Write-Host "  2. Copie para dentro dela TODOS os arquivos do atualizador"
    Write-Host "  3. De dois cliques no BadROPatcher.exe de la"
    Pausa "Pressione ENTER para fechar"
  }
  exit 1
}

Status "procurando novidades no servidor"
if (-not $Silencioso) { Write-Host "Verificando novidades no servidor..." }

# 1) Pega o manifesto (lista de atualizacoes). Tenta cada endereco 2x.
$man  = $null
$Base = $null
foreach ($b in $Bases) {
  for ($tent = 1; $tent -le 2; $tent++) {
    try {
      $man  = Invoke-RestMethod -Uri "$b/patches.json" -UseBasicParsing -TimeoutSec 20
      $Base = $b
      break
    } catch {
      Log ("manifesto falhou (" + $b + ", tentativa " + $tent + "/2): " + $_.Exception.Message)
      if ($tent -lt 2) { Start-Sleep -Seconds 3 }
    }
  }
  if ($man) { break }
}
if (-not $man) {
  Status "nao consegui falar com o servidor"
  Log "nenhum endereco respondeu"
  if (-not $Silencioso) {
    Write-Host ""
    Write-Host "Nao consegui falar com o servidor (voce esta sem internet ou o servidor esta fora?)."
    Write-Host "Vou abrir o jogo assim mesmo..."
    Abrir-Jogo
    Pausa "Pressione ENTER para fechar"
    exit 0
  }
  # No patcher isso e falha: ele mostra o aviso e o jogador ainda pode clicar em JOGAR.
  exit 1
}
Log ("usando o endereco " + $Base)

$local  = Versao-Local
$latest = [int]$man.latest

# 2) Aplica cada atualizacao pendente, em ordem
if ($latest -gt $local) {
  if (-not $Silencioso) { Write-Host ("Ha atualizacoes novas ({0} -> {1}). Baixando..." -f $local, $latest) }
  $pendentes = @($man.patches | Where-Object { [int]$_.n -gt $local } | Sort-Object { [int]$_.n })

  $script:BytesTotalGeral = 0
  foreach ($p in $pendentes) { $script:BytesTotalGeral += [long]$p.size }
  $script:BytesFeitos = 0
  $quantas = $pendentes.Count
  $indice  = 0

  foreach ($p in $pendentes) {
    $indice++
    $n    = [int]$p.n
    $file = [System.IO.Path]::GetFileName([string]$p.file)
    $desc = [string]$p.desc
    $mb   = [math]::Round([long]$p.size / 1MB, 1)
    Status ("baixando novidade " + $indice + " de " + $quantas + ": " + $desc)
    if (-not $Silencioso) { Write-Host ("  -> Atualizacao {0}: {1} ({2} MB)" -f $n, $desc, $mb) }
    Log ("aplicando patch " + $n + " (" + $file + ", " + $mb + " MB)")

    # tem espaco no disco? (zip + arquivos extraidos + folga)
    $precisa    = 3 * [long]$p.size
    $semEspaco  = $false
    foreach ($lugar in @($Root, $env:TEMP)) {
      $livre = Espaco-Livre $lugar
      if (($null -ne $livre) -and ($livre -lt $precisa)) { $semEspaco = $true }
    }
    if ($semEspaco) {
      Problema ("seu disco esta quase cheio - libere uns " + [math]::Round($precisa / 1MB) + " MB e atualize de novo. Parei aqui; continuo deste ponto na proxima vez.")
      break
    }

    $tmp = Join-Path $env:TEMP ("badro-" + $PID + "-" + $file)

    # baixa e confere; se vier corrompido, baixa mais uma vez
    $baixou = $false
    for ($rodada = 1; $rodada -le 2; $rodada++) {
      if (-not (Baixar "$Base/$file" $tmp $mb)) { continue }
      if (Conferir-Sha $tmp $p.sha256) { $baixou = $true; break }
      Log "sha nao confere (download corrompido ou antivirus mexeu no arquivo)"
      Status "o download nao veio inteiro, baixando de novo"
      if (-not $Silencioso) { Write-Host "     (o download nao veio inteiro, baixando de novo...)" }
      Remove-Item -LiteralPath $tmp -Force -ErrorAction SilentlyContinue
    }
    if (-not $baixou) {
      Problema ("nao consegui baixar a atualizacao " + $n + ". Parei aqui; na proxima vez eu continuo deste ponto. Se a sua internet esta ok, o antivirus pode estar apagando o arquivo - abra o antivirus e libere a pasta do BadRO.")
      break
    }

    Status ("instalando novidade " + $indice + " de " + $quantas)
    $falhas = Aplicar-Patch $tmp
    Remove-Item -LiteralPath $tmp -Force -ErrorAction SilentlyContinue

    if ($falhas -lt 0) {
      Problema ("nao consegui aplicar a atualizacao " + $n + ". Parei aqui; atualize de novo. Se repetir, o antivirus pode estar bloqueando - libere a pasta do BadRO nele.")
      $script:VersaoTravada = $true
      break
    }
    if ($falhas -gt 0) {
      # NAO anota a versao: assim essa atualizacao inteira e baixada de novo na proxima vez
      Problema ("a atualizacao " + $n + " NAO entrou completa: " + $falhas + " arquivo(s) ficaram de fora (detalhes no atualizador.log). Vou baixar ela de novo na proxima vez. Se repetir, o antivirus deve estar bloqueando - libere a pasta do BadRO nele.")
      $script:VersaoTravada = $true
    }
    if (-not $script:VersaoTravada) { Gravar-Versao $n }
    $script:BytesFeitos += [long]$p.size
    if ($script:BytesTotalGeral -gt 0) {
      Progresso (($script:BytesFeitos * 97.0) / $script:BytesTotalGeral)
    }
    if (-not $Silencioso) { Write-Host ("     OK (atualizacao {0} aplicada)." -f $n) }
    Log ("patch " + $n + " aplicado" + $(if ($falhas -gt 0) { " (" + $falhas + " arquivos de fora)" } else { "" }))
  }
} else {
  if (-not $Silencioso) { Write-Host ("Tudo em dia (versao {0})." -f $local) }
}

# 3) Conferencias finais
$versaoFinal = Versao-Local

# 3a) A traducao em ingles esta mesmo na pasta? (entra com a atualizacao 3)
if ($versaoFinal -ge 3 -and -not (Traducao-Ok)) {
  $reparou = $false
  try { Set-Content -LiteralPath $VerFile -Value 2; $reparou = $true } catch { }
  if ($reparou) {
    if ($Silencioso) {
      Problema "a traducao do jogo nao esta completa. Ja deixei preparado: clique em ATUALIZAR mais uma vez que eu baixo a traducao inteira (54 MB). Se este aviso repetir, o antivirus esta apagando os arquivos - libere a pasta do BadRO nele."
    } else {
      Problema "a traducao do jogo nao esta completa nesta pasta. Ja deixei preparado: FECHE esta janela e abra o atualizador DE NOVO, que eu baixo a traducao inteira (54 MB). Se este aviso repetir, o antivirus esta apagando os arquivos - libere a pasta do BadRO nele e mande o atualizador.log pro Pedro."
    }
  } else {
    Problema "a traducao do jogo nao esta completa e nao consegui preparar o reparo (disco cheio?). Mande o atualizador.log pro Pedro."
  }
}

# 3b) Windows com "Beta: usar Unicode UTF-8" ligado -> o jogo fica em coreano
$AvisoUtf8 = $false
try {
  $acp = [string](Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage" -ErrorAction Stop).ACP
  if ($acp -eq "65001") { $AvisoUtf8 = $true }
} catch { }
if ($AvisoUtf8) {
  Log "AVISO: Windows com UTF-8 beta ligado (ACP 65001) - o jogo aparece em coreano ate desligar"
  if (-not $Silencioso) {
    Write-Host ""
    Write-Host "  +---------------------------------------------------------------+"
    Write-Host "  |  IMPORTANTE: seu Windows esta com a opcao 'Beta: usar         |"
    Write-Host "  |  Unicode UTF-8' LIGADA. Com ela o jogo aparece EM COREANO.    |"
    Write-Host "  |                                                               |"
    Write-Host "  |  Como desligar (leva 2 minutos):                              |"
    Write-Host "  |   1. Aperte a tecla Windows, digite  regiao  e abra           |"
    Write-Host "  |      'Configuracoes de regiao'                                |"
    Write-Host "  |   2. Role a tela ate o fim e clique em 'Configuracoes         |"
    Write-Host "  |      administrativas de idioma'                               |"
    Write-Host "  |   3. Na janelinha que abrir, clique em 'Alterar localidade    |"
    Write-Host "  |      do sistema...'                                           |"
    Write-Host "  |   4. DESMARQUE a caixinha que comeca com 'Beta:' e de OK      |"
    Write-Host "  |   5. Reinicie o computador e abra o jogo de novo              |"
    Write-Host "  +---------------------------------------------------------------+"
  }
}

# 3c) Chegou o BadRO Patcher? Avisa e cria o atalho (so no modo janela).
Avisar-Do-Patcher

# 4) Resumo e abertura do jogo
if (-not $Silencioso) { Write-Host "" }
if ($script:Problemas.Count -gt 0) {
  Status ($script:Problemas[0])
  if (-not $Silencioso) {
    Write-Host "A atualizacao NAO terminou 100%:"
    foreach ($pr in $script:Problemas) { Write-Host ("  - " + $pr) }
    Write-Host ""
    Write-Host "Se o problema continuar, mande pro Pedro o arquivo:"
    Write-Host ("  " + $LogFile)
    Pausa "Pressione ENTER para abrir o jogo mesmo assim"
    Abrir-Jogo
  }
  Log "----- terminou COM problemas -----"
  exit 1
}

Progresso 100
Log "----- terminou ok -----"
if ($AvisoUtf8) {
  Status "atualizado - mas ligue/desligue o UTF-8 beta do Windows (veja o atualizador.log)"
  if (-not $Silencioso) {
    Pausa "Pressione ENTER para abrir o jogo mesmo assim (vai aparecer em coreano ate ajustar o Windows)"
    Abrir-Jogo
  }
  exit 0
}
Status "tudo em dia - pode jogar"
if (-not $Silencioso) {
  Write-Host "Tudo certo! Abrindo o jogo..."
  Abrir-Jogo
}
exit 0
