# 交互式测试服务器启动脚本 (Paper 1.21.11) # 在独立可见的控制台窗口中启动服务器并保持运行,等待玩家连接。 # 停止方式: 在服务器窗口输入 stop 并回车(推荐),或直接关闭该窗口。 param( [int]$BootTimeoutSec = 240 ) $ErrorActionPreference = 'Stop' $Root = Split-Path -Parent $MyInvocation.MyCommand.Path # tools\smoke-test $ProjectRoot = Split-Path -Parent (Split-Path -Parent $Root) # 项目根 $CacheDir = Join-Path $env:USERPROFILE '.ost-smoke-cache' $ServerDir = Join-Path $ProjectRoot 'test-server' $BuiltJar = Join-Path $ProjectRoot 'target\OpenSourceTools-2.1.0.jar' if (-not (Test-Path $BuiltJar)) { Write-Output "FATAL: 找不到构建产物 $BuiltJar (请先执行 mvn clean package)"; exit 2 } $PaperJar = Join-Path $CacheDir 'paper-1.21.11-132.jar' $PapiJar = Join-Path $CacheDir 'PlaceholderAPI-2.12.3.jar' if (-not (Test-Path $PaperJar)) { Write-Output "FATAL: 缓存缺少 Paper jar: $PaperJar"; exit 2 } if (-not (Test-Path $PapiJar)) { Write-Output "FATAL: 缓存缺少 PAPI jar: $PapiJar"; exit 2 } # 检查端口占用(已有实例在运行则直接退出) $existing = Get-NetTCPConnection -LocalPort 25565 -State Listen -ErrorAction SilentlyContinue if ($existing) { Write-Output "WARN: 端口 25565 已被占用 (PID $($existing.OwningProcess)),可能服务器已在运行"; exit 3 } # 准备服务器目录(保留世界数据,不删除) New-Item -ItemType Directory -Force -Path (Join-Path $ServerDir 'plugins') | Out-Null Copy-Item -Force (Join-Path $Root 'server-live.properties') (Join-Path $ServerDir 'server.properties') if (-not (Test-Path (Join-Path $ServerDir 'eula.txt'))) { Copy-Item -Force (Join-Path $Root 'eula.txt') (Join-Path $ServerDir 'eula.txt') } Copy-Item -Force $PaperJar (Join-Path $ServerDir 'paper.jar') Copy-Item -Force $PapiJar (Join-Path $ServerDir 'plugins\PlaceholderAPI.jar') Copy-Item -Force $BuiltJar (Join-Path $ServerDir 'plugins\OpenSourceTools.jar') # 清理旧日志(保留世界) Remove-Item -Recurse -Force (Join-Path $ServerDir 'logs') -ErrorAction SilentlyContinue Write-Output "启动测试服务器 (Paper 1.21.11, 端口 25565, 离线模式)..." $paperPath = Join-Path $ServerDir 'paper.jar' $argsLine = "-Xmx2048M -XX:+UseG1GC -jar `"$paperPath`" nogui" Start-Process -FilePath 'java' -ArgumentList $argsLine -WorkingDirectory $ServerDir -WindowStyle Normal Write-Output '服务器进程已在新窗口中启动' $logFile = Join-Path $ServerDir 'logs\latest.log' $booted = $false $deadline = (Get-Date).AddSeconds($BootTimeoutSec) while ((Get-Date) -lt $deadline) { Start-Sleep -Seconds 2 if (Test-Path $logFile) { $tail = Get-Content $logFile -Raw -Encoding UTF8 -ErrorAction SilentlyContinue if ($tail -match 'Done \(') { $booted = $true; break } if ($tail -match 'FAILED TO BIND TO PORT') { break } } } if (-not $booted) { Write-Output 'FAIL: 服务器未能在超时时间内完成启动' if (Test-Path $logFile) { Get-Content $logFile -Tail 30 -Encoding UTF8 } exit 1 } Write-Output '==================== 服务器已就绪, 等待玩家连接 ====================' $ip = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '127.*' -and $_.IPAddress -notlike '169.254.*' } | Select-Object -First 1 -ExpandProperty IPAddress Write-Output "本机连接: localhost:25565" Write-Output "局域网连接: ${ip}:25565 (如无法连接请放行 Windows 防火墙 25565 端口)" Write-Output '客户端版本要求: Minecraft 1.21.11' Write-Output '管理员: 在服务器控制台窗口输入 op <你的游戏ID> 即可获得 OP 权限测试管理命令' Write-Output '停止服务器: 在服务器控制台窗口输入 stop 并回车(推荐), 或直接关闭窗口' exit 0