bdf0ae866a
Проект начинается с двух вещей: клиент, который мы действительно собрали, и загрузчик, который является его частью, а не чем-то рядом. Форк - prepare-game.ps1 пересобирает клиент целиком: ванильный jar, SRG и MCP, SpecialSource, FernFlower, патчи, автофиксеры, javac. Идемпотентен. - Свой код игры лежит в src-overlay, потому что src пересоздаётся при каждой сборке и всё написанное вручную там погибает. - 116 патчей в patches/decompiler-fixes.txt. Каждый сверялся с оригинальным байткодом через javap: компиляция не ловит ошибки декомпиляции. - struct_diff.py сравнивает исходный байткод с нашей сборкой по классам, интерфейсам, суперклассам, методам и полям, и отдельно проверяет, что пропавшие классы действительно никому не нужны. Загрузчик - Собирается и тестируется без игры: build.ps1 не использует classpath вообще, поэтому SelfTest из 128 проверок проходит без запущенного форка. - Клиентский API не содержит ни одного игрового типа, реализацию даёт игра. - Политика: мод меняет то, что клиент показывает, но никогда то, что истинно в мире. Мир, предметы, игроки и сеть принадлежат серверу. - Capability приведены в соответствие с этой политикой: осталось шесть, и за каждым стоит реальная проверка. Прежние WORLD, PLAYER, NETWORK, TEXT, INPUT и COMMAND выдавались, но ничего не проверяли. - Команды модов имеют область CLIENT, SERVER или BOTH. Серверные не выполняются на клиенте никогда. - Свой jar загрузчика лежит в classpath игры и сборки форка. Инструменты - add_patch.py, чтобы каждое исправление переживало передекомпиляцию - find_self_comparisons.py, find_remove_index_bugs.py, find_callers.py - stage_run.py и fetch_missing.py для запуска клиента
63 lines
3.0 KiB
PowerShell
63 lines
3.0 KiB
PowerShell
# Compiles the forked client from the existing sources. Fast iteration loop:
|
|
# fix, run this, look at the numbers. Use prepare-game.ps1 when the sources
|
|
# themselves need regenerating.
|
|
#
|
|
# ASCII only: PowerShell 5.1 reads a .ps1 without a byte order mark using the
|
|
# system ANSI code page.
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$Fork = Split-Path -Parent $PSScriptRoot
|
|
if (-not $Fork) { $Fork = $PSCommandPath | Split-Path -Parent | Split-Path -Parent }
|
|
$Root = Split-Path -Parent $Fork
|
|
$Client = Join-Path $Root 'rsx-client'
|
|
|
|
$Astral = Join-Path $env:APPDATA 'AstralRinthApp\meta'
|
|
$Src = Join-Path $Fork 'src'
|
|
$Out = Join-Path $Fork 'build\classes'
|
|
$Temp = Join-Path $env:TEMP 'opencode'
|
|
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
|
$good = New-Object System.Collections.Generic.List[string]
|
|
foreach ($j in (Get-ChildItem (Join-Path $Astral 'libraries') -Recurse -Filter '*.jar' -File)) {
|
|
if ($j.Length -le 100) { continue }
|
|
$ok = $false
|
|
try { $z = [System.IO.Compression.ZipFile]::OpenRead($j.FullName); $z.Dispose(); $ok = $true } catch { $ok = $false }
|
|
if ($ok) { $good.Add(($j.FullName -replace '\\', '/')) }
|
|
}
|
|
|
|
# The fork calls into the mod loader, so the loader has to be visible to javac
|
|
# exactly as it is at runtime. Building the loader first is what keeps the two
|
|
# from drifting apart.
|
|
$Loader = Join-Path $Client 'dist\rsx-loader.jar'
|
|
|
|
$cp = @($good + $(if (Test-Path $Loader) { $Loader -replace '\\', '/' } else { $null })) -join ';'
|
|
$argf = Join-Path $Temp 'fork-build.txt'
|
|
$errf = Join-Path $Temp 'fork-build-errors.txt'
|
|
$sb = New-Object System.Text.StringBuilder
|
|
foreach ($a in @('-nowarn', '-proc:none', '-encoding', 'UTF-8', '--release', '17', '-d', ($Out -replace '\\', '/'))) { [void]$sb.AppendLine($a) }
|
|
[void]$sb.AppendLine('-cp'); [void]$sb.AppendLine('"' + $cp + '"')
|
|
Get-ChildItem $Src -Recurse -Filter '*.java' | ForEach-Object { [void]$sb.AppendLine(($_.FullName -replace '\\', '/')) }
|
|
Set-Content -LiteralPath $argf -Value $sb.ToString() -Encoding ASCII
|
|
|
|
Remove-Item $Out -Recurse -Force -ErrorAction SilentlyContinue
|
|
New-Item -ItemType Directory -Force -Path $Out | Out-Null
|
|
$javac = (Get-Command javac).Source
|
|
& cmd /c "`"$javac`" @`"$argf`" -Xmaxerrs 10000 > `"$errf`" 2>&1"
|
|
|
|
$errors = Get-Content -LiteralPath $errf | Select-String -Pattern ': error:'
|
|
$classes = (Get-ChildItem $Out -Recurse -Filter '*.class' -File -ErrorAction SilentlyContinue).Count
|
|
|
|
if ($errors.Count -eq 0) {
|
|
Write-Host ''
|
|
Write-Host " FORK COMPILES CLEAN - $classes classes" -ForegroundColor Green
|
|
exit 0
|
|
}
|
|
|
|
$files = $errors | ForEach-Object { if ($_.Line -match '^([A-Z]:.*?\.java):\d+:') { $matches[1] } } | Sort-Object -Unique
|
|
Write-Host ''
|
|
Write-Host " $classes classes, $($errors.Count) errors in $($files.Count) files" -ForegroundColor Yellow
|
|
$errors | ForEach-Object { if ($_.Line -match '^([A-Z]:.*?\.java):\d+:') { $matches[1] } } |
|
|
Group-Object | Sort-Object Count -Descending | Select-Object -First 25 |
|
|
ForEach-Object { Write-Host (" {0,4} {1}" -f $_.Count, ($_.Name.Replace(($Src + '\'), ''))) -ForegroundColor Gray } |