feat: OpenSourceTools v2.1.0 - 升级 Bukkit 1.21.11, 补充 README 与自动化测试设施

This commit is contained in:
database-mysql committed 2026-11-09 07:57:59 +08:00
commit 6c7d7fedcb
50 files changed
+3241

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://aka.ms/MinecraftEULA).
eula=true
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>aliyun-public</id>
<name>Aliyun Maven Public (central+sonatype)</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central,sonatype</mirrorOf>
</mirror>
</mirrors>
</settings>
+104
View File
@@ -0,0 +1,104 @@
# OpenSourceTools 冒烟测试脚本 (Paper 1.21.11)
# 流程: 校验构建产物 -> 准备服务器目录 -> 启动 -> 等待 Done -> 校验插件日志 -> 优雅停止 -> 校验卸载日志
param(
[int]$BootTimeoutSec = 300,
[int]$ShutdownTimeoutSec = 120
)
$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 $env:TEMP 'ost-smoke-test\server'
$BuiltJar = Join-Path $ProjectRoot 'target\OpenSourceTools-2.1.0.jar'
if (-not (Test-Path $BuiltJar)) { Write-Output "FATAL: 找不到构建产物 $BuiltJar"; 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: 缓存缺少 $PaperJar"; exit 2 }
if (-not (Test-Path $PapiJar)) { Write-Output "FATAL: 缓存缺少 $PapiJar"; exit 2 }
# 准备服务器目录(每次全新)
if (Test-Path $ServerDir) { Remove-Item -Recurse -Force $ServerDir -ErrorAction SilentlyContinue }
New-Item -ItemType Directory -Force -Path (Join-Path $ServerDir 'plugins') | Out-Null
Copy-Item -Force (Join-Path $Root 'server.properties') (Join-Path $ServerDir 'server.properties')
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')
Write-Output "启动服务器: paper.jar + PlaceholderAPI.jar + OpenSourceTools.jar"
$psi = [System.Diagnostics.ProcessStartInfo]::new()
$psi.FileName = 'java'
$psi.Arguments = "-Xmx1024M -XX:+UseG1GC -jar `"$((Join-Path $ServerDir 'paper.jar'))`" nogui"
$psi.WorkingDirectory = $ServerDir
$psi.UseShellExecute = $false
$psi.RedirectStandardInput = $true
$psi.RedirectStandardOutput = $false
$psi.RedirectStandardError = $false
$proc = [System.Diagnostics.Process]::Start($psi)
Write-Output "服务器进程已启动 PID=$($proc.Id)"
$logFile = Join-Path $ServerDir 'logs\latest.log'
$booted = $false
$deadline = (Get-Date).AddSeconds($BootTimeoutSec)
while (-not $proc.HasExited -and (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|Exception in thread "main"') { break }
}
}
if (-not $booted) {
Write-Output 'FAIL: 服务器未能在超时时间内完成启动'
if (Test-Path $logFile) { Get-Content $logFile -Tail 40 -Encoding UTF8 }
if (-not $proc.HasExited) { $proc.Kill(); $proc.WaitForExit(15000) }
exit 1
}
Write-Output '服务器启动完成 (Done),正在发送 stop...'
Start-Sleep -Seconds 2
$proc.StandardInput.WriteLine('stop')
$proc.StandardInput.Flush()
if (-not $proc.WaitForExit($ShutdownTimeoutSec * 1000)) {
Write-Output 'FAIL: 服务器未能优雅停止'
$proc.Kill()
exit 1
}
Write-Output "服务器已退出, ExitCode=$($proc.ExitCode)"
# ---------- 日志校验 ----------
$log = Get-Content $logFile -Raw -Encoding UTF8
$errors = @()
function Check-Pass($name, $pattern) {
if ($log -match $pattern) { Write-Output "PASS: $name" }
else { Write-Output "FAIL: $name"; $script:errors += $name }
}
function Check-Absent($name, $pattern) {
if ($log -match $pattern) { Write-Output "FAIL: $name"; $script:errors += $name }
else { Write-Output "PASS: $name" }
}
Check-Pass '检测到PlaceholderAPI前置' '已检测到PlaceholderAPI前置'
Check-Pass '插件启动成功' '插件启动成功'
Check-Pass '插件已卸载' '插件已卸载'
Check-Absent '无插件加载错误' 'Error occurred while enabling OpenSourceTools|Could not load ''plugins/OpenSourceTools|Invalid plugin.yml|Invalid description'
if ($proc.ExitCode -ne 0) { Write-Output "FAIL: 服务器退出码非0 ($($proc.ExitCode))"; $errors += "退出码$($proc.ExitCode)" }
if ($errors.Count -eq 0) {
Write-Output '==================== 冒烟测试全部通过 ===================='
exit 0
} else {
Write-Output "==================== 冒烟测试失败 ($($errors -join ', ')) ===================="
Write-Output '----- 关键日志片段 -----'
Get-Content $logFile -Encoding UTF8 | Select-String -Pattern 'OpenSourceTools|PlaceholderAPI|ERROR|Caused by' | Select-Object -First 40
exit 1
}
+17
View File
@@ -0,0 +1,17 @@
#Minecraft server properties (live test server)
online-mode=false
server-port=25565
server-ip=
level-name=world
level-type=minecraft\:flat
generate-structures=false
spawn-monsters=true
spawn-npcs=true
spawn-animals=true
view-distance=6
simulation-distance=6
max-players=20
spawn-protection=0
motd=OpenSourceTools v2.1.0 测试服 (1.21.11)
enable-rcon=false
network-compression-threshold=256
+17
View File
@@ -0,0 +1,17 @@
#Minecraft server properties (smoke test)
online-mode=false
server-port=25570
server-ip=
level-name=world
level-type=minecraft\:flat
generate-structures=false
spawn-monsters=false
spawn-npcs=false
spawn-animals=false
view-distance=2
simulation-distance=2
max-players=10
spawn-protection=0
motd=OST-smoke-test
enable-rcon=false
network-compression-threshold=256
+69
View File
@@ -0,0 +1,69 @@
# 交互式测试服务器启动脚本 (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