﻿$ErrorActionPreference = 'Stop'
$gameDir = $PSScriptRoot
$publicSite = 'https://era270.161-33-153-92.sslip.io'
$bridgeScript = Join-Path $gameDir 'Start-PlayerGameBridge.ps1'
$gameLauncher = Join-Path $gameDir 'Start-PlayerPortal.ps1'

if (-not (Test-Path -LiteralPath $bridgeScript -PathType Leaf) -or
    -not (Test-Path -LiteralPath (Join-Path $gameDir 'PlayerGameBridge.cs') -PathType Leaf)) {
    throw '玩家連線檔案不完整，請重新安裝整份共用連線包。'
}
if (-not (Test-Path -LiteralPath $gameLauncher -PathType Leaf)) {
    throw '找不到玩家啟動檔，請重新安裝整份共用連線包。'
}

# The former connection pack installed a privileged Windows port proxy.
# Never remove an unrelated rule automatically.
$rules = (& netsh interface portproxy show v4tov4) -join "`n"
if ($rules -match '(?m)^\s*127\.0\.0\.1\s+2200\s+(\S+)\s+(\d+)\s*$') {
    $target = $Matches[1] + ':' + $Matches[2]
    if ($target -eq '100.125.12.92:2200') {
        throw '連線設定在啟動過程中發生變更。請關閉這個視窗，再開啟「啟動玩家2.7.cmd」；若仍出現訊息，請通知 GM。'
    }
    throw ('本機 2200 有其他連線設定（' + $target + '）。未修改原設定，請聯絡 GM。')
}

. (Join-Path $gameDir 'Check-PlayerConnection.ps1') -GameDir $gameDir
$connectionCheck=Invoke-EraPortCheck $gameDir 2200 $true
if(-not $connectionCheck.free){
 foreach($occupied in $connectionCheck.listeners){Write-Host ('占用程式：'+$occupied.program+'；PID：'+$occupied.pid+'；判定：'+$occupied.kind)}
 throw '本機遊戲連線入口仍被占用。請關閉這份遊戲後執行「檢查與修復連線.cmd」；未知程式不會自動關閉。'
}

$bridgeStarted = $null
$probe = New-Object Net.Sockets.TcpClient
try {
    try { $probe.Connect('127.0.0.1', 2200) } catch { }
    if ($probe.Connected) { throw '本機遊戲連線埠由其他程式使用；未改動該程式，請聯絡 GM。' }
    if (-not $probe.Connected) {
        $start = New-Object Diagnostics.ProcessStartInfo
        $start.FileName = Join-Path $PSHOME 'powershell.exe'
        $start.Arguments = '-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File "' + $bridgeScript + '" -LocalPort 2200'
        $start.WorkingDirectory = $gameDir
        $start.UseShellExecute = $false
        $start.CreateNoWindow = $true
        $start.WindowStyle = [Diagnostics.ProcessWindowStyle]::Hidden
        $bridgeStarted = [Diagnostics.Process]::Start($start)
        if (-not $bridgeStarted) { throw '無法啟動玩家連線程式。' }
    }
} finally { $probe.Dispose() }

try {
    $healthy = $false
    $until = (Get-Date).AddSeconds(15)
    do {
        $test = New-Object Net.Sockets.TcpClient
        try {
            $pending = $test.BeginConnect('127.0.0.1', 2200, $null, $null)
            if ($pending.AsyncWaitHandle.WaitOne(1500)) {
                $test.EndConnect($pending)
                $test.ReceiveTimeout = 3500
                $bytes = New-Object byte[] 18
                $received = 0
                while ($received -lt $bytes.Length) {
                    $count = $test.GetStream().Read($bytes, $received, $bytes.Length - $received)
                    if ($count -le 0) { break }
                    $received += $count
                }
                if ($received -eq 18) {
                    $healthy = $true
                    break
                }
            }
        } catch { }
        finally { $test.Dispose() }
        Start-Sleep -Milliseconds 400
    } while ((Get-Date) -lt $until)
    if (-not $healthy) { throw '目前無法連到遊戲公開入口，請稍後重試。' }

    & (Join-Path $PSHOME 'powershell.exe') -NoProfile -ExecutionPolicy Bypass -File $gameLauncher -BaseUrl $publicSite
    if ($LASTEXITCODE -ne 0) { throw '玩家端更新或啟動失敗；已清理本次開啟的連線程式。請執行檢查與修復連線。' }
} catch {
    if ($bridgeStarted -and -not $bridgeStarted.HasExited) {
        try { $bridgeStarted.Kill() } catch { }
    }
    throw
}
