From 1bfb306db68370b8155436ec1e8077cdd69fd789 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Fri, 8 May 2026 11:16:34 +0300 Subject: [PATCH] Add extract-missing-ru-translations.ps1 to .gitignore for improved resource management. --- .gitignore | 1 + Server/extract-missing-ru-translations.ps1 | 131 +++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 Server/extract-missing-ru-translations.ps1 diff --git a/.gitignore b/.gitignore index ade3a5c..df88f79 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ !/Server/start.bat !/Server/start.ps1 !/Server/sync-mods-from-client.ps1 +!/Server/extract-missing-ru-translations.ps1 !/Server/start.sh !/Server/variables.txt !/Server/manifest.json diff --git a/Server/extract-missing-ru-translations.ps1 b/Server/extract-missing-ru-translations.ps1 new file mode 100644 index 0000000..557ff71 --- /dev/null +++ b/Server/extract-missing-ru-translations.ps1 @@ -0,0 +1,131 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS +Ищет в mods/*.jar переводы en_us без ru_ru и копирует en_us в наш ресурспак как ru_ru. + +.DESCRIPTION +Для каждого файла вида assets//lang/en_us.json: + - если в этом же jar нет assets//lang/ru_ru.json + - копируется en_us.json в: + resourcepacks/PupaMLupa-Translations/assets//lang/ru_ru.json + +Это заготовка для ручного перевода (сохраняется английский текст в русское имя файла). +#> +param( + [switch] $DryRun, + [switch] $Force +) + +$ErrorActionPreference = "Stop" + +Add-Type -AssemblyName System.IO.Compression +Add-Type -AssemblyName System.IO.Compression.FileSystem + +$instanceRoot = Split-Path $PSScriptRoot -Parent +$modsDir = Join-Path $instanceRoot "mods" +$resourcepackRoot = Join-Path $instanceRoot "resourcepacks/PupaMLupa-Translations" +$resourcepackAssets = Join-Path $resourcepackRoot "assets" + +if (-not (Test-Path -LiteralPath $modsDir)) { + Write-Error "Папка mods не найдена: $modsDir" +} + +if (-not (Test-Path -LiteralPath $resourcepackRoot)) { + if ($DryRun) { + Write-Host "[dry-run] Создал бы ресурспак: $resourcepackRoot" + } else { + New-Item -ItemType Directory -Path $resourcepackRoot -Force | Out-Null + } +} + +if (-not (Test-Path -LiteralPath $resourcepackAssets)) { + if ($DryRun) { + Write-Host "[dry-run] Создал бы папку assets: $resourcepackAssets" + } else { + New-Item -ItemType Directory -Path $resourcepackAssets -Force | Out-Null + } +} + +$enRegex = '^assets/(?[^/]+)/lang/en_us\.json$' +$ruTemplate = 'assets/{0}/lang/ru_ru.json' + +$totalJars = 0 +$missingRuFound = 0 +$createdFiles = 0 +$skippedExisting = 0 +$errors = 0 + +foreach ($jar in Get-ChildItem -LiteralPath $modsDir -File -Filter "*.jar") { + $totalJars++ + $zip = $null + try { + $zip = [System.IO.Compression.ZipFile]::OpenRead($jar.FullName) + + $entryMap = @{} + foreach ($entry in $zip.Entries) { + $entryMap[$entry.FullName] = $entry + } + + foreach ($entry in $zip.Entries) { + $match = [System.Text.RegularExpressions.Regex]::Match($entry.FullName, $enRegex) + if (-not $match.Success) { + continue + } + + $modid = $match.Groups["modid"].Value + $ruPathInJar = $ruTemplate -f $modid + if ($entryMap.ContainsKey($ruPathInJar)) { + continue + } + + $missingRuFound++ + $destFile = Join-Path $resourcepackRoot $ruPathInJar + $destDir = Split-Path $destFile -Parent + + if ((Test-Path -LiteralPath $destFile) -and -not $Force) { + $skippedExisting++ + if ($DryRun) { + Write-Host "[dry-run] уже есть, пропуск: $ruPathInJar" + } + continue + } + + if ($DryRun) { + Write-Host "[dry-run] $($jar.Name): $($entry.FullName) -> $destFile" + $createdFiles++ + continue + } + + New-Item -ItemType Directory -Path $destDir -Force | Out-Null + + $srcStream = $null + $dstStream = $null + try { + $srcStream = $entry.Open() + $dstStream = [System.IO.File]::Create($destFile) + $srcStream.CopyTo($dstStream) + $createdFiles++ + } finally { + if ($null -ne $dstStream) { $dstStream.Dispose() } + if ($null -ne $srcStream) { $srcStream.Dispose() } + } + } + } catch { + $errors++ + Write-Warning ("Не удалось обработать jar: {0} ({1})" -f $jar.Name, $_.Exception.Message) + } finally { + if ($null -ne $zip) { + $zip.Dispose() + } + } +} + +Write-Host ("Проверено jar: {0}" -f $totalJars) +Write-Host ("Найдено en_us без ru_ru: {0}" -f $missingRuFound) +Write-Host ("Подготовлено файлов ru_ru: {0}" -f $createdFiles) +if ($skippedExisting -gt 0) { + Write-Host ("Пропущено (файл уже существует, без -Force): {0}" -f $skippedExisting) +} +if ($errors -gt 0) { + Write-Host ("Ошибок чтения jar: {0}" -f $errors) +}