chore(history): squash 59 commit(s) from 2026-09-23
- refactor(hud/weather/render): Scoreboard 931→240 + Rain 903→159 + UiMeshGeometry 956→99 (8.5.2) - refactor(chams): Chams 985 → 129 + 4×≤195 (8.5.2) - refactor(module): Module 1031 → 139 + 4×≤134 (8.5.2) - refactor(tooltips): BetterTooltips 960 → 181 + 4×≤199 (8.5.2) - refactor(clickgui): ClickGuiPickerState 970→166 + ModulesMenuScreen 966→145 (8.5.2) - refactor(clickgui): CombatProtocolHeuristicsEditorState 932→79 + 4×≤192 (8.5.2) - refactor(hud): CompactHudStatModel 894 → 125 + 4×≤175 (8.5.2) - refactor(iris): ShaderPatchCompiler 843→66 + 4×≤174 (8.5.2) - refactor(tab): CustomTabList 834→136 + 4×≤166 (8.5.2) - refactor(relations): OnlineRelationPlayerPickerComponent 837→74 + 4×≤192 (8.5.2) - refactor(hits): HitEffect 770→120 + 4×≤176 (8.5.2) - refactor(predict): Predictions 815→150 + 4×≤195 (8.5.2) - refactor(config): ConfigProfilesComponent 799→125 + 4×≤195 (8.5.2) - refactor(sim): PlayerMovementSimulation 757→157 + 4×≤194 (8.5.2) - refactor(predict): ProjectilePuncher 747→104 + 3×≤134 (8.5.2) - refactor(crosshair): Crosshair 743→143 + 4×≤167 (8.5.2) - refactor(mediaplayer): MediaPlayer 743→174 + 4×≤196 (8.5.2) - refactor(hud): Itemizer 699→193 + Cooldowns 707→151 (8.5.2) - refactor(hud): Potions 617→176 + 4×≤166 (8.5.2) - refactor(hud): Admins 702→118 + 4×≤138 (8.5.2) - refactor(hud): Keybinds 611→157 + 4×≤160 (8.5.2) - refactor(hud): ModuleList 499→181 + 3×≤150 (8.5.2) - refactor(hud): Radar 392→161 + 2×≤124 (8.5.2) - refactor(hud): Fps 309→168 + 3×≤107 (8.5.2) - refactor(hud): Memory 304→151 + 3×≤144 (8.5.2) - refactor(hud): Tps 339→154 + 3×≤143 (8.5.2) - refactor(hud): Ping 309→145 + 3×≤125 (8.5.2) - refactor(hud): SpeedBps 334→156 + 3×≤142 (8.5.2) - refactor(hud): GameTime 314→150 + 3×≤127 (8.5.2) - refactor(hud): SystemTime 300→136 + 3×≤130 (8.5.2) - refactor(hud): Coordinates 337→174 + 2×≤172 (8.5.2) - refactor(hud): Armor 324→162 + 2×≤148 (8.5.2) - refactor(hud): Inventory 476→153 + 3×≤181 (8.5.2) - docs(todo): обновлён 8.5.2 — отмечены готовые гиганты (BetterButtons/InventorySwap/Svg/Темы/WorldParticles/Module/Chams и хвост) - docs(api): папка combatant-client-26.2/docs + addons.md (API можно ломать при рефакторе) - refactor(visuals): BlockHighlight 692→271 + 4×≤200 (8.5.2) - refactor(mixins): GameRendererMixin 830→344 (хуки) + 4 хелпера (8.5.2) - refactor(visuals): WorldParticles 821→260 + 6×≤200, режимы добиты (8.5.2) - docs(todo): 8.5.2 — WorldParticles/GameRendererMixin/BlockHighlight отмечены ГОТОВО - refactor(render): MeshBuilder 738→447 (фасад write-API) + 3 хелпера, FrameStats снесён (8.5.2) - docs(todo): Фаза 10 — дизайн платформы (аккаунты/конфиги/аватарки), backlog RPC-чата - docs(todo): Подсистема 3 — Аддоны 2.0 (скрипты/версии) + витрина аддонов + админка - docs(todo): Подсистема 2 — RPC-чат/друзья/виджеты-телеметрия + рейт-лимиты, доп. правки Подсистемы 3 - chore: переименование combatant-client-26.2 -> mod, добавлены backend/ и frontend/ - docs(backend): implementation plan for accounts-service (Подсистема 1, часть 1) - chore: пересоздать backend/frontend через cargo new и bun create vite + tailwind; убрать таблицу компонентов из TODO.md - docs(backend): edition 2024 в плане вместо 2021 - chore: обновить версии до реально актуальных (проверено компиляцией) - docs: правила платформы (лимит 250 строк, антипаттерны backend/frontend по итогам ресёрча) + frontend/ARCHITECTURE.md - docs: добавить правило ≤4 файла на папку в правила платформы (backend/frontend) - docs: commit messages in English from now on - chore: gitignore .superpowers/ scratch directory - docs: commit messages in English from now on (mod) - feat(backend): scaffold accounts-service with health check - chore(backend): remove target/ build artifacts from git, add gitignore - chore: track docs/ in git (was accidentally gitignored, never committed) - chore(backend): convert to Cargo workspace, plan full microservice layout - feat(backend): accounts/avatars/device_links schema + migration - feat(backend): argon2id password hashing
This commit is contained in:
parent
ec10395511
commit
9d08fa910a
2239 changed files with 35265 additions and 28110 deletions
168
mod/tools/msdf/GenerateSvgMsdf.ps1
Normal file
168
mod/tools/msdf/GenerateSvgMsdf.ps1
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
param(
|
||||
[string]$InputRoot = "src/main/resources/assets/combatant/svg",
|
||||
[string]$OutRoot = "build/generated/resources/svgMsdf/assets/combatant/svg/msdf",
|
||||
[int]$Dimension = 64,
|
||||
[int]$PxRange = 4,
|
||||
[string]$Type = "mtsdf",
|
||||
[string]$PreprocessorClasspath = "build/classes/java/main",
|
||||
[string]$JavaExe = "java",
|
||||
[switch]$Strict
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repoRoot = (Resolve-Path "${PSScriptRoot}\..\..").Path
|
||||
|
||||
function Resolve-RepoPath {
|
||||
param([string]$Path)
|
||||
|
||||
if ([System.IO.Path]::IsPathRooted($Path)) {
|
||||
return [System.IO.Path]::GetFullPath($Path)
|
||||
}
|
||||
return [System.IO.Path]::GetFullPath((Join-Path $repoRoot $Path))
|
||||
}
|
||||
|
||||
$inputRootPath = Resolve-RepoPath $InputRoot
|
||||
$outRootPath = Resolve-RepoPath $OutRoot
|
||||
$toolDir = Join-Path $repoRoot "tools/msdf"
|
||||
$msdfgenPath = Join-Path $toolDir "msdfgen.exe"
|
||||
$workRoot = Join-Path $repoRoot "build/tmp/svg-msdf"
|
||||
|
||||
function Get-Msdfgen {
|
||||
if (Test-Path $msdfgenPath) { return $msdfgenPath }
|
||||
|
||||
$api = "https://api.github.com/repos/Chlumsky/msdfgen/releases/latest"
|
||||
$release = Invoke-RestMethod -Uri $api -Headers @{ "User-Agent" = "CombatantSvgMsdfGen" }
|
||||
$asset = $release.assets |
|
||||
Where-Object { $_.name -match "win64" -and $_.name -match "\.zip$" -and $_.name -notmatch "openmp" } |
|
||||
Select-Object -First 1
|
||||
if (-not $asset) {
|
||||
$asset = $release.assets |
|
||||
Where-Object { $_.name -match "win" -and $_.name -match "\.zip$" -and $_.name -notmatch "openmp" } |
|
||||
Select-Object -First 1
|
||||
}
|
||||
if (-not $asset) { throw "No Windows msdfgen zip found in latest release." }
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $toolDir | Out-Null
|
||||
$archivePath = Join-Path $toolDir $asset.name
|
||||
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $archivePath -Headers @{ "User-Agent" = "CombatantSvgMsdfGen" }
|
||||
|
||||
$extractDir = Join-Path $toolDir ([System.IO.Path]::GetFileNameWithoutExtension($asset.name))
|
||||
Expand-Archive -Path $archivePath -DestinationPath $extractDir -Force
|
||||
$found = Get-ChildItem -Path $extractDir -Filter "msdfgen.exe" -Recurse | Select-Object -First 1
|
||||
if (-not $found) { throw "msdfgen.exe not found after extraction." }
|
||||
|
||||
Copy-Item $found.FullName -Destination $msdfgenPath -Force
|
||||
return $msdfgenPath
|
||||
}
|
||||
|
||||
function Read-ViewBox {
|
||||
param([string]$Path)
|
||||
|
||||
[xml]$xml = Get-Content -LiteralPath $Path -Raw
|
||||
$root = $xml.DocumentElement
|
||||
$viewBox = $root.GetAttribute("viewBox")
|
||||
if ($viewBox) {
|
||||
$parts = [regex]::Split($viewBox.Trim(), "[,\s]+") | Where-Object { $_ -ne "" }
|
||||
if ($parts.Count -eq 4) {
|
||||
return @{
|
||||
X = [double]::Parse($parts[0], [Globalization.CultureInfo]::InvariantCulture)
|
||||
Y = [double]::Parse($parts[1], [Globalization.CultureInfo]::InvariantCulture)
|
||||
W = [double]::Parse($parts[2], [Globalization.CultureInfo]::InvariantCulture)
|
||||
H = [double]::Parse($parts[3], [Globalization.CultureInfo]::InvariantCulture)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$w = $root.GetAttribute("width") -replace "[^0-9.+-]", ""
|
||||
$h = $root.GetAttribute("height") -replace "[^0-9.+-]", ""
|
||||
$width = if ($w) { [double]::Parse($w, [Globalization.CultureInfo]::InvariantCulture) } else { 24.0 }
|
||||
$height = if ($h) { [double]::Parse($h, [Globalization.CultureInfo]::InvariantCulture) } else { 24.0 }
|
||||
return @{ X = 0.0; Y = 0.0; W = $width; H = $height }
|
||||
}
|
||||
|
||||
function Write-Metadata {
|
||||
param(
|
||||
[string]$Path,
|
||||
[string]$SourceRelative,
|
||||
[string]$TextureRelative,
|
||||
[hashtable]$ViewBox
|
||||
)
|
||||
|
||||
$metadata = [ordered]@{
|
||||
type = $Type
|
||||
width = $Dimension
|
||||
height = $Dimension
|
||||
pxRange = $PxRange
|
||||
yOrigin = "top"
|
||||
source = "combatant:svg/$SourceRelative"
|
||||
texture = "combatant:svg/msdf/$TextureRelative"
|
||||
viewBox = @($ViewBox.X, $ViewBox.Y, $ViewBox.W, $ViewBox.H)
|
||||
}
|
||||
$json = $metadata | ConvertTo-Json -Depth 4
|
||||
[System.IO.File]::WriteAllText($Path, $json + [Environment]::NewLine, [System.Text.UTF8Encoding]::new($false))
|
||||
}
|
||||
|
||||
if (-not (Test-Path $inputRootPath)) {
|
||||
Write-Host "SVG input root not found: $inputRootPath" -ForegroundColor Yellow
|
||||
exit 0
|
||||
}
|
||||
|
||||
try {
|
||||
$msdfgen = Get-Msdfgen
|
||||
} catch {
|
||||
if ($Strict) { throw }
|
||||
Write-Host "msdfgen unavailable; skipping SVG MSDF generation: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (Test-Path $outRootPath) {
|
||||
Remove-Item -LiteralPath $outRootPath -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $outRootPath | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path $workRoot | Out-Null
|
||||
|
||||
$svgs = Get-ChildItem -Path $inputRootPath -Filter "*.svg" -Recurse
|
||||
$inputRootFull = [System.IO.Path]::GetFullPath($inputRootPath).TrimEnd('\', '/') + [System.IO.Path]::DirectorySeparatorChar
|
||||
$generated = 0
|
||||
$skipped = 0
|
||||
|
||||
foreach ($svg in $svgs) {
|
||||
$fileFull = [System.IO.Path]::GetFullPath($svg.FullName)
|
||||
$relative = $fileFull.Substring($inputRootFull.Length).Replace('\', '/')
|
||||
if ($relative.StartsWith("msdf/")) { continue }
|
||||
|
||||
$relativeNoExt = $relative.Substring(0, $relative.Length - 4)
|
||||
$outPng = Join-Path $outRootPath ($relativeNoExt + ".png")
|
||||
$outJson = Join-Path $outRootPath ($relativeNoExt + ".json")
|
||||
$outlineSvg = Join-Path $workRoot ($relativeNoExt.Replace("/", "_") + ".outline.svg")
|
||||
|
||||
New-Item -ItemType Directory -Force -Path ([System.IO.Path]::GetDirectoryName($outPng)) | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path ([System.IO.Path]::GetDirectoryName($outlineSvg)) | Out-Null
|
||||
|
||||
try {
|
||||
$viewBox = Read-ViewBox $svg.FullName
|
||||
if ($viewBox.W -le 0 -or $viewBox.H -le 0) { throw "invalid viewBox" }
|
||||
|
||||
$preprocessOutput = & $JavaExe -cp $PreprocessorClasspath combatant.client.render.engine.svg.SvgMsdfPreprocessor $svg.FullName $outlineSvg 2>&1
|
||||
if ($LASTEXITCODE -ne 0) { throw "svg preprocessor failed: $preprocessOutput" }
|
||||
if (-not (Test-Path $outlineSvg)) { throw "outline svg was not produced" }
|
||||
|
||||
$scale = [Math]::Min($Dimension / $viewBox.W, $Dimension / $viewBox.H)
|
||||
$translateX = -$viewBox.X
|
||||
$translateY = -$viewBox.Y
|
||||
|
||||
$msdfgenOutput = & $msdfgen $Type -svg $outlineSvg -o $outPng -dimensions $Dimension $Dimension -pxrange $PxRange -scale $scale -translate $translateX $translateY 2>&1
|
||||
if ($LASTEXITCODE -ne 0 -or -not (Test-Path $outPng)) { throw "msdfgen failed: $msdfgenOutput" }
|
||||
|
||||
Write-Metadata $outJson $relative ($relativeNoExt + ".png") $viewBox
|
||||
$generated++
|
||||
} catch {
|
||||
$skipped++
|
||||
$message = "Skipped ${relative}: $($_.Exception.Message)"
|
||||
if ($Strict) { throw $message }
|
||||
Write-Host $message -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Generated $generated SVG MSDF assets, skipped $skipped." -ForegroundColor Green
|
||||
Loading…
Add table
Add a link
Reference in a new issue